diff --git a/.gitignore b/.gitignore
index cf2aea2e..f09cf88 100644
--- a/.gitignore
+++ b/.gitignore
@@ -149,6 +149,7 @@
 /components/cloud_policy_proto_generated_compile.xml
 /components/gcm_driver.xml
 /components/leveldb_proto_test_support.xml
+/components/ntp_tiles/resources/internal
 /components/rappor.xml
 /components/resources/default_100_percent/google_chrome
 /components/resources/default_200_percent/google_chrome
diff --git a/DEPS b/DEPS
index 5e3af81..15e6b53 100644
--- a/DEPS
+++ b/DEPS
@@ -232,7 +232,7 @@
     Var('chromium_git') + '/native_client/src/third_party/scons-2.0.1.git' + '@' + '1c1550e17fc26355d08627fbdec13d8291227067',
 
   'src/third_party/webrtc':
-    Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + '116ada2ed2aa98de38132699153eca6d646561eb', # commit position 16925
+    Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + 'c75ad4e9c0897ab3d4355872bd4a5c3702d7110e', # commit position 16937
 
   'src/third_party/openmax_dl':
     Var('chromium_git') + '/external/webrtc/deps/third_party/openmax.git' + '@' +  Var('openmax_dl_revision'),
@@ -406,10 +406,6 @@
     'src/third_party/cros_system_api':
       Var('chromium_git') + '/chromiumos/platform/system_api.git' + '@' + 'cc0eda812a8aaa665d4f26f5da74875284849bf6',
 
-    # Note that this is different from Android's freetype repo.
-    'src/third_party/freetype2/src':
-      Var('chromium_git') + '/chromium/src/third_party/freetype2.git' + '@' + Var('freetype_android_revision'),
-
     'src/third_party/freetype-android/src':
       Var('chromium_git') + '/chromium/src/third_party/freetype2.git' + '@' + Var('freetype_android_revision'),
 
diff --git a/android_webview/apk/java/AndroidManifest.xml b/android_webview/apk/java/AndroidManifest.xml
index 9c42594..1c7f6a0a 100644
--- a/android_webview/apk/java/AndroidManifest.xml
+++ b/android_webview/apk/java/AndroidManifest.xml
@@ -13,50 +13,56 @@
     </uses-sdk>
 
     <uses-feature android:name="android.hardware.touchscreen"
-            android:required="false"/>
+                  android:required="false"/>
 
     <uses-permission android:name="android.permission.INTERNET"/>
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
 
     <application android:label="Android System WebView"
-        android:icon="@drawable/icon_webview"
-        android:multiArch="true"
-        android:use32bitAbi="true">
+                 android:icon="@drawable/icon_webview"
+                 android:multiArch="true"
+                 android:use32bitAbi="true">
         {# This part is shared between stand-alone WebView and Monochrome #}
         {% macro common(manifest_package, webview_lib) %}
-            <activity android:name="com.android.webview.chromium.LicenseActivity"
-                    android:label="@string/license_activity_title">
-                <intent-filter>
-                    <action android:name="android.settings.WEBVIEW_LICENSE" />
-                    <category android:name="android.intent.category.DEFAULT" />
-                </intent-filter>
-                <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
-                        android:value="true" />
-            </activity>
-            <provider android:name="com.android.webview.chromium.LicenseContentProvider"
-                    android:exported="true"
-                    android:authorities="{{ manifest_package }}.LicenseContentProvider" />
             <meta-data android:name="com.android.webview.WebViewLibrary"
-                    android:value="{{ webview_lib }}" />
-            <service android:name="org.chromium.android_webview.crash.CrashReceiverService"
-                     android:exported="true"
-                     android:process=":crash_receiver_service"/>
-            <service android:name="org.chromium.android_webview.crash.AwMinidumpUploadJobService"
-                     android:permission="android.permission.BIND_JOB_SERVICE"
-                     android:exported="true"
-                     android:process=":crash_receiver_service"/>
+                       android:value="{{ webview_lib }}" />
+            {% if donor_package is not defined %}
+                <activity android:name="com.android.webview.chromium.LicenseActivity"
+                          android:label="@string/license_activity_title">
+                    <intent-filter>
+                        <action android:name="android.settings.WEBVIEW_LICENSE" />
+                        <category android:name="android.intent.category.DEFAULT" />
+                    </intent-filter>
+                    <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
+                               android:value="true" />
+                </activity>
+                <provider android:name="com.android.webview.chromium.LicenseContentProvider"
+                          android:exported="true"
+                          android:authorities="{{ manifest_package }}.LicenseContentProvider" />
+                <service android:name="org.chromium.android_webview.crash.CrashReceiverService"
+                         android:exported="true"
+                         android:process=":crash_receiver_service"/>
+                <service android:name="org.chromium.android_webview.crash.AwMinidumpUploadJobService"
+                         android:permission="android.permission.BIND_JOB_SERVICE"
+                         android:exported="true"
+                         android:process=":crash_receiver_service"/>
+            {% endif %}
         {% endmacro %}
-        {{ common(package|default('com.android.webview'), 'libwebviewchromium.so') }}
+        {{ common(package|default('com.android.webview'), library|default('libwebviewchromium.so')) }}
+        {% if donor_package is defined %}
+            <meta-data android:name="com.android.webview.WebViewDonorPackage"
+                       android:value="{{ donor_package }}" />
+        {% endif %}
         {% set num_sandboxed_services = 20 %}
         <meta-data android:name="org.chromium.content.browser.NUM_SANDBOXED_SERVICES"
                    android:value="{{ num_sandboxed_services }}"/>
         {% for i in range(num_sandboxed_services) %}
-        <service android:name="org.chromium.content.app.SandboxedProcessService{{ i }}"
-                 android:process=":sandboxed_process{{ i }}"
-                 android:isolatedProcess="true"
-                 android:exported="true"
-                 android:externalService="true"
-                 tools:ignore="ExportedService" />
+            <service android:name="org.chromium.content.app.SandboxedProcessService{{ i }}"
+                     android:process=":sandboxed_process{{ i }}"
+                     android:isolatedProcess="true"
+                     android:exported="true"
+                     android:externalService="true"
+                     tools:ignore="ExportedService" />
         {% endfor %}
         <meta-data android:name="org.chromium.content.browser.NUM_PRIVILEGED_SERVICES"
                    android:value="0"/>
diff --git a/base/allocator/allocator_shim.cc b/base/allocator/allocator_shim.cc
index 48b1350..7a5cfd6 100644
--- a/base/allocator/allocator_shim.cc
+++ b/base/allocator/allocator_shim.cc
@@ -142,8 +142,10 @@
 }  // namespace base
 
 // The Shim* functions below are the entry-points into the shim-layer and
-// are supposed to be invoked / aliased by the allocator_shim_override_*
+// are supposed to be invoked by the allocator_shim_override_*
 // headers to route the malloc / new symbols through the shim layer.
+// They are defined as ALWAYS_INLINE in order to remove a level of indirection
+// between the system-defined entry points and the shim implementations.
 extern "C" {
 
 // The general pattern for allocations is:
@@ -158,7 +160,7 @@
 //       just suicide priting a message).
 //     - Assume it did succeed if it returns, in which case reattempt the alloc.
 
-void* ShimCppNew(size_t size) {
+ALWAYS_INLINE void* ShimCppNew(size_t size) {
   const allocator::AllocatorDispatch* const chain_head = GetChainHead();
   void* ptr;
   do {
@@ -171,7 +173,7 @@
   return ptr;
 }
 
-void ShimCppDelete(void* address) {
+ALWAYS_INLINE void ShimCppDelete(void* address) {
   void* context = nullptr;
 #if defined(OS_MACOSX)
   context = malloc_default_zone();
@@ -180,7 +182,7 @@
   return chain_head->free_function(chain_head, address, context);
 }
 
-void* ShimMalloc(size_t size, void* context) {
+ALWAYS_INLINE void* ShimMalloc(size_t size, void* context) {
   const allocator::AllocatorDispatch* const chain_head = GetChainHead();
   void* ptr;
   do {
@@ -190,7 +192,7 @@
   return ptr;
 }
 
-void* ShimCalloc(size_t n, size_t size, void* context) {
+ALWAYS_INLINE void* ShimCalloc(size_t n, size_t size, void* context) {
   const allocator::AllocatorDispatch* const chain_head = GetChainHead();
   void* ptr;
   do {
@@ -201,7 +203,7 @@
   return ptr;
 }
 
-void* ShimRealloc(void* address, size_t size, void* context) {
+ALWAYS_INLINE void* ShimRealloc(void* address, size_t size, void* context) {
   // realloc(size == 0) means free() and might return a nullptr. We should
   // not call the std::new_handler in that case, though.
   const allocator::AllocatorDispatch* const chain_head = GetChainHead();
@@ -213,7 +215,7 @@
   return ptr;
 }
 
-void* ShimMemalign(size_t alignment, size_t size, void* context) {
+ALWAYS_INLINE void* ShimMemalign(size_t alignment, size_t size, void* context) {
   const allocator::AllocatorDispatch* const chain_head = GetChainHead();
   void* ptr;
   do {
@@ -224,7 +226,7 @@
   return ptr;
 }
 
-int ShimPosixMemalign(void** res, size_t alignment, size_t size) {
+ALWAYS_INLINE int ShimPosixMemalign(void** res, size_t alignment, size_t size) {
   // posix_memalign is supposed to check the arguments. See tc_posix_memalign()
   // in tc_malloc.cc.
   if (((alignment % sizeof(void*)) != 0) ||
@@ -236,11 +238,11 @@
   return ptr ? 0 : ENOMEM;
 }
 
-void* ShimValloc(size_t size, void* context) {
+ALWAYS_INLINE void* ShimValloc(size_t size, void* context) {
   return ShimMemalign(GetCachedPageSize(), size, context);
 }
 
-void* ShimPvalloc(size_t size) {
+ALWAYS_INLINE void* ShimPvalloc(size_t size) {
   // pvalloc(0) should allocate one page, according to its man page.
   if (size == 0) {
     size = GetCachedPageSize();
@@ -252,35 +254,35 @@
   return ShimMemalign(GetCachedPageSize(), size, nullptr);
 }
 
-void ShimFree(void* address, void* context) {
+ALWAYS_INLINE void ShimFree(void* address, void* context) {
   const allocator::AllocatorDispatch* const chain_head = GetChainHead();
   return chain_head->free_function(chain_head, address, context);
 }
 
-size_t ShimGetSizeEstimate(const void* address, void* context) {
+ALWAYS_INLINE size_t ShimGetSizeEstimate(const void* address, void* context) {
   const allocator::AllocatorDispatch* const chain_head = GetChainHead();
   return chain_head->get_size_estimate_function(
       chain_head, const_cast<void*>(address), context);
 }
 
-unsigned ShimBatchMalloc(size_t size,
-                         void** results,
-                         unsigned num_requested,
-                         void* context) {
+ALWAYS_INLINE unsigned ShimBatchMalloc(size_t size,
+                                       void** results,
+                                       unsigned num_requested,
+                                       void* context) {
   const allocator::AllocatorDispatch* const chain_head = GetChainHead();
   return chain_head->batch_malloc_function(chain_head, size, results,
                                            num_requested, context);
 }
 
-void ShimBatchFree(void** to_be_freed,
-                   unsigned num_to_be_freed,
-                   void* context) {
+ALWAYS_INLINE void ShimBatchFree(void** to_be_freed,
+                                 unsigned num_to_be_freed,
+                                 void* context) {
   const allocator::AllocatorDispatch* const chain_head = GetChainHead();
   return chain_head->batch_free_function(chain_head, to_be_freed,
                                          num_to_be_freed, context);
 }
 
-void ShimFreeDefiniteSize(void* ptr, size_t size, void* context) {
+ALWAYS_INLINE void ShimFreeDefiniteSize(void* ptr, size_t size, void* context) {
   const allocator::AllocatorDispatch* const chain_head = GetChainHead();
   return chain_head->free_definite_size_function(chain_head, ptr, size,
                                                  context);
diff --git a/base/allocator/allocator_shim_internals.h b/base/allocator/allocator_shim_internals.h
index fc3624c..82624ee 100644
--- a/base/allocator/allocator_shim_internals.h
+++ b/base/allocator/allocator_shim_internals.h
@@ -20,8 +20,6 @@
 // Shim layer symbols need to be ALWAYS exported, regardless of component build.
 #define SHIM_ALWAYS_EXPORT __attribute__((visibility("default")))
 
-#define SHIM_ALIAS_SYMBOL(fn) __attribute__((alias(#fn)))
-
 #endif  // __GNUC__
 
 #endif  // BASE_ALLOCATOR_ALLOCATOR_SHIM_INTERNALS_H_
diff --git a/base/allocator/allocator_shim_override_cpp_symbols.h b/base/allocator/allocator_shim_override_cpp_symbols.h
index 616716fb..3313687 100644
--- a/base/allocator/allocator_shim_override_cpp_symbols.h
+++ b/base/allocator/allocator_shim_override_cpp_symbols.h
@@ -7,36 +7,45 @@
 #endif
 #define BASE_ALLOCATOR_ALLOCATOR_SHIM_OVERRIDE_CPP_SYMBOLS_H_
 
-// Alias the default new/delete C++ symbols to the shim entry points.
-// This file is strongly inspired by tcmalloc's libc_override_redefine.h.
+// Preempt the default new/delete C++ symbols so they call the shim entry
+// points. This file is strongly inspired by tcmalloc's
+// libc_override_redefine.h.
 
 #include <new>
 
 #include "base/allocator/allocator_shim_internals.h"
 
-SHIM_ALWAYS_EXPORT void* operator new(size_t size)
-    SHIM_ALIAS_SYMBOL(ShimCppNew);
+SHIM_ALWAYS_EXPORT void* operator new(size_t size) {
+  return ShimCppNew(size);
+}
 
-SHIM_ALWAYS_EXPORT void operator delete(void* p) __THROW
-    SHIM_ALIAS_SYMBOL(ShimCppDelete);
+SHIM_ALWAYS_EXPORT void operator delete(void* p) __THROW {
+  ShimCppDelete(p);
+}
 
-SHIM_ALWAYS_EXPORT void* operator new[](size_t size)
-    SHIM_ALIAS_SYMBOL(ShimCppNew);
+SHIM_ALWAYS_EXPORT void* operator new[](size_t size) {
+  return ShimCppNew(size);
+}
 
-SHIM_ALWAYS_EXPORT void operator delete[](void* p) __THROW
-    SHIM_ALIAS_SYMBOL(ShimCppDelete);
+SHIM_ALWAYS_EXPORT void operator delete[](void* p) __THROW {
+  ShimCppDelete(p);
+}
 
 SHIM_ALWAYS_EXPORT void* operator new(size_t size,
-                                      const std::nothrow_t&) __THROW
-    SHIM_ALIAS_SYMBOL(ShimCppNew);
+                                      const std::nothrow_t&) __THROW {
+  return ShimCppNew(size);
+}
 
 SHIM_ALWAYS_EXPORT void* operator new[](size_t size,
-                                        const std::nothrow_t&) __THROW
-    SHIM_ALIAS_SYMBOL(ShimCppNew);
+                                        const std::nothrow_t&) __THROW {
+  return ShimCppNew(size);
+}
 
-SHIM_ALWAYS_EXPORT void operator delete(void* p, const std::nothrow_t&) __THROW
-    SHIM_ALIAS_SYMBOL(ShimCppDelete);
+SHIM_ALWAYS_EXPORT void operator delete(void* p, const std::nothrow_t&) __THROW {
+  ShimCppDelete(p);
+}
 
 SHIM_ALWAYS_EXPORT void operator delete[](void* p,
-                                          const std::nothrow_t&) __THROW
-    SHIM_ALIAS_SYMBOL(ShimCppDelete);
+                                          const std::nothrow_t&) __THROW {
+  ShimCppDelete(p);
+}
diff --git a/base/allocator/allocator_shim_override_glibc_weak_symbols.h b/base/allocator/allocator_shim_override_glibc_weak_symbols.h
index a0b46183..b1296369 100644
--- a/base/allocator/allocator_shim_override_glibc_weak_symbols.h
+++ b/base/allocator/allocator_shim_override_glibc_weak_symbols.h
@@ -76,30 +76,41 @@
 
 // 2) Redefine libc symbols themselves.
 
-SHIM_ALWAYS_EXPORT void* __libc_malloc(size_t size)
-    SHIM_ALIAS_SYMBOL(ShimMalloc);
+SHIM_ALWAYS_EXPORT void* __libc_malloc(size_t size) {
+  return ShimMalloc(size, nullptr);
+}
 
-SHIM_ALWAYS_EXPORT void __libc_free(void* ptr) SHIM_ALIAS_SYMBOL(ShimFree);
+SHIM_ALWAYS_EXPORT void __libc_free(void* ptr) {
+  ShimFree(ptr, nullptr);
+}
 
-SHIM_ALWAYS_EXPORT void* __libc_realloc(void* ptr, size_t size)
-    SHIM_ALIAS_SYMBOL(ShimRealloc);
+SHIM_ALWAYS_EXPORT void* __libc_realloc(void* ptr, size_t size) {
+  return ShimRealloc(ptr, size, nullptr);
+}
 
-SHIM_ALWAYS_EXPORT void* __libc_calloc(size_t n, size_t size)
-    SHIM_ALIAS_SYMBOL(ShimCalloc);
+SHIM_ALWAYS_EXPORT void* __libc_calloc(size_t n, size_t size) {
+  return ShimCalloc(n, size, nullptr);
+}
 
-SHIM_ALWAYS_EXPORT void __libc_cfree(void* ptr) SHIM_ALIAS_SYMBOL(ShimFree);
+SHIM_ALWAYS_EXPORT void __libc_cfree(void* ptr) {
+  return ShimFree(ptr, nullptr);
+}
 
-SHIM_ALWAYS_EXPORT void* __libc_memalign(size_t align, size_t s)
-    SHIM_ALIAS_SYMBOL(ShimMemalign);
+SHIM_ALWAYS_EXPORT void* __libc_memalign(size_t align, size_t s) {
+  return ShimMemalign(align, s, nullptr);
+}
 
-SHIM_ALWAYS_EXPORT void* __libc_valloc(size_t size)
-    SHIM_ALIAS_SYMBOL(ShimValloc);
+SHIM_ALWAYS_EXPORT void* __libc_valloc(size_t size) {
+  return ShimValloc(size, nullptr);
+}
 
-SHIM_ALWAYS_EXPORT void* __libc_pvalloc(size_t size)
-    SHIM_ALIAS_SYMBOL(ShimPvalloc);
+SHIM_ALWAYS_EXPORT void* __libc_pvalloc(size_t size) {
+  return ShimPvalloc(size);
+}
 
-SHIM_ALWAYS_EXPORT int __posix_memalign(void** r, size_t a, size_t s)
-    SHIM_ALIAS_SYMBOL(ShimPosixMemalign);
+SHIM_ALWAYS_EXPORT int __posix_memalign(void** r, size_t a, size_t s) {
+  return ShimPosixMemalign(r, a, s);
+}
 
 }  // extern "C"
 
diff --git a/base/allocator/allocator_shim_override_libc_symbols.h b/base/allocator/allocator_shim_override_libc_symbols.h
index 37b3b4eb..b77cbb1 100644
--- a/base/allocator/allocator_shim_override_libc_symbols.h
+++ b/base/allocator/allocator_shim_override_libc_symbols.h
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// Its purpose is to SHIM_ALIAS_SYMBOL the Libc symbols for malloc/new to the
+// Its purpose is to preempt the Libc symbols for malloc/new so they call the
 // shim layer entry points.
 
 #ifdef BASE_ALLOCATOR_ALLOCATOR_SHIM_OVERRIDE_LIBC_SYMBOLS_H_
@@ -16,32 +16,41 @@
 
 extern "C" {
 
-SHIM_ALWAYS_EXPORT void* malloc(size_t size) __THROW
-    SHIM_ALIAS_SYMBOL(ShimMalloc);
+SHIM_ALWAYS_EXPORT void* malloc(size_t size) __THROW {
+  return ShimMalloc(size, nullptr);
+}
 
-SHIM_ALWAYS_EXPORT void free(void* ptr) __THROW
-    SHIM_ALIAS_SYMBOL(ShimFree);
+SHIM_ALWAYS_EXPORT void free(void* ptr) __THROW {
+  ShimFree(ptr, nullptr);
+}
 
-SHIM_ALWAYS_EXPORT void* realloc(void* ptr, size_t size) __THROW
-    SHIM_ALIAS_SYMBOL(ShimRealloc);
+SHIM_ALWAYS_EXPORT void* realloc(void* ptr, size_t size) __THROW {
+  return ShimRealloc(ptr, size, nullptr);
+}
 
-SHIM_ALWAYS_EXPORT void* calloc(size_t n, size_t size) __THROW
-    SHIM_ALIAS_SYMBOL(ShimCalloc);
+SHIM_ALWAYS_EXPORT void* calloc(size_t n, size_t size) __THROW {
+  return ShimCalloc(n, size, nullptr);
+}
 
-SHIM_ALWAYS_EXPORT void cfree(void* ptr) __THROW
-    SHIM_ALIAS_SYMBOL(ShimFree);
+SHIM_ALWAYS_EXPORT void cfree(void* ptr) __THROW {
+  ShimFree(ptr, nullptr);
+}
 
-SHIM_ALWAYS_EXPORT void* memalign(size_t align, size_t s) __THROW
-    SHIM_ALIAS_SYMBOL(ShimMemalign);
+SHIM_ALWAYS_EXPORT void* memalign(size_t align, size_t s) __THROW {
+  return ShimMemalign(align, s, nullptr);
+}
 
-SHIM_ALWAYS_EXPORT void* valloc(size_t size) __THROW
-    SHIM_ALIAS_SYMBOL(ShimValloc);
+SHIM_ALWAYS_EXPORT void* valloc(size_t size) __THROW {
+  return ShimValloc(size, nullptr);
+}
 
-SHIM_ALWAYS_EXPORT void* pvalloc(size_t size) __THROW
-    SHIM_ALIAS_SYMBOL(ShimPvalloc);
+SHIM_ALWAYS_EXPORT void* pvalloc(size_t size) __THROW {
+  return ShimPvalloc(size);
+}
 
-SHIM_ALWAYS_EXPORT int posix_memalign(void** r, size_t a, size_t s) __THROW
-    SHIM_ALIAS_SYMBOL(ShimPosixMemalign);
+SHIM_ALWAYS_EXPORT int posix_memalign(void** r, size_t a, size_t s) __THROW {
+  return ShimPosixMemalign(r, a, s);
+}
 
 // The default dispatch translation unit has to define also the following
 // symbols (unless they are ultimately routed to the system symbols):
diff --git a/base/allocator/allocator_shim_override_linker_wrapped_symbols.h b/base/allocator/allocator_shim_override_linker_wrapped_symbols.h
index 5b85d6e..6bf73c3 100644
--- a/base/allocator/allocator_shim_override_linker_wrapped_symbols.h
+++ b/base/allocator/allocator_shim_override_linker_wrapped_symbols.h
@@ -17,28 +17,38 @@
 
 extern "C" {
 
-SHIM_ALWAYS_EXPORT void* __wrap_calloc(size_t, size_t)
-    SHIM_ALIAS_SYMBOL(ShimCalloc);
+SHIM_ALWAYS_EXPORT void* __wrap_calloc(size_t n, size_t size) {
+  return ShimCalloc(n, size, nullptr);
+}
 
-SHIM_ALWAYS_EXPORT void __wrap_free(void*)
-    SHIM_ALIAS_SYMBOL(ShimFree);
+SHIM_ALWAYS_EXPORT void __wrap_free(void* ptr) {
+  ShimFree(ptr, nullptr);
+}
 
-SHIM_ALWAYS_EXPORT void* __wrap_malloc(size_t)
-    SHIM_ALIAS_SYMBOL(ShimMalloc);
+SHIM_ALWAYS_EXPORT void* __wrap_malloc(size_t size) {
+  return ShimMalloc(size, nullptr);
+}
 
-SHIM_ALWAYS_EXPORT void* __wrap_memalign(size_t, size_t)
-    SHIM_ALIAS_SYMBOL(ShimMemalign);
+SHIM_ALWAYS_EXPORT void* __wrap_memalign(size_t align, size_t size) {
+  return ShimMemalign(align, size, nullptr);
+}
 
-SHIM_ALWAYS_EXPORT int __wrap_posix_memalign(void**, size_t, size_t)
-    SHIM_ALIAS_SYMBOL(ShimPosixMemalign);
+SHIM_ALWAYS_EXPORT int __wrap_posix_memalign(void** res,
+                                             size_t align,
+                                             size_t size) {
+  return ShimPosixMemalign(res, align, size);
+}
 
-SHIM_ALWAYS_EXPORT void* __wrap_pvalloc(size_t)
-    SHIM_ALIAS_SYMBOL(ShimPvalloc);
+SHIM_ALWAYS_EXPORT void* __wrap_pvalloc(size_t size) {
+  return ShimPvalloc(size);
+}
 
-SHIM_ALWAYS_EXPORT void* __wrap_realloc(void*, size_t)
-    SHIM_ALIAS_SYMBOL(ShimRealloc);
+SHIM_ALWAYS_EXPORT void* __wrap_realloc(void* address, size_t size) {
+  return ShimRealloc(address, size, nullptr);
+}
 
-SHIM_ALWAYS_EXPORT void* __wrap_valloc(size_t)
-    SHIM_ALIAS_SYMBOL(ShimValloc);
+SHIM_ALWAYS_EXPORT void* __wrap_valloc(size_t size) {
+  return ShimValloc(size, nullptr);
+}
 
 }  // extern "C"
diff --git a/base/trace_event/memory_dump_manager.cc b/base/trace_event/memory_dump_manager.cc
index f86b9e9..31016f9 100644
--- a/base/trace_event/memory_dump_manager.cc
+++ b/base/trace_event/memory_dump_manager.cc
@@ -156,6 +156,7 @@
 
 MemoryDumpManager::MemoryDumpManager()
     : delegate_(nullptr),
+      is_coordinator_(false),
       memory_tracing_enabled_(0),
       tracing_process_id_(kInvalidTracingProcessId),
       dumper_registrations_ignored_for_testing_(false),
@@ -213,12 +214,14 @@
   heap_profiling_enabled_ = true;
 }
 
-void MemoryDumpManager::Initialize(MemoryDumpManagerDelegate* delegate) {
+void MemoryDumpManager::Initialize(MemoryDumpManagerDelegate* delegate,
+                                   bool is_coordinator) {
   {
     AutoLock lock(lock_);
     DCHECK(delegate);
     DCHECK(!delegate_);
     delegate_ = delegate;
+    is_coordinator_ = is_coordinator;
     EnableHeapProfilingIfNeeded();
   }
 
@@ -457,10 +460,21 @@
                                     TRACE_ID_MANGLE(guid));
   MemoryDumpCallback wrapped_callback = Bind(&OnGlobalDumpDone, callback);
 
+  // Technically there is no need to grab the |lock_| here as the delegate is
+  // long-lived and can only be set by Initialize(), which is locked and
+  // necessarily happens before memory_tracing_enabled_ == true.
+  // Not taking the |lock_|, though, is lakely make TSan barf and, at this point
+  // (memory-infra is enabled) we're not in the fast-path anymore.
+  MemoryDumpManagerDelegate* delegate;
+  {
+    AutoLock lock(lock_);
+    delegate = delegate_;
+  }
+
   // The delegate will coordinate the IPC broadcast and at some point invoke
   // CreateProcessDump() to get a dump for the current process.
   MemoryDumpRequestArgs args = {guid, dump_type, level_of_detail};
-  delegate_->RequestGlobalMemoryDump(args, wrapped_callback);
+  delegate->RequestGlobalMemoryDump(args, wrapped_callback);
 }
 
 void MemoryDumpManager::RequestGlobalDump(
@@ -848,7 +862,7 @@
       dump_scheduler_->NotifyPollingSupported();
 
     // Only coordinator process triggers periodic global memory dumps.
-    if (delegate_->IsCoordinator())
+    if (is_coordinator_)
       dump_scheduler_->NotifyPeriodicTriggerSupported();
   }
 
@@ -893,6 +907,10 @@
   return session_state_->IsDumpModeAllowed(dump_mode);
 }
 
+uint64_t MemoryDumpManager::GetTracingProcessId() const {
+  return delegate_->GetTracingProcessId();
+}
+
 MemoryDumpManager::MemoryDumpProviderInfo::MemoryDumpProviderInfo(
     MemoryDumpProvider* dump_provider,
     const char* name,
diff --git a/base/trace_event/memory_dump_manager.h b/base/trace_event/memory_dump_manager.h
index c1f565c..92cc2f4 100644
--- a/base/trace_event/memory_dump_manager.h
+++ b/base/trace_event/memory_dump_manager.h
@@ -22,14 +22,6 @@
 #include "base/trace_event/process_memory_dump.h"
 #include "base/trace_event/trace_event.h"
 
-// Forward declare |MemoryDumpManagerDelegateImplTest| so that we can make it a
-// friend of |MemoryDumpManager| and give it access to |SetInstanceForTesting|.
-namespace memory_instrumentation {
-
-class MemoryDumpManagerDelegateImplTest;
-
-}  // namespace memory_instrumentation
-
 namespace base {
 
 class SingleThreadTaskRunner;
@@ -62,10 +54,13 @@
   // On the other side, the MemoryDumpManager will not be fully operational
   // (i.e. will NACK any RequestGlobalMemoryDump()) until initialized.
   // Arguments:
+  //  is_coordinator: if true this MemoryDumpManager instance will act as a
+  //      coordinator and schedule periodic dumps (if enabled via TraceConfig);
+  //      false when the MemoryDumpManager is initialized in a slave process.
   //  delegate: inversion-of-control interface for embedder-specific behaviors
   //      (multiprocess handshaking). See the lifetime and thread-safety
   //      requirements in the |MemoryDumpManagerDelegate| docstring.
-  void Initialize(MemoryDumpManagerDelegate* delegate);
+  void Initialize(MemoryDumpManagerDelegate* delegate, bool is_coordinator);
 
   // (Un)Registers a MemoryDumpProvider instance.
   // Args:
@@ -140,10 +135,7 @@
   // retrieved by child processes only when tracing is enabled. This is
   // intended to express cross-process sharing of memory dumps on the
   // child-process side, without having to know its own child process id.
-  uint64_t GetTracingProcessId() const { return tracing_process_id_; }
-  void set_tracing_process_id(uint64_t tracing_process_id) {
-    tracing_process_id_ = tracing_process_id;
-  }
+  uint64_t GetTracingProcessId() const;
 
   // Returns the name for a the allocated_objects dump. Use this to declare
   // suballocator dumps from other dump providers.
@@ -164,7 +156,6 @@
   friend class MemoryDumpManagerDelegate;
   friend class MemoryDumpManagerTest;
   friend class MemoryDumpScheduler;
-  friend class memory_instrumentation::MemoryDumpManagerDelegateImplTest;
 
   // Descriptor used to hold information about registered MDPs.
   // Some important considerations about lifetime of this object:
@@ -359,6 +350,9 @@
 
   MemoryDumpManagerDelegate* delegate_;  // Not owned.
 
+  // When true, this instance is in charge of coordinating periodic dumps.
+  bool is_coordinator_;
+
   // Protects from concurrent accesses to the |dump_providers_*| and |delegate_|
   // to guard against disabling logging while dumping on another thread.
   Lock lock_;
@@ -394,7 +388,9 @@
   virtual void RequestGlobalMemoryDump(const MemoryDumpRequestArgs& args,
                                        const MemoryDumpCallback& callback) = 0;
 
-  virtual bool IsCoordinator() const = 0;
+  // Returns tracing process id of the current process. This is used by
+  // MemoryDumpManager::GetTracingProcessId.
+  virtual uint64_t GetTracingProcessId() const = 0;
 
  protected:
   MemoryDumpManagerDelegate() {}
diff --git a/base/trace_event/memory_dump_manager_unittest.cc b/base/trace_event/memory_dump_manager_unittest.cc
index 330c75d..51d4194 100644
--- a/base/trace_event/memory_dump_manager_unittest.cc
+++ b/base/trace_event/memory_dump_manager_unittest.cc
@@ -119,8 +119,7 @@
 // requests locally to the MemoryDumpManager instead of performing IPC dances.
 class MemoryDumpManagerDelegateForTesting : public MemoryDumpManagerDelegate {
  public:
-  MemoryDumpManagerDelegateForTesting(bool is_coordinator)
-      : is_coordinator_(is_coordinator) {
+  MemoryDumpManagerDelegateForTesting() {
     ON_CALL(*this, RequestGlobalMemoryDump(_, _))
         .WillByDefault(Invoke(
             this, &MemoryDumpManagerDelegateForTesting::CreateProcessDump));
@@ -130,13 +129,13 @@
                void(const MemoryDumpRequestArgs& args,
                     const MemoryDumpCallback& callback));
 
-  bool IsCoordinator() const override { return is_coordinator_; }
+  uint64_t GetTracingProcessId() const override {
+    NOTREACHED();
+    return MemoryDumpManager::kInvalidTracingProcessId;
+  }
 
   // Promote the CreateProcessDump to public so it can be used by test fixtures.
   using MemoryDumpManagerDelegate::CreateProcessDump;
-
- private:
-  bool is_coordinator_;
 };
 
 class MockMemoryDumpProvider : public MemoryDumpProvider {
@@ -221,12 +220,13 @@
     mdm_.reset(new MemoryDumpManager());
     MemoryDumpManager::SetInstanceForTesting(mdm_.get());
     ASSERT_EQ(mdm_.get(), MemoryDumpManager::GetInstance());
+    delegate_.reset(new MemoryDumpManagerDelegateForTesting);
   }
 
   void TearDown() override {
     MemoryDumpManager::SetInstanceForTesting(nullptr);
-    delegate_.reset();
     mdm_.reset();
+    delegate_.reset();
     message_loop_.reset();
     TraceLog::DeleteForTesting();
   }
@@ -248,8 +248,7 @@
  protected:
   void InitializeMemoryDumpManager(bool is_coordinator) {
     mdm_->set_dumper_registrations_ignored_for_testing(true);
-    delegate_.reset(new MemoryDumpManagerDelegateForTesting(is_coordinator));
-    mdm_->Initialize(delegate_.get());
+    mdm_->Initialize(delegate_.get(), is_coordinator);
   }
 
   void RequestGlobalDumpAndWait(MemoryDumpType dump_type,
@@ -898,6 +897,7 @@
   // initialization gets NACK-ed cleanly.
   {
     EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0);
+    EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)).Times(0);
     RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
                              MemoryDumpLevelOfDetail::DETAILED);
     EXPECT_FALSE(last_callback_success_);
@@ -906,9 +906,9 @@
   // Now late-initialize the MemoryDumpManager and check that the
   // RequestGlobalDump completes successfully.
   {
-    InitializeMemoryDumpManager(false /* is_coordinator */);
     EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(1);
     EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)).Times(1);
+    InitializeMemoryDumpManager(false /* is_coordinator */);
     RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
                              MemoryDumpLevelOfDetail::DETAILED);
     EXPECT_TRUE(last_callback_success_);
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni
index 1bfb3217..c265b569 100644
--- a/build/config/android/rules.gni
+++ b/build/config/android/rules.gni
@@ -1464,6 +1464,9 @@
   #   testonly: Marks this target as "test-only".
   #   write_asset_list: Adds an extra file to the assets, which contains a list of
   #     all other asset files.
+  #   generate_buildconfig_java: If defined and false, skip generating the
+  #     BuildConfig java class describing the build configuration. The default
+  #     is true for non-test APKs.
   #   requires_sdk_api_level_23: If defined and true, the apk is intended for
   #     installation only on Android M or later. In these releases the system
   #     linker does relocation unpacking, so we can enable it unconditionally.
@@ -1675,6 +1678,10 @@
         defined(invoker.create_density_splits) && invoker.create_density_splits
     _create_language_splits =
         defined(invoker.language_splits) && invoker.language_splits != []
+    _generate_buildconfig_java = !defined(invoker.apk_under_test)
+    if (defined(invoker.generate_buildconfig_java)) {
+      _generate_buildconfig_java = invoker.generate_buildconfig_java
+    }
 
     # Help GN understand that _create_abi_split is not unused (bug in GN).
     assert(_create_abi_split || true)
@@ -1835,7 +1842,7 @@
       _srcjar_deps += [ ":${_template_name}__native_libraries_java" ]
     }
 
-    if (!defined(invoker.apk_under_test)) {
+    if (_generate_buildconfig_java) {
       java_cpp_template("${_template_name}__build_config_java") {
         package_name = "org/chromium/base"
         sources = [
diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc
index dd900f8..f5b71710 100644
--- a/cc/resources/resource_provider.cc
+++ b/cc/resources/resource_provider.cc
@@ -37,7 +37,6 @@
 #include "third_party/skia/include/core/SkCanvas.h"
 #include "third_party/skia/include/core/SkSurface.h"
 #include "third_party/skia/include/gpu/GrContext.h"
-#include "third_party/skia/include/gpu/GrTextureProvider.h"
 #include "third_party/skia/include/gpu/gl/GrGLTypes.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/vector2d.h"
diff --git a/cc/tiles/gpu_image_decode_cache.cc b/cc/tiles/gpu_image_decode_cache.cc
index d5b3148d4..735afc7f 100644
--- a/cc/tiles/gpu_image_decode_cache.cc
+++ b/cc/tiles/gpu_image_decode_cache.cc
@@ -29,7 +29,6 @@
 #include "third_party/skia/include/core/SkRefCnt.h"
 #include "third_party/skia/include/core/SkSurface.h"
 #include "third_party/skia/include/gpu/GrContext.h"
-#include "third_party/skia/include/gpu/GrTexture.h"
 #include "ui/gfx/skia_util.h"
 #include "ui/gl/trace_util.h"
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaSessionTabHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaSessionTabHelper.java
index 80b942e..e6a0c87 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaSessionTabHelper.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaSessionTabHelper.java
@@ -300,7 +300,6 @@
                                 + "Using the full URL instead.");
             }
 
-            if (mOrigin != null && mOrigin.equals(origin)) return;
             mOrigin = origin;
             mFavicon = null;
             mPageMediaImage = null;
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni
index edf02fec..9dfc055 100644
--- a/chrome/android/java_sources.gni
+++ b/chrome/android/java_sources.gni
@@ -1345,6 +1345,7 @@
   "javatests/src/org/chromium/chrome/browser/media/router/MockMediaRouteProvider.java",
   "javatests/src/org/chromium/chrome/browser/media/ui/AutoplayMutedNotificationTest.java",
   "javatests/src/org/chromium/chrome/browser/media/ui/NotificationActionsUpdatedTest.java",
+  "javatests/src/org/chromium/chrome/browser/media/ui/NotificationTestUtils.java",
   "javatests/src/org/chromium/chrome/browser/media/ui/NotificationTitleUpdatedTest.java",
   "javatests/src/org/chromium/chrome/browser/media/ui/PauseOnHeadsetUnplugTest.java",
   "javatests/src/org/chromium/chrome/browser/metrics/PageLoadMetricsTest.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/media/ui/NotificationActionsUpdatedTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/media/ui/NotificationActionsUpdatedTest.java
index 105203e8..3660c91 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/media/ui/NotificationActionsUpdatedTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/media/ui/NotificationActionsUpdatedTest.java
@@ -28,7 +28,7 @@
  */
 public class NotificationActionsUpdatedTest extends ChromeActivityTestCaseBase<ChromeActivity> {
     private static final int NOTIFICATION_ID = R.id.media_playback_notification;
-    private static final String SIMPLE_PAGE_URL = "/simple_page.html";
+    private static final String SIMPLE_PAGE_URL = "/content/test/data/simple_page.html";
 
     private Tab mTab;
     private EmbeddedTestServer mTestServer;
@@ -75,14 +75,15 @@
     }
 
     @SmallTest
-    public void testActionsPersistAfterInPageNavigation() throws Throwable {
+    public void testActionsPersistAfterSamePageNavigation() throws Throwable {
         ensureTestServer();
         loadUrl(mTestServer.getURL(SIMPLE_PAGE_URL));
         simulateMediaSessionActionsChanged(mTab, buildActions());
         simulateMediaSessionStateChanged(mTab, true, false);
         assertActionsMatch(buildActions());
 
-        loadUrl(mTestServer.getURL(SIMPLE_PAGE_URL + "#some-anchor"));
+        NotificationTestUtils.simulateSamePageNavigation(
+                getInstrumentation(), mTab, mTestServer.getURL(SIMPLE_PAGE_URL));
         assertActionsMatch(buildActions());
     }
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/media/ui/NotificationTestUtils.java b/chrome/android/javatests/src/org/chromium/chrome/browser/media/ui/NotificationTestUtils.java
new file mode 100644
index 0000000..143d234
--- /dev/null
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/media/ui/NotificationTestUtils.java
@@ -0,0 +1,33 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.media.ui;
+
+import android.app.Instrumentation;
+
+import org.chromium.base.ThreadUtils;
+import org.chromium.chrome.browser.tab.Tab;
+import org.chromium.content_public.browser.LoadUrlParams;
+
+/**
+ * Helper functions used in notification instrumentation tests.
+ */
+public class NotificationTestUtils {
+    /**
+     * Simulates a same page navigation.
+     * @param instrumentation The Instrumentation object for the test.
+     * @param tab The tab to be navigated.
+     * @param url The original URL. The URL to be navigated to is |url| + "#some-anchor".
+     */
+    public static void simulateSamePageNavigation(
+            Instrumentation instrumentation, final Tab tab, final String url) {
+        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
+            @Override
+            public void run() {
+                tab.loadUrl(new LoadUrlParams(url + "#some-anchor"));
+            }
+        });
+        instrumentation.waitForIdleSync();
+    }
+}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/media/ui/NotificationTitleUpdatedTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/media/ui/NotificationTitleUpdatedTest.java
index c49a01f..263c13d 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/media/ui/NotificationTitleUpdatedTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/media/ui/NotificationTitleUpdatedTest.java
@@ -36,7 +36,8 @@
 @RetryOnFailure
 public class NotificationTitleUpdatedTest extends ChromeActivityTestCaseBase<ChromeActivity> {
     private static final int NOTIFICATION_ID = R.id.media_playback_notification;
-    private static final String SIMPLE_PAGE_URL = "/simple_page.html";
+    private static final String SIMPLE_PAGE_URL_1 = "/content/test/data/title1.html";
+    private static final String SIMPLE_PAGE_URL_2 = "/content/test/data/title2.html";
 
     private Tab mTab;
     private EmbeddedTestServer mTestServer;
@@ -163,14 +164,28 @@
     }
 
     @SmallTest
-    public void testMediaMetadataPersistsAfterInPageNavigation() throws Throwable {
+    public void testMediaMetadataResetsAfterSameOriginNavigation() throws Throwable {
         ensureTestServer();
-        loadUrl(mTestServer.getURL(SIMPLE_PAGE_URL));
+        loadUrl(mTestServer.getURL(SIMPLE_PAGE_URL_1));
         simulateMediaSessionStateChanged(mTab, true, false);
         simulateMediaSessionMetadataChanged(mTab, new MediaMetadata("title2", "", ""));
         assertTitleMatches("title2");
 
-        loadUrl(mTestServer.getURL(SIMPLE_PAGE_URL + "#some-anchor"));
+        loadUrl(mTestServer.getURL(SIMPLE_PAGE_URL_2));
+        simulateUpdateTitle(mTab, "title3");
+        assertTitleMatches("title3");
+    }
+
+    @SmallTest
+    public void testMediaMetadataPersistsAfterSamePageNavigation() throws Throwable {
+        ensureTestServer();
+        loadUrl(mTestServer.getURL(SIMPLE_PAGE_URL_1));
+        simulateMediaSessionStateChanged(mTab, true, false);
+        simulateMediaSessionMetadataChanged(mTab, new MediaMetadata("title2", "", ""));
+        assertTitleMatches("title2");
+
+        NotificationTestUtils.simulateSamePageNavigation(
+                getInstrumentation(), mTab, mTestServer.getURL(SIMPLE_PAGE_URL_1));
         assertTitleMatches("title2");
     }
 
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 76e2d82..89a7db5 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -5904,12 +5904,6 @@
       <message name="IDS_FLAGS_PASSWORD_GENERATION_DESCRIPTION" desc="Description of flag to enable password generation.">
         Allow the user to have Chrome generate passwords when it detects account creation pages.
       </message>
-      <message name="IDS_FLAGS_AUTOMATIC_PASSWORD_SAVING_NAME" desc="Name of the flag to automatically save password.">
-        Save passwords automatically
-      </message>
-      <message name="IDS_FLAGS_AUTOMATIC_PASSWORD_SAVING_DESCRIPTION" desc="Description of the flag to automatically save password.">
-        Skip the passwords prompt and save passwords automatically.
-      </message>
       <message name="IDS_FLAGS_PASSWORD_FORCE_SAVING_NAME" desc="Name of the flag for the password manager's force-saving option.">
         Force-saving of passwords
       </message>
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 99001871..757c5429 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -1564,7 +1564,6 @@
     "//rlz/features",
     "//services/image_decoder/public/cpp",
     "//services/preferences/public/interfaces/",
-    "//services/resource_coordinator:lib",
     "//services/service_manager/public/cpp",
     "//services/shape_detection/public/interfaces",
     "//skia",
diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS
index b532bf1..b5c99f9 100644
--- a/chrome/browser/DEPS
+++ b/chrome/browser/DEPS
@@ -50,7 +50,6 @@
   "+services/image_decoder/public/interfaces",
   "+services/preferences/public/cpp",
   "+services/preferences/public/interfaces",
-  "+services/resource_coordinator",
   "+services/service_manager",
   "+services/shape_detection/public/interfaces",
   "+services/ui/public",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index f726549..ea4ad486 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -1098,11 +1098,6 @@
      IDS_FLAGS_PASSWORD_GENERATION_DESCRIPTION, kOsAll,
      ENABLE_DISABLE_VALUE_TYPE(autofill::switches::kEnablePasswordGeneration,
                                autofill::switches::kDisablePasswordGeneration)},
-    {"enable-automatic-password-saving",
-     IDS_FLAGS_AUTOMATIC_PASSWORD_SAVING_NAME,
-     IDS_FLAGS_AUTOMATIC_PASSWORD_SAVING_DESCRIPTION, kOsDesktop,
-     FEATURE_VALUE_TYPE(
-         password_manager::features::kEnableAutomaticPasswordSaving)},
     {"enable-password-force-saving", IDS_FLAGS_PASSWORD_FORCE_SAVING_NAME,
      IDS_FLAGS_PASSWORD_FORCE_SAVING_DESCRIPTION, kOsAll,
      FEATURE_VALUE_TYPE(
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 23773731..8b3d55a 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -196,7 +196,6 @@
 #include "printing/features/features.h"
 #include "services/image_decoder/public/interfaces/constants.mojom.h"
 #include "services/preferences/public/interfaces/preferences.mojom.h"
-#include "services/resource_coordinator/memory/coordinator/coordinator_impl.h"
 #include "services/service_manager/public/cpp/interface_provider.h"
 #include "services/service_manager/public/cpp/interface_registry.h"
 #include "services/service_manager/public/cpp/service.h"
@@ -3101,13 +3100,6 @@
       base::Bind(&metrics::LeakDetectorRemoteController::Create),
       ui_task_runner);
 #endif
-
-  registry->AddInterface(
-      base::Bind(
-          &memory_instrumentation::CoordinatorImpl::BindCoordinatorRequest,
-          base::Unretained(memory_instrumentation::CoordinatorImpl::GetInstance(
-              ui_task_runner))),
-      ui_task_runner);
 }
 
 void ChromeContentBrowserClient::ExposeInterfacesToMediaService(
@@ -3205,15 +3197,6 @@
   registry->AddInterface(
       base::Bind(&metrics::CallStackProfileCollector::Create,
                  metrics::CallStackProfileParams::GPU_PROCESS));
-
-  auto ui_task_runner = content::BrowserThread::GetTaskRunnerForThread(
-      content::BrowserThread::UI);
-  registry->AddInterface(
-      base::Bind(
-          &memory_instrumentation::CoordinatorImpl::BindCoordinatorRequest,
-          base::Unretained(memory_instrumentation::CoordinatorImpl::GetInstance(
-              ui_task_runner))),
-      ui_task_runner);
 }
 
 void ChromeContentBrowserClient::RegisterInProcessServices(
diff --git a/chrome/browser/chromeos/file_manager/image_loader_jstest.cc b/chrome/browser/chromeos/file_manager/image_loader_jstest.cc
index 17fbc2c8..2de91a72 100644
--- a/chrome/browser/chromeos/file_manager/image_loader_jstest.cc
+++ b/chrome/browser/chromeos/file_manager/image_loader_jstest.cc
@@ -22,3 +22,7 @@
 IN_PROC_BROWSER_TEST_F(ImageLoaderJsTest, ImageLoaderTest) {
   RunTest(base::FilePath(FILE_PATH_LITERAL("image_loader_unittest.html")));
 }
+
+IN_PROC_BROWSER_TEST_F(ImageLoaderJsTest, PiexLoaderTest) {
+  RunTest(base::FilePath(FILE_PATH_LITERAL("piex_loader_unittest.html")));
+}
diff --git a/chrome/browser/extensions/user_script_listener.cc b/chrome/browser/extensions/user_script_listener.cc
index 5c47c49..e106334 100644
--- a/chrome/browser/extensions/user_script_listener.cc
+++ b/chrome/browser/extensions/user_script_listener.cc
@@ -8,8 +8,10 @@
 #include "base/macros.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/timer/elapsed_timer.h"
+#include "chrome/browser/browser_process.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_service.h"
@@ -77,20 +79,22 @@
 };
 
 UserScriptListener::UserScriptListener()
-    : user_scripts_ready_(false) {
+    : user_scripts_ready_(false), extension_registry_observer_(this) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
-  registrar_.Add(this,
-                 extensions::NOTIFICATION_EXTENSION_LOADED_DEPRECATED,
+  for (auto* profile :
+       g_browser_process->profile_manager()->GetLoadedProfiles()) {
+    extension_registry_observer_.Add(ExtensionRegistry::Get(profile));
+  }
+
+  registrar_.Add(this, chrome::NOTIFICATION_PROFILE_ADDED,
                  content::NotificationService::AllSources());
-  registrar_.Add(this,
-                 extensions::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED,
+
+  registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED,
                  content::NotificationService::AllSources());
   registrar_.Add(this,
                  extensions::NOTIFICATION_USER_SCRIPTS_UPDATED,
                  content::NotificationService::AllSources());
-  registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED,
-                 content::NotificationService::AllSources());
 }
 
 ResourceThrottle* UserScriptListener::CreateResourceThrottle(
@@ -218,62 +222,71 @@
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   switch (type) {
-    case extensions::NOTIFICATION_EXTENSION_LOADED_DEPRECATED: {
-      Profile* profile = content::Source<Profile>(source).ptr();
-      const Extension* extension =
-          content::Details<const Extension>(details).ptr();
-      if (ContentScriptsInfo::GetContentScripts(extension).empty())
-        return;  // no new patterns from this extension.
-
-      URLPatterns new_patterns;
-      CollectURLPatterns(extension, &new_patterns);
-      if (!new_patterns.empty()) {
-        BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(
-            &UserScriptListener::AppendNewURLPatterns, this,
-            profile, new_patterns));
-      }
+    case chrome::NOTIFICATION_PROFILE_ADDED: {
+      auto* registry =
+          ExtensionRegistry::Get(content::Source<Profile>(source).ptr());
+      DCHECK(!extension_registry_observer_.IsObserving(registry));
+      extension_registry_observer_.Add(registry);
       break;
     }
-
-    case extensions::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED: {
-      Profile* profile = content::Source<Profile>(source).ptr();
-      const Extension* unloaded_extension =
-          content::Details<UnloadedExtensionInfo>(details)->extension;
-      if (ContentScriptsInfo::GetContentScripts(unloaded_extension).empty())
-        return;  // no patterns to delete for this extension.
-
-      // Clear all our patterns and reregister all the still-loaded extensions.
-      const ExtensionSet& extensions =
-          ExtensionRegistry::Get(profile)->enabled_extensions();
-      URLPatterns new_patterns;
-      for (ExtensionSet::const_iterator it = extensions.begin();
-           it != extensions.end(); ++it) {
-        if (it->get() != unloaded_extension)
-          CollectURLPatterns(it->get(), &new_patterns);
-      }
-      BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(
-          &UserScriptListener::ReplaceURLPatterns, this,
-          profile, new_patterns));
-      break;
-    }
-
-    case extensions::NOTIFICATION_USER_SCRIPTS_UPDATED: {
-      Profile* profile = content::Source<Profile>(source).ptr();
-      BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(
-          &UserScriptListener::UserScriptsReady, this, profile));
-      break;
-    }
-
     case chrome::NOTIFICATION_PROFILE_DESTROYED: {
       Profile* profile = content::Source<Profile>(source).ptr();
-      BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(
-          &UserScriptListener::ProfileDestroyed, this, profile));
+      BrowserThread::PostTask(
+          BrowserThread::IO, FROM_HERE,
+          base::Bind(&UserScriptListener::ProfileDestroyed, this, profile));
       break;
     }
-
+    case extensions::NOTIFICATION_USER_SCRIPTS_UPDATED: {
+      Profile* profile = content::Source<Profile>(source).ptr();
+      BrowserThread::PostTask(
+          BrowserThread::IO, FROM_HERE,
+          base::Bind(&UserScriptListener::UserScriptsReady, this, profile));
+      break;
+    }
     default:
       NOTREACHED();
   }
 }
 
+void UserScriptListener::OnExtensionLoaded(
+    content::BrowserContext* browser_context,
+    const Extension* extension) {
+  if (ContentScriptsInfo::GetContentScripts(extension).empty())
+    return;  // no new patterns from this extension.
+
+  URLPatterns new_patterns;
+  CollectURLPatterns(extension, &new_patterns);
+  if (!new_patterns.empty()) {
+    BrowserThread::PostTask(
+        BrowserThread::IO, FROM_HERE,
+        base::Bind(&UserScriptListener::AppendNewURLPatterns, this,
+                   browser_context, new_patterns));
+  }
+}
+
+void UserScriptListener::OnExtensionUnloaded(
+    content::BrowserContext* browser_context,
+    const Extension* extension,
+    UnloadedExtensionInfo::Reason reason) {
+  if (ContentScriptsInfo::GetContentScripts(extension).empty())
+    return;  // No patterns to delete for this extension.
+
+  // Clear all our patterns and reregister all the still-loaded extensions.
+  const ExtensionSet& extensions =
+      ExtensionRegistry::Get(browser_context)->enabled_extensions();
+  URLPatterns new_patterns;
+  for (ExtensionSet::const_iterator it = extensions.begin();
+       it != extensions.end(); ++it) {
+    if (it->get() != extension)
+      CollectURLPatterns(it->get(), &new_patterns);
+  }
+  BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+                          base::Bind(&UserScriptListener::ReplaceURLPatterns,
+                                     this, browser_context, new_patterns));
+}
+
+void UserScriptListener::OnShutdown(ExtensionRegistry* registry) {
+  extension_registry_observer_.Remove(registry);
+}
+
 }  // namespace extensions
diff --git a/chrome/browser/extensions/user_script_listener.h b/chrome/browser/extensions/user_script_listener.h
index 92426e7..951a16f4 100644
--- a/chrome/browser/extensions/user_script_listener.h
+++ b/chrome/browser/extensions/user_script_listener.h
@@ -13,10 +13,12 @@
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
+#include "base/scoped_observer.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
 #include "content/public/common/resource_type.h"
+#include "extensions/browser/extension_registry_observer.h"
 
 class GURL;
 class URLPattern;
@@ -35,11 +37,11 @@
 //
 // This class lives mostly on the IO thread. It listens on the UI thread for
 // updates to loaded extensions.
-class UserScriptListener
-    : public base::RefCountedThreadSafe<
-          UserScriptListener,
-          content::BrowserThread::DeleteOnUIThread>,
-      public content::NotificationObserver {
+class UserScriptListener : public base::RefCountedThreadSafe<
+                               UserScriptListener,
+                               content::BrowserThread::DeleteOnUIThread>,
+                           public content::NotificationObserver,
+                           public ExtensionRegistryObserver {
  public:
   UserScriptListener();
 
@@ -106,6 +108,18 @@
                const content::NotificationSource& source,
                const content::NotificationDetails& details) override;
 
+  // ExtensionRegistryObserver:
+  void OnExtensionLoaded(content::BrowserContext* browser_context,
+                         const Extension* extension) override;
+  void OnExtensionUnloaded(content::BrowserContext* browser_context,
+                           const Extension* extension,
+                           UnloadedExtensionInfo::Reason reason) override;
+  void OnShutdown(ExtensionRegistry* registry) override;
+
+  ScopedObserver<extensions::ExtensionRegistry,
+                 extensions::ExtensionRegistryObserver>
+      extension_registry_observer_;
+
   content::NotificationRegistrar registrar_;
 
   DISALLOW_COPY_AND_ASSIGN(UserScriptListener);
diff --git a/chrome/browser/extensions/user_script_listener_unittest.cc b/chrome/browser/extensions/user_script_listener_unittest.cc
index 48a6f9a0..3614c119 100644
--- a/chrome/browser/extensions/user_script_listener_unittest.cc
+++ b/chrome/browser/extensions/user_script_listener_unittest.cc
@@ -6,6 +6,7 @@
 
 #include <memory>
 
+#include "base/command_line.h"
 #include "base/files/file_util.h"
 #include "base/json/json_file_value_serializer.h"
 #include "base/macros.h"
@@ -13,12 +14,15 @@
 #include "base/threading/thread.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_service.h"
-#include "chrome/browser/extensions/extension_service_test_base.h"
+#include "chrome/browser/extensions/test_extension_system.h"
 #include "chrome/browser/extensions/unpacked_installer.h"
 #include "chrome/common/chrome_paths.h"
+#include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
+#include "chrome/test/base/testing_profile_manager.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/resource_throttle.h"
+#include "content/public/test/test_browser_thread_bundle.h"
 #include "extensions/browser/extension_registry.h"
 #include "net/base/request_priority.h"
 #include "net/url_request/url_request.h"
@@ -28,6 +32,11 @@
 #include "net/url_request/url_request_test_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+#if defined(OS_CHROMEOS)
+#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h"
+#include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h"
+#endif
+
 using content::ResourceThrottle;
 
 namespace extensions {
@@ -115,9 +124,14 @@
 
 }  // namespace
 
-class UserScriptListenerTest : public ExtensionServiceTestBase {
+class UserScriptListenerTest : public testing::Test {
  public:
-  UserScriptListenerTest() {
+  UserScriptListenerTest()
+      : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
+        profile_manager_(
+            new TestingProfileManager(TestingBrowserProcess::GetGlobal())),
+        profile_(nullptr),
+        service_(nullptr) {
     net::URLRequestFilter::GetInstance()->AddHostnameInterceptor(
         "http", "google.com", std::unique_ptr<net::URLRequestInterceptor>(
                                   new SimpleTestJobURLRequestInterceptor()));
@@ -134,19 +148,25 @@
   }
 
   void SetUp() override {
-    ExtensionServiceTestBase::SetUp();
+#if defined(OS_CHROMEOS)
+    user_manager_enabler_ =
+        base::MakeUnique<chromeos::ScopedUserManagerEnabler>(
+            new chromeos::FakeChromeUserManager());
+#endif
+    ASSERT_TRUE(profile_manager_->SetUp());
+    profile_ = profile_manager_->CreateTestingProfile("test-profile");
+    ASSERT_TRUE(profile_);
 
-    InitializeEmptyExtensionService();
-    service_->Init();
-    base::RunLoop().RunUntilIdle();
+    TestExtensionSystem* test_extension_system =
+        static_cast<TestExtensionSystem*>(ExtensionSystem::Get(profile_));
+    service_ = test_extension_system->CreateExtensionService(
+        base::CommandLine::ForCurrentProcess(), base::FilePath(), false);
 
     listener_ = new UserScriptListener();
   }
 
   void TearDown() override {
     listener_ = NULL;
-    base::RunLoop().RunUntilIdle();
-    ExtensionServiceTestBase::TearDown();
   }
 
  protected:
@@ -189,13 +209,20 @@
 
   void UnloadTestExtension() {
     const extensions::ExtensionSet& extensions =
-        registry()->enabled_extensions();
+        ExtensionRegistry::Get(profile_)->enabled_extensions();
     ASSERT_FALSE(extensions.is_empty());
     service_->UnloadExtension((*extensions.begin())->id(),
                               UnloadedExtensionInfo::REASON_DISABLE);
   }
 
+  content::TestBrowserThreadBundle thread_bundle_;
+  std::unique_ptr<TestingProfileManager> profile_manager_;
   scoped_refptr<UserScriptListener> listener_;
+  TestingProfile* profile_;
+  ExtensionService* service_;
+#if defined(OS_CHROMEOS)
+  std::unique_ptr<chromeos::ScopedUserManagerEnabler> user_manager_enabler_;
+#endif
 };
 
 namespace {
@@ -212,7 +239,7 @@
 
   content::NotificationService::current()->Notify(
       extensions::NOTIFICATION_USER_SCRIPTS_UPDATED,
-      content::Source<Profile>(profile_.get()),
+      content::Source<Profile>(profile_),
       content::NotificationService::NoDetails());
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(kTestData, delegate.data_received());
@@ -237,7 +264,7 @@
 
   content::NotificationService::current()->Notify(
       extensions::NOTIFICATION_USER_SCRIPTS_UPDATED,
-      content::Source<Profile>(profile_.get()),
+      content::Source<Profile>(profile_),
       content::NotificationService::NoDetails());
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(kTestData, delegate.data_received());
@@ -278,18 +305,17 @@
 
   // Fire up a second profile and have it load an extension with a content
   // script.
-  TestingProfile profile2;
+  TestingProfile* profile2 =
+      profile_manager_->CreateTestingProfile("test-profile2");
+  ASSERT_TRUE(profile2);
   std::string error;
   scoped_refptr<Extension> extension = LoadExtension(
       "content_script_yahoo.json", &error);
   ASSERT_TRUE(extension.get());
 
-  extensions::ExtensionRegistry::Get(&profile2)->AddEnabled(extension);
-
-  content::NotificationService::current()->Notify(
-      extensions::NOTIFICATION_EXTENSION_LOADED_DEPRECATED,
-      content::Source<Profile>(&profile2),
-      content::Details<Extension>(extension.get()));
+  ExtensionRegistry* registry = ExtensionRegistry::Get(profile2);
+  registry->AddEnabled(extension);
+  registry->TriggerOnLoaded(extension.get());
 
   net::TestDelegate delegate;
   net::TestURLRequestContext context;
@@ -301,7 +327,7 @@
   // be blocked waiting for profile2.
   content::NotificationService::current()->Notify(
       extensions::NOTIFICATION_USER_SCRIPTS_UPDATED,
-      content::Source<Profile>(profile_.get()),
+      content::Source<Profile>(profile_),
       content::NotificationService::NoDetails());
   base::RunLoop().RunUntilIdle();
   ASSERT_FALSE(request->is_pending());
@@ -310,7 +336,7 @@
   // After profile2 is ready, the request should proceed.
   content::NotificationService::current()->Notify(
       extensions::NOTIFICATION_USER_SCRIPTS_UPDATED,
-      content::Source<Profile>(&profile2),
+      content::Source<Profile>(profile2),
       content::NotificationService::NoDetails());
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(kTestData, delegate.data_received());
@@ -337,7 +363,7 @@
 
   content::NotificationService::current()->Notify(
       extensions::NOTIFICATION_USER_SCRIPTS_UPDATED,
-      content::Source<Profile>(profile_.get()),
+      content::Source<Profile>(profile_),
       content::NotificationService::NoDetails());
   base::RunLoop().RunUntilIdle();
 
diff --git a/chrome/browser/loader/chrome_resource_dispatcher_host_delegate_unittest.cc b/chrome/browser/loader/chrome_resource_dispatcher_host_delegate_unittest.cc
index 5c145ed..313f5f4c 100644
--- a/chrome/browser/loader/chrome_resource_dispatcher_host_delegate_unittest.cc
+++ b/chrome/browser/loader/chrome_resource_dispatcher_host_delegate_unittest.cc
@@ -6,12 +6,13 @@
 
 #include <memory>
 
-#include "base/message_loop/message_loop.h"
 #include "chrome/browser/loader/chrome_navigation_data.h"
 #include "chrome/browser/loader/chrome_resource_dispatcher_host_delegate.h"
+#include "chrome/test/base/testing_browser_process.h"
+#include "chrome/test/base/testing_profile_manager.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_data.h"
 #include "content/public/browser/navigation_data.h"
-#include "content/public/test/test_browser_thread.h"
+#include "content/public/test/test_browser_thread_bundle.h"
 #include "net/base/request_priority.h"
 #include "net/url_request/url_request.h"
 #include "net/url_request/url_request_context.h"
@@ -21,12 +22,16 @@
 class ChromeResourceDispatcherHostDelegateTest : public testing::Test {
  public:
   ChromeResourceDispatcherHostDelegateTest()
-      : ui_thread_(content::BrowserThread::UI, &message_loop_) {}
+      : profile_manager_(
+            new TestingProfileManager(TestingBrowserProcess::GetGlobal())) {}
   ~ChromeResourceDispatcherHostDelegateTest() override {}
 
+  void SetUp() override { ASSERT_TRUE(profile_manager_->SetUp()); }
+
  private:
-  base::MessageLoopForIO message_loop_;
-  content::TestBrowserThread ui_thread_;
+  content::TestBrowserThreadBundle thread_bundle_;
+  // Set up TestingProfileManager for extensions::UserScriptListener.
+  std::unique_ptr<TestingProfileManager> profile_manager_;
 };
 
 TEST_F(ChromeResourceDispatcherHostDelegateTest,
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.cc b/chrome/browser/password_manager/chrome_password_manager_client.cc
index 118b61b8..02ea0fa 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client.cc
+++ b/chrome/browser/password_manager/chrome_password_manager_client.cc
@@ -180,12 +180,6 @@
 
 ChromePasswordManagerClient::~ChromePasswordManagerClient() {}
 
-bool ChromePasswordManagerClient::IsAutomaticPasswordSavingEnabled() const {
-  return base::FeatureList::IsEnabled(
-             password_manager::features::kEnableAutomaticPasswordSaving) &&
-         chrome::GetChannel() == version_info::Channel::UNKNOWN;
-}
-
 bool ChromePasswordManagerClient::IsPasswordManagementEnabledForCurrentPage()
     const {
   DCHECK(web_contents());
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.h b/chrome/browser/password_manager/chrome_password_manager_client.h
index d1edf73..1181d53 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client.h
+++ b/chrome/browser/password_manager/chrome_password_manager_client.h
@@ -46,7 +46,6 @@
   ~ChromePasswordManagerClient() override;
 
   // PasswordManagerClient implementation.
-  bool IsAutomaticPasswordSavingEnabled() const override;
   bool IsSavingAndFillingEnabledForCurrentPage() const override;
   bool IsFillingEnabledForCurrentPage() const override;
   bool IsHSTSActiveForHost(const GURL& origin) const override;
diff --git a/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc b/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
index 91e2301..e8aeee5 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
+++ b/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
@@ -14,11 +14,9 @@
 #include "base/strings/string16.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/scoped_feature_list.h"
 #include "chrome/browser/metrics/chrome_metrics_service_accessor.h"
 #include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/sync/profile_sync_test_util.h"
-#include "chrome/common/channel_info.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/autofill/content/common/autofill_agent.mojom.h"
@@ -30,7 +28,6 @@
 #include "components/password_manager/core/browser/password_manager_internals_service.h"
 #include "components/password_manager/core/browser/password_manager_test_utils.h"
 #include "components/password_manager/core/common/credential_manager_types.h"
-#include "components/password_manager/core/common/password_manager_features.h"
 #include "components/password_manager/core/common/password_manager_pref_names.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
@@ -42,7 +39,6 @@
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/url_constants.h"
 #include "content/public/test/web_contents_tester.h"
-#include "extensions/features/features.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "services/service_manager/public/cpp/interface_provider.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -253,24 +249,6 @@
   EXPECT_FALSE(logging_active);
 }
 
-TEST_F(ChromePasswordManagerClientTest,
-       IsAutomaticPasswordSavingEnabledDefaultBehaviourTest) {
-  EXPECT_FALSE(GetClient()->IsAutomaticPasswordSavingEnabled());
-}
-
-TEST_F(ChromePasswordManagerClientTest,
-       IsAutomaticPasswordSavingEnabledWhenFlagIsSetTest) {
-  // Add the enable-automatic-password-saving feature.
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndEnableFeature(
-      password_manager::features::kEnableAutomaticPasswordSaving);
-
-  if (chrome::GetChannel() == version_info::Channel::UNKNOWN)
-    EXPECT_TRUE(GetClient()->IsAutomaticPasswordSavingEnabled());
-  else
-    EXPECT_FALSE(GetClient()->IsAutomaticPasswordSavingEnabled());
-}
-
 TEST_F(ChromePasswordManagerClientTest, GetPasswordSyncState) {
   ProfileSyncServiceMock* mock_sync_service = SetupBasicMockSync();
 
diff --git a/chrome/browser/password_manager/password_manager_browsertest.cc b/chrome/browser/password_manager/password_manager_browsertest.cc
index 607b9a2..bb692e70 100644
--- a/chrome/browser/password_manager/password_manager_browsertest.cc
+++ b/chrome/browser/password_manager/password_manager_browsertest.cc
@@ -29,7 +29,6 @@
 #include "chrome/browser/ui/login/login_handler_test_utils.h"
 #include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/channel_info.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/ui_test_utils.h"
@@ -40,7 +39,6 @@
 #include "components/password_manager/content/browser/content_password_manager_driver_factory.h"
 #include "components/password_manager/core/browser/login_model.h"
 #include "components/password_manager/core/browser/test_password_store.h"
-#include "components/password_manager/core/common/password_manager_features.h"
 #include "components/version_info/version_info.h"
 #include "content/public/browser/navigation_controller.h"
 #include "content/public/browser/notification_service.h"
@@ -1225,44 +1223,6 @@
   EXPECT_TRUE(prompt_observer->IsShowingSavePrompt());
 }
 
-IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
-                       DontPromptWhenEnableAutomaticPasswordSavingSwitchIsSet) {
-  scoped_refptr<password_manager::TestPasswordStore> password_store =
-      static_cast<password_manager::TestPasswordStore*>(
-          PasswordStoreFactory::GetForProfile(
-              browser()->profile(), ServiceAccessType::IMPLICIT_ACCESS).get());
-
-  EXPECT_TRUE(password_store->IsEmpty());
-
-  NavigateToFile("/password/password_form.html");
-
-  // Add the enable-automatic-password-saving feature.
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndEnableFeature(
-      password_manager::features::kEnableAutomaticPasswordSaving);
-
-  // Fill a form and submit through a <input type="submit"> button.
-  NavigationObserver observer(WebContents());
-  std::unique_ptr<BubbleObserver> prompt_observer(
-      new BubbleObserver(WebContents()));
-  // Make sure that the only passwords saved are the auto-saved ones.
-  std::string fill_and_submit =
-      "document.getElementById('username_field').value = 'temp';"
-      "document.getElementById('password_field').value = 'random';"
-      "document.getElementById('input_submit_button').click()";
-  ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
-  observer.Wait();
-  if (chrome::GetChannel() == version_info::Channel::UNKNOWN) {
-    // Passwords getting auto-saved, no prompt.
-    EXPECT_FALSE(prompt_observer->IsShowingSavePrompt());
-    EXPECT_FALSE(password_store->IsEmpty());
-  } else {
-    // Prompt shown, and no passwords saved automatically.
-    EXPECT_TRUE(prompt_observer->IsShowingSavePrompt());
-    EXPECT_TRUE(password_store->IsEmpty());
-  }
-}
-
 // Test fix for crbug.com/368690.
 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase, NoPromptWhenReloading) {
   NavigateToFile("/password/password_form.html");
diff --git a/chrome/browser/password_manager/password_manager_test_base.cc b/chrome/browser/password_manager/password_manager_test_base.cc
index 4487c03..5d46088 100644
--- a/chrome/browser/password_manager/password_manager_test_base.cc
+++ b/chrome/browser/password_manager/password_manager_test_base.cc
@@ -18,7 +18,6 @@
 #include "components/autofill/core/browser/autofill_test_utils.h"
 #include "components/password_manager/core/browser/password_manager_test_utils.h"
 #include "components/password_manager/core/browser/test_password_store.h"
-#include "components/password_manager/core/common/password_manager_features.h"
 #include "content/public/browser/navigation_details.h"
 #include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/render_frame_host.h"
@@ -132,8 +131,6 @@
       password_manager::BuildPasswordStore<
           content::BrowserContext, password_manager::TestPasswordStore>);
   ASSERT_TRUE(embedded_test_server()->Start());
-  ASSERT_FALSE(base::FeatureList::IsEnabled(
-      password_manager::features::kEnableAutomaticPasswordSaving));
 }
 
 void PasswordManagerBrowserTestBase::TearDownOnMainThread() {
diff --git a/chrome/browser/ui/views/profiles/profile_chooser_view.cc b/chrome/browser/ui/views/profiles/profile_chooser_view.cc
index 8af320e..b443ca9 100644
--- a/chrome/browser/ui/views/profiles/profile_chooser_view.cc
+++ b/chrome/browser/ui/views/profiles/profile_chooser_view.cc
@@ -318,20 +318,6 @@
   gfx::Size preferred_size_;
 };
 
-// NonInteractiveContainer -------------------------------------------------
-
-// A simple container view that does not process events within subtree.
-class NonInteractiveContainer : public views::View {
- public:
-  NonInteractiveContainer() {}
-
-  // views::CanProcessEventsWithinSubtree:
-  bool CanProcessEventsWithinSubtree() const override { return false; }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(NonInteractiveContainer);
-};
-
 // A view to host the GAIA webview overlapped with a back button.  This class
 // is needed to reparent the back button inside a native view so that on
 // windows, user input can be be properly routed to the button.
@@ -1760,6 +1746,27 @@
   // Container for the profile photo and avatar/user name.
   BackgroundColorHoverButton* current_profile_card =
       new BackgroundColorHoverButton(this, base::string16());
+  views::GridLayout* grid_layout = new views::GridLayout(current_profile_card);
+  current_profile_card->SetLayoutManager(grid_layout);
+  views::ColumnSet* columns = grid_layout->AddColumnSet(0);
+  columns->AddPaddingColumn(0, kMaterialMenuEdgeMargin);
+  columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 0,
+                     views::GridLayout::USE_PREF, 0, 0);
+  columns->AddPaddingColumn(
+      0, kMaterialMenuEdgeMargin - EditableProfilePhoto::badge_spacing());
+  columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1,
+                     views::GridLayout::USE_PREF, 0, 0);
+  columns->AddPaddingColumn(0, kMaterialMenuEdgeMargin);
+  grid_layout->AddPaddingRow(0, 0);
+  const int num_labels =
+      (avatar_item.signed_in && !switches::IsEnableAccountConsistency()) ? 2
+                                                                         : 1;
+  int profile_card_height = EditableProfilePhoto::icon_image_side() +
+                            2 *
+                                (EditableProfilePhoto::badge_spacing() +
+                                 views::kRelatedControlSmallVerticalSpacing);
+  const int line_height = profile_card_height / num_labels;
+  grid_layout->StartRow(0, 0, line_height);
   current_profile_card_ = current_profile_card;
 
   // Profile picture, left-aligned.
@@ -1775,23 +1782,15 @@
       ui::ResourceBundle::GetSharedInstance().GetFontListWithDelta(
           1, gfx::Font::FontStyle::NORMAL, gfx::Font::Weight::MEDIUM));
   current_profile_name->SetHorizontalAlignment(gfx::ALIGN_LEFT);
-  NonInteractiveContainer* profile_name_container =
-      new NonInteractiveContainer();
-  int name_container_v_spacing =
-      (current_profile_photo->GetPreferredSize().height() -
-       current_profile_name->GetPreferredSize().height()) / 2;
-  views::BoxLayout* profile_name_layout = new views::BoxLayout(
-      views::BoxLayout::kVertical, 0, name_container_v_spacing, 0);
-  profile_name_container->SetLayoutManager(profile_name_layout);
-  profile_name_container->AddChildView(current_profile_name);
 
-  const int between_child_spacing =
-      kMaterialMenuEdgeMargin - EditableProfilePhoto::badge_spacing();
-  current_profile_card_->SetLayoutManager(new views::BoxLayout(
-      views::BoxLayout::kHorizontal, 0,
-      views::kRelatedControlSmallVerticalSpacing, between_child_spacing));
-  current_profile_card_->AddChildView(current_profile_photo);
-  current_profile_card_->AddChildView(profile_name_container);
+  // The grid layout contains one row if not signed in or account consistency is
+  // enabled. It contains 2 rows if signed in and account consistency is
+  // disabled (the second row is for the email label). For the second case the
+  // profile photo has to be over 2 rows.
+  grid_layout->AddView(current_profile_photo, 1, num_labels);
+  grid_layout->AddView(current_profile_name, 1, 1, views::GridLayout::LEADING,
+                       (num_labels == 2) ? views::GridLayout::TRAILING
+                                         : views::GridLayout::CENTER);
   current_profile_card_->SetMinSize(gfx::Size(
       GetFixedMenuWidth(), current_profile_photo->GetPreferredSize().height() +
                                2 * views::kRelatedControlSmallVerticalSpacing));
@@ -1825,13 +1824,11 @@
       email_label->SetElideBehavior(gfx::ELIDE_EMAIL);
       email_label->SetEnabled(false);
       email_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
-      name_container_v_spacing =
-          (current_profile_photo->GetPreferredSize().height() -
-           current_profile_name->GetPreferredSize().height() -
-           email_label->GetPreferredSize().height()) / 2;
-      profile_name_layout->set_inside_border_insets(
-          gfx::Insets(name_container_v_spacing, 0));
-      profile_name_container->AddChildView(email_label);
+      grid_layout->StartRow(1, 0);
+      // Skip first column for the profile icon.
+      grid_layout->SkipColumns(1);
+      grid_layout->AddView(email_label, 1, 1, views::GridLayout::LEADING,
+                           views::GridLayout::LEADING);
     }
 
     current_profile_card_->SetAccessibleName(
diff --git a/components/BUILD.gn b/components/BUILD.gn
index 61a73bb5..57a41703 100644
--- a/components/BUILD.gn
+++ b/components/BUILD.gn
@@ -396,6 +396,7 @@
       "dom_distiller/content/browser/test/dom_distiller_js_browsertest.cc",
       "password_manager/content/renderer/credential_manager_client_browsertest.cc",
       "security_state/content/content_utils_browsertest.cc",
+      "tracing/child/child_trace_message_filter_browsertest.cc",
     ]
 
     data = [
diff --git a/components/certificate_transparency/log_dns_client.cc b/components/certificate_transparency/log_dns_client.cc
index fabbbac4..b5631743 100644
--- a/components/certificate_transparency/log_dns_client.cc
+++ b/components/certificate_transparency/log_dns_client.cc
@@ -10,6 +10,7 @@
 #include "base/location.h"
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
+#include "base/metrics/histogram_macros.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
@@ -30,6 +31,28 @@
 
 namespace {
 
+// Used by UMA_HISTOGRAM_ENUMERATION to record query success/failures.
+// These values are written to logs.  New enum values can be added, but existing
+// enums must never be renumbered or deleted and reused.
+enum QueryStatus {
+  QUERY_STATUS_SUCCESS = 0,
+  QUERY_STATUS_FAILED_UNKNOWN = 1,
+  QUERY_STATUS_FAILED_NAME_RESOLUTION = 2,
+  QUERY_STATUS_FAILED_LEAF_INDEX_MALFORMED = 3,
+  QUERY_STATUS_FAILED_INCLUSION_PROOF_MALFORMED = 4,
+  QUERY_STATUS_MAX  // Upper bound
+};
+
+void LogQueryStatus(QueryStatus result) {
+  UMA_HISTOGRAM_ENUMERATION("Net.CertificateTransparency.DnsQueryStatus",
+                            result, QUERY_STATUS_MAX);
+}
+
+void LogQueryDuration(const base::TimeDelta& duration) {
+  UMA_HISTOGRAM_MEDIUM_TIMES("Net.CertificateTransparency.DnsQueryDuration",
+                             duration);
+}
+
 // Parses the DNS response and extracts a single string from the TXT RDATA.
 // If the response is malformed, not a TXT record, or contains any number of
 // strings other than 1, this returns false and extracts nothing.
@@ -191,6 +214,8 @@
   const net::DnsResponse* last_dns_response_;
   // The NetLog that DNS transactions will log to.
   net::NetLogWithSource net_log_;
+  // The time that Start() was last called. Used to measure query duration.
+  base::TimeTicks start_time_;
   // Produces WeakPtrs to |this| for binding callbacks.
   base::WeakPtrFactory<AuditProofQuery> weak_ptr_factory_;
 };
@@ -217,6 +242,7 @@
     net::ct::MerkleAuditProof* proof) {
   // It should not already be in progress.
   DCHECK_EQ(State::NONE, next_state_);
+  start_time_ = base::TimeTicks::Now();
   proof_ = proof;
   proof_->tree_size = tree_size;
   leaf_hash_ = std::move(leaf_hash);
@@ -230,8 +256,9 @@
 
 net::Error LogDnsClient::AuditProofQuery::DoLoop(net::Error result) {
   CHECK_NE(State::NONE, next_state_);
+  State state;
   do {
-    State state = next_state_;
+    state = next_state_;
     next_state_ = State::NONE;
     switch (state) {
       case State::REQUEST_LEAF_INDEX:
@@ -252,6 +279,37 @@
     }
   } while (result != net::ERR_IO_PENDING && next_state_ != State::NONE);
 
+  if (result != net::ERR_IO_PENDING) {
+    // If the query is complete, log some metrics.
+    LogQueryDuration(base::TimeTicks::Now() - start_time_);
+
+    switch (result) {
+      case net::OK:
+        LogQueryStatus(QUERY_STATUS_SUCCESS);
+        break;
+      case net::ERR_NAME_RESOLUTION_FAILED:
+        LogQueryStatus(QUERY_STATUS_FAILED_NAME_RESOLUTION);
+        break;
+      case net::ERR_DNS_MALFORMED_RESPONSE:
+        switch (state) {
+          case State::REQUEST_LEAF_INDEX_COMPLETE:
+            LogQueryStatus(QUERY_STATUS_FAILED_LEAF_INDEX_MALFORMED);
+            break;
+          case State::REQUEST_AUDIT_PROOF_NODES_COMPLETE:
+            LogQueryStatus(QUERY_STATUS_FAILED_INCLUSION_PROOF_MALFORMED);
+            break;
+          default:
+            NOTREACHED();
+            break;
+        }
+        break;
+      default:
+        // Some other error occurred.
+        LogQueryStatus(QUERY_STATUS_FAILED_UNKNOWN);
+        break;
+    }
+  }
+
   return result;
 }
 
diff --git a/components/password_manager/core/browser/password_manager.cc b/components/password_manager/core/browser/password_manager.cc
index 59e693f5..55bc1a73 100644
--- a/components/password_manager/core/browser/password_manager.cc
+++ b/components/password_manager/core/browser/password_manager.cc
@@ -590,8 +590,7 @@
 }
 
 bool PasswordManager::ShouldPromptUserToSavePassword() const {
-  return !client_->IsAutomaticPasswordSavingEnabled() &&
-         (provisional_save_manager_->IsNewLogin() ||
+  return (provisional_save_manager_->IsNewLogin() ||
           provisional_save_manager_
               ->is_possible_change_password_form_without_username() ||
           provisional_save_manager_->retry_password_form_password_update() ||
diff --git a/components/password_manager/core/browser/password_manager_client.cc b/components/password_manager/core/browser/password_manager_client.cc
index fc790141..8e61e49 100644
--- a/components/password_manager/core/browser/password_manager_client.cc
+++ b/components/password_manager/core/browser/password_manager_client.cc
@@ -7,10 +7,6 @@
 
 namespace password_manager {
 
-bool PasswordManagerClient::IsAutomaticPasswordSavingEnabled() const {
-  return false;
-}
-
 bool PasswordManagerClient::IsSavingAndFillingEnabledForCurrentPage() const {
   return true;
 }
diff --git a/components/password_manager/core/browser/password_manager_client.h b/components/password_manager/core/browser/password_manager_client.h
index f4ac3aca..e1a0cb3e 100644
--- a/components/password_manager/core/browser/password_manager_client.h
+++ b/components/password_manager/core/browser/password_manager_client.h
@@ -50,12 +50,6 @@
   PasswordManagerClient() {}
   virtual ~PasswordManagerClient() {}
 
-  // For automated testing, the save password prompt should sometimes not be
-  // shown, and password immediately saved instead. That can be enforced by
-  // a command-line flag. If auto-saving is enforced, this method returns true.
-  // The default return value is false.
-  virtual bool IsAutomaticPasswordSavingEnabled() const;
-
   // Is saving new data for password autofill and filling of saved data enabled
   // for the current profile and page? For example, saving is disabled in
   // Incognito mode.
diff --git a/components/password_manager/core/common/password_manager_features.cc b/components/password_manager/core/common/password_manager_features.cc
index 645d686..1b880b3 100644
--- a/components/password_manager/core/common/password_manager_features.cc
+++ b/components/password_manager/core/common/password_manager_features.cc
@@ -18,11 +18,6 @@
 const base::Feature kDropSyncCredential = {"drop-sync-credential",
                                            base::FEATURE_ENABLED_BY_DEFAULT};
 
-// Disables the save-password prompt. Passwords are then saved automatically,
-// without asking the user.
-const base::Feature kEnableAutomaticPasswordSaving = {
-    "enable-automatic-password-saving", base::FEATURE_DISABLED_BY_DEFAULT};
-
 // Enable a context menu item in the password field that allows the user
 // to manually enforce saving of their password.
 const base::Feature kEnablePasswordForceSaving = {
diff --git a/components/password_manager/core/common/password_manager_features.h b/components/password_manager/core/common/password_manager_features.h
index 1eb7ec9..57a216c7 100644
--- a/components/password_manager/core/common/password_manager_features.h
+++ b/components/password_manager/core/common/password_manager_features.h
@@ -19,7 +19,6 @@
 
 extern const base::Feature kAffiliationBasedMatching;
 extern const base::Feature kDropSyncCredential;
-extern const base::Feature kEnableAutomaticPasswordSaving;
 extern const base::Feature kEnableManualPasswordGeneration;
 extern const base::Feature kEnablePasswordForceSaving;
 extern const base::Feature kProtectSyncCredential;
diff --git a/components/reading_list/ios/reading_list_entry_unittest.cc b/components/reading_list/ios/reading_list_entry_unittest.cc
index 875fc7da..a4e38b5 100644
--- a/components/reading_list/ios/reading_list_entry_unittest.cc
+++ b/components/reading_list/ios/reading_list_entry_unittest.cc
@@ -18,10 +18,6 @@
 const int kFourthBackoff = 120;
 const int kFifthBackoff = 120;
 
-// Returns the number of microseconds since Jan 1st 1970.
-int64_t Now() {
-  return (base::Time::Now() - base::Time::UnixEpoch()).InMicroseconds();
-}
 }  // namespace
 
 TEST(ReadingListEntry, CompareIgnoreTitle) {
@@ -322,11 +318,11 @@
 // sync_pb::ReadingListLocal.
 TEST(ReadingListEntry, FromReadingListLocal) {
   ReadingListEntry entry(GURL("http://example.com/"), "title");
-  base::Time next_call = base::Time::Now() + entry.TimeUntilNextTry();
+  entry.SetDistilledState(ReadingListEntry::ERROR);
 
   std::unique_ptr<reading_list::ReadingListLocal> pb_entry(
       entry.AsReadingListLocal());
-  int64_t now = Now();
+  int64_t now = 12345;
 
   pb_entry->set_entry_id("http://example.com/");
   pb_entry->set_url("http://example.com/");
@@ -349,10 +345,9 @@
   EXPECT_EQ(waiting_entry->DistilledPath(), base::FilePath());
   EXPECT_EQ(waiting_entry->DistillationSize(), 50);
   EXPECT_EQ(waiting_entry->DistillationTime(), now);
-  base::Time waiting_next_call =
-      base::Time::Now() + waiting_entry->TimeUntilNextTry();
-  base::TimeDelta delta = next_call - waiting_next_call;
-  EXPECT_NEAR(delta.InMillisecondsRoundedUp(), 0, 10);
+  double fuzzing = ReadingListEntry::kBackoffPolicy.jitter_factor;
+  int nextTry = waiting_entry->TimeUntilNextTry().InMinutes();
+  EXPECT_NEAR(kFirstBackoff, nextTry, kFirstBackoff * fuzzing);
 }
 
 // Tests the merging of two ReadingListEntry.
@@ -361,7 +356,6 @@
 TEST(ReadingListEntry, MergeWithEntry) {
   ReadingListEntry local_entry(GURL("http://example.com/"), "title");
   local_entry.SetDistilledState(ReadingListEntry::ERROR);
-  base::Time next_call = base::Time::Now() + local_entry.TimeUntilNextTry();
   int64_t local_update_time_us = local_entry.UpdateTime();
 
   ReadingListEntry sync_entry(GURL("http://example.com/"), "title2");
@@ -375,8 +369,7 @@
   EXPECT_EQ(local_entry.UpdateTime(), sync_update_time_us);
   EXPECT_EQ(local_entry.FailedDownloadCounter(), 1);
   EXPECT_EQ(local_entry.DistilledState(), ReadingListEntry::ERROR);
-  base::Time merge_next_call =
-      base::Time::Now() + local_entry.TimeUntilNextTry();
-  base::TimeDelta delta = merge_next_call - next_call;
-  EXPECT_NEAR(delta.InMillisecondsRoundedUp(), 0, 10);
+  double fuzzing = ReadingListEntry::kBackoffPolicy.jitter_factor;
+  int nextTry = local_entry.TimeUntilNextTry().InMinutes();
+  EXPECT_NEAR(kFirstBackoff, nextTry, kFirstBackoff * fuzzing);
 }
diff --git a/components/tracing/BUILD.gn b/components/tracing/BUILD.gn
index 6608413..deab4a6 100644
--- a/components/tracing/BUILD.gn
+++ b/components/tracing/BUILD.gn
@@ -7,6 +7,8 @@
 
 component("tracing") {
   sources = [
+    "child/child_memory_dump_manager_delegate_impl.cc",
+    "child/child_memory_dump_manager_delegate_impl.h",
     "child/child_trace_message_filter.cc",
     "child/child_trace_message_filter.h",
     "common/graphics_memory_dump_provider_android.cc",
diff --git a/components/tracing/child/child_memory_dump_manager_delegate_impl.cc b/components/tracing/child/child_memory_dump_manager_delegate_impl.cc
new file mode 100644
index 0000000..f0c4517b
--- /dev/null
+++ b/components/tracing/child/child_memory_dump_manager_delegate_impl.cc
@@ -0,0 +1,114 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/tracing/child/child_memory_dump_manager_delegate_impl.h"
+
+#include "base/single_thread_task_runner.h"
+#include "build/build_config.h"
+#include "components/tracing/child/child_trace_message_filter.h"
+#include "components/tracing/common/process_metrics_memory_dump_provider.h"
+
+namespace tracing {
+
+namespace {
+void AbortDumpRequest(const base::trace_event::MemoryDumpRequestArgs& args,
+                      const base::trace_event::MemoryDumpCallback& callback) {
+  if (!callback.is_null())
+    callback.Run(args.dump_guid, false /* success */);
+}
+}  // namespace
+
+// static
+ChildMemoryDumpManagerDelegateImpl*
+ChildMemoryDumpManagerDelegateImpl::GetInstance() {
+  return base::Singleton<
+      ChildMemoryDumpManagerDelegateImpl,
+      base::LeakySingletonTraits<ChildMemoryDumpManagerDelegateImpl>>::get();
+}
+
+ChildMemoryDumpManagerDelegateImpl::ChildMemoryDumpManagerDelegateImpl()
+    : ctmf_(nullptr),
+      tracing_process_id_(
+          base::trace_event::MemoryDumpManager::kInvalidTracingProcessId) {
+}
+
+ChildMemoryDumpManagerDelegateImpl::~ChildMemoryDumpManagerDelegateImpl() {}
+
+void ChildMemoryDumpManagerDelegateImpl::SetChildTraceMessageFilter(
+    ChildTraceMessageFilter* ctmf) {
+  auto* task_runner = ctmf ? (ctmf->ipc_task_runner()) : nullptr;
+  // Check that we are either registering the CTMF or tearing it down, but not
+  // replacing a valid instance with another one (should never happen).
+  DCHECK(!ctmf_ || (!ctmf && ctmf_task_runner_));
+  ctmf_ = ctmf;
+
+  {
+    base::AutoLock lock(lock_);
+    ctmf_task_runner_ = task_runner;
+  }
+
+  if (ctmf) {
+    base::trace_event::MemoryDumpManager::GetInstance()->Initialize(
+      this /* delegate */, false /* is_coordinator */);
+
+#if !defined(OS_LINUX) && !defined(OS_NACL)
+    // On linux the browser process takes care of dumping process metrics.
+    // The child process is not allowed to do so due to BPF sandbox.
+    tracing::ProcessMetricsMemoryDumpProvider::RegisterForProcess(
+        base::kNullProcessId);
+#endif
+  }
+}
+
+// Invoked in child processes by the MemoryDumpManager.
+void ChildMemoryDumpManagerDelegateImpl::RequestGlobalMemoryDump(
+    const base::trace_event::MemoryDumpRequestArgs& args,
+    const base::trace_event::MemoryDumpCallback& callback) {
+  // RequestGlobalMemoryDump can be called on any thread, cannot access
+  // ctmf_task_runner_ as it could be racy.
+  scoped_refptr<base::SingleThreadTaskRunner> ctmf_task_runner;
+  {
+    base::AutoLock lock(lock_);
+    ctmf_task_runner = ctmf_task_runner_;
+  }
+
+  // Bail out if we receive a dump request from the manager before the
+  // ChildTraceMessageFilter has been initialized.
+  if (!ctmf_task_runner) {
+    VLOG(1) << base::trace_event::MemoryDumpManager::kLogPrefix
+            << " failed because child trace message filter hasn't been"
+            << " initialized";
+    return AbortDumpRequest(args, callback);
+  }
+
+  // Make sure we access |ctmf_| only on the thread where it lives to avoid
+  // races on shutdown.
+  if (!ctmf_task_runner->BelongsToCurrentThread()) {
+    const bool did_post_task = ctmf_task_runner->PostTask(
+        FROM_HERE,
+        base::Bind(&ChildMemoryDumpManagerDelegateImpl::RequestGlobalMemoryDump,
+                   base::Unretained(this), args, callback));
+    if (!did_post_task)
+      return AbortDumpRequest(args, callback);
+    return;
+  }
+
+  // The ChildTraceMessageFilter could have been destroyed while hopping on the
+  // right thread. If this is the case, bail out.
+  if (!ctmf_) {
+    VLOG(1) << base::trace_event::MemoryDumpManager::kLogPrefix
+            << " failed because child trace message filter was"
+            << " destroyed while switching threads";
+    return AbortDumpRequest(args, callback);
+  }
+
+  // Send the request up to the browser process' MessageDumpmanager.
+  ctmf_->SendGlobalMemoryDumpRequest(args, callback);
+}
+
+uint64_t ChildMemoryDumpManagerDelegateImpl::GetTracingProcessId() const {
+  return tracing_process_id_;
+}
+
+}  // namespace tracing
diff --git a/components/tracing/child/child_memory_dump_manager_delegate_impl.h b/components/tracing/child/child_memory_dump_manager_delegate_impl.h
new file mode 100644
index 0000000..fc27d96
--- /dev/null
+++ b/components/tracing/child/child_memory_dump_manager_delegate_impl.h
@@ -0,0 +1,85 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_TRACING_CHILD_CHILD_MEMORY_DUMP_MANAGER_DELEGATE_IMPL_H_
+#define COMPONENTS_TRACING_CHILD_CHILD_MEMORY_DUMP_MANAGER_DELEGATE_IMPL_H_
+
+#include "base/trace_event/memory_dump_manager.h"
+
+#include <stdint.h>
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/singleton.h"
+#include "base/synchronization/lock.h"
+#include "components/tracing/tracing_export.h"
+
+namespace base {
+class SingleThreadTaskRunner;
+}  // namespace base
+
+namespace tracing {
+
+class ChildTraceMessageFilter;
+
+// This class is a simple proxy class between the MemoryDumpManager and the
+// ChildTraceMessageFilter. It's only purpose is to adapt the lifetime of
+// CTMF to the demands of MDM, which expects the delegate to be thread-safe
+// and long lived. CTMF, instead, can be torn down during browser shutdown.
+// This class is registered as MDM delegate in child processes and handles
+// gracefully (and thread-safely) failures in the case of a lack of the CTMF.
+class TRACING_EXPORT ChildMemoryDumpManagerDelegateImpl
+    : public base::trace_event::MemoryDumpManagerDelegate {
+ public:
+  static ChildMemoryDumpManagerDelegateImpl* GetInstance();
+
+  // base::trace_event::MemoryDumpManagerDelegate implementation.
+  void RequestGlobalMemoryDump(
+      const base::trace_event::MemoryDumpRequestArgs& args,
+      const base::trace_event::MemoryDumpCallback& callback) override;
+  uint64_t GetTracingProcessId() const override;
+
+  void SetChildTraceMessageFilter(ChildTraceMessageFilter* ctmf);
+
+  // Pass kInvalidTracingProcessId to invalidate the id.
+  void set_tracing_process_id(uint64_t id) {
+    DCHECK(tracing_process_id_ ==
+               base::trace_event::MemoryDumpManager::kInvalidTracingProcessId ||
+           id ==
+               base::trace_event::MemoryDumpManager::kInvalidTracingProcessId ||
+           id == tracing_process_id_);
+    tracing_process_id_ = id;
+  }
+
+ protected:
+  // Make CreateProcessDump() visible to ChildTraceMessageFilter.
+  friend class ChildTraceMessageFilter;
+
+ private:
+  friend struct base::DefaultSingletonTraits<
+      ChildMemoryDumpManagerDelegateImpl>;
+
+  ChildMemoryDumpManagerDelegateImpl();
+  ~ChildMemoryDumpManagerDelegateImpl() override;
+
+  ChildTraceMessageFilter* ctmf_;  // Not owned.
+
+  // The SingleThreadTaskRunner where the |ctmf_| lives.
+  // It is NULL iff |cmtf_| is NULL.
+  scoped_refptr<base::SingleThreadTaskRunner> ctmf_task_runner_;
+
+  // Protects from concurrent access to |ctmf_task_runner_| to allow
+  // RequestGlobalMemoryDump to be called from arbitrary threads.
+  base::Lock lock_;
+
+  // The unique id of the child process, created for tracing and is expected to
+  // be valid only when tracing is enabled.
+  uint64_t tracing_process_id_;
+
+  DISALLOW_COPY_AND_ASSIGN(ChildMemoryDumpManagerDelegateImpl);
+};
+
+}  // namespace tracing
+
+#endif  // COMPONENTS_TRACING_CHILD_CHILD_MEMORY_DUMP_MANAGER_DELEGATE_IMPL_H_
diff --git a/components/tracing/child/child_trace_message_filter.cc b/components/tracing/child/child_trace_message_filter.cc
index 6012a96a..ed2be875 100644
--- a/components/tracing/child/child_trace_message_filter.cc
+++ b/components/tracing/child/child_trace_message_filter.cc
@@ -8,13 +8,11 @@
 
 #include "base/memory/ref_counted_memory.h"
 #include "base/metrics/statistics_recorder.h"
-#include "base/trace_event/memory_dump_manager.h"
 #include "base/trace_event/trace_event.h"
-#include "components/tracing/common/process_metrics_memory_dump_provider.h"
+#include "components/tracing/child/child_memory_dump_manager_delegate_impl.h"
 #include "components/tracing/common/tracing_messages.h"
 #include "ipc/ipc_channel.h"
 
-using base::trace_event::MemoryDumpManager;
 using base::trace_event::TraceLog;
 
 namespace tracing {
@@ -27,18 +25,16 @@
 
 ChildTraceMessageFilter::ChildTraceMessageFilter(
     base::SingleThreadTaskRunner* ipc_task_runner)
-    : sender_(NULL), ipc_task_runner_(ipc_task_runner) {}
+    : sender_(NULL),
+      ipc_task_runner_(ipc_task_runner),
+      pending_memory_dump_guid_(0) {
+}
 
 void ChildTraceMessageFilter::OnFilterAdded(IPC::Channel* channel) {
   sender_ = channel;
   sender_->Send(new TracingHostMsg_ChildSupportsTracing());
-
-#if !defined(OS_LINUX) && !defined(OS_NACL)
-  // On linux the browser process takes care of dumping process metrics.
-  // The child process is not allowed to do so due to BPF sandbox.
-  tracing::ProcessMetricsMemoryDumpProvider::RegisterForProcess(
-      base::kNullProcessId);
-#endif
+  ChildMemoryDumpManagerDelegateImpl::GetInstance()->SetChildTraceMessageFilter(
+      this);
 }
 
 void ChildTraceMessageFilter::SetSenderForTesting(IPC::Sender* sender) {
@@ -46,6 +42,8 @@
 }
 
 void ChildTraceMessageFilter::OnFilterRemoved() {
+  ChildMemoryDumpManagerDelegateImpl::GetInstance()->SetChildTraceMessageFilter(
+      nullptr);
   sender_ = NULL;
 }
 
@@ -56,6 +54,10 @@
     IPC_MESSAGE_HANDLER(TracingMsg_EndTracing, OnEndTracing)
     IPC_MESSAGE_HANDLER(TracingMsg_CancelTracing, OnCancelTracing)
     IPC_MESSAGE_HANDLER(TracingMsg_GetTraceLogStatus, OnGetTraceLogStatus)
+    IPC_MESSAGE_HANDLER(TracingMsg_ProcessMemoryDumpRequest,
+                        OnProcessMemoryDumpRequest)
+    IPC_MESSAGE_HANDLER(TracingMsg_GlobalMemoryDumpResponse,
+                        OnGlobalMemoryDumpResponse)
     IPC_MESSAGE_HANDLER(TracingMsg_SetUMACallback, OnSetUMACallback)
     IPC_MESSAGE_HANDLER(TracingMsg_ClearUMACallback, OnClearUMACallback)
     IPC_MESSAGE_UNHANDLED(handled = false)
@@ -76,7 +78,8 @@
   base::TimeDelta time_offset = base::TimeTicks::Now() - browser_time;
   TraceLog::GetInstance()->SetTimeOffset(time_offset);
 #endif
-  MemoryDumpManager::GetInstance()->set_tracing_process_id(tracing_process_id);
+  ChildMemoryDumpManagerDelegateImpl::GetInstance()->set_tracing_process_id(
+      tracing_process_id);
   TraceLog::GetInstance()->SetEnabled(
       base::trace_event::TraceConfig(trace_config_str),
       base::trace_event::TraceLog::RECORDING_MODE);
@@ -92,8 +95,8 @@
   TraceLog::GetInstance()->Flush(
       base::Bind(&ChildTraceMessageFilter::OnTraceDataCollected, this));
 
-  MemoryDumpManager::GetInstance()->set_tracing_process_id(
-      MemoryDumpManager::kInvalidTracingProcessId);
+  ChildMemoryDumpManagerDelegateImpl::GetInstance()->set_tracing_process_id(
+      base::trace_event::MemoryDumpManager::kInvalidTracingProcessId);
 }
 
 void ChildTraceMessageFilter::OnCancelTracing() {
@@ -126,6 +129,52 @@
   }
 }
 
+// Sent by the Browser's MemoryDumpManager when coordinating a global dump.
+void ChildTraceMessageFilter::OnProcessMemoryDumpRequest(
+    const base::trace_event::MemoryDumpRequestArgs& args) {
+  ChildMemoryDumpManagerDelegateImpl::GetInstance()->CreateProcessDump(
+      args,
+      base::Bind(&ChildTraceMessageFilter::OnProcessMemoryDumpDone, this));
+}
+
+void ChildTraceMessageFilter::OnProcessMemoryDumpDone(uint64_t dump_guid,
+                                                      bool success) {
+  sender_->Send(
+      new TracingHostMsg_ProcessMemoryDumpResponse(dump_guid, success));
+}
+
+// Initiates a dump request, asking the Browser's MemoryDumpManager to
+// coordinate a global memory dump. The Browser's MDM will answer back with a
+// MemoryDumpResponse when all the child processes (including this one) have
+// dumped, or with a NACK (|success| == false) if the dump failed (e.g., due to
+// a collision with a concurrent request from another child process).
+void ChildTraceMessageFilter::SendGlobalMemoryDumpRequest(
+    const base::trace_event::MemoryDumpRequestArgs& args,
+    const base::trace_event::MemoryDumpCallback& callback) {
+  // If there is already another dump request pending from this child process,
+  // there is no point bothering the Browser's MemoryDumpManager.
+  if (pending_memory_dump_guid_) {
+    if (!callback.is_null())
+      callback.Run(args.dump_guid, false);
+    return;
+  }
+
+  pending_memory_dump_guid_ = args.dump_guid;
+  pending_memory_dump_callback_ = callback;
+  sender_->Send(new TracingHostMsg_GlobalMemoryDumpRequest(args));
+}
+
+// Sent by the Browser's MemoryDumpManager in response of a dump request
+// initiated by this child process.
+void ChildTraceMessageFilter::OnGlobalMemoryDumpResponse(uint64_t dump_guid,
+                                                         bool success) {
+  DCHECK_NE(0U, pending_memory_dump_guid_);
+  pending_memory_dump_guid_ = 0;
+  if (pending_memory_dump_callback_.is_null())
+    return;
+  pending_memory_dump_callback_.Run(dump_guid, success);
+}
+
 void ChildTraceMessageFilter::OnHistogramChanged(
     const std::string& histogram_name,
     base::Histogram::Sample reference_lower_value,
diff --git a/components/tracing/child/child_trace_message_filter.h b/components/tracing/child/child_trace_message_filter.h
index 619de78..287abd3 100644
--- a/components/tracing/child/child_trace_message_filter.h
+++ b/components/tracing/child/child_trace_message_filter.h
@@ -12,6 +12,7 @@
 #include "base/memory/ref_counted_memory.h"
 #include "base/metrics/histogram.h"
 #include "base/time/time.h"
+#include "base/trace_event/memory_dump_request_args.h"
 #include "components/tracing/tracing_export.h"
 #include "ipc/message_filter.h"
 
@@ -32,6 +33,10 @@
   void OnFilterRemoved() override;
   bool OnMessageReceived(const IPC::Message& message) override;
 
+  void SendGlobalMemoryDumpRequest(
+      const base::trace_event::MemoryDumpRequestArgs& args,
+      const base::trace_event::MemoryDumpCallback& callback);
+
   base::SingleThreadTaskRunner* ipc_task_runner() const {
     return ipc_task_runner_;
   }
@@ -53,6 +58,9 @@
                        const std::string& event_name);
   void OnCancelWatchEvent();
   void OnWatchEventMatched();
+  void OnProcessMemoryDumpRequest(
+      const base::trace_event::MemoryDumpRequestArgs& args);
+  void OnGlobalMemoryDumpResponse(uint64_t dump_guid, bool success);
   void OnSetUMACallback(const std::string& histogram_name,
                         int histogram_lower_value,
                         int histogram_upper_value,
@@ -71,11 +79,20 @@
       const scoped_refptr<base::RefCountedString>& events_str_ptr,
       bool has_more_events);
 
+  void OnProcessMemoryDumpDone(uint64_t dump_guid, bool success);
+
   void SetSenderForTesting(IPC::Sender* sender);
 
   IPC::Sender* sender_;
   base::SingleThreadTaskRunner* ipc_task_runner_;
 
+  // guid of the outstanding request (to the Browser's MemoryDumpManager), if
+  // any. 0 if there is no request pending.
+  uint64_t pending_memory_dump_guid_;
+
+  // callback of the outstanding memory dump request, if any.
+  base::trace_event::MemoryDumpCallback pending_memory_dump_callback_;
+
   base::Time histogram_last_changed_;
 
   DISALLOW_COPY_AND_ASSIGN(ChildTraceMessageFilter);
diff --git a/components/tracing/child/child_trace_message_filter_browsertest.cc b/components/tracing/child/child_trace_message_filter_browsertest.cc
new file mode 100644
index 0000000..d0d2d020
--- /dev/null
+++ b/components/tracing/child/child_trace_message_filter_browsertest.cc
@@ -0,0 +1,326 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <stdint.h>
+
+#include <memory>
+#include <tuple>
+
+#include "base/callback.h"
+#include "base/run_loop.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "base/trace_event/memory_dump_manager.h"
+#include "base/trace_event/memory_dump_provider.h"
+#include "base/trace_event/trace_event.h"
+#include "components/tracing/child/child_memory_dump_manager_delegate_impl.h"
+#include "components/tracing/child/child_trace_message_filter.h"
+#include "components/tracing/common/tracing_messages.h"
+#include "content/public/test/render_view_test.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+using base::trace_event::MemoryDumpManager;
+using base::trace_event::MemoryDumpRequestArgs;
+using base::trace_event::MemoryDumpArgs;
+using base::trace_event::MemoryDumpLevelOfDetail;
+using base::trace_event::MemoryDumpType;
+using testing::_;
+using testing::Return;
+
+namespace tracing {
+
+// A mock dump provider, used to check that dump requests actually end up
+// creating memory dumps.
+class MockDumpProvider : public base::trace_event::MemoryDumpProvider {
+ public:
+  MOCK_METHOD2(OnMemoryDump,
+               bool(const MemoryDumpArgs& args,
+                    base::trace_event::ProcessMemoryDump* pmd));
+};
+
+class ChildTracingTest : public content::RenderViewTest, public IPC::Listener {
+ public:
+  // Used as callback argument for MemoryDumpManager::RequestGlobalDump():
+  void OnMemoryDumpCallback(uint64_t dump_guid, bool status) {
+    last_callback_dump_guid_ = dump_guid;
+    last_callback_status_ = status;
+    ++callback_call_count_;
+  }
+
+ protected:
+  void SetUp() override {
+    // RenderViewTest::SetUp causes additional registrations, so we first
+    // register the mock dump provider and ignore registrations from then on.
+    // In addition to the mock dump provider, the TraceLog has already
+    // registered itself by now; this cannot be prevented easily.
+    mock_dump_provider_.reset(new MockDumpProvider());
+    MemoryDumpManager::GetInstance()->RegisterDumpProvider(
+        mock_dump_provider_.get(), "MockDumpProvider",
+        base::ThreadTaskRunnerHandle::Get());
+    MemoryDumpManager::GetInstance()
+        ->set_dumper_registrations_ignored_for_testing(true);
+
+    RenderViewTest::SetUp();
+
+    callback_call_count_ = 0;
+    last_callback_dump_guid_ = 0;
+    last_callback_status_ = false;
+    wait_for_ipc_message_type_ = 0;
+    callback_ = base::Bind(&ChildTracingTest::OnMemoryDumpCallback,
+                           base::Unretained(this));
+    task_runner_ = base::ThreadTaskRunnerHandle::Get();
+    ctmf_ = make_scoped_refptr(new ChildTraceMessageFilter(task_runner_.get()));
+    render_thread_->AddFilter(ctmf_.get());
+
+    // Add a filter to the TestSink which allows to WaitForIPCMessage() by
+    // posting a nested RunLoop closure when a given IPC Message is seen.
+    render_thread_->sink().AddFilter(this);
+
+    // Getting an instance of |ChildMemoryDumpManagerDelegateImpl| calls
+    // |MemoryDumpManager::Initialize| with the correct delegate.
+    ChildMemoryDumpManagerDelegateImpl::GetInstance();
+  }
+
+  void TearDown() override {
+    render_thread_->sink().RemoveFilter(this);
+    RenderViewTest::TearDown();
+    MemoryDumpManager::GetInstance()->UnregisterDumpProvider(
+        mock_dump_provider_.get());
+    mock_dump_provider_.reset();
+    ctmf_ = nullptr;
+    task_runner_ = nullptr;
+  }
+
+  // IPC::Filter implementation.
+  bool OnMessageReceived(const IPC::Message& message) override {
+    if (message.type() == wait_for_ipc_message_type_) {
+      DCHECK(!wait_for_ipc_closure_.is_null());
+      task_runner_->PostTask(FROM_HERE, wait_for_ipc_closure_);
+    }
+    // Always propagate messages to the sink, never consume them here.
+    return false;
+  }
+
+  const IPC::Message* WaitForIPCMessage(uint32_t message_type) {
+    base::RunLoop run_loop;
+    wait_for_ipc_message_type_ = message_type;
+    wait_for_ipc_closure_ = run_loop.QuitClosure();
+    run_loop.Run();
+    wait_for_ipc_message_type_ = 0;
+    wait_for_ipc_closure_.Reset();
+    return render_thread_->sink().GetUniqueMessageMatching(message_type);
+  }
+
+  // Simulates a synthetic browser -> child (this process) IPC message.
+  void SimulateSyntheticMessageFromBrowser(const IPC::Message& msg) {
+    ctmf_->OnMessageReceived(msg);
+  }
+
+  void EnableTracingWithMemoryDumps() {
+    // Re-enabling tracing could crash these tests https://crbug.com/656729 .
+    if (base::trace_event::TraceLog::GetInstance()->IsEnabled()) {
+      FAIL() << "Tracing seems to be already enabled. "
+                "Very likely this is because the startup tracing file "
+                "has been leaked from a previous test.";
+    }
+
+    std::string category_filter = "-*,";  // Disable all other trace categories.
+    category_filter += MemoryDumpManager::kTraceCategory;
+    base::trace_event::TraceConfig trace_config(category_filter, "");
+    TracingMsg_BeginTracing msg(trace_config.ToString(), base::TimeTicks(), 0);
+    SimulateSyntheticMessageFromBrowser(msg);
+  }
+
+  void DisableTracing() {
+    SimulateSyntheticMessageFromBrowser(TracingMsg_EndTracing());
+  }
+
+  // Simulates a synthetic browser -> child process memory dump request and
+  // checks that the child actually sends a response to that.
+  void RequestProcessMemoryDumpAndCheckResponse(uint64_t dump_guid) {
+    SimulateSyntheticMessageFromBrowser(TracingMsg_ProcessMemoryDumpRequest(
+        {dump_guid, MemoryDumpType::EXPLICITLY_TRIGGERED,
+         MemoryDumpLevelOfDetail::DETAILED}));
+
+    // Check that a child -> browser response to the local dump request is sent.
+    const IPC::Message* msg =
+        WaitForIPCMessage(TracingHostMsg_ProcessMemoryDumpResponse::ID);
+    EXPECT_NE(nullptr, msg);
+
+    // Check that the |dump_guid| and the |success| fields are properly set.
+    TracingHostMsg_ProcessMemoryDumpResponse::Param params;
+    TracingHostMsg_ProcessMemoryDumpResponse::Read(msg, &params);
+    const uint64_t resp_guid = std::get<0>(params);
+    const bool resp_success = std::get<1>(params);
+    EXPECT_EQ(dump_guid, resp_guid);
+    EXPECT_TRUE(resp_success);
+  }
+
+  // Retrieves the MemoryDumpRequestArgs of the global memory dump request that
+  // this child process tried to send to the browser. Fails if either none or
+  // multiple requests were sent.
+  MemoryDumpRequestArgs GetInterceptedGlobalMemoryDumpRequest() {
+    const IPC::Message* msg = render_thread_->sink().GetUniqueMessageMatching(
+        TracingHostMsg_GlobalMemoryDumpRequest::ID);
+    EXPECT_NE(nullptr, msg);
+    TracingHostMsg_GlobalMemoryDumpRequest::Param params;
+    TracingHostMsg_GlobalMemoryDumpRequest::Read(msg, &params);
+    MemoryDumpRequestArgs args = std::get<0>(params);
+    EXPECT_NE(0U, args.dump_guid);
+    return args;
+  }
+
+  scoped_refptr<ChildTraceMessageFilter> ctmf_;
+  std::unique_ptr<MockDumpProvider> mock_dump_provider_;
+  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+  base::trace_event::MemoryDumpCallback callback_;
+  uint32_t wait_for_ipc_message_type_;
+  base::Closure wait_for_ipc_closure_;
+  uint32_t callback_call_count_;
+  uint64_t last_callback_dump_guid_;
+  bool last_callback_status_;
+};
+
+// Covers the case of some browser-initiated memory dumps.
+#if defined(OS_ANDROID)
+// Flaky on Android. http://crbug.com/620734.
+#define MAYBE_BrowserInitiatedMemoryDumps DISABLED_BrowserInitiatedMemoryDumps
+#else
+#define MAYBE_BrowserInitiatedMemoryDumps BrowserInitiatedMemoryDumps
+#endif
+TEST_F(ChildTracingTest, MAYBE_BrowserInitiatedMemoryDumps) {
+  const uint32_t kNumDumps = 3;
+
+  EnableTracingWithMemoryDumps();
+  EXPECT_CALL(*mock_dump_provider_, OnMemoryDump(_, _))
+      .Times(kNumDumps)
+      .WillRepeatedly(Return(true));
+
+  for (uint32_t i = 0; i < kNumDumps; ++i) {
+    render_thread_->sink().ClearMessages();
+    RequestProcessMemoryDumpAndCheckResponse(i + 1);
+  }
+
+  DisableTracing();
+}
+
+// Covers the case of one simple child-initiated memory dump without callback,
+// simulating a global memory dump request to the browser (+ response).
+TEST_F(ChildTracingTest, SingleChildInitiatedMemoryDump) {
+  EnableTracingWithMemoryDumps();
+
+  // Expect that our mock dump provider is called when the emulated memory dump
+  // request (browser -> child) is sent.
+  EXPECT_CALL(*mock_dump_provider_, OnMemoryDump(_, _))
+      .Times(1)
+      .WillRepeatedly(Return(true));
+
+  // Send the global memory dump request to the browser.
+  render_thread_->sink().ClearMessages();
+  MemoryDumpManager::GetInstance()->RequestGlobalDump(
+      MemoryDumpType::EXPLICITLY_TRIGGERED, MemoryDumpLevelOfDetail::DETAILED);
+  base::RunLoop().RunUntilIdle();
+
+  // Check that the child -> browser global dump request IPC is actually sent.
+  MemoryDumpRequestArgs args = GetInterceptedGlobalMemoryDumpRequest();
+  EXPECT_EQ(MemoryDumpType::EXPLICITLY_TRIGGERED, args.dump_type);
+
+  // Emulate a browser -> child process dump request and corresponding response.
+  RequestProcessMemoryDumpAndCheckResponse(args.dump_guid);
+
+  // Send a synthetic browser -> child global memory dump response.
+  SimulateSyntheticMessageFromBrowser(
+      TracingMsg_GlobalMemoryDumpResponse(args.dump_guid, true));
+
+  DisableTracing();
+}
+
+// Covers the case of a global memory dump being requested while another one is
+// in progress and has not been acknowledged by the browser. The second request
+// is expected to fail immediately, while the first one is expected to suceed.
+TEST_F(ChildTracingTest, OverlappingChildInitiatedMemoryDumps) {
+  EnableTracingWithMemoryDumps();
+
+  // Expect that our mock dump provider is called only once.
+  EXPECT_CALL(*mock_dump_provider_, OnMemoryDump(_, _))
+      .Times(1)
+      .WillRepeatedly(Return(true));
+
+  // Send the global memory dump request to the browser.
+  render_thread_->sink().ClearMessages();
+  MemoryDumpManager::GetInstance()->RequestGlobalDump(
+      MemoryDumpType::EXPLICITLY_TRIGGERED, MemoryDumpLevelOfDetail::DETAILED,
+      callback_);
+  base::RunLoop().RunUntilIdle();
+
+  // Check that the child -> browser global dump request IPC is actually sent.
+  MemoryDumpRequestArgs args = GetInterceptedGlobalMemoryDumpRequest();
+  EXPECT_EQ(MemoryDumpType::EXPLICITLY_TRIGGERED, args.dump_type);
+
+  // Emulate a browser -> child process dump request and corresponding response.
+  RequestProcessMemoryDumpAndCheckResponse(args.dump_guid);
+
+  // Before the response for the first global dump is sent, send another one,
+  // and expect that to fail.
+  render_thread_->sink().ClearMessages();
+  MemoryDumpManager::GetInstance()->RequestGlobalDump(
+      MemoryDumpType::EXPLICITLY_TRIGGERED, MemoryDumpLevelOfDetail::DETAILED,
+      callback_);
+  base::RunLoop().RunUntilIdle();
+
+  EXPECT_EQ(1u, callback_call_count_);
+  EXPECT_FALSE(last_callback_status_);
+  // Whatever the guid of the second failing request is, it cannot possibly be
+  // equal to the guid of the first request.
+  EXPECT_NE(args.dump_guid, last_callback_dump_guid_);
+
+  // Also, check that no request has been forwarded to the browser (because the
+  // first request is still outstanding and has not received any response yet).
+  EXPECT_EQ(nullptr, render_thread_->sink().GetUniqueMessageMatching(
+                         TracingHostMsg_GlobalMemoryDumpRequest::ID));
+
+  // Now send a synthetic browser -> child response to the first request.
+  SimulateSyntheticMessageFromBrowser(
+      TracingMsg_GlobalMemoryDumpResponse(args.dump_guid, true));
+
+  // Verify that the the callback for the first request is finally called.
+  EXPECT_EQ(2u, callback_call_count_);
+  EXPECT_EQ(args.dump_guid, last_callback_dump_guid_);
+  EXPECT_TRUE(last_callback_status_);
+
+  DisableTracing();
+}
+
+// Covers the case of five child-initiated global memory dumps. Each global dump
+// request has a callback, which is expected to fail for 3 out of 5 cases.
+TEST_F(ChildTracingTest, MultipleChildInitiatedMemoryDumpWithFailures) {
+  const uint32_t kNumRequests = 5;
+  MemoryDumpType kDumpType = MemoryDumpType::EXPLICITLY_TRIGGERED;
+
+  EnableTracingWithMemoryDumps();
+  EXPECT_CALL(*mock_dump_provider_, OnMemoryDump(_, _))
+      .Times(kNumRequests)
+      .WillRepeatedly(Return(true));
+
+  for (uint32_t i = 0; i < kNumRequests; ++i) {
+    render_thread_->sink().ClearMessages();
+    MemoryDumpManager::GetInstance()->RequestGlobalDump(
+        kDumpType, MemoryDumpLevelOfDetail::DETAILED, callback_);
+    base::RunLoop().RunUntilIdle();
+
+    MemoryDumpRequestArgs args = GetInterceptedGlobalMemoryDumpRequest();
+    EXPECT_EQ(kDumpType, args.dump_type);
+    RequestProcessMemoryDumpAndCheckResponse(args.dump_guid);
+
+    const bool success = (i & 1) ? true : false;
+    SimulateSyntheticMessageFromBrowser(
+        TracingMsg_GlobalMemoryDumpResponse(args.dump_guid, success));
+    EXPECT_EQ(i + 1, callback_call_count_);
+    EXPECT_EQ(args.dump_guid, last_callback_dump_guid_);
+    EXPECT_EQ(success, last_callback_status_);
+  }
+
+  DisableTracing();
+}
+
+}  // namespace tracing
diff --git a/content/browser/browser_main.cc b/content/browser/browser_main.cc
index 5625a020..772010c 100644
--- a/content/browser/browser_main.cc
+++ b/content/browser/browser_main.cc
@@ -6,9 +6,7 @@
 
 #include <memory>
 
-#include "base/trace_event/memory_dump_manager.h"
 #include "base/trace_event/trace_event.h"
-#include "content/common/child_process_host_impl.h"
 #include "content/common/content_constants_internal.h"
 #include "content/public/browser/browser_main_runner.h"
 
@@ -38,8 +36,7 @@
   base::trace_event::TraceLog::GetInstance()->SetProcessName("Browser");
   base::trace_event::TraceLog::GetInstance()->SetProcessSortIndex(
       kTraceEventBrowserProcessSortIndex);
-  base::trace_event::MemoryDumpManager::GetInstance()->set_tracing_process_id(
-      ChildProcessHost::kBrowserTracingProcessId);
+
   std::unique_ptr<BrowserMainRunner> main_runner(BrowserMainRunner::Create());
 
   int exit_code = main_runner->Initialize(parameters);
diff --git a/content/browser/media/session/media_session_impl.cc b/content/browser/media/session/media_session_impl.cc
index dd2e1db..c3025c16 100644
--- a/content/browser/media/session/media_session_impl.cc
+++ b/content/browser/media/session/media_session_impl.cc
@@ -12,6 +12,7 @@
 #include "content/browser/web_contents/web_contents_impl.h"
 #include "content/public/browser/media_session.h"
 #include "content/public/browser/media_session_observer.h"
+#include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/web_contents.h"
 #include "media/base/media_content_type.h"
 
@@ -115,6 +116,16 @@
     OnServiceDestroyed(services_[rfh]);
 }
 
+void MediaSessionImpl::DidFinishNavigation(
+    NavigationHandle* navigation_handle) {
+  if (!navigation_handle->HasCommitted() || navigation_handle->IsSamePage())
+    return;
+
+  RenderFrameHost* rfh = navigation_handle->GetRenderFrameHost();
+  if (services_.count(rfh))
+    services_[rfh]->DidFinishNavigation();
+}
+
 void MediaSessionImpl::AddObserver(MediaSessionObserver* observer) {
   observers_.AddObserver(observer);
 }
diff --git a/content/browser/media/session/media_session_impl.h b/content/browser/media/session/media_session_impl.h
index 351486eb..f95ffba 100644
--- a/content/browser/media/session/media_session_impl.h
+++ b/content/browser/media/session/media_session_impl.h
@@ -44,6 +44,7 @@
 class MediaSessionObserver;
 class MediaSessionPlayerObserver;
 class MediaSessionServiceImpl;
+class MediaSessionServiceImplBrowserTest;
 
 #if defined(OS_ANDROID)
 class MediaSessionAndroid;
@@ -167,6 +168,7 @@
   // WebContentsObserver implementation
   void WebContentsDestroyed() override;
   void RenderFrameDeleted(RenderFrameHost* rfh) override;
+  void DidFinishNavigation(NavigationHandle* navigation_handle) override;
 
   // MediaSessionService-related methods
 
@@ -199,6 +201,7 @@
   friend class content::AudioFocusManagerTest;
   friend class content::MediaSessionImplServiceRoutingTest;
   friend class content::MediaSessionImplStateObserver;
+  friend class content::MediaSessionServiceImplBrowserTest;
 
   CONTENT_EXPORT void SetDelegateForTests(
       std::unique_ptr<AudioFocusDelegate> delegate);
diff --git a/content/browser/media/session/media_session_service_impl.cc b/content/browser/media/session/media_session_service_impl.cc
index cf452e22..524399df 100644
--- a/content/browser/media/session/media_session_service_impl.cc
+++ b/content/browser/media/session/media_session_service_impl.cc
@@ -43,6 +43,14 @@
                                  render_frame_routing_id_);
 }
 
+void MediaSessionServiceImpl::DidFinishNavigation() {
+  // At this point the BrowsingContext of the frame has changed, so the members
+  // need to be reset, and notify MediaSessionImpl.
+  SetPlaybackState(blink::mojom::MediaSessionPlaybackState::NONE);
+  SetMetadata(base::nullopt);
+  ClearActions();
+}
+
 void MediaSessionServiceImpl::SetClient(
     blink::mojom::MediaSessionClientPtr client) {
   client_ = std::move(client);
@@ -92,6 +100,13 @@
     session->OnMediaSessionActionsChanged(this);
 }
 
+void MediaSessionServiceImpl::ClearActions() {
+  actions_.clear();
+  MediaSessionImpl* session = GetMediaSession();
+  if (session)
+    session->OnMediaSessionActionsChanged(this);
+}
+
 MediaSessionImpl* MediaSessionServiceImpl::GetMediaSession() {
   RenderFrameHost* rfh = GetRenderFrameHost();
   if (!rfh)
diff --git a/content/browser/media/session/media_session_service_impl.h b/content/browser/media/session/media_session_service_impl.h
index 03113849..edcca6d 100644
--- a/content/browser/media/session/media_session_service_impl.h
+++ b/content/browser/media/session/media_session_service_impl.h
@@ -36,6 +36,8 @@
     return actions_;
   }
 
+  void DidFinishNavigation();
+
   // blink::mojom::MediaSessionService implementation.
   void SetClient(blink::mojom::MediaSessionClientPtr client) override;
 
@@ -53,6 +55,8 @@
 
   void Bind(blink::mojom::MediaSessionServiceRequest request);
 
+  void ClearActions();
+
   const int render_frame_process_id_;
   const int render_frame_routing_id_;
 
diff --git a/content/browser/media/session/media_session_service_impl_browsertest.cc b/content/browser/media/session/media_session_service_impl_browsertest.cc
index 959bbae..cfbdef1 100644
--- a/content/browser/media/session/media_session_service_impl_browsertest.cc
+++ b/content/browser/media/session/media_session_service_impl_browsertest.cc
@@ -2,19 +2,139 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "content/browser/media/session/media_session_service_impl.h"
+
 #include "base/command_line.h"
+#include "base/run_loop.h"
+#include "content/browser/media/session/media_session_impl.h"
+#include "content/browser/media/session/media_session_player_observer.h"
+#include "content/public/browser/web_contents_observer.h"
+#include "content/public/test/browser_test_utils.h"
 #include "content/public/test/content_browser_test.h"
 #include "content/public/test/content_browser_test_utils.h"
 #include "content/shell/browser/shell.h"
+#include "media/base/media_content_type.h"
+#include "testing/gtest/include/gtest/gtest.h"
 
 namespace content {
 
+namespace {
+
+class MockMediaSessionObserver : public MediaSessionObserver {
+ public:
+  explicit MockMediaSessionObserver(
+      MediaSession* session,
+      const base::Closure& closure_on_actions_change)
+      : MediaSessionObserver(session),
+        closure_on_actions_change_(closure_on_actions_change) {}
+
+  void MediaSessionActionsChanged(
+      const std::set<blink::mojom::MediaSessionAction>& actions) override {
+    // The actions might be empty when the service becomes routed for the first
+    // time.
+    if (actions.size() == 1)
+      closure_on_actions_change_.Run();
+  }
+
+ private:
+  base::Closure closure_on_actions_change_;
+};
+
+class MockWebContentsObserver : public WebContentsObserver {
+ public:
+  explicit MockWebContentsObserver(WebContents* contents,
+                                   const base::Closure& closure_on_navigate)
+      : WebContentsObserver(contents),
+        closure_on_navigate_(closure_on_navigate) {}
+
+  void DidFinishNavigation(NavigationHandle* navigation_handle) override {
+    closure_on_navigate_.Run();
+  }
+
+ private:
+  base::Closure closure_on_navigate_;
+};
+
+class MockMediaSessionPlayerObserver : public MediaSessionPlayerObserver {
+ public:
+  explicit MockMediaSessionPlayerObserver(RenderFrameHost* rfh)
+      : render_frame_host_(rfh) {}
+
+  ~MockMediaSessionPlayerObserver() override = default;
+
+  void OnSuspend(int player_id) override {}
+  void OnResume(int player_id) override {}
+  void OnSetVolumeMultiplier(int player_id, double volume_multiplier) override {
+  }
+
+  RenderFrameHost* GetRenderFrameHost() const override {
+    return render_frame_host_;
+  }
+
+ private:
+  RenderFrameHost* render_frame_host_;
+};
+
+void NavigateToURLAndWaitForFinish(Shell* window, const GURL& url) {
+  base::RunLoop run_loop;
+  MockWebContentsObserver observer(window->web_contents(),
+                                   run_loop.QuitClosure());
+
+  NavigateToURL(window, url);
+  run_loop.Run();
+}
+
+char kSetUpMediaSessionScript[] =
+    "navigator.mediaSession.playbackState = \"playing\";\n"
+    "navigator.mediaSession.metadata = new MediaMetadata({ title: \"foo\" });\n"
+    "navigator.mediaSession.setActionHandler(\"play\", _ => {});";
+
+const int kPlayerId = 0;
+
+}  // anonymous namespace
+
 class MediaSessionServiceImplBrowserTest : public ContentBrowserTest {
  protected:
   void SetUpCommandLine(base::CommandLine* command_line) override {
     ContentBrowserTest::SetUpCommandLine(command_line);
     command_line->AppendSwitchASCII("--enable-blink-features", "MediaSession");
   }
+
+  void EnsurePlayer() {
+    if (player_)
+      return;
+
+    player_.reset(new MockMediaSessionPlayerObserver(
+        shell()->web_contents()->GetMainFrame()));
+
+    MediaSessionImpl::Get(shell()->web_contents())
+        ->AddPlayer(player_.get(), kPlayerId,
+                    media::MediaContentType::Persistent);
+  }
+
+  MediaSessionImpl* GetSession() {
+    return MediaSessionImpl::Get(shell()->web_contents());
+  }
+
+  MediaSessionServiceImpl* GetService() {
+    RenderFrameHost* main_frame = shell()->web_contents()->GetMainFrame();
+    if (GetSession()->services_.count(main_frame))
+      return GetSession()->services_[main_frame];
+
+    return nullptr;
+  }
+
+  bool ExecuteScriptToSetUpMediaSessionSync() {
+    // Using the actions change as the signal of completion.
+    base::RunLoop run_loop;
+    MockMediaSessionObserver observer(GetSession(), run_loop.QuitClosure());
+    bool result = ExecuteScript(shell(), kSetUpMediaSessionScript);
+    run_loop.Run();
+    return result;
+  }
+
+ private:
+  std::unique_ptr<MockMediaSessionPlayerObserver> player_;
 };
 
 // Two windows from the same BrowserContext.
@@ -26,4 +146,51 @@
   // Should not crash.
 }
 
+// Tests for checking if the media session service members are correctly reset
+// when navigating. Due to the mojo services have different message queues, it's
+// hard to wait for the messages to arrive. Temporarily, the tests are using
+// observers to wait for the message to be processed on the MediaSessionObserver
+// side.
+
+IN_PROC_BROWSER_TEST_F(MediaSessionServiceImplBrowserTest,
+                       ResetServiceWhenNavigatingAway) {
+  NavigateToURL(shell(), GetTestUrl(".", "title1.html"));
+  EnsurePlayer();
+
+  EXPECT_TRUE(ExecuteScriptToSetUpMediaSessionSync());
+
+  EXPECT_EQ(blink::mojom::MediaSessionPlaybackState::PLAYING,
+            GetService()->playback_state());
+  EXPECT_TRUE(GetService()->metadata().has_value());
+  EXPECT_EQ(1u, GetService()->actions().size());
+
+  // Start a non-same-page navigation and check the playback state, metadata,
+  // actions are reset.
+  NavigateToURLAndWaitForFinish(shell(), GetTestUrl(".", "title2.html"));
+
+  EXPECT_EQ(blink::mojom::MediaSessionPlaybackState::NONE,
+            GetService()->playback_state());
+  EXPECT_FALSE(GetService()->metadata().has_value());
+  EXPECT_EQ(0u, GetService()->actions().size());
+}
+
+IN_PROC_BROWSER_TEST_F(MediaSessionServiceImplBrowserTest,
+                       DontResetServiceForSamePageNavigation) {
+  NavigateToURL(shell(), GetTestUrl(".", "title1.html"));
+  EnsurePlayer();
+
+  EXPECT_TRUE(ExecuteScriptToSetUpMediaSessionSync());
+
+  // Start a same-page navigation and check the playback state, metadata,
+  // actions are not reset.
+  GURL same_page_url = GetTestUrl(".", "title1.html");
+  same_page_url = GURL(same_page_url.spec() + "#some-anchor");
+  NavigateToURLAndWaitForFinish(shell(), same_page_url);
+
+  EXPECT_EQ(blink::mojom::MediaSessionPlaybackState::PLAYING,
+            GetService()->playback_state());
+  EXPECT_TRUE(GetService()->metadata().has_value());
+  EXPECT_EQ(1u, GetService()->actions().size());
+}
+
 }  // namespace content
diff --git a/content/browser/tracing/memory_tracing_browsertest.cc b/content/browser/tracing/memory_tracing_browsertest.cc
index 3ef05bfd..fe96666 100644
--- a/content/browser/tracing/memory_tracing_browsertest.cc
+++ b/content/browser/tracing/memory_tracing_browsertest.cc
@@ -20,7 +20,6 @@
 #include "content/public/test/content_browser_test.h"
 #include "content/public/test/content_browser_test_utils.h"
 #include "content/shell/browser/shell.h"
-#include "services/resource_coordinator/memory/coordinator/coordinator_impl.h"
 #include "testing/gmock/include/gmock/gmock.h"
 
 using base::trace_event::MemoryDumpArgs;
@@ -123,9 +122,6 @@
             GetTraceConfig_EmptyTriggers());
 
     base::RunLoop run_loop;
-    // Start the Coordinator service.
-    memory_instrumentation::CoordinatorImpl::GetInstance(
-        base::ThreadTaskRunnerHandle::Get().get());
     bool success = TracingController::GetInstance()->StartTracing(
       trace_config, run_loop.QuitClosure());
     EXPECT_TRUE(success);
diff --git a/content/browser/tracing/trace_message_filter.cc b/content/browser/tracing/trace_message_filter.cc
index a0e97d1b3..70089d9 100644
--- a/content/browser/tracing/trace_message_filter.cc
+++ b/content/browser/tracing/trace_message_filter.cc
@@ -46,6 +46,10 @@
                         OnTraceDataCollected)
     IPC_MESSAGE_HANDLER(TracingHostMsg_TraceLogStatusReply,
                         OnTraceLogStatusReply)
+    IPC_MESSAGE_HANDLER(TracingHostMsg_GlobalMemoryDumpRequest,
+                        OnGlobalMemoryDumpRequest)
+    IPC_MESSAGE_HANDLER(TracingHostMsg_ProcessMemoryDumpResponse,
+                        OnProcessMemoryDumpResponse)
     IPC_MESSAGE_HANDLER(TracingHostMsg_TriggerBackgroundTrace,
                         OnTriggerBackgroundTrace)
     IPC_MESSAGE_HANDLER(TracingHostMsg_AbortBackgroundTrace,
@@ -83,6 +87,18 @@
   Send(new TracingMsg_GetTraceLogStatus);
 }
 
+// Called by TracingControllerImpl, which handles the multiprocess coordination.
+void TraceMessageFilter::SendProcessMemoryDumpRequest(
+    const base::trace_event::MemoryDumpRequestArgs& args) {
+  Send(new TracingMsg_ProcessMemoryDumpRequest(args));
+}
+
+// Called by TracingControllerImpl, which handles the multiprocess coordination.
+void TraceMessageFilter::SendGlobalMemoryDumpResponse(uint64_t dump_guid,
+                                                      bool success) {
+  Send(new TracingMsg_GlobalMemoryDumpResponse(dump_guid, success));
+}
+
 void TraceMessageFilter::OnChildSupportsTracing() {
   has_child_ = true;
   TracingControllerImpl::GetInstance()->AddTraceMessageFilter(this);
@@ -117,6 +133,19 @@
   }
 }
 
+void TraceMessageFilter::OnGlobalMemoryDumpRequest(
+    const base::trace_event::MemoryDumpRequestArgs& args) {
+  TracingControllerImpl::GetInstance()->RequestGlobalMemoryDump(
+      args,
+      base::Bind(&TraceMessageFilter::SendGlobalMemoryDumpResponse, this));
+}
+
+void TraceMessageFilter::OnProcessMemoryDumpResponse(uint64_t dump_guid,
+                                                     bool success) {
+  TracingControllerImpl::GetInstance()->OnProcessMemoryDumpResponse(
+      this, dump_guid, success);
+}
+
 void TraceMessageFilter::OnTriggerBackgroundTrace(const std::string& name) {
   BackgroundTracingManagerImpl::GetInstance()->OnHistogramTrigger(name);
 }
diff --git a/content/browser/tracing/trace_message_filter.h b/content/browser/tracing/trace_message_filter.h
index 97ae0a2..94c435e 100644
--- a/content/browser/tracing/trace_message_filter.h
+++ b/content/browser/tracing/trace_message_filter.h
@@ -11,6 +11,7 @@
 #include <vector>
 
 #include "base/macros.h"
+#include "base/trace_event/memory_dump_request_args.h"
 #include "base/trace_event/trace_event.h"
 #include "content/public/browser/browser_message_filter.h"
 
@@ -35,6 +36,8 @@
   void SendSetWatchEvent(const std::string& category_name,
                          const std::string& event_name);
   void SendCancelWatchEvent();
+  void SendProcessMemoryDumpRequest(
+      const base::trace_event::MemoryDumpRequestArgs& args);
 
  protected:
   ~TraceMessageFilter() override;
@@ -46,6 +49,11 @@
   void OnWatchEventMatched();
   void OnTraceLogStatusReply(const base::trace_event::TraceLogStatus& status);
   void OnTraceDataCollected(const std::string& data);
+  void OnGlobalMemoryDumpRequest(
+      const base::trace_event::MemoryDumpRequestArgs& args);
+  void OnProcessMemoryDumpResponse(uint64_t dump_guid, bool success);
+
+  void SendGlobalMemoryDumpResponse(uint64_t dump_guid, bool success);
   void OnTriggerBackgroundTrace(const std::string& histogram_name);
   void OnAbortBackgroundTrace();
 
diff --git a/content/browser/tracing/tracing_controller_impl.cc b/content/browser/tracing/tracing_controller_impl.cc
index 54d1455..5fc480346 100644
--- a/content/browser/tracing/tracing_controller_impl.cc
+++ b/content/browser/tracing/tracing_controller_impl.cc
@@ -193,8 +193,13 @@
       pending_trace_log_status_ack_count_(0),
       maximum_trace_buffer_usage_(0),
       approximate_event_count_(0),
+      pending_memory_dump_ack_count_(0),
+      failed_memory_dump_count_(0),
       pending_clock_sync_ack_count_(0),
       is_tracing_(false) {
+  base::trace_event::MemoryDumpManager::GetInstance()->Initialize(
+      this /* delegate */, true /* is_coordinator */);
+
   // Deliberately leaked, like this class.
   base::FileTracing::SetProvider(new FileTracingProviderImpl);
 }
@@ -531,6 +536,20 @@
                      base::trace_event::TraceLogStatus()));
     }
   }
+  if (pending_memory_dump_ack_count_ > 0) {
+    DCHECK(!queued_memory_dump_requests_.empty());
+    TraceMessageFilterSet::const_iterator it =
+        pending_memory_dump_filters_.find(trace_message_filter);
+    if (it != pending_memory_dump_filters_.end()) {
+      BrowserThread::PostTask(
+          BrowserThread::UI, FROM_HERE,
+          base::Bind(&TracingControllerImpl::OnProcessMemoryDumpResponse,
+                     base::Unretained(this),
+                     base::RetainedRef(trace_message_filter),
+                     queued_memory_dump_requests_.front().args.dump_guid,
+                     false /* success */));
+    }
+  }
   trace_message_filters_.erase(trace_message_filter);
 }
 
@@ -877,6 +896,87 @@
   sink->AddMetadata(std::move(filtered_metadata));
 }
 
+void TracingControllerImpl::RequestGlobalMemoryDump(
+    const base::trace_event::MemoryDumpRequestArgs& args,
+    const base::trace_event::MemoryDumpCallback& callback) {
+  if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
+    BrowserThread::PostTask(
+        BrowserThread::UI, FROM_HERE,
+        base::Bind(&TracingControllerImpl::RequestGlobalMemoryDump,
+                   base::Unretained(this), args, callback));
+    return;
+  }
+
+  bool another_dump_already_in_progress = !queued_memory_dump_requests_.empty();
+
+  // If this is a periodic memory dump request and there already is another
+  // request in the queue with the same level of detail, there's no point in
+  // enqueuing this request.
+  if (another_dump_already_in_progress &&
+      args.dump_type == base::trace_event::MemoryDumpType::PERIODIC_INTERVAL) {
+    for (const auto& request : queued_memory_dump_requests_) {
+      if (request.args.level_of_detail == args.level_of_detail) {
+        VLOG(1) << base::trace_event::MemoryDumpManager::kLogPrefix << " ("
+                << base::trace_event::MemoryDumpTypeToString(args.dump_type)
+                << ") skipped because another dump request with the same "
+                   "level of detail ("
+                << base::trace_event::MemoryDumpLevelOfDetailToString(
+                       args.level_of_detail)
+                << ") is already in the queue";
+        if (!callback.is_null())
+          callback.Run(args.dump_guid, false /* success */);
+        return;
+      }
+    }
+  }
+
+  queued_memory_dump_requests_.emplace_back(args, callback);
+
+  // If another dump is already in progress, this dump will automatically be
+  // scheduled when the other dump finishes.
+  if (another_dump_already_in_progress)
+    return;
+
+  PerformNextQueuedGlobalMemoryDump();
+}
+
+void TracingControllerImpl::PerformNextQueuedGlobalMemoryDump() {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  DCHECK(!queued_memory_dump_requests_.empty());
+  const base::trace_event::MemoryDumpRequestArgs& args =
+      queued_memory_dump_requests_.front().args;
+
+  // Count myself (local trace) in pending_memory_dump_ack_count_, acked by
+  // OnBrowserProcessMemoryDumpDone().
+  pending_memory_dump_ack_count_ = trace_message_filters_.size() + 1;
+  pending_memory_dump_filters_.clear();
+  failed_memory_dump_count_ = 0;
+
+  MemoryDumpManagerDelegate::CreateProcessDump(
+      args, base::Bind(&TracingControllerImpl::OnBrowserProcessMemoryDumpDone,
+                       base::Unretained(this)));
+
+  // If there are no child processes we are just done.
+  if (pending_memory_dump_ack_count_ == 1)
+    return;
+
+  pending_memory_dump_filters_ = trace_message_filters_;
+
+  for (const scoped_refptr<TraceMessageFilter>& tmf : trace_message_filters_)
+    tmf->SendProcessMemoryDumpRequest(args);
+}
+
+TracingControllerImpl::QueuedMemoryDumpRequest::QueuedMemoryDumpRequest(
+    const base::trace_event::MemoryDumpRequestArgs& args,
+    const base::trace_event::MemoryDumpCallback& callback)
+    : args(args), callback(callback) {}
+
+TracingControllerImpl::QueuedMemoryDumpRequest::~QueuedMemoryDumpRequest() {}
+
+uint64_t TracingControllerImpl::GetTracingProcessId() const {
+  return ChildProcessHost::kBrowserTracingProcessId;
+}
+
 void TracingControllerImpl::AddTraceMessageFilterObserver(
     TraceMessageFilterObserver* observer) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -895,4 +995,76 @@
     observer->OnTraceMessageFilterRemoved(filter.get());
 }
 
+void TracingControllerImpl::OnProcessMemoryDumpResponse(
+    TraceMessageFilter* trace_message_filter,
+    uint64_t dump_guid,
+    bool success) {
+  if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
+    BrowserThread::PostTask(
+        BrowserThread::UI, FROM_HERE,
+        base::Bind(&TracingControllerImpl::OnProcessMemoryDumpResponse,
+                   base::Unretained(this),
+                   base::RetainedRef(trace_message_filter), dump_guid,
+                   success));
+    return;
+  }
+
+  TraceMessageFilterSet::iterator it =
+      pending_memory_dump_filters_.find(trace_message_filter);
+
+  DCHECK(!queued_memory_dump_requests_.empty());
+  if (queued_memory_dump_requests_.front().args.dump_guid != dump_guid ||
+      it == pending_memory_dump_filters_.end()) {
+    DLOG(WARNING) << "Received unexpected memory dump response: " << dump_guid;
+    return;
+  }
+
+  DCHECK_GT(pending_memory_dump_ack_count_, 0);
+  --pending_memory_dump_ack_count_;
+  pending_memory_dump_filters_.erase(it);
+  if (!success) {
+    ++failed_memory_dump_count_;
+    VLOG(1) << base::trace_event::MemoryDumpManager::kLogPrefix
+            << " failed because of NACK from child "
+            << trace_message_filter->peer_pid();
+  }
+  FinalizeGlobalMemoryDumpIfAllProcessesReplied();
+}
+
+void TracingControllerImpl::OnBrowserProcessMemoryDumpDone(uint64_t dump_guid,
+                                                           bool success) {
+  DCHECK_GT(pending_memory_dump_ack_count_, 0);
+  --pending_memory_dump_ack_count_;
+  if (!success) {
+    ++failed_memory_dump_count_;
+    VLOG(1) << base::trace_event::MemoryDumpManager::kLogPrefix
+            << " aborted on the current process";
+  }
+  FinalizeGlobalMemoryDumpIfAllProcessesReplied();
+}
+
+void TracingControllerImpl::FinalizeGlobalMemoryDumpIfAllProcessesReplied() {
+  if (pending_memory_dump_ack_count_ > 0)
+    return;
+
+  DCHECK(!queued_memory_dump_requests_.empty());
+  {
+    const auto& callback = queued_memory_dump_requests_.front().callback;
+    if (!callback.is_null()) {
+      const bool global_success = failed_memory_dump_count_ == 0;
+      callback.Run(queued_memory_dump_requests_.front().args.dump_guid,
+                   global_success);
+    }
+  }
+  queued_memory_dump_requests_.pop_front();
+
+  // Schedule the next queued dump (if applicable).
+  if (!queued_memory_dump_requests_.empty()) {
+    BrowserThread::PostTask(
+        BrowserThread::UI, FROM_HERE,
+        base::Bind(&TracingControllerImpl::PerformNextQueuedGlobalMemoryDump,
+                   base::Unretained(this)));
+  }
+}
+
 }  // namespace content
diff --git a/content/browser/tracing/tracing_controller_impl.h b/content/browser/tracing/tracing_controller_impl.h
index 81ce092..0c7b8ea7 100644
--- a/content/browser/tracing/tracing_controller_impl.h
+++ b/content/browser/tracing/tracing_controller_impl.h
@@ -47,6 +47,7 @@
 
 class TracingControllerImpl
     : public TracingController,
+      public base::trace_event::MemoryDumpManagerDelegate,
       public base::trace_event::TracingAgent {
  public:
   // Create an endpoint that may be supplied to any TraceDataSink to
@@ -87,6 +88,12 @@
       const std::string& sync_id,
       const RecordClockSyncMarkerCallback& callback) override;
 
+  // base::trace_event::MemoryDumpManagerDelegate implementation.
+  void RequestGlobalMemoryDump(
+      const base::trace_event::MemoryDumpRequestArgs& args,
+      const base::trace_event::MemoryDumpCallback& callback) override;
+  uint64_t GetTracingProcessId() const override;
+
   class TraceMessageFilterObserver {
    public:
     virtual void OnTraceMessageFilterAdded(TraceMessageFilter* filter) = 0;
@@ -99,6 +106,16 @@
   friend struct base::DefaultLazyInstanceTraits<TracingControllerImpl>;
   friend class TraceMessageFilter;
 
+  // The arguments and callback for an queued global memory dump request.
+  struct QueuedMemoryDumpRequest {
+    QueuedMemoryDumpRequest(
+        const base::trace_event::MemoryDumpRequestArgs& args,
+        const base::trace_event::MemoryDumpCallback& callback);
+    ~QueuedMemoryDumpRequest();
+    const base::trace_event::MemoryDumpRequestArgs args;
+    const base::trace_event::MemoryDumpCallback callback;
+  };
+
   TracingControllerImpl();
   ~TracingControllerImpl() override;
 
@@ -122,6 +139,8 @@
     return pending_trace_buffer_usage_callback_.is_null();
   }
 
+  void PerformNextQueuedGlobalMemoryDump();
+
   // Methods for use by TraceMessageFilter.
   void AddTraceMessageFilter(TraceMessageFilter* trace_message_filter);
   void RemoveTraceMessageFilter(TraceMessageFilter* trace_message_filter);
@@ -151,6 +170,14 @@
 
   void OnTraceLogStatusReply(TraceMessageFilter* trace_message_filter,
                              const base::trace_event::TraceLogStatus& status);
+  void OnProcessMemoryDumpResponse(TraceMessageFilter* trace_message_filter,
+                                   uint64_t dump_guid,
+                                   bool success);
+
+  // Callback of MemoryDumpManager::CreateProcessDump().
+  void OnBrowserProcessMemoryDumpDone(uint64_t dump_guid, bool success);
+
+  void FinalizeGlobalMemoryDumpIfAllProcessesReplied();
 
   void SetEnabledOnFileThread(
       const base::trace_event::TraceConfig& trace_config,
@@ -191,6 +218,12 @@
   float maximum_trace_buffer_usage_;
   size_t approximate_event_count_;
 
+  // Pending acks for memory RequestGlobalDumpPoint.
+  int pending_memory_dump_ack_count_;
+  int failed_memory_dump_count_;
+  TraceMessageFilterSet pending_memory_dump_filters_;
+  std::list<QueuedMemoryDumpRequest> queued_memory_dump_requests_;
+
   std::vector<base::trace_event::TracingAgent*> additional_tracing_agents_;
   int pending_clock_sync_ack_count_;
   base::OneShotTimer clock_sync_timer_;
diff --git a/content/child/BUILD.gn b/content/child/BUILD.gn
index 4eb0e6b6..da0aba5 100644
--- a/content/child/BUILD.gn
+++ b/content/child/BUILD.gn
@@ -240,7 +240,6 @@
     "//net",
     "//services/device/public/cpp/power_monitor",
     "//services/device/public/interfaces:constants",
-    "//services/resource_coordinator/public/cpp",
     "//services/service_manager/public/cpp",
     "//services/service_manager/public/interfaces",
     "//services/service_manager/runner/common",
diff --git a/content/child/DEPS b/content/child/DEPS
index 3a07c1cb..3f315c9 100644
--- a/content/child/DEPS
+++ b/content/child/DEPS
@@ -11,7 +11,6 @@
   "+content/public/child",
   "+services/device/public/cpp/power_monitor",
   "+services/device/public/interfaces",
-  "+services/resource_coordinator",
   "+services/service_manager",
   "+services/service_manager",
   "+v8/include/v8.h"
diff --git a/content/child/child_thread_impl.cc b/content/child/child_thread_impl.cc
index 135a424..0e42540 100644
--- a/content/child/child_thread_impl.cc
+++ b/content/child/child_thread_impl.cc
@@ -66,7 +66,6 @@
 #include "mojo/public/cpp/system/platform_handle.h"
 #include "services/device/public/cpp/power_monitor/power_monitor_broadcast_source.h"
 #include "services/device/public/interfaces/constants.mojom.h"
-#include "services/resource_coordinator/public/cpp/memory/memory_dump_manager_delegate_impl.h"
 #include "services/service_manager/public/cpp/connector.h"
 #include "services/service_manager/public/cpp/interface_factory.h"
 #include "services/service_manager/public/cpp/interface_provider.h"
@@ -503,10 +502,6 @@
     channel_->AddFilter(new tracing::ChildTraceMessageFilter(
         ChildProcess::current()->io_task_runner()));
     channel_->AddFilter(new ChildMemoryMessageFilter());
-
-    memory_instrumentation::MemoryDumpManagerDelegateImpl* delegate =
-        memory_instrumentation::MemoryDumpManagerDelegateImpl::GetInstance();
-    delegate->InitializeWithInterfaceProvider(GetRemoteInterfaces());
   }
 
   // In single process mode we may already have a power monitor,
diff --git a/content/public/app/mojo/content_browser_manifest.json b/content/public/app/mojo/content_browser_manifest.json
index 89024675..5628eb4 100644
--- a/content/public/app/mojo/content_browser_manifest.json
+++ b/content/public/app/mojo/content_browser_manifest.json
@@ -4,9 +4,6 @@
   "interface_provider_specs": {
     "service_manager:connector": {
       "provides": {
-        "gpu": [
-          "memory_instrumentation::mojom::Coordinator"
-        ],
         "plugin": [
           "discardable_memory::mojom::DiscardableSharedMemoryManager",
           "ui::mojom::Gpu"
@@ -37,7 +34,6 @@
           "discardable_memory::mojom::DiscardableSharedMemoryManager",
           "media::mojom::ImageCapture",
           "memory_coordinator::mojom::MemoryCoordinatorHandle",
-          "memory_instrumentation::mojom::Coordinator",
           "payments::mojom::PaymentAppManager",
           "shape_detection::mojom::BarcodeDetection",
           "shape_detection::mojom::FaceDetectionProvider",
diff --git a/content/shell/BUILD.gn b/content/shell/BUILD.gn
index 8058e76..d31f4685 100644
--- a/content/shell/BUILD.gn
+++ b/content/shell/BUILD.gn
@@ -369,7 +369,7 @@
   }
 
   if (is_linux) {
-    deps += [ "//third_party/freetype2" ]
+    deps += [ "//third_party/freetype-android:freetype" ]
   }
 
   if (!enable_plugins) {
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index 538bd27..e02d1a1 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -738,7 +738,6 @@
     "//net:test_support",
     "//ppapi/features",
     "//services/catalog:lib",
-    "//services/resource_coordinator:lib",
     "//services/service_manager/public/cpp",
     "//services/ui/public/cpp/gpu",
     "//storage/browser",
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_coordinator.mm b/ios/chrome/browser/ui/reading_list/reading_list_coordinator.mm
index 1dd5158..1dcd04a 100644
--- a/ios/chrome/browser/ui/reading_list/reading_list_coordinator.mm
+++ b/ios/chrome/browser/ui/reading_list/reading_list_coordinator.mm
@@ -58,7 +58,11 @@
 @property(nonatomic, strong) AlertCoordinator* alertCoordinator;
 
 // Opens |URL| in a new tab |incognito| or not.
-- (void)openNewTabWithURL:(const GURL&)URL incognito:(BOOL)incognito;
+- (void)openNewTabWithURL:(const GURL&)URL
+                                  incognito:(BOOL)incognito
+    fromReadingListCollectionViewController:
+        (ReadingListCollectionViewController*)
+            readingListCollectionViewController;
 
 // Opens the offline url |offlineURL| of the entry saved in the reading list
 // model with the |entryURL| url.
@@ -159,6 +163,8 @@
   const GURL entryURL = entry->URL();
 
   __weak ReadingListCoordinator* weakSelf = self;
+  __weak ReadingListCollectionViewController* weakCollection =
+      readingListCollectionViewController;
 
   _alertCoordinator = [[ActionSheetCoordinator alloc]
       initWithBaseViewController:self.containerViewController
@@ -174,7 +180,9 @@
   [_alertCoordinator
       addItemWithTitle:openInNewTabTitle
                 action:^{
-                  [weakSelf openNewTabWithURL:entryURL incognito:NO];
+                  [weakSelf openNewTabWithURL:entryURL
+                                                    incognito:NO
+                      fromReadingListCollectionViewController:weakCollection];
                   UMA_HISTOGRAM_ENUMERATION("ReadingList.ContextMenu", NEW_TAB,
                                             ENUM_MAX);
 
@@ -186,9 +194,11 @@
   [_alertCoordinator
       addItemWithTitle:openInNewTabIncognitoTitle
                 action:^{
+                  [weakSelf openNewTabWithURL:entryURL
+                                                    incognito:YES
+                      fromReadingListCollectionViewController:weakCollection];
                   UMA_HISTOGRAM_ENUMERATION("ReadingList.ContextMenu",
                                             NEW_INCOGNITO_TAB, ENUM_MAX);
-                  [weakSelf openNewTabWithURL:entryURL incognito:YES];
                 }
                  style:UIAlertActionStyleDefault];
 
@@ -215,8 +225,7 @@
                                               VIEW_OFFLINE, ENUM_MAX);
                     [weakSelf openOfflineURL:offlineURL
                                           correspondingEntryURL:entryURL
-                        fromReadingListCollectionViewController:
-                            readingListCollectionViewController];
+                        fromReadingListCollectionViewController:weakCollection];
                   }
                    style:UIAlertActionStyleDefault];
   }
@@ -248,6 +257,8 @@
 
   base::RecordAction(base::UserMetricsAction("MobileReadingListOpen"));
 
+  [readingListCollectionViewController willBeDismissed];
+
   [self.URLLoader loadURL:entry->URL()
                  referrer:web::Referrer()
                transition:ui::PAGE_TRANSITION_AUTO_BOOKMARK
@@ -263,9 +274,10 @@
     fromReadingListCollectionViewController:
         (ReadingListCollectionViewController*)
             readingListCollectionViewController {
-  [readingListCollectionViewController willBeDismissed];
-
-  [self openNewTabWithURL:offlineURL incognito:NO];
+  [self openNewTabWithURL:offlineURL
+                                    incognito:NO
+      fromReadingListCollectionViewController:
+          readingListCollectionViewController];
 
   UMA_HISTOGRAM_BOOLEAN("ReadingList.OfflineVersionDisplayed", true);
   const GURL updateURL = entryURL;
@@ -273,9 +285,14 @@
                                                                       true);
 }
 
-- (void)openNewTabWithURL:(const GURL&)URL incognito:(BOOL)incognito {
+- (void)openNewTabWithURL:(const GURL&)URL
+                                  incognito:(BOOL)incognito
+    fromReadingListCollectionViewController:
+        (ReadingListCollectionViewController*)
+            readingListCollectionViewController {
   base::RecordAction(base::UserMetricsAction("MobileReadingListOpen"));
 
+  [readingListCollectionViewController willBeDismissed];
   [self.URLLoader webPageOrderedOpen:URL
                             referrer:web::Referrer()
                          inIncognito:incognito
diff --git a/ios/chrome/browser/ui/settings/password_details_collection_view_controller.mm b/ios/chrome/browser/ui/settings/password_details_collection_view_controller.mm
index ebd4ba10..b07bc27e4 100644
--- a/ios/chrome/browser/ui/settings/password_details_collection_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/password_details_collection_view_controller.mm
@@ -37,8 +37,7 @@
   ItemTypeHeader = kItemTypeEnumZero,
   ItemTypeUsername,
   ItemTypePassword,
-  ItemTypeShow,
-  ItemTypeHide,
+  ItemTypeShowHide,
   ItemTypeCopy,
   ItemTypeDelete,
 };
@@ -148,9 +147,7 @@
 
   // TODO(crbug.com/159166): Change the style of the buttons once there are
   // final mocks.
-  [model addItem:[self showPasswordButtonItem]
-      toSectionWithIdentifier:SectionIdentifierPassword];
-  [model addItem:[self hidePasswordButtonItem]
+  [model addItem:[self showHidePasswordButtonItem]
       toSectionWithIdentifier:SectionIdentifierPassword];
   [model addItem:[self passwordCopyButtonItem]
       toSectionWithIdentifier:SectionIdentifierPassword];
@@ -165,14 +162,6 @@
 
 #pragma mark - Items
 
-- (CollectionViewItem*)showPasswordButtonItem {
-  CollectionViewTextItem* item =
-      [[[CollectionViewTextItem alloc] initWithType:ItemTypeShow] autorelease];
-  item.text = l10n_util::GetNSString(IDS_IOS_SETTINGS_PASSWORD_SHOW_BUTTON);
-  item.accessibilityTraits |= UIAccessibilityTraitButton;
-  return item;
-}
-
 - (CollectionViewItem*)passwordCopyButtonItem {
   CollectionViewTextItem* item =
       [[[CollectionViewTextItem alloc] initWithType:ItemTypeCopy] autorelease];
@@ -181,10 +170,10 @@
   return item;
 }
 
-- (CollectionViewItem*)hidePasswordButtonItem {
-  CollectionViewTextItem* item =
-      [[[CollectionViewTextItem alloc] initWithType:ItemTypeHide] autorelease];
-  item.text = l10n_util::GetNSString(IDS_IOS_SETTINGS_PASSWORD_HIDE_BUTTON);
+- (CollectionViewItem*)showHidePasswordButtonItem {
+  CollectionViewTextItem* item = [[[CollectionViewTextItem alloc]
+      initWithType:ItemTypeShowHide] autorelease];
+  item.text = [self showHideButtonText];
   item.accessibilityTraits |= UIAccessibilityTraitButton;
   return item;
 }
@@ -199,6 +188,28 @@
 
 #pragma mark - Actions
 
+- (NSString*)showHideButtonText {
+  if (_plainTextPasswordShown) {
+    return l10n_util::GetNSString(IDS_IOS_SETTINGS_PASSWORD_HIDE_BUTTON);
+  }
+  return l10n_util::GetNSString(IDS_IOS_SETTINGS_PASSWORD_SHOW_BUTTON);
+}
+
+// Changes the text on the Show/Hide button appropriately according to
+// |_plainTextPasswordShown|.
+- (void)toggleShowHideButton {
+  CollectionViewModel* model = self.collectionViewModel;
+  NSIndexPath* path = [model indexPathForItemType:ItemTypeShowHide
+                                sectionIdentifier:SectionIdentifierPassword];
+  CollectionViewTextItem* item =
+      base::mac::ObjCCastStrict<CollectionViewTextItem>(
+          [model itemAtIndexPath:path]);
+  item.text = [self showHideButtonText];
+  [self reconfigureCellsForItems:@[ item ]
+         inSectionWithIdentifier:SectionIdentifierPassword];
+  [self.collectionView.collectionViewLayout invalidateLayout];
+}
+
 - (void)showPassword {
   if (_plainTextPasswordShown) {
     return;
@@ -217,6 +228,7 @@
                    inSectionWithIdentifier:SectionIdentifierPassword];
       [[strongSelf collectionView].collectionViewLayout invalidateLayout];
       strongSelf.get()->_plainTextPasswordShown = YES;
+      [strongSelf toggleShowHideButton];
     };
 
     [_weakReauthenticationModule
@@ -235,6 +247,7 @@
          inSectionWithIdentifier:SectionIdentifierPassword];
   [self.collectionView.collectionViewLayout invalidateLayout];
   _plainTextPasswordShown = NO;
+  [self toggleShowHideButton];
 }
 
 - (void)copyPassword {
@@ -322,11 +335,12 @@
   NSInteger itemType =
       [self.collectionViewModel itemTypeForIndexPath:indexPath];
   switch (itemType) {
-    case ItemTypeShow:
-      [self showPassword];
-      break;
-    case ItemTypeHide:
-      [self hidePassword];
+    case ItemTypeShowHide:
+      if (_plainTextPasswordShown) {
+        [self hidePassword];
+      } else {
+        [self showPassword];
+      }
       break;
     case ItemTypeCopy:
       [self copyPassword];
diff --git a/ios/chrome/browser/ui/settings/password_details_collection_view_controller_unittest.mm b/ios/chrome/browser/ui/settings/password_details_collection_view_controller_unittest.mm
index 523c8602..1b588974 100644
--- a/ios/chrome/browser/ui/settings/password_details_collection_view_controller_unittest.mm
+++ b/ios/chrome/browser/ui/settings/password_details_collection_view_controller_unittest.mm
@@ -65,10 +65,9 @@
 
 NSString* kUsername = @"testusername";
 NSString* kPassword = @"testpassword";
-int kShowButtonItem = 1;
-int kHideButtonItem = 2;
-int kCopyButtonItem = 3;
-int kDeleteButtonItem = 4;
+int kShowHideButtonItem = 1;
+int kCopyButtonItem = 2;
+int kDeleteButtonItem = 3;
 int kUsernameSection = 0;
 int kUsernameItem = 0;
 int kPasswordSection = 1;
@@ -120,7 +119,7 @@
   EXPECT_NSEQ(kUsername, usernameItem.text);
   EXPECT_TRUE(usernameItem.showingText);
   // Password section
-  EXPECT_EQ(5, NumberOfItemsInSection(kPasswordSection));
+  EXPECT_EQ(4, NumberOfItemsInSection(kPasswordSection));
   CheckSectionHeaderWithId(IDS_IOS_SHOW_PASSWORD_VIEW_PASSWORD,
                            kPasswordSection);
   PasswordDetailsItem* passwordItem =
@@ -128,9 +127,7 @@
   EXPECT_NSEQ(kPassword, passwordItem.text);
   EXPECT_FALSE(passwordItem.showingText);
   CheckTextCellTitleWithId(IDS_IOS_SETTINGS_PASSWORD_SHOW_BUTTON,
-                           kPasswordSection, kShowButtonItem);
-  CheckTextCellTitleWithId(IDS_IOS_SETTINGS_PASSWORD_HIDE_BUTTON,
-                           kPasswordSection, kHideButtonItem);
+                           kPasswordSection, kShowHideButtonItem);
   CheckTextCellTitleWithId(IDS_IOS_SETTINGS_PASSWORD_COPY_BUTTON,
                            kPasswordSection, kCopyButtonItem);
   CheckTextCellTitleWithId(IDS_IOS_SETTINGS_PASSWORD_DELETE_BUTTON,
@@ -160,7 +157,7 @@
 TEST_F(PasswordDetailsCollectionViewControllerTest, ShowPassword) {
   CreateController();
   [controller() collectionView:[controller() collectionView]
-      didSelectItemAtIndexPath:[NSIndexPath indexPathForRow:kShowButtonItem
+      didSelectItemAtIndexPath:[NSIndexPath indexPathForRow:kShowHideButtonItem
                                                   inSection:kPasswordSection]];
   PasswordDetailsItem* passwordItem =
       GetCollectionViewItem(kPasswordSection, kPasswordItem);
@@ -169,17 +166,26 @@
   EXPECT_NSEQ(
       l10n_util::GetNSString(IDS_IOS_SETTINGS_PASSWORD_REAUTH_REASON_SHOW),
       reauthenticationModule_.get().localizedReasonForAuthentication);
+  CheckTextCellTitleWithId(IDS_IOS_SETTINGS_PASSWORD_HIDE_BUTTON,
+                           kPasswordSection, kShowHideButtonItem);
 }
 
 TEST_F(PasswordDetailsCollectionViewControllerTest, HidePassword) {
   CreateController();
+  // First show the password.
   [controller() collectionView:[controller() collectionView]
-      didSelectItemAtIndexPath:[NSIndexPath indexPathForRow:kHideButtonItem
+      didSelectItemAtIndexPath:[NSIndexPath indexPathForRow:kShowHideButtonItem
+                                                  inSection:kPasswordSection]];
+  // Then hide it.
+  [controller() collectionView:[controller() collectionView]
+      didSelectItemAtIndexPath:[NSIndexPath indexPathForRow:kShowHideButtonItem
                                                   inSection:kPasswordSection]];
   PasswordDetailsItem* passwordItem =
       GetCollectionViewItem(kPasswordSection, kPasswordItem);
   EXPECT_NSEQ(kPassword, passwordItem.text);
   EXPECT_FALSE(passwordItem.showingText);
+  CheckTextCellTitleWithId(IDS_IOS_SETTINGS_PASSWORD_SHOW_BUTTON,
+                           kPasswordSection, kShowHideButtonItem);
 }
 
 TEST_F(PasswordDetailsCollectionViewControllerTest, CopyPassword) {
diff --git a/media/renderers/skcanvas_video_renderer.cc b/media/renderers/skcanvas_video_renderer.cc
index 82a99ca..418c8be 100644
--- a/media/renderers/skcanvas_video_renderer.cc
+++ b/media/renderers/skcanvas_video_renderer.cc
@@ -22,8 +22,6 @@
 #include "third_party/skia/include/core/SkImageGenerator.h"
 #include "third_party/skia/include/gpu/GrContext.h"
 #include "third_party/skia/include/gpu/GrPaint.h"
-#include "third_party/skia/include/gpu/GrTexture.h"
-#include "third_party/skia/include/gpu/GrTextureProvider.h"
 #include "third_party/skia/include/gpu/SkGr.h"
 #include "third_party/skia/include/gpu/gl/GrGLTypes.h"
 #include "ui/gfx/geometry/rect_f.h"
diff --git a/net/tools/transport_security_state_generator/pinsets.h b/net/tools/transport_security_state_generator/pinsets.h
index b22f8c9..76790307 100644
--- a/net/tools/transport_security_state_generator/pinsets.h
+++ b/net/tools/transport_security_state_generator/pinsets.h
@@ -13,7 +13,6 @@
 #include "base/strings/string_piece.h"
 #include "net/tools/transport_security_state_generator/cert_util.h"
 #include "net/tools/transport_security_state_generator/pinset.h"
-#include "net/tools/transport_security_state_generator/pinsets.h"
 #include "net/tools/transport_security_state_generator/spki_hash.h"
 
 namespace net {
diff --git a/net/tools/transport_security_state_generator/preloaded_state_generator.cc b/net/tools/transport_security_state_generator/preloaded_state_generator.cc
index 64e89890..b1bcabb 100644
--- a/net/tools/transport_security_state_generator/preloaded_state_generator.cc
+++ b/net/tools/transport_security_state_generator/preloaded_state_generator.cc
@@ -4,10 +4,9 @@
 
 #include "net/tools/transport_security_state_generator/preloaded_state_generator.h"
 
-#include <iostream>
-
 #include <string>
 
+#include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "net/tools/transport_security_state_generator/cert_util.h"
@@ -133,8 +132,7 @@
     const std::string& preload_template,
     const TransportSecurityStateEntries& entries,
     const DomainIDList& domain_ids,
-    const Pinsets& pinsets,
-    bool verbose) {
+    const Pinsets& pinsets) {
   std::string output = preload_template;
 
   NameIDMap domain_ids_map;
@@ -161,32 +159,28 @@
   TrieWriter writer(table, domain_ids_map, expect_ct_report_uri_map,
                     expect_staple_report_uri_map, pinsets_map,
                     &huffman_builder);
-  writer.WriteEntries(entries);
-  uint32_t initial_length = writer.position();
+  uint32_t root_position;
+  if (!writer.WriteEntries(entries, &root_position)) {
+    return std::string();
+  }
 
   HuffmanRepresentationTable optimal_table = huffman_builder.ToTable();
   TrieWriter new_writer(optimal_table, domain_ids_map, expect_ct_report_uri_map,
                         expect_staple_report_uri_map, pinsets_map, nullptr);
 
-  uint32_t root_position = new_writer.WriteEntries(entries);
+  if (!new_writer.WriteEntries(entries, &root_position)) {
+    return std::string();
+  }
+
   uint32_t new_length = new_writer.position();
-
   std::vector<uint8_t> huffman_tree = huffman_builder.ToVector();
-
   new_writer.Flush();
 
   ReplaceTag("HUFFMAN_TREE", FormatVectorAsArray(huffman_tree), &output);
   ReplaceTag("HSTS_TRIE", FormatVectorAsArray(new_writer.bytes()), &output);
 
-  ReplaceTag("HSTS_TRIE_BITS", std::to_string(new_length), &output);
-  ReplaceTag("HSTS_TRIE_ROOT", std::to_string(root_position), &output);
-
-  if (verbose) {
-    std::cout << "Saved " << std::to_string(initial_length - new_length)
-              << " bits by using accurate Huffman counts." << std::endl;
-    std::cout << "Bit length " << std::to_string(new_length) << std::endl;
-    std::cout << "Root position " << std::to_string(root_position) << std::endl;
-  }
+  ReplaceTag("HSTS_TRIE_BITS", base::SizeTToString(new_length), &output);
+  ReplaceTag("HSTS_TRIE_ROOT", base::SizeTToString(root_position), &output);
 
   return output;
 }
@@ -275,6 +269,11 @@
     }
   }
 
+  output.append(kIndent);
+  output.append(kIndent);
+  output.append("NULL,");
+  output.append(kNewLine);
+
   output.append("}");
   ReplaceTag("EXPECT_CT_REPORT_URIS", output, tpl);
 }
@@ -302,6 +301,11 @@
     }
   }
 
+  output.append(kIndent);
+  output.append(kIndent);
+  output.append("NULL,");
+  output.append(kNewLine);
+
   output.append("}");
   ReplaceTag("EXPECT_STAPLE_REPORT_URIS", output, tpl);
 }
diff --git a/net/tools/transport_security_state_generator/preloaded_state_generator.h b/net/tools/transport_security_state_generator/preloaded_state_generator.h
index 562c4f38..f6b1573 100644
--- a/net/tools/transport_security_state_generator/preloaded_state_generator.h
+++ b/net/tools/transport_security_state_generator/preloaded_state_generator.h
@@ -28,11 +28,11 @@
   PreloadedStateGenerator();
   ~PreloadedStateGenerator();
 
+  // Returns the generated C++ code on success and the empty string on failure.
   std::string Generate(const std::string& preload_template,
                        const TransportSecurityStateEntries& entries,
                        const DomainIDList& domain_ids,
-                       const Pinsets& pinsets,
-                       bool verbose);
+                       const Pinsets& pinsets);
 
  private:
   // TODO(Martijnc): Remove the domain IDs from the preload format.
diff --git a/net/tools/transport_security_state_generator/transport_security_state_entry.cc b/net/tools/transport_security_state_generator/transport_security_state_entry.cc
index 189dc7c..729f990a 100644
--- a/net/tools/transport_security_state_generator/transport_security_state_entry.cc
+++ b/net/tools/transport_security_state_generator/transport_security_state_entry.cc
@@ -1,6 +1,7 @@
 // Copyright (c) 2016 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
+
 #include "net/tools/transport_security_state_generator/transport_security_state_entry.h"
 
 namespace net {
diff --git a/net/tools/transport_security_state_generator/transport_security_state_generator.cc b/net/tools/transport_security_state_generator/transport_security_state_generator.cc
index 8473414..45c528d 100644
--- a/net/tools/transport_security_state_generator/transport_security_state_generator.cc
+++ b/net/tools/transport_security_state_generator/transport_security_state_generator.cc
@@ -12,7 +12,9 @@
 #include "base/command_line.h"
 #include "base/files/file_util.h"
 #include "base/json/json_reader.h"
+#include "base/logging.h"
 #include "base/path_service.h"
+#include "base/strings/string_number_conversions.h"
 #include "base/strings/string_piece.h"
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
@@ -40,7 +42,7 @@
 // Print the command line help.
 void PrintHelp() {
   std::cout << "transport_security_state_generator <json-file> <pins-file>"
-            << " <template-file> <output-file> [-v]" << std::endl;
+            << " <template-file> <output-file> [--v=1]" << std::endl;
 }
 
 // Parses the |json| string and copies the items under the "entries" key to
@@ -56,20 +58,21 @@
   std::unique_ptr<base::Value> value = base::JSONReader::Read(json);
   base::DictionaryValue* dict_value = nullptr;
   if (!value.get() || !value->GetAsDictionary(&dict_value)) {
-    std::cerr << "Could not parse the input JSON" << std::endl;
+    LOG(ERROR) << "Could not parse the input JSON file";
     return false;
   }
 
   const base::ListValue* preload_entries = nullptr;
   if (!dict_value->GetList("entries", &preload_entries)) {
-    std::cerr << "Could not parse the entries in the input JSON" << std::endl;
+    LOG(ERROR) << "Could not parse the entries in the input JSON";
     return false;
   }
 
   for (size_t i = 0; i < preload_entries->GetSize(); ++i) {
     const base::DictionaryValue* parsed = nullptr;
     if (!preload_entries->GetDictionary(i, &parsed)) {
-      std::cerr << "Could not parse entry " << i << std::endl;
+      LOG(ERROR) << "Could not parse entry " << base::SizeTToString(i)
+                 << " in the input JSON";
       return false;
     }
 
@@ -77,7 +80,8 @@
         new TransportSecurityStateEntry());
 
     if (!parsed->GetString("name", &entry->hostname)) {
-      std::cerr << "Could not extract the name for entry " << i << std::endl;
+      LOG(ERROR) << "Could not extract the hostname for entry "
+                 << base::SizeTToString(i) << " from the input JSON";
       return false;
     }
 
@@ -101,20 +105,22 @@
 
   const base::ListValue* pinsets_list = nullptr;
   if (!dict_value->GetList("pinsets", &pinsets_list)) {
-    std::cerr << "Could not parse the pinsets in the input JSON" << std::endl;
+    LOG(ERROR) << "Could not parse the pinsets in the input JSON";
     return false;
   }
 
   for (size_t i = 0; i < pinsets_list->GetSize(); ++i) {
     const base::DictionaryValue* parsed = nullptr;
     if (!pinsets_list->GetDictionary(i, &parsed)) {
-      std::cerr << "Could not parse pinset " << i << std::endl;
+      LOG(ERROR) << "Could not parse pinset " << base::SizeTToString(i)
+                 << " in the input JSON";
       return false;
     }
 
     std::string name;
     if (!parsed->GetString("name", &name)) {
-      std::cerr << "Could not extract the name for pinset " << i << std::endl;
+      LOG(ERROR) << "Could not extract the name for pinset "
+                 << base::SizeTToString(i) << " from the input JSON";
       return false;
     }
 
@@ -149,7 +155,7 @@
   // https://crbug.com/661206.
   const base::ListValue* domain_ids_list = nullptr;
   if (!dict_value->GetList("domain_ids", &domain_ids_list)) {
-    std::cerr << "Failed parsing JSON (domain_ids)" << std::endl;
+    LOG(ERROR) << "Could not parse the domain IDs in the input JSON";
     return false;
   }
 
@@ -193,7 +199,8 @@
   std::vector<base::StringPiece> words = base::SplitStringPiece(
       name, " ", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
   if (words.empty()) {
-    std::cerr << "no words in certificate name" << std::endl;
+    LOG(ERROR) << "No words in certificate name for pin "
+               << pin_name.as_string();
     return false;
   }
   base::StringPiece first_word = words[0];
@@ -217,7 +224,8 @@
   }
 
   if (first_word.empty()) {
-    std::cerr << "first word of certificate name is empty" << std::endl;
+    LOG(ERROR) << "First word of certificate name (" << name.as_string()
+               << ") is empty";
     return false;
   }
 
@@ -225,10 +233,10 @@
   first_word = filtered_word;
   if (!base::EqualsCaseInsensitiveASCII(pin_name.substr(0, first_word.size()),
                                         first_word)) {
-    std::cerr << "the first word of the certificate name ("
-              << first_word.as_string()
-              << ") isn't a prefix of the variable name ("
-              << pin_name.as_string() << ")" << std::endl;
+    LOG(ERROR) << "The first word of the certificate name ("
+               << first_word.as_string()
+               << ") isn't a prefix of the variable name ("
+               << pin_name.as_string() << ")";
     return false;
   }
 
@@ -240,21 +248,25 @@
 
       size_t pos = pin_name.find(class_name);
       if (pos == std::string::npos) {
-        std::cerr << "class specification doesn't appear in the variable name"
-                  << std::endl;
+        LOG(ERROR)
+            << "Certficate class specification doesn't appear in the variable "
+               "name ("
+            << pin_name.as_string() << ")";
         return false;
       }
     } else if (word.size() == 1 && word[0] >= '0' && word[0] <= '9') {
       size_t pos = pin_name.find(word);
       if (pos == std::string::npos) {
-        std::cerr << "number doesn't appear in the variable name" << std::endl;
+        LOG(ERROR) << "Number doesn't appear in the certificate variable name ("
+                   << pin_name.as_string() << ")";
         return false;
       }
     } else if (IsImportantWordInCertificateName(word)) {
       size_t pos = pin_name.find(word);
       if (pos == std::string::npos) {
-        std::cerr << word.as_string() << " doesn't appear in the variable name"
-                  << std::endl;
+        LOG(ERROR) << word.as_string() +
+                          " doesn't appear in the certificate variable name ("
+                   << pin_name.as_string() << ")";
         return false;
       }
     }
@@ -324,7 +336,7 @@
     switch (current_state) {
       case CertificateParserState::PRE_NAME:
         if (!IsValidName(line)) {
-          std::cerr << "Invalid name in certificates file: " << line;
+          LOG(ERROR) << "Invalid name in pins file: " << line;
           return false;
         }
         name = line;
@@ -333,8 +345,7 @@
       case CertificateParserState::POST_NAME:
         if (base::StartsWith(line, kStartOfSHA256, compare_mode)) {
           if (!hash.FromString(line)) {
-            std::cerr << "Invalid hash value in certificate file for " << name
-                      << std::endl;
+            LOG(ERROR) << "Invalid hash value in pins file for " << name;
             return false;
           }
 
@@ -347,8 +358,7 @@
           buffer = line + '\n';
           current_state = CertificateParserState::IN_PUBLIC_KEY;
         } else {
-          std::cerr << "Invalid value in certificates file for " << name
-                    << std::endl;
+          LOG(ERROR) << "Invalid value in pins file for " << name;
           return false;
         }
         break;
@@ -360,26 +370,24 @@
 
         certificate = GetX509CertificateFromPEM(buffer);
         if (!certificate) {
-          std::cerr << "Could not parse certificate " << name << std::endl;
+          LOG(ERROR) << "Could not parse certificate " << name;
           return false;
         }
 
         if (!CalculateSPKIHashFromCertificate(certificate.get(), &hash)) {
-          std::cerr << "Could not extract SPKI from certificate " << name
-                    << std::endl;
+          LOG(ERROR) << "Could not extract SPKI from certificate " << name;
           return false;
         }
 
         if (!ExtractSubjectNameFromCertificate(certificate.get(),
                                                &subject_name)) {
-          std::cerr << "Could not extract name from certificate " << name
-                    << std::endl;
+          LOG(ERROR) << "Could not extract name from certificate " << name;
           return false;
         }
 
         if (!MatchCertificateName(subject_name, name)) {
-          std::cerr << name << " is not a reasonable name for " << subject_name
-                    << std::endl;
+          LOG(ERROR) << name << " is not a reasonable name for "
+                     << subject_name;
           return false;
         }
 
@@ -393,8 +401,7 @@
         }
 
         if (!CalculateSPKIHashFromKey(buffer, &hash)) {
-          std::cerr << "Parsing of the public key " << name << " failed"
-                    << std::endl;
+          LOG(ERROR) << "Could not parse the public key for " << name;
           return false;
         }
 
@@ -416,7 +423,7 @@
 
   for (const auto& pin : pinsets.spki_hashes()) {
     if (seen_names.find(pin.first) != seen_names.cend()) {
-      std::cerr << "Duplicate pin name " << pin.first << std::endl;
+      LOG(ERROR) << "Duplicate pin name " << pin.first << " in pins file";
       return false;
     }
     seen_names.insert(pin.first);
@@ -425,8 +432,8 @@
         std::string(pin.second.data(), pin.second.data() + pin.second.size());
     std::map<std::string, std::string>::iterator it = seen_hashes.find(hash);
     if (it != seen_hashes.cend()) {
-      std::cerr << "Duplicate pin hash for " << pin.first
-                << ", already seen as " << it->second << std::endl;
+      LOG(ERROR) << "Duplicate pin hash for " << pin.first
+                 << ", already seen as " << it->second;
       return false;
     }
     seen_hashes.insert(std::pair<std::string, std::string>(hash, pin.first));
@@ -447,8 +454,7 @@
   std::set<std::string> pinset_names;
   for (const auto& pinset : pinsets.pinsets()) {
     if (pinset_names.find(pinset.second->name()) != pinset_names.cend()) {
-      std::cerr << "Duplicate pinset name " << pinset.second->name()
-                << std::endl;
+      LOG(ERROR) << "Duplicate pinset name " << pinset.second->name();
       return false;
     }
     pinset_names.insert(pinset.second->name());
@@ -467,7 +473,8 @@
 
     for (const auto& pin_name : all_pin_names) {
       if (pin_names.find(pin_name) == pin_names.cend()) {
-        std::cerr << "Unknown pin: " << pin_name << std::endl;
+        LOG(ERROR) << "Pinset " << pinset.second->name()
+                   << " references pin " + pin_name << " which doesn't exist";
         return false;
       }
       used_pin_names.insert(pin_name);
@@ -476,7 +483,7 @@
 
   for (const auto& pin_name : pin_names) {
     if (used_pin_names.find(pin_name) == used_pin_names.cend()) {
-      std::cerr << "Unused pin: " << pin_name << std::endl;
+      LOG(ERROR) << "Pin " << pin_name << " is unused.";
       return false;
     }
   }
@@ -489,7 +496,7 @@
   std::set<std::string> seen_entries;
   for (const auto& entry : entries) {
     if (seen_entries.find(entry->hostname) != seen_entries.cend()) {
-      std::cerr << "Duplicate entry for " << entry->hostname << std::endl;
+      LOG(ERROR) << "Duplicate entry for " << entry->hostname;
       return false;
     }
     seen_entries.insert(entry->hostname);
@@ -507,10 +514,9 @@
         continue;
       }
 
-      std::cerr
-          << "Entry for " + entry->hostname +
-                 " has no mode, no pins and is not expect-CT or expect-staple"
-          << std::endl;
+      LOG(ERROR)
+          << "Entry for " << entry->hostname
+          << " has no mode, no pins and is not expect-CT or expect-staple";
       return false;
     }
   }
@@ -521,10 +527,9 @@
 bool CheckSubdomainsFlags(const TransportSecurityStateEntries& entries) {
   for (const auto& entry : entries) {
     if (entry->include_subdomains && entry->hpkp_include_subdomains) {
-      std::cerr << "Entry for \"" << entry->hostname
-                << "\" sets include_subdomains_for_pinning but also sets "
-                   "include_subdomains, which implies it"
-                << std::endl;
+      LOG(ERROR) << "Entry for " << entry->hostname
+                 << " sets include_subdomains_for_pinning but also sets "
+                    "include_subdomains, which implies it";
       return false;
     }
   }
@@ -540,6 +545,9 @@
   const base::CommandLine& command_line =
       *base::CommandLine::ForCurrentProcess();
 
+  logging::LoggingSettings settings;
+  logging::InitLogging(settings);
+
 #if defined(OS_WIN)
   std::vector<std::string> args;
   base::CommandLine::StringVector wide_args = command_line.GetArgs();
@@ -554,31 +562,29 @@
     return 1;
   }
 
-  bool verbose = command_line.HasSwitch("v");
-
   base::FilePath json_filepath = base::FilePath::FromUTF8Unsafe(argv[1]);
   if (!base::PathExists(json_filepath)) {
-    std::cerr << "Input JSON file doesn't exist." << std::endl;
+    LOG(ERROR) << "Input JSON file doesn't exist.";
     return 1;
   }
   json_filepath = base::MakeAbsoluteFilePath(json_filepath);
 
   std::string json_input;
   if (!base::ReadFileToString(json_filepath, &json_input)) {
-    std::cerr << "Could not read input JSON file." << std::endl;
+    LOG(ERROR) << "Could not read input JSON file.";
     return 1;
   }
 
   base::FilePath pins_filepath = base::FilePath::FromUTF8Unsafe(argv[2]);
   if (!base::PathExists(pins_filepath)) {
-    std::cerr << "Input pins file doesn't exist." << std::endl;
+    LOG(ERROR) << "Input pins file doesn't exist.";
     return 1;
   }
   pins_filepath = base::MakeAbsoluteFilePath(pins_filepath);
 
   std::string certs_input;
   if (!base::ReadFileToString(pins_filepath, &certs_input)) {
-    std::cerr << "Could not read input pins file." << std::endl;
+    LOG(ERROR) << "Could not read input pins file.";
     return 1;
   }
 
@@ -586,48 +592,53 @@
   Pinsets pinsets;
   DomainIDList domain_ids;
 
-  if (!ParseCertificatesFile(certs_input, &pinsets)) {
-    std::cerr << "Error while parsing the pins file." << std::endl;
-    return 1;
-  }
-  if (!ParseJSON(json_input, &entries, &pinsets, &domain_ids)) {
-    std::cerr << "Error while parsing the JSON file." << std::endl;
+  if (!ParseCertificatesFile(certs_input, &pinsets) ||
+      !ParseJSON(json_input, &entries, &pinsets, &domain_ids)) {
+    LOG(ERROR) << "Error while parsing the input files.";
     return 1;
   }
 
   if (!CheckDuplicateEntries(entries) || !CheckNoopEntries(entries) ||
       !CheckSubdomainsFlags(entries) || !CheckForDuplicatePins(pinsets) ||
       !CheckCertificatesInPinsets(pinsets)) {
-    std::cerr << "Checks failed. Aborting." << std::endl;
+    LOG(ERROR) << "Checks failed. Aborting.";
     return 1;
   }
 
   base::FilePath template_path = base::FilePath::FromUTF8Unsafe(argv[3]);
   if (!base::PathExists(template_path)) {
-    std::cerr << "Template file doesn't exist." << std::endl;
+    LOG(ERROR) << "Template file doesn't exist.";
     return 1;
   }
   template_path = base::MakeAbsoluteFilePath(template_path);
 
   std::string preload_template;
   if (!base::ReadFileToString(template_path, &preload_template)) {
-    std::cerr << "Could not read template file." << std::endl;
+    LOG(ERROR) << "Could not read template file.";
     return 1;
   }
 
-  std::string result;
+  std::string output;
   PreloadedStateGenerator generator;
-  result = generator.Generate(preload_template, entries, domain_ids, pinsets,
-                              verbose);
+  output = generator.Generate(preload_template, entries, domain_ids, pinsets);
+  if (output.empty()) {
+    LOG(ERROR) << "Trie generation failed.";
+    return 1;
+  }
 
   base::FilePath output_path;
   output_path = base::FilePath::FromUTF8Unsafe(argv[4]);
 
-  if (base::WriteFile(output_path, result.c_str(),
-                      static_cast<uint32_t>(result.size())) <= 0) {
-    std::cerr << "Failed to write output." << std::endl;
+  if (base::WriteFile(output_path, output.c_str(),
+                      static_cast<uint32_t>(output.size())) <= 0) {
+    LOG(ERROR) << "Failed to write output.";
     return 1;
   }
 
+  VLOG(1) << "Wrote trie containing " << entries.size()
+          << " entries, referencing " << pinsets.size() << " pinsets and "
+          << domain_ids.size() << " domain IDs to "
+          << output_path.AsUTF8Unsafe() << std::endl;
+
   return 0;
 }
diff --git a/net/tools/transport_security_state_generator/trie/trie_bit_buffer.h b/net/tools/transport_security_state_generator/trie/trie_bit_buffer.h
index f49ffb1..b2e14eb 100644
--- a/net/tools/transport_security_state_generator/trie/trie_bit_buffer.h
+++ b/net/tools/transport_security_state_generator/trie/trie_bit_buffer.h
@@ -9,6 +9,7 @@
 
 #include <vector>
 
+#include "base/macros.h"
 #include "net/tools/transport_security_state_generator/huffman/huffman_builder.h"
 
 namespace net {
@@ -49,8 +50,8 @@
   // at before the buffer was written to it.
   uint32_t WriteToBitWriter(BitWriter* writer);
 
-  // Appends the buffered bits in |current_byte_| to |elements_|. Empty bits
-  // are filled with zero's.
+  // Appends the buffered bits in |current_byte_| to |elements_|. No padding
+  // will occur.
   void Flush();
 
  private:
@@ -76,6 +77,8 @@
   uint32_t used_ = 0;
 
   std::vector<BitsOrPosition> elements_;
+
+  DISALLOW_COPY_AND_ASSIGN(TrieBitBuffer);
 };
 
 }  // namespace transport_security_state
diff --git a/net/tools/transport_security_state_generator/trie/trie_writer.cc b/net/tools/transport_security_state_generator/trie/trie_writer.cc
index 68dc1da..cf0b4c6 100644
--- a/net/tools/transport_security_state_generator/trie/trie_writer.cc
+++ b/net/tools/transport_security_state_generator/trie/trie_writer.cc
@@ -64,10 +64,12 @@
 
 TrieWriter::~TrieWriter() {}
 
-uint32_t TrieWriter::WriteEntries(
-    const TransportSecurityStateEntries& entries) {
-  ReversedEntries reversed_entries;
+bool TrieWriter::WriteEntries(const TransportSecurityStateEntries& entries,
+                              uint32_t* root_position) {
+  if (entries.empty())
+    return false;
 
+  ReversedEntries reversed_entries;
   for (auto const& entry : entries) {
     std::unique_ptr<ReversedEntry> reversed_entry(
         new ReversedEntry(ReverseName(entry->hostname), entry.get()));
@@ -77,11 +79,13 @@
   std::stable_sort(reversed_entries.begin(), reversed_entries.end(),
                    CompareReversedEntries);
 
-  return WriteDispatchTables(reversed_entries.begin(), reversed_entries.end());
+  return WriteDispatchTables(reversed_entries.begin(), reversed_entries.end(),
+                             root_position);
 }
 
-uint32_t TrieWriter::WriteDispatchTables(ReversedEntries::iterator start,
-                                         ReversedEntries::iterator end) {
+bool TrieWriter::WriteDispatchTables(ReversedEntries::iterator start,
+                                     ReversedEntries::iterator end,
+                                     uint32_t* position) {
   DCHECK(start != end) << "No entries passed to WriteDispatchTables";
 
   TrieBitBuffer writer;
@@ -114,13 +118,20 @@
     writer.WriteChar(candidate, huffman_table_, huffman_builder_);
 
     if (candidate == kTerminalValue) {
-      DCHECK((sub_entries_end - start) == 1)
-          << "Multiple values with the same name";
-      WriteEntry((*start)->entry, &writer);
+      if (sub_entries_end - start != 1) {
+        return false;
+      }
+      if (!WriteEntry((*start)->entry, &writer)) {
+        return false;
+      }
     } else {
       RemovePrefix(1, start, sub_entries_end);
-      uint32_t position = WriteDispatchTables(start, sub_entries_end);
-      writer.WritePosition(position, &last_position);
+      uint32_t table_position;
+      if (!WriteDispatchTables(start, sub_entries_end, &table_position)) {
+        return false;
+      }
+
+      writer.WritePosition(table_position, &last_position);
     }
 
     start = sub_entries_end;
@@ -128,13 +139,13 @@
 
   writer.WriteChar(kEndOfTableValue, huffman_table_, huffman_builder_);
 
-  uint32_t position = buffer_.position();
+  *position = buffer_.position();
   writer.Flush();
   writer.WriteToBitWriter(&buffer_);
-  return position;
+  return true;
 }
 
-void TrieWriter::WriteEntry(const TransportSecurityStateEntry* entry,
+bool TrieWriter::WriteEntry(const TransportSecurityStateEntry* entry,
                             TrieBitBuffer* writer) {
   uint8_t include_subdomains = 0;
   if (entry->include_subdomains) {
@@ -150,17 +161,30 @@
 
   if (entry->pinset.size()) {
     writer->WriteBit(1);
+
     NameIDMap::const_iterator pin_id_it = pinsets_map_.find(entry->pinset);
-    DCHECK(pin_id_it != pinsets_map_.cend()) << "invalid pinset";
+    if (pin_id_it == pinsets_map_.cend()) {
+      return false;
+    }
+
     const uint8_t& pin_id = pin_id_it->second;
-    DCHECK(pin_id <= 16) << "too many pinsets";
+    if (pin_id > 15) {
+      return false;
+    }
+
     writer->WriteBits(pin_id, 4);
 
     NameIDMap::const_iterator domain_id_it =
         domain_ids_map_.find(DomainConstant(entry->hostname));
-    DCHECK(domain_id_it != domain_ids_map_.cend()) << "invalid domain id";
+    if (domain_id_it == domain_ids_map_.cend()) {
+      return false;
+    }
+
     uint32_t domain_id = domain_id_it->second;
-    DCHECK(domain_id < 512) << "too many domain ids";
+    if (domain_id > 511) {
+      return false;
+    }
+
     writer->WriteBits(domain_id, 9);
 
     if (!entry->include_subdomains) {
@@ -178,11 +202,14 @@
     writer->WriteBit(1);
     NameIDMap::const_iterator expect_ct_report_uri_it =
         expect_ct_report_uri_map_.find(entry->expect_ct_report_uri);
-    DCHECK(expect_ct_report_uri_it != expect_ct_report_uri_map_.cend())
-        << "invalid expect-ct report-uri";
-    const uint8_t& expect_ct_report_id = expect_ct_report_uri_it->second;
+    if (expect_ct_report_uri_it == expect_ct_report_uri_map_.cend()) {
+      return false;
+    }
 
-    DCHECK(expect_ct_report_id < 16) << "too many expect-ct ids";
+    const uint8_t& expect_ct_report_id = expect_ct_report_uri_it->second;
+    if (expect_ct_report_id > 15) {
+      return false;
+    }
 
     writer->WriteBits(expect_ct_report_id, 4);
   } else {
@@ -200,16 +227,22 @@
 
     NameIDMap::const_iterator expect_staple_report_uri_it =
         expect_staple_report_uri_map_.find(entry->expect_staple_report_uri);
-    DCHECK(expect_staple_report_uri_it != expect_staple_report_uri_map_.cend())
-        << "invalid expect-ct report-uri";
+    if (expect_staple_report_uri_it == expect_staple_report_uri_map_.cend()) {
+      return false;
+    }
+
     const uint8_t& expect_staple_report_id =
         expect_staple_report_uri_it->second;
-    DCHECK(expect_staple_report_id < 16) << "too many expect-staple ids";
+    if (expect_staple_report_id > 15) {
+      return false;
+    }
 
     writer->WriteBits(expect_staple_report_id, 4);
   } else {
     writer->WriteBit(0);
   }
+
+  return true;
 }
 
 void TrieWriter::RemovePrefix(size_t length,
@@ -222,8 +255,8 @@
 }
 
 std::vector<uint8_t> TrieWriter::LongestCommonPrefix(
-    ReversedEntries::iterator start,
-    ReversedEntries::iterator end) const {
+    ReversedEntries::const_iterator start,
+    ReversedEntries::const_iterator end) const {
   if (start == end) {
     return std::vector<uint8_t>();
   }
@@ -240,7 +273,7 @@
     }
 
     bool ok = true;
-    for (ReversedEntries::iterator it = start + 1; it != end; ++it) {
+    for (ReversedEntries::const_iterator it = start + 1; it != end; ++it) {
       if (i > (*it)->reversed_name.size() ||
           (*it)->reversed_name.at(i) != candidate) {
         ok = false;
diff --git a/net/tools/transport_security_state_generator/trie/trie_writer.h b/net/tools/transport_security_state_generator/trie/trie_writer.h
index 93fce36..b3d5d88 100644
--- a/net/tools/transport_security_state_generator/trie/trie_writer.h
+++ b/net/tools/transport_security_state_generator/trie/trie_writer.h
@@ -39,8 +39,10 @@
   ~TrieWriter();
 
   // Constructs a trie containing all |entries|. The output is written to
-  // |buffer_|. Returns the position of the trie root.
-  uint32_t WriteEntries(const TransportSecurityStateEntries& entries);
+  // |buffer_| and |*position| is set to the position of the trie root. Returns
+  // true on success and false on failure.
+  bool WriteEntries(const TransportSecurityStateEntries& entries,
+                    uint32_t* position);
 
   // Returns the position |buffer_| is currently at. The returned value
   // represents the number of bits.
@@ -54,11 +56,12 @@
   const std::vector<uint8_t>& bytes() const { return buffer_.bytes(); }
 
  private:
-  uint32_t WriteDispatchTables(ReversedEntries::iterator start,
-                               ReversedEntries::iterator end);
+  bool WriteDispatchTables(ReversedEntries::iterator start,
+                           ReversedEntries::iterator end,
+                           uint32_t* position);
 
   // Serializes |*entry| and writes it to |*writer|.
-  void WriteEntry(const TransportSecurityStateEntry* entry,
+  bool WriteEntry(const TransportSecurityStateEntry* entry,
                   TrieBitBuffer* writer);
 
   // Removes the first |length| characters from all entries between |start| and
@@ -69,8 +72,9 @@
 
   // Searches for the longest common prefix for all entries between |start| and
   // |end|.
-  std::vector<uint8_t> LongestCommonPrefix(ReversedEntries::iterator start,
-                                           ReversedEntries::iterator end) const;
+  std::vector<uint8_t> LongestCommonPrefix(
+      ReversedEntries::const_iterator start,
+      ReversedEntries::const_iterator end) const;
 
   // Returns the reversed |hostname| as a vector of bytes. The reversed hostname
   // will be terminated by |kTerminalValue|.
diff --git a/services/resource_coordinator/BUILD.gn b/services/resource_coordinator/BUILD.gn
index 27edac5..9c5f07ef 100644
--- a/services/resource_coordinator/BUILD.gn
+++ b/services/resource_coordinator/BUILD.gn
@@ -10,7 +10,6 @@
 
   public_deps = [
     "//base",
-    "//mojo/public/cpp/bindings",
     "//services/resource_coordinator/public/cpp",
     "//services/resource_coordinator/public/interfaces",
   ]
@@ -21,15 +20,12 @@
 
   sources = [
     "memory/coordinator/coordinator_impl_unittest.cc",
-    "public/cpp/memory/memory_dump_manager_delegate_impl_unittest.cc",
   ]
 
   deps = [
     ":lib",
     "//base",
     "//mojo/public/cpp/bindings",
-    "//services/resource_coordinator/public/cpp",
-    "//services/resource_coordinator/public/interfaces",
     "//testing/gtest",
   ]
 }
diff --git a/services/resource_coordinator/memory/coordinator/coordinator_impl.cc b/services/resource_coordinator/memory/coordinator/coordinator_impl.cc
index 68e6de84b..5c133f8 100644
--- a/services/resource_coordinator/memory/coordinator/coordinator_impl.cc
+++ b/services/resource_coordinator/memory/coordinator/coordinator_impl.cc
@@ -4,18 +4,14 @@
 
 #include "services/resource_coordinator/memory/coordinator/coordinator_impl.h"
 
-#include "base/bind.h"
 #include "base/bind_helpers.h"
 #include "base/lazy_instance.h"
 #include "base/location.h"
 #include "base/logging.h"
 #include "base/memory/ref_counted.h"
-#include "base/single_thread_task_runner.h"
-#include "base/threading/platform_thread.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/trace_event/memory_dump_manager.h"
 #include "base/trace_event/memory_dump_request_args.h"
-#include "services/resource_coordinator/public/cpp/memory/memory_dump_manager_delegate_impl.h"
 #include "services/resource_coordinator/public/interfaces/memory/memory_instrumentation.mojom.h"
 
 namespace memory_instrumentation {
@@ -28,38 +24,20 @@
 }  // namespace
 
 // static
-CoordinatorImpl* CoordinatorImpl::GetInstance(
-    scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
-  CoordinatorImpl* out = g_coordinator.Pointer();
-  out->Initialize(task_runner);
-  return out;
+CoordinatorImpl* CoordinatorImpl::GetInstance() {
+  return g_coordinator.Pointer();
 }
 
-CoordinatorImpl::CoordinatorImpl()
-    : failed_memory_dump_count_(0), task_runner_(nullptr) {}
+// TODO(chiniforooshan): Initialize the global MemoryDumpManager instance here.
+// This is how the global MemoryDumpManager gets a reference to the delegate on
+// the service (read the browser) process for service process memory dumps. This
+// can be done when the delegate implementation is landed.
+CoordinatorImpl::CoordinatorImpl() : failed_memory_dump_count_(0) {}
 
 CoordinatorImpl::~CoordinatorImpl() {}
 
-void CoordinatorImpl::Initialize(
-    scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
-  DCHECK(!task_runner_ || task_runner_ == task_runner);
-
-  if (!task_runner_) {
-    task_runner_ = task_runner;
-    MemoryDumpManagerDelegateImpl* delegate =
-        MemoryDumpManagerDelegateImpl::GetInstance();
-    delegate->InitializeWithCoordinator(this, task_runner_);
-  }
-}
-
-void CoordinatorImpl::InitializeForTest(
-    scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
-  task_runner_ = task_runner;
-}
-
 void CoordinatorImpl::BindCoordinatorRequest(
     mojom::CoordinatorRequest request) {
-  DCHECK(task_runner_->RunsTasksOnCurrentThread());
   bindings_.AddBinding(this, std::move(request));
 }
 
@@ -73,7 +51,8 @@
 void CoordinatorImpl::RequestGlobalMemoryDump(
     const base::trace_event::MemoryDumpRequestArgs& args,
     const RequestGlobalMemoryDumpCallback& callback) {
-  DCHECK(task_runner_->RunsTasksOnCurrentThread());
+  DCHECK(thread_checker_.CalledOnValidThread());
+
   bool another_dump_already_in_progress = !queued_memory_dump_requests_.empty();
 
   // If this is a periodic memory dump request and there already is another
@@ -108,7 +87,8 @@
 
 void CoordinatorImpl::RegisterProcessLocalDumpManager(
     mojom::ProcessLocalDumpManagerPtr process_manager) {
-  DCHECK(task_runner_->RunsTasksOnCurrentThread());
+  DCHECK(thread_checker_.CalledOnValidThread());
+
   process_manager.set_connection_error_handler(
       base::Bind(&CoordinatorImpl::UnregisterProcessLocalDumpManager,
                  base::Unretained(this), process_manager.get()));
@@ -121,8 +101,7 @@
 
 void CoordinatorImpl::UnregisterProcessLocalDumpManager(
     mojom::ProcessLocalDumpManager* process_manager) {
-  size_t num_deleted = process_managers_.erase(process_manager);
-  DCHECK(num_deleted == 1);
+  DCHECK(process_managers_.erase(process_manager) == 1);
 
   // Check if we are waiting for an ack from this process-local manager.
   if (pending_process_managers_.find(process_manager) !=
diff --git a/services/resource_coordinator/memory/coordinator/coordinator_impl.h b/services/resource_coordinator/memory/coordinator/coordinator_impl.h
index 69f63cd..80ce6ae 100644
--- a/services/resource_coordinator/memory/coordinator/coordinator_impl.h
+++ b/services/resource_coordinator/memory/coordinator/coordinator_impl.h
@@ -11,7 +11,7 @@
 
 #include "base/lazy_instance.h"
 #include "base/memory/ref_counted.h"
-#include "base/single_thread_task_runner.h"
+#include "base/threading/thread_checker.h"
 #include "base/trace_event/memory_dump_request_args.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "mojo/public/cpp/bindings/binding_set.h"
@@ -22,15 +22,13 @@
 
 class CoordinatorImpl : public Coordinator, public mojom::Coordinator {
  public:
-  static CoordinatorImpl* GetInstance(
-      scoped_refptr<base::SingleThreadTaskRunner> task_runner);
+  static CoordinatorImpl* GetInstance();
 
   // Coordinator
   void BindCoordinatorRequest(mojom::CoordinatorRequest) override;
 
  private:
-  friend std::default_delete<CoordinatorImpl>;  // For testing
-  friend class CoordinatorImplTest;             // For testing
+  friend class CoordinatorImplTest;  // For testing
   friend struct base::DefaultLazyInstanceTraits<CoordinatorImpl>;
 
   struct QueuedMemoryDumpRequest {
@@ -44,10 +42,6 @@
   CoordinatorImpl();
   ~CoordinatorImpl() override;
 
-  void Initialize(scoped_refptr<base::SingleThreadTaskRunner> task_runner);
-  void InitializeForTest(
-      scoped_refptr<base::SingleThreadTaskRunner> task_runner);
-
   // mojom::Coordinator
   void RegisterProcessLocalDumpManager(
       mojom::ProcessLocalDumpManagerPtr process_manager) override;
@@ -84,7 +78,7 @@
   int failed_memory_dump_count_;
   std::list<QueuedMemoryDumpRequest> queued_memory_dump_requests_;
 
-  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+  base::ThreadChecker thread_checker_;
 
   DISALLOW_COPY_AND_ASSIGN(CoordinatorImpl);
 };
diff --git a/services/resource_coordinator/memory/coordinator/coordinator_impl_unittest.cc b/services/resource_coordinator/memory/coordinator/coordinator_impl_unittest.cc
index 4d63e98..1bc8254 100644
--- a/services/resource_coordinator/memory/coordinator/coordinator_impl_unittest.cc
+++ b/services/resource_coordinator/memory/coordinator/coordinator_impl_unittest.cc
@@ -3,7 +3,6 @@
 // found in the LICENSE file.
 
 #include "services/resource_coordinator/memory/coordinator/coordinator_impl.h"
-#include "base/bind.h"
 #include "base/bind_helpers.h"
 #include "base/callback_forward.h"
 #include "base/memory/ref_counted.h"
@@ -21,20 +20,15 @@
  public:
   CoordinatorImplTest() {}
   void SetUp() override {
-    dump_response_args_ = {0U, false};
-    coordinator_.reset(new CoordinatorImpl());
-    coordinator_->InitializeForTest(base::ThreadTaskRunnerHandle::Get());
+    dump_response_args_ = {static_cast<uint64_t>(-1), false};
   }
 
-  void TearDown() override { coordinator_.reset(); }
-
   void RegisterProcessLocalDumpManager(
       mojom::ProcessLocalDumpManagerPtr process_manager) {
     base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE,
-        base::Bind(&CoordinatorImpl::RegisterProcessLocalDumpManager,
-                   base::Unretained(coordinator_.get()),
-                   base::Passed(&process_manager)));
+        FROM_HERE, base::Bind(&CoordinatorImpl::RegisterProcessLocalDumpManager,
+                              base::Unretained(&coordinator_),
+                              base::Passed(&process_manager)));
   }
 
   void RequestGlobalMemoryDump(base::trace_event::MemoryDumpRequestArgs args,
@@ -42,7 +36,7 @@
     base::ThreadTaskRunnerHandle::Get()->PostTask(
         FROM_HERE,
         base::Bind(&CoordinatorImpl::RequestGlobalMemoryDump,
-                   base::Unretained(coordinator_.get()), args,
+                   base::Unretained(&coordinator_), args,
                    base::Bind(&CoordinatorImplTest::OnGlobalMemoryDumpResponse,
                               base::Unretained(this), closure)));
   }
@@ -63,11 +57,11 @@
   DumpResponseArgs dump_response_args_;
 
  private:
-  std::unique_ptr<CoordinatorImpl> coordinator_;
+  CoordinatorImpl coordinator_;
   base::MessageLoop message_loop_;
 };
 
-class MockDumpManager : public mojom::ProcessLocalDumpManager {
+class MockDumpManager : mojom::ProcessLocalDumpManager {
  public:
   MockDumpManager(CoordinatorImplTest* test_coordinator, int expected_calls)
       : binding_(this), expected_calls_(expected_calls) {
@@ -99,7 +93,7 @@
       base::trace_event::MemoryDumpLevelOfDetail::DETAILED};
   RequestGlobalMemoryDump(args, run_loop.QuitClosure());
   run_loop.Run();
-  EXPECT_EQ(1234U, dump_response_args_.dump_guid);
+  EXPECT_EQ(static_cast<uint64_t>(1234), dump_response_args_.dump_guid);
   EXPECT_TRUE(dump_response_args_.success);
 }
 
@@ -115,7 +109,7 @@
 
   run_loop.Run();
 
-  EXPECT_EQ(2345U, dump_response_args_.dump_guid);
+  EXPECT_EQ(static_cast<uint64_t>(2345), dump_response_args_.dump_guid);
   EXPECT_TRUE(dump_response_args_.success);
 }
 
@@ -138,7 +132,7 @@
 
   run_loop.Run();
 
-  EXPECT_EQ(3456U, dump_response_args_.dump_guid);
+  EXPECT_EQ(static_cast<uint64_t>(3456), dump_response_args_.dump_guid);
   EXPECT_FALSE(dump_response_args_.success);
 }
 }  // namespace memory_instrumentation
diff --git a/services/resource_coordinator/public/cpp/memory/memory_dump_manager_delegate_impl.cc b/services/resource_coordinator/public/cpp/memory/memory_dump_manager_delegate_impl.cc
index 1057794..7072b67 100644
--- a/services/resource_coordinator/public/cpp/memory/memory_dump_manager_delegate_impl.cc
+++ b/services/resource_coordinator/public/cpp/memory/memory_dump_manager_delegate_impl.cc
@@ -4,11 +4,6 @@
 
 #include "services/resource_coordinator/public/cpp/memory/memory_dump_manager_delegate_impl.h"
 
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/lazy_instance.h"
-#include "base/single_thread_task_runner.h"
-#include "base/synchronization/lock.h"
 #include "base/trace_event/memory_dump_request_args.h"
 #include "mojo/public/cpp/bindings/interface_request.h"
 #include "services/resource_coordinator/public/cpp/memory/coordinator.h"
@@ -17,68 +12,26 @@
 
 namespace memory_instrumentation {
 
-namespace {
-
-base::LazyInstance<MemoryDumpManagerDelegateImpl>::Leaky
-    g_memory_dump_manager_delegate = LAZY_INSTANCE_INITIALIZER;
-
-}  // namespace
-
-// static
-MemoryDumpManagerDelegateImpl* MemoryDumpManagerDelegateImpl::GetInstance() {
-  return g_memory_dump_manager_delegate.Pointer();
-}
-
-MemoryDumpManagerDelegateImpl::MemoryDumpManagerDelegateImpl()
-    : initialized_(false),
-      binding_(this),
-      task_runner_(nullptr),
-      pending_memory_dump_guid_(0) {}
-
-MemoryDumpManagerDelegateImpl::~MemoryDumpManagerDelegateImpl() {}
-
-void MemoryDumpManagerDelegateImpl::InitializeWithInterfaceProvider(
-    service_manager::InterfaceProvider* interface_provider) {
-  {
-    base::AutoLock lock(initialized_lock_);
-    DCHECK(!initialized_);
-    initialized_ = true;
-  }
-
+MemoryDumpManagerDelegateImpl::MemoryDumpManagerDelegateImpl(
+    service_manager::InterfaceProvider* interface_provider)
+    : is_coordinator_(false), binding_(this) {
   interface_provider->GetInterface(mojo::MakeRequest(&coordinator_));
   coordinator_->RegisterProcessLocalDumpManager(
       binding_.CreateInterfacePtrAndBind());
-  base::trace_event::MemoryDumpManager::GetInstance()->Initialize(this);
 }
 
-void MemoryDumpManagerDelegateImpl::InitializeWithCoordinator(
-    Coordinator* coordinator,
-    scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
-  DCHECK(task_runner);
-  if (!task_runner->RunsTasksOnCurrentThread()) {
-    task_runner->PostTask(
-        FROM_HERE,
-        base::Bind(&MemoryDumpManagerDelegateImpl::InitializeWithCoordinator,
-                   base::Unretained(this), base::Unretained(coordinator),
-                   task_runner));
-    return;
-  }
-
-  {
-    base::AutoLock lock(initialized_lock_);
-    DCHECK(!initialized_);
-    initialized_ = true;
-  }
-
-  task_runner_ = task_runner;
+MemoryDumpManagerDelegateImpl::MemoryDumpManagerDelegateImpl(
+    Coordinator* coordinator)
+    : is_coordinator_(true), binding_(this) {
   coordinator->BindCoordinatorRequest(mojo::MakeRequest(&coordinator_));
   coordinator_->RegisterProcessLocalDumpManager(
       binding_.CreateInterfacePtrAndBind());
-  base::trace_event::MemoryDumpManager::GetInstance()->Initialize(this);
 }
 
+MemoryDumpManagerDelegateImpl::~MemoryDumpManagerDelegateImpl() {}
+
 bool MemoryDumpManagerDelegateImpl::IsCoordinator() const {
-  return task_runner_ != nullptr;
+  return is_coordinator_;
 }
 
 void MemoryDumpManagerDelegateImpl::RequestProcessMemoryDump(
@@ -90,50 +43,7 @@
 void MemoryDumpManagerDelegateImpl::RequestGlobalMemoryDump(
     const base::trace_event::MemoryDumpRequestArgs& args,
     const base::trace_event::MemoryDumpCallback& callback) {
-  // Note: This condition is here to match the old behavior. If the delegate is
-  // in the browser process, we do not drop parallel requests in the delegate
-  // and so they will be queued by the Coordinator service (see
-  // CoordinatorImpl::RequestGlobalMemoryDump). If the delegate is in a child
-  // process, parallel requests will be cancelled.
-  //
-  // TODO(chiniforooshan): After transitioning to the mojo-based service is
-  // completed, we should enable queueing parallel global memory dump requests
-  // by delegates on all processes.
-  if (task_runner_) {
-    DCHECK(task_runner_);
-    task_runner_->PostTask(
-        FROM_HERE,
-        base::Bind(&mojom::Coordinator::RequestGlobalMemoryDump,
-                   base::Unretained(coordinator_.get()), args, callback));
-    return;
-  }
-
-  {
-    base::AutoLock lock(pending_memory_dump_guid_lock_);
-    if (pending_memory_dump_guid_) {
-      callback.Run(args.dump_guid, false);
-      return;
-    }
-    pending_memory_dump_guid_ = args.dump_guid;
-  }
-  DCHECK(!task_runner_);
-  auto callback_proxy =
-      base::Bind(&MemoryDumpManagerDelegateImpl::MemoryDumpCallbackProxy,
-                 base::Unretained(this), callback);
-  coordinator_->RequestGlobalMemoryDump(args, callback_proxy);
-}
-
-void MemoryDumpManagerDelegateImpl::MemoryDumpCallbackProxy(
-    const base::trace_event::MemoryDumpCallback& callback,
-    uint64_t dump_guid,
-    bool success) {
-  DCHECK_NE(0U, pending_memory_dump_guid_);
-  pending_memory_dump_guid_ = 0;
-  callback.Run(dump_guid, success);
-}
-
-void MemoryDumpManagerDelegateImpl::SetAsNonCoordinatorForTesting() {
-  task_runner_ = nullptr;
+  coordinator_->RequestGlobalMemoryDump(args, callback);
 }
 
 }  // namespace memory_instrumentation
diff --git a/services/resource_coordinator/public/cpp/memory/memory_dump_manager_delegate_impl.h b/services/resource_coordinator/public/cpp/memory/memory_dump_manager_delegate_impl.h
index 0986e22..1176619 100644
--- a/services/resource_coordinator/public/cpp/memory/memory_dump_manager_delegate_impl.h
+++ b/services/resource_coordinator/public/cpp/memory/memory_dump_manager_delegate_impl.h
@@ -5,9 +5,6 @@
 #ifndef SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_MEMORY_MEMORY_DUMP_MANAGER_DELEGATE_IMPL_H_
 #define SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_MEMORY_MEMORY_DUMP_MANAGER_DELEGATE_IMPL_H_
 
-#include "base/lazy_instance.h"
-#include "base/single_thread_task_runner.h"
-#include "base/synchronization/lock.h"
 #include "base/trace_event/memory_dump_manager.h"
 #include "base/trace_event/memory_dump_request_args.h"
 #include "mojo/public/cpp/bindings/binding.h"
@@ -21,56 +18,30 @@
     : public base::trace_event::MemoryDumpManagerDelegate,
       public mojom::ProcessLocalDumpManager {
  public:
-  static MemoryDumpManagerDelegateImpl* GetInstance();
-
   // Use to bind to a remote coordinator.
-  void InitializeWithInterfaceProvider(
+  MemoryDumpManagerDelegateImpl(
       service_manager::InterfaceProvider* interface_provider);
 
   // Use to bind to a coordinator in the same process.
-  void InitializeWithCoordinator(
-      Coordinator* coordinator,
-      scoped_refptr<base::SingleThreadTaskRunner> task_runner);
+  MemoryDumpManagerDelegateImpl(Coordinator* coordinator);
+  ~MemoryDumpManagerDelegateImpl() override;
 
-  bool IsCoordinator() const override;
+  bool IsCoordinator() const;
 
   // The base::trace_event::MemoryDumpManager calls this.
   void RequestGlobalMemoryDump(
       const base::trace_event::MemoryDumpRequestArgs& args,
       const base::trace_event::MemoryDumpCallback& callback) override;
 
-  void SetAsNonCoordinatorForTesting();
-
  private:
-  friend std::default_delete<MemoryDumpManagerDelegateImpl>;  // For testing
-  friend class MemoryDumpManagerDelegateImplTest;             // For testing
-  friend struct base::DefaultLazyInstanceTraits<MemoryDumpManagerDelegateImpl>;
-
-  MemoryDumpManagerDelegateImpl();
-  ~MemoryDumpManagerDelegateImpl() override;
-
   // The ProcessLocalDumpManager interface. The coordinator calls this.
   void RequestProcessMemoryDump(
       const base::trace_event::MemoryDumpRequestArgs& args,
       const RequestProcessMemoryDumpCallback& callback) override;
 
-  // A proxy callback for updating |pending_memory_dump_guid_|.
-  void MemoryDumpCallbackProxy(
-      const base::trace_event::MemoryDumpCallback& callback,
-      uint64_t dump_guid,
-      bool success);
-
-  bool initialized_;
+  bool is_coordinator_;
   mojom::CoordinatorPtr coordinator_;
   mojo::Binding<mojom::ProcessLocalDumpManager> binding_;
-  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
-  uint64_t pending_memory_dump_guid_;
-
-  // Prevents racy access to |pending_memory_dump_guid_|.
-  base::Lock pending_memory_dump_guid_lock_;
-
-  // Prevents racy access to |initialized_|.
-  base::Lock initialized_lock_;
 
   DISALLOW_COPY_AND_ASSIGN(MemoryDumpManagerDelegateImpl);
 };
diff --git a/services/resource_coordinator/public/cpp/memory/memory_dump_manager_delegate_impl_unittest.cc b/services/resource_coordinator/public/cpp/memory/memory_dump_manager_delegate_impl_unittest.cc
deleted file mode 100644
index 09a712b..0000000
--- a/services/resource_coordinator/public/cpp/memory/memory_dump_manager_delegate_impl_unittest.cc
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "services/resource_coordinator/public/cpp/memory/memory_dump_manager_delegate_impl.h"
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/message_loop/message_loop.h"
-#include "base/run_loop.h"
-#include "base/trace_event/memory_dump_manager.h"
-#include "base/trace_event/memory_dump_request_args.h"
-#include "base/trace_event/trace_config.h"
-#include "base/trace_event/trace_log.h"
-#include "mojo/public/cpp/bindings/binding_set.h"
-#include "services/resource_coordinator/public/cpp/memory/coordinator.h"
-#include "services/resource_coordinator/public/interfaces/memory/memory_instrumentation.mojom.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using base::trace_event::MemoryDumpLevelOfDetail;
-using base::trace_event::MemoryDumpManager;
-using base::trace_event::MemoryDumpType;
-
-namespace memory_instrumentation {
-
-class MockCoordinator : public Coordinator, public mojom::Coordinator {
- public:
-  void BindCoordinatorRequest(mojom::CoordinatorRequest request) override {
-    bindings_.AddBinding(this, std::move(request));
-  }
-
-  void RegisterProcessLocalDumpManager(
-      mojom::ProcessLocalDumpManagerPtr process_manager) override {}
-
-  void RequestGlobalMemoryDump(
-      const base::trace_event::MemoryDumpRequestArgs& args,
-      const RequestGlobalMemoryDumpCallback& callback) override {
-    callback.Run(args.dump_guid, true);
-  }
-
- private:
-  mojo::BindingSet<mojom::Coordinator> bindings_;
-};
-
-class MemoryDumpManagerDelegateImplTest : public testing::Test {
- public:
-  void SetUp() override {
-    message_loop_.reset(new base::MessageLoop());
-    coordinator_.reset(new MockCoordinator());
-    delegate_.reset(new MemoryDumpManagerDelegateImpl());
-    mdm_.reset(new MemoryDumpManager());
-    MemoryDumpManager::SetInstanceForTesting(mdm_.get());
-
-    // This will initialize |MemoryDumpManager|, too.
-    delegate_->InitializeWithCoordinator(coordinator_.get(),
-                                         base::ThreadTaskRunnerHandle::Get());
-    delegate_->SetAsNonCoordinatorForTesting();
-
-    // Enable tracing.
-    std::string category_filter = "-*,";
-    category_filter += MemoryDumpManager::kTraceCategory;
-    base::trace_event::TraceConfig trace_config(category_filter, "");
-    base::trace_event::TraceLog::GetInstance()->SetEnabled(
-        trace_config, base::trace_event::TraceLog::RECORDING_MODE);
-
-    // Reset the counters.
-    expected_callback_calls_ = 0;
-    dump_requests_received_by_coordinator_ = 0;
-    quit_closure_.Reset();
-  }
-
-  void TearDown() override {
-    base::trace_event::TraceLog::GetInstance()->SetDisabled();
-    MemoryDumpManager::SetInstanceForTesting(nullptr);
-    mdm_.reset();
-    delegate_.reset();
-    coordinator_.reset();
-    message_loop_.reset();
-  }
-
-  void OnGlobalMemoryDumpDone(int more_requests,
-                              uint64_t dump_guid,
-                              bool success) {
-    EXPECT_GT(expected_callback_calls_, 0);
-    EXPECT_FALSE(quit_closure_.is_null());
-
-    dump_requests_received_by_coordinator_ += success ? 1 : 0;
-    expected_callback_calls_--;
-    if (expected_callback_calls_ == 0)
-      quit_closure_.Run();
-
-    if (more_requests > 0)
-      SequentiallyRequestGlobalDumps(more_requests);
-  }
-
-  void SequentiallyRequestGlobalDumps(int num_requests) {
-    MemoryDumpManager::GetInstance()->RequestGlobalDump(
-        MemoryDumpType::EXPLICITLY_TRIGGERED, MemoryDumpLevelOfDetail::LIGHT,
-        base::Bind(&MemoryDumpManagerDelegateImplTest::OnGlobalMemoryDumpDone,
-                   base::Unretained(this), num_requests - 1));
-  }
-
-  int expected_callback_calls_;
-  int dump_requests_received_by_coordinator_;
-  base::Closure quit_closure_;
-
- private:
-  std::unique_ptr<base::MessageLoop> message_loop_;
-  std::unique_ptr<MockCoordinator> coordinator_;
-  std::unique_ptr<MemoryDumpManagerDelegateImpl> delegate_;
-  std::unique_ptr<MemoryDumpManager> mdm_;
-};
-
-// Makes several global dump requests each after receiving the ACK for the
-// previous one. There should be no throttling and all requests should be
-// forwarded to the coordinator.
-TEST_F(MemoryDumpManagerDelegateImplTest, NonOverlappingMemoryDumpRequests) {
-  base::RunLoop run_loop;
-  expected_callback_calls_ = 3;
-  quit_closure_ = run_loop.QuitClosure();
-  SequentiallyRequestGlobalDumps(3);
-  run_loop.Run();
-  EXPECT_EQ(3, dump_requests_received_by_coordinator_);
-}
-
-// Makes several global dump requests without waiting for previous requests to
-// finish. Only the first request should make it to the coordinator. The rest
-// should be cancelled.
-TEST_F(MemoryDumpManagerDelegateImplTest, OverlappingMemoryDumpRequests) {
-  base::RunLoop run_loop;
-  expected_callback_calls_ = 3;
-  quit_closure_ = run_loop.QuitClosure();
-  SequentiallyRequestGlobalDumps(1);
-  SequentiallyRequestGlobalDumps(1);
-  SequentiallyRequestGlobalDumps(1);
-  run_loop.Run();
-  EXPECT_EQ(1, dump_requests_received_by_coordinator_);
-}
-
-}  // namespace memory_instrumentation
diff --git a/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-constructor.html b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-constructor.html
index 16cb9e7d..5ced91c5 100644
--- a/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-constructor.html
+++ b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-constructor.html
@@ -169,9 +169,17 @@
 }, 'Parse =');
 
 test(function() {
-    var params = new URLSearchParams('foobar=a\nb');
-    assert_equals(params.toString(), 'foobar=a%0Ab');
-}, 'Parse \\n');
+    let params = new URLSearchParams([]);
+    assert_true(params !== null, 'Empty sequence');
+    assert_equals(params.toString(), '');
+
+    params = new URLSearchParams([[1, 2], ['a', 'b']]);
+    assert_equals(params.toString(), '1=2&a=b');
+
+    assert_type_error(() => { new URLSearchParams([[1, 2, 3]]) },
+      "Sequence elements must be pairs");
+}, 'sequence initializer');
+
 </script>
 </head>
 </html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/origin_trials/webexposed/rootscroller-origin-trial-interfaces-script-added-expected.txt b/third_party/WebKit/LayoutTests/http/tests/origin_trials/webexposed/rootscroller-origin-trial-interfaces-script-added-expected.txt
deleted file mode 100644
index 10ea9fd9..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/origin_trials/webexposed/rootscroller-origin-trial-interfaces-script-added-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-FAIL RootScroller related properties on interfaces before adding trial token via script. assert_equals: Property rootScroller exists on Document expected false but got true
-PASS RootScroller related properties on interfaces after adding trial token via script. 
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/http/tests/origin_trials/webexposed/rootscroller-origin-trial-interfaces-script-added.html b/third_party/WebKit/LayoutTests/http/tests/origin_trials/webexposed/rootscroller-origin-trial-interfaces-script-added.html
deleted file mode 100644
index 07128af..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/origin_trials/webexposed/rootscroller-origin-trial-interfaces-script-added.html
+++ /dev/null
@@ -1,23 +0,0 @@
-<!DOCTYPE html>
-<meta charset="utf-8">
-<title>RootScroller - origin trial is enabled by script-added meta tag</title>
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
-<script src="../../resources/origin-trials-helper.js"></script>
-<script>
-// Generate token with the command:
-// generate_token.py  http://127.0.0.1:8000 RootScroller --expire-timestamp=2000000000
-var token = "AuKypT9HyT7fv0cU54WMd1bUmdBYTFED3hKRFWfvxauV8saEM1CoOFLXDd3ApWwJCvimlrGVcqj+0Z9rJL8uFgIAAABUeyJvcmlnaW4iOiAiaHR0cDovLzEyNy4wLjAuMTo4MDAwIiwgImZlYXR1cmUiOiAiUm9vdFNjcm9sbGVyIiwgImV4cGlyeSI6IDIwMDAwMDAwMDB9";
-
-let properties_to_check = {'Document': ['rootScroller']};
-
-test(t => {
-  OriginTrialsHelper.check_properties_missing(this, properties_to_check);
-}, "RootScroller related properties on interfaces before adding trial token via script.");
-
-OriginTrialsHelper.add_token(token);
-
-test(t => {
-  OriginTrialsHelper.check_properties(this, properties_to_check);
-}, "RootScroller related properties on interfaces after adding trial token via script.");
-</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/origin_trials/webexposed/rootscroller-origin-trial-interfaces.html b/third_party/WebKit/LayoutTests/http/tests/origin_trials/webexposed/rootscroller-origin-trial-interfaces.html
deleted file mode 100644
index d03df0b..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/origin_trials/webexposed/rootscroller-origin-trial-interfaces.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<!DOCTYPE html>
-<meta charset="utf-8">
-<!-- Generate token with the command:
-generate_token.py  http://127.0.0.1:8000 RootScroller --expire-timestamp=2000000000
--->
-<meta http-equiv="origin-trial" content="AuKypT9HyT7fv0cU54WMd1bUmdBYTFED3hKRFWfvxauV8saEM1CoOFLXDd3ApWwJCvimlrGVcqj+0Z9rJL8uFgIAAABUeyJvcmlnaW4iOiAiaHR0cDovLzEyNy4wLjAuMTo4MDAwIiwgImZlYXR1cmUiOiAiUm9vdFNjcm9sbGVyIiwgImV4cGlyeSI6IDIwMDAwMDAwMDB9" />
-<title>RootScroller - interfaces exposed by origin trial</title>
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
-<script src="../../resources/origin-trials-helper.js"></script>
-<script>
-test(t => {
-  OriginTrialsHelper.check_properties(this, {'Document': ['rootScroller']});
-}, "RootScroller related properties on interfaces in Origin-Trial enabled document.");
-</script>
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/text/emoji-web-font-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/text/emoji-web-font-expected.png
index d25a784a..21e4412 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/text/emoji-web-font-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/text/emoji-web-font-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/text/emoji-web-font-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/text/emoji-web-font-expected.txt
index 234f305..a79d5c45 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/text/emoji-web-font-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/text/emoji-web-font-expected.txt
@@ -7,8 +7,8 @@
         LayoutText {#text} at (0,0) size 500x19
           text run at (0,0) width 500: "Following should show Asterisk with FruitGirl similar to Asterisk Image below"
       LayoutBlockFlow {P} at (0,45) size 784x25
-        LayoutText {#text} at (0,0) size 0x25
-          text run at (0,0) width 0: "*"
+        LayoutText {#text} at (0,0) size 17x25
+          text run at (0,0) width 17: "*"
       LayoutBlockFlow (anonymous) at (0,95) size 784x25
         LayoutImage {IMG} at (0,0) size 25x25
         LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/virtual/origin-trials-runtimeflags-disabled/http/tests/origin_trials/webexposed/rootscroller-origin-trial-interfaces-script-added-expected.txt b/third_party/WebKit/LayoutTests/virtual/origin-trials-runtimeflags-disabled/http/tests/origin_trials/webexposed/rootscroller-origin-trial-interfaces-script-added-expected.txt
deleted file mode 100644
index d007a49..0000000
--- a/third_party/WebKit/LayoutTests/virtual/origin-trials-runtimeflags-disabled/http/tests/origin_trials/webexposed/rootscroller-origin-trial-interfaces-script-added-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-PASS RootScroller related properties on interfaces before adding trial token via script. 
-PASS RootScroller related properties on interfaces after adding trial token via script. 
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/Source/bindings/core/v8/BUILD.gn b/third_party/WebKit/Source/bindings/core/v8/BUILD.gn
index c5571697..7709db3 100644
--- a/third_party/WebKit/Source/bindings/core/v8/BUILD.gn
+++ b/third_party/WebKit/Source/bindings/core/v8/BUILD.gn
@@ -200,8 +200,8 @@
   "$bindings_core_v8_output_dir/StringOrDictionary.h",
   "$bindings_core_v8_output_dir/StringOrFloat.cpp",
   "$bindings_core_v8_output_dir/StringOrFloat.h",
-  "$bindings_core_v8_output_dir/USVStringOrURLSearchParams.cpp",
-  "$bindings_core_v8_output_dir/USVStringOrURLSearchParams.h",
+  "$bindings_core_v8_output_dir/USVStringSequenceSequenceOrUSVStringOrURLSearchParams.cpp",
+  "$bindings_core_v8_output_dir/USVStringSequenceSequenceOrUSVStringOrURLSearchParams.h",
   "$bindings_core_v8_output_dir/UnrestrictedDoubleOrString.cpp",
   "$bindings_core_v8_output_dir/UnrestrictedDoubleOrString.h",
   "$bindings_core_v8_output_dir/VideoTrackOrAudioTrackOrTextTrack.cpp",
diff --git a/third_party/WebKit/Source/bindings/core/v8/ConditionalFeaturesForCore.cpp b/third_party/WebKit/Source/bindings/core/v8/ConditionalFeaturesForCore.cpp
index 0f223d2..1a408f9 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ConditionalFeaturesForCore.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/ConditionalFeaturesForCore.cpp
@@ -44,11 +44,6 @@
           isolate, world, v8::Local<v8::Object>(), prototypeObject,
           interfaceObject);
     }
-  } else if (wrapperTypeInfo == &V8Document::wrapperTypeInfo) {
-    if (OriginTrials::setRootScrollerEnabled(executionContext)) {
-      V8Document::installRootScroller(isolate, world, v8::Local<v8::Object>(),
-                                      prototypeObject, interfaceObject);
-    }
   }
 }
 
@@ -74,14 +69,6 @@
     }
     return;
   }
-  if (feature == "RootScroller") {
-    if (contextData->getExistingConstructorAndPrototypeForType(
-            &V8Document::wrapperTypeInfo, &prototypeObject, &interfaceObject)) {
-      V8Document::installRootScroller(isolate, world, v8::Local<v8::Object>(),
-                                      prototypeObject, interfaceObject);
-    }
-    return;
-  }
 }
 
 void installConditionalFeaturesOnWindow(const ScriptState* scriptState) {
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptController.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptController.cpp
index 3dcd2b0..2b9f4005 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptController.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptController.cpp
@@ -62,9 +62,9 @@
 #include "core/loader/NavigationScheduler.h"
 #include "core/loader/ProgressTracker.h"
 #include "core/plugins/PluginView.h"
+#include "platform/FrameViewBase.h"
 #include "platform/Histogram.h"
 #include "platform/UserGestureIndicator.h"
-#include "platform/Widget.h"
 #include "platform/instrumentation/tracing/TraceEvent.h"
 #include "platform/weborigin/SecurityOrigin.h"
 #include "public/platform/Platform.h"
@@ -205,15 +205,15 @@
 }
 
 PassRefPtr<SharedPersistent<v8::Object>> ScriptController::createPluginWrapper(
-    Widget* widget) {
-  ASSERT(widget);
+    FrameViewBase* frameViewBase) {
+  DCHECK(frameViewBase);
 
-  if (!widget->isPluginView())
+  if (!frameViewBase->isPluginView())
     return nullptr;
 
   v8::HandleScope handleScope(isolate());
   v8::Local<v8::Object> scriptableObject =
-      toPluginView(widget)->scriptableObject(isolate());
+      toPluginView(frameViewBase)->scriptableObject(isolate());
 
   if (scriptableObject.IsEmpty())
     return nullptr;
@@ -294,7 +294,7 @@
   String scriptResult = toCoreString(v8::Local<v8::String>::Cast(result));
 
   // We're still in a frame, so there should be a DocumentLoader.
-  ASSERT(frame()->document()->loader());
+  DCHECK(frame()->document()->loader());
   if (!locationChangeBefore &&
       frame()->navigationScheduler().locationChangePending())
     return true;
@@ -355,7 +355,7 @@
     int worldID,
     const HeapVector<ScriptSourceCode>& sources,
     Vector<v8::Local<v8::Value>>* results) {
-  ASSERT(worldID > 0);
+  DCHECK_GT(worldID, 0);
 
   RefPtr<DOMWrapperWorld> world =
       DOMWrapperWorld::ensureIsolatedWorld(isolate(), worldID);
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp
index 5110dd5..68f3db8 100644
--- a/third_party/WebKit/Source/core/dom/Document.cpp
+++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -368,7 +368,7 @@
   return true;
 }
 
-static Widget* widgetForElement(const Element& focusedElement) {
+static FrameViewBase* widgetForElement(const Element& focusedElement) {
   LayoutObject* layoutObject = focusedElement.layoutObject();
   if (!layoutObject || !layoutObject->isLayoutPart())
     return 0;
@@ -2060,7 +2060,8 @@
 
   unsigned initialElementCount = styleEngine().styleForElementCount();
 
-  HTMLFrameOwnerElement::UpdateSuspendScope suspendWidgetHierarchyUpdates;
+  HTMLFrameOwnerElement::UpdateSuspendScope
+      suspendFrameViewBaseHierarchyUpdates;
   m_lifecycle.advanceTo(DocumentLifecycle::InStyleRecalc);
 
   StyleRecalcChange change = NoChange;
@@ -2456,20 +2457,21 @@
   // to trigger navigation here.  However, plugins (see below) can cause lots of
   // crazy things to happen, since plugin detach involves nested message loops.
   FrameNavigationDisabler navigationDisabler(*m_frame);
-  // Defer widget updates to avoid plugins trying to run script inside
+  // Defer FrameViewBase updates to avoid plugins trying to run script inside
   // ScriptForbiddenScope, which will crash the renderer after
   // https://crrev.com/200984
-  HTMLFrameOwnerElement::UpdateSuspendScope suspendWidgetHierarchyUpdates;
+  HTMLFrameOwnerElement::UpdateSuspendScope
+      suspendFrameViewBaseHierarchyUpdates;
   // Don't allow script to run in the middle of detachLayoutTree() because a
   // detaching Document is not in a consistent state.
   ScriptForbiddenScope forbidScript;
 
   view()->dispose();
 
-  // If the widget of the document's frame owner doesn't match view() then
-  // FrameView::dispose() didn't clear the owner's widget. If we don't clear it
-  // here, it may be clobbered later in LocalFrame::createView(). See also
-  // https://crbug.com/673170 and the comment in FrameView::dispose().
+  // If the FrameViewBase of the document's frame owner doesn't match view()
+  // then FrameView::dispose() didn't clear the owner's FrameViewBase. If we
+  // don't clear it here, it may be clobbered later in LocalFrame::createView().
+  // See also https://crbug.com/673170 and the comment in FrameView::dispose().
   HTMLFrameOwnerElement* ownerElement = m_frame->deprecatedLocalOwner();
   if (ownerElement)
     ownerElement->setWidget(nullptr);
@@ -4036,9 +4038,9 @@
     }
 
     if (view()) {
-      Widget* oldWidget = widgetForElement(*oldFocusedElement);
-      if (oldWidget)
-        oldWidget->setFocused(false, params.type);
+      FrameViewBase* oldFrameViewBase = widgetForElement(*oldFocusedElement);
+      if (oldFrameViewBase)
+        oldFrameViewBase->setFocused(false, params.type);
       else
         view()->setFocused(false, params.type);
     }
@@ -4110,17 +4112,17 @@
     // eww, I suck. set the qt focus correctly
     // ### find a better place in the code for this
     if (view()) {
-      Widget* focusWidget = widgetForElement(*m_focusedElement);
-      if (focusWidget) {
-        // Make sure a widget has the right size before giving it focus.
-        // Otherwise, we are testing edge cases of the Widget code.
+      FrameViewBase* focusFrameViewBase = widgetForElement(*m_focusedElement);
+      if (focusFrameViewBase) {
+        // Make sure a FrameViewBase has the right size before giving it focus.
+        // Otherwise, we are testing edge cases of the FrameViewBase code.
         // Specifically, in WebCore this does not work well for text fields.
         updateStyleAndLayout();
-        // Re-get the widget in case updating the layout changed things.
-        focusWidget = widgetForElement(*m_focusedElement);
+        // Re-get the FrameViewBase in case updating the layout changed things.
+        focusFrameViewBase = widgetForElement(*m_focusedElement);
       }
-      if (focusWidget)
-        focusWidget->setFocused(true, params.type);
+      if (focusFrameViewBase)
+        focusFrameViewBase->setFocused(true, params.type);
       else
         view()->setFocused(true, params.type);
     }
diff --git a/third_party/WebKit/Source/core/dom/Document.idl b/third_party/WebKit/Source/core/dom/Document.idl
index 84e147b7..8b3ae3e 100644
--- a/third_party/WebKit/Source/core/dom/Document.idl
+++ b/third_party/WebKit/Source/core/dom/Document.idl
@@ -78,7 +78,7 @@
     [NewObject] TreeWalker createTreeWalker(Node root, optional unsigned long whatToShow = 0xFFFFFFFF, optional NodeFilter? filter = null);
 
     // NonDocumentRootScroller (https://github.com/bokand/NonDocumentRootScroller)
-    [RaisesException=Setter, OriginTrialEnabled=RootScroller, Measure] attribute Element? rootScroller;
+    [RaisesException=Setter, RuntimeEnabled=SetRootScroller, Measure] attribute Element? rootScroller;
 
     // FIXME: xmlEncoding/xmlVersion/xmlStandalone have been removed from the spec.
     [MeasureAs=DocumentXMLEncoding] readonly attribute DOMString? xmlEncoding;
diff --git a/third_party/WebKit/Source/core/dom/URLSearchParams.cpp b/third_party/WebKit/Source/core/dom/URLSearchParams.cpp
index 30ba1da48..8de28baf 100644
--- a/third_party/WebKit/Source/core/dom/URLSearchParams.cpp
+++ b/third_party/WebKit/Source/core/dom/URLSearchParams.cpp
@@ -4,6 +4,7 @@
 
 #include "core/dom/URLSearchParams.h"
 
+#include <utility>
 #include "core/dom/DOMURL.h"
 #include "platform/network/FormDataEncoder.h"
 #include "platform/weborigin/KURL.h"
@@ -39,20 +40,47 @@
 
 }  // namespace
 
-URLSearchParams* URLSearchParams::create(const URLSearchParamsInit& init) {
+URLSearchParams* URLSearchParams::create(const URLSearchParamsInit& init,
+                                         ExceptionState& exceptionState) {
   if (init.isUSVString()) {
     const String& queryString = init.getAsUSVString();
     if (queryString.startsWith('?'))
       return new URLSearchParams(queryString.substring(1));
     return new URLSearchParams(queryString);
   }
+  // TODO(sof): copy constructor no longer in the spec,
+  // consider removing.
   if (init.isURLSearchParams())
     return new URLSearchParams(init.getAsURLSearchParams());
 
+  if (init.isUSVStringSequenceSequence()) {
+    return URLSearchParams::create(init.getAsUSVStringSequenceSequence(),
+                                   exceptionState);
+  }
+
   DCHECK(init.isNull());
   return new URLSearchParams(String());
 }
 
+URLSearchParams* URLSearchParams::create(const Vector<Vector<String>>& init,
+                                         ExceptionState& exceptionState) {
+  URLSearchParams* instance = new URLSearchParams(String());
+  if (!init.size())
+    return instance;
+  for (unsigned i = 0; i < init.size(); ++i) {
+    const Vector<String>& pair = init[i];
+    if (pair.size() != 2) {
+      exceptionState.throwTypeError(ExceptionMessages::failedToConstruct(
+          "URLSearchParams",
+          "Sequence initializer must only contain pair elements"));
+      return nullptr;
+    }
+    instance->appendWithoutUpdate(pair[0], pair[1]);
+  }
+  instance->runUpdateSteps();
+  return instance;
+}
+
 URLSearchParams::URLSearchParams(const String& queryString, DOMURL* urlObject)
     : m_urlObject(urlObject) {
   if (!queryString.isEmpty())
@@ -112,7 +140,7 @@
             queryString.substring(endOfName + 1, nameValueEnd - endOfName - 1));
       if (value.isNull())
         value = "";
-      m_params.push_back(std::make_pair(name, value));
+      appendWithoutUpdate(name, value);
     }
     start = nameValueEnd + 1;
   }
@@ -125,8 +153,13 @@
   return String(encodedData.data(), encodedData.size());
 }
 
-void URLSearchParams::append(const String& name, const String& value) {
+void URLSearchParams::appendWithoutUpdate(const String& name,
+                                          const String& value) {
   m_params.push_back(std::make_pair(name, value));
+}
+
+void URLSearchParams::append(const String& name, const String& value) {
+  appendWithoutUpdate(name, value);
   runUpdateSteps();
 }
 
diff --git a/third_party/WebKit/Source/core/dom/URLSearchParams.h b/third_party/WebKit/Source/core/dom/URLSearchParams.h
index b6afb63f..0813f5a9 100644
--- a/third_party/WebKit/Source/core/dom/URLSearchParams.h
+++ b/third_party/WebKit/Source/core/dom/URLSearchParams.h
@@ -5,22 +5,23 @@
 #ifndef URLSearchParams_h
 #define URLSearchParams_h
 
+#include <base/gtest_prod_util.h>
+#include <utility>
 #include "bindings/core/v8/Iterable.h"
 #include "bindings/core/v8/ScriptWrappable.h"
-#include "bindings/core/v8/USVStringOrURLSearchParams.h"
+#include "bindings/core/v8/USVStringSequenceSequenceOrUSVStringOrURLSearchParams.h"
 #include "platform/heap/Handle.h"
 #include "platform/network/EncodedFormData.h"
 #include "wtf/Forward.h"
 #include "wtf/text/WTFString.h"
-#include <base/gtest_prod_util.h>
-#include <utility>
 
 namespace blink {
 
 class ExceptionState;
 class DOMURL;
 
-typedef USVStringOrURLSearchParams URLSearchParamsInit;
+typedef USVStringSequenceSequenceOrUSVStringOrURLSearchParams
+    URLSearchParamsInit;
 
 class CORE_EXPORT URLSearchParams final
     : public GarbageCollectedFinalized<URLSearchParams>,
@@ -29,7 +30,9 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
-  static URLSearchParams* create(const URLSearchParamsInit&);
+  static URLSearchParams* create(const URLSearchParamsInit&, ExceptionState&);
+  static URLSearchParams* create(const Vector<Vector<String>>&,
+                                 ExceptionState&);
 
   static URLSearchParams* create(const String& queryString,
                                  DOMURL* urlObject = nullptr) {
@@ -68,6 +71,8 @@
   IterationSource* startIteration(ScriptState*, ExceptionState&) override;
   void encodeAsFormData(Vector<char>&) const;
 
+  void appendWithoutUpdate(const String& name, const String& value);
+
   Vector<std::pair<String, String>> m_params;
 
   WeakMember<DOMURL> m_urlObject;
diff --git a/third_party/WebKit/Source/core/dom/URLSearchParams.idl b/third_party/WebKit/Source/core/dom/URLSearchParams.idl
index 1c2642f..a350573 100644
--- a/third_party/WebKit/Source/core/dom/URLSearchParams.idl
+++ b/third_party/WebKit/Source/core/dom/URLSearchParams.idl
@@ -5,8 +5,9 @@
 // https://url.spec.whatwg.org/#interface-urlsearchparams
 
 [
-    Constructor(optional (USVString or URLSearchParams) init = ""),
-    Exposed=(Window,Worker)
+    Constructor(optional (sequence<sequence<USVString>> or USVString or URLSearchParams) init = ""),
+    Exposed=(Window,Worker),
+    RaisesException=Constructor,
 ] interface URLSearchParams {
     void append(USVString name, USVString value);
     [ImplementedAs=deleteAllWithName] void delete(USVString name);
diff --git a/third_party/WebKit/Source/core/editing/FrameSelection.cpp b/third_party/WebKit/Source/core/editing/FrameSelection.cpp
index 6ab0026..9247096 100644
--- a/third_party/WebKit/Source/core/editing/FrameSelection.cpp
+++ b/third_party/WebKit/Source/core/editing/FrameSelection.cpp
@@ -842,8 +842,8 @@
   LayoutObject* layoutObject = n->layoutObject();
   if (!layoutObject || !layoutObject->isLayoutPart())
     return false;
-  Widget* widget = toLayoutPart(layoutObject)->widget();
-  return widget && widget->isFrameView();
+  FrameViewBase* frameViewBase = toLayoutPart(layoutObject)->widget();
+  return frameViewBase && frameViewBase->isFrameView();
 }
 
 void FrameSelection::setFocusedNodeIfNeeded() {
diff --git a/third_party/WebKit/Source/core/frame/FrameView.cpp b/third_party/WebKit/Source/core/frame/FrameView.cpp
index 8481f106..80477b8 100644
--- a/third_party/WebKit/Source/core/frame/FrameView.cpp
+++ b/third_party/WebKit/Source/core/frame/FrameView.cpp
@@ -220,7 +220,7 @@
 
 FrameView* FrameView::create(LocalFrame& frame, const IntSize& initialSize) {
   FrameView* view = new FrameView(frame);
-  view->Widget::setFrameRect(IntRect(view->location(), initialSize));
+  view->FrameViewBase::setFrameRect(IntRect(view->location(), initialSize));
   view->setLayoutSizeInternal(initialSize);
 
   view->show();
@@ -244,7 +244,7 @@
   visitor->trace(m_anchoringAdjustmentQueue);
   visitor->trace(m_scrollbarManager);
   visitor->trace(m_printContext);
-  Widget::trace(visitor);
+  FrameViewBase::trace(visitor);
   ScrollableArea::trace(visitor);
 }
 
@@ -371,10 +371,11 @@
   // FIXME: Do we need to do something here for OOPI?
   HTMLFrameOwnerElement* ownerElement = m_frame->deprecatedLocalOwner();
   // TODO(dcheng): It seems buggy that we can have an owner element that points
-  // to another Widget. This can happen when a plugin element loads a frame
-  // (widget A of type FrameView) and then loads a plugin (widget B of type
-  // WebPluginContainerImpl). In this case, the frame's view is A and the frame
-  // element's owned widget is B. See https://crbug.com/673170 for an example.
+  // to another FrameViewBase. This can happen when a plugin element loads a
+  // frame (FrameViewBase A of type FrameView) and then loads a plugin
+  // (FrameViewBase B of type WebPluginContainerImpl). In this case, the frame's
+  // view is A and the frame element's owned FrameViewBase is B. See
+  // https://crbug.com/673170 for an example.
   if (ownerElement && ownerElement->ownedWidget() == this)
     ownerElement->setWidget(nullptr);
 
@@ -490,13 +491,15 @@
       m_frame->document()->styleEngine().usesWindowInactiveSelector();
 
   const ChildrenWidgetSet* viewChildren = children();
-  for (const Member<Widget>& child : *viewChildren) {
-    Widget* widget = child.get();
-    if (widget->isFrameView())
-      toFrameView(widget)->invalidateAllCustomScrollbarsOnActiveChanged();
-    else if (usesWindowInactiveSelector && widget->isScrollbar() &&
-             toScrollbar(widget)->isCustomScrollbar())
-      toScrollbar(widget)->styleChanged();
+  for (const Member<FrameViewBase>& child : *viewChildren) {
+    FrameViewBase* frameViewBase = child.get();
+    if (frameViewBase->isFrameView()) {
+      toFrameView(frameViewBase)
+          ->invalidateAllCustomScrollbarsOnActiveChanged();
+    } else if (usesWindowInactiveSelector && frameViewBase->isScrollbar() &&
+               toScrollbar(frameViewBase)->isCustomScrollbar()) {
+      toScrollbar(frameViewBase)->styleChanged();
+    }
   }
   if (usesWindowInactiveSelector)
     recalculateCustomScrollbarStyle();
@@ -531,7 +534,7 @@
   if (newRect == oldRect)
     return;
 
-  Widget::setFrameRect(newRect);
+  FrameViewBase::setFrameRect(newRect);
 
   const bool frameSizeChanged = oldRect.size() != newRect.size();
 
@@ -1140,9 +1143,10 @@
   if (!m_postLayoutTasksTimer.isActive() &&
       (needsLayout() || m_inSynchronousPostLayout)) {
     // If we need layout or are already in a synchronous call to
-    // postLayoutTasks(), defer widget updates and event dispatch until after we
-    // return.  postLayoutTasks() can make us need to update again, and we can
-    // get stuck in a nasty cycle unless we call it through the timer here.
+    // postLayoutTasks(), defer FrameViewBase updates and event dispatch until
+    // after we return.  postLayoutTasks() can make us need to update again, and
+    // we can get stuck in a nasty cycle unless we call it through the timer
+    // here.
     m_postLayoutTasksTimer.startOneShot(0, BLINK_FROM_HERE);
     if (needsLayout())
       layout();
@@ -1469,9 +1473,9 @@
     if (layoutViewItem().isNull())
       break;
 
-    if (Widget* widget = part->widget()) {
-      if (widget->isFrameView()) {
-        FrameView* frameView = toFrameView(widget);
+    if (FrameViewBase* frameViewBase = part->widget()) {
+      if (frameViewBase->isFrameView()) {
+        FrameView* frameView = toFrameView(frameViewBase);
         bool didNeedLayout = frameView->needsLayout();
         part->updateWidgetGeometry();
         if (!didNeedLayout && !frameView->shouldThrottleRendering())
@@ -1485,7 +1489,7 @@
 
 void FrameView::addPartToUpdate(LayoutEmbeddedObject& object) {
   ASSERT(isInPerformLayout());
-  // Tell the DOM element that it needs a widget update.
+  // Tell the DOM element that it needs a FrameViewBase update.
   Node* node = object.node();
   ASSERT(node);
   if (isHTMLObjectElement(*node) || isHTMLEmbedElement(*node))
@@ -1995,8 +1999,8 @@
   }
 
   // If there fixed position elements, scrolling may cause compositing layers to
-  // change.  Update widget and layer positions after scrolling, but only if
-  // we're not inside of layout.
+  // change.  Update FrameViewBase and layer positions after scrolling, but only
+  // if we're not inside of layout.
   if (!m_nestedLayoutCount) {
     updateWidgetGeometries();
     LayoutViewItem layoutViewItem = this->layoutViewItem();
@@ -2407,8 +2411,9 @@
 
 bool FrameView::updateWidgets() {
   // This is always called from updateWidgetsTimerFired.
-  // m_updateWidgetsTimer should only be scheduled if we have widgets to update.
-  // Thus I believe we can stop checking isEmpty here, and just ASSERT isEmpty:
+  // m_updateWidgetsTimer should only be scheduled if we have FrameViewBases to
+  // update. Thus I believe we can stop checking isEmpty here, and just ASSERT
+  // isEmpty:
   // FIXME: This assert has been temporarily removed due to
   // https://crbug.com/430344
   if (m_nestedLayoutCount > 1 || m_partUpdateSet.isEmpty())
@@ -3305,7 +3310,7 @@
   // We should have a way to only run these other Documents to the same
   // lifecycle stage as this frame.
   const ChildrenWidgetSet* viewChildren = children();
-  for (const Member<Widget>& child : *viewChildren) {
+  for (const Member<FrameViewBase>& child : *viewChildren) {
     if ((*child).isPluginContainer())
       toPluginView(child.get())->updateAllLifecyclePhases();
   }
@@ -3743,11 +3748,11 @@
   m_animatingScrollableAreas->erase(scrollableArea);
 }
 
-void FrameView::setParent(Widget* parentView) {
+void FrameView::setParent(FrameViewBase* parentView) {
   if (parentView == parent())
     return;
 
-  Widget::setParent(parentView);
+  FrameViewBase::setParent(parentView);
 
   updateParentScrollableAreaSet();
   setupRenderThrottling();
@@ -3756,7 +3761,7 @@
     m_subtreeThrottled = parentFrameView()->canThrottleRendering();
 }
 
-void FrameView::removeChild(Widget* child) {
+void FrameView::removeChild(FrameViewBase* child) {
   ASSERT(child->parent() == this);
 
   if (child->isFrameView() &&
@@ -3852,7 +3857,7 @@
   return maximumOffset.expandedTo(minimumScrollOffsetInt());
 }
 
-void FrameView::addChild(Widget* child) {
+void FrameView::addChild(FrameViewBase* child) {
   ASSERT(child != this && !child->parent());
   child->setParent(this);
   m_children.insert(child);
@@ -4307,8 +4312,8 @@
     setNeedsPaintPropertyUpdate();
   }
 
-  // This call will move children with native widgets (plugins) and invalidate
-  // them as well.
+  // This call will move children with native FrameViewBases (plugins) and
+  // invalidate them as well.
   frameRectsChanged();
 }
 
@@ -4474,7 +4479,7 @@
   return false;
 }
 
-Widget* FrameView::getWidget() {
+FrameViewBase* FrameView::getWidget() {
   return this;
 }
 
@@ -4642,7 +4647,7 @@
   // and potentially child frame views.
   setNeedsCompositingUpdate(layoutViewItem(), CompositingUpdateRebuildTree);
 
-  Widget::setParentVisible(visible);
+  FrameViewBase::setParentVisible(visible);
 
   if (!isSelfVisible())
     return;
@@ -4671,7 +4676,7 @@
     }
   }
 
-  Widget::show();
+  FrameViewBase::show();
 }
 
 void FrameView::hide() {
@@ -4694,7 +4699,7 @@
     }
   }
 
-  Widget::hide();
+  FrameViewBase::hide();
 }
 
 int FrameView::viewportWidth() const {
@@ -4745,11 +4750,11 @@
 
 void FrameView::updateViewportIntersectionsForSubtree(
     DocumentLifecycle::LifecycleState targetState) {
-  // TODO(dcheng): Since widget tree updates are deferred, FrameViews might
-  // still be in the widget hierarchy even though the associated Document is
-  // already detached. Investigate if this check and a similar check in
-  // lifecycle updates are still needed when there are no more deferred widget
-  // updates: https://crbug.com/561683
+  // TODO(dcheng): Since FrameViewBase tree updates are deferred, FrameViews
+  // might still be in the FrameViewBase hierarchy even though the associated
+  // Document is already detached. Investigate if this check and a similar check
+  // in lifecycle updates are still needed when there are no more deferred
+  // FrameViewBase updates: https://crbug.com/561683
   if (!frame().document()->isActive())
     return;
 
@@ -4824,7 +4829,7 @@
   if (notifyChildrenBehavior == NotifyChildren &&
       (wasThrottled != isThrottled ||
        forceThrottlingInvalidationBehavior == ForceThrottlingInvalidation)) {
-    for (const Member<Widget>& child : *children()) {
+    for (const Member<FrameViewBase>& child : *children()) {
       if (child->isFrameView()) {
         FrameView* childView = toFrameView(child);
         childView->updateRenderThrottlingStatus(
diff --git a/third_party/WebKit/Source/core/frame/FrameView.h b/third_party/WebKit/Source/core/frame/FrameView.h
index be06444d..229a844 100644
--- a/third_party/WebKit/Source/core/frame/FrameView.h
+++ b/third_party/WebKit/Source/core/frame/FrameView.h
@@ -26,6 +26,7 @@
 #ifndef FrameView_h
 #define FrameView_h
 
+#include <memory>
 #include "core/CoreExport.h"
 #include "core/dom/DocumentLifecycle.h"
 #include "core/frame/FrameViewAutoSizeInfo.h"
@@ -38,8 +39,8 @@
 #include "core/paint/PaintInvalidationCapableScrollableArea.h"
 #include "core/paint/PaintPhase.h"
 #include "core/paint/ScrollbarManager.h"
+#include "platform/FrameViewBase.h"
 #include "platform/RuntimeEnabledFeatures.h"
-#include "platform/Widget.h"
 #include "platform/animation/CompositorAnimationHost.h"
 #include "platform/animation/CompositorAnimationTimeline.h"
 #include "platform/geometry/IntRect.h"
@@ -57,7 +58,6 @@
 #include "wtf/HashSet.h"
 #include "wtf/ListHashSet.h"
 #include "wtf/text/WTFString.h"
-#include <memory>
 
 namespace blink {
 
@@ -99,7 +99,7 @@
 typedef unsigned long long DOMTimeStamp;
 
 class CORE_EXPORT FrameView final
-    : public Widget,
+    : public FrameViewBase,
       public PaintInvalidationCapableScrollableArea {
   USING_GARBAGE_COLLECTED_MIXIN(FrameView);
 
@@ -441,7 +441,7 @@
   bool isScrollCornerVisible() const override;
   bool userInputScrollable(ScrollbarOrientation) const override;
   bool shouldPlaceVerticalScrollbarOnLeft() const override;
-  Widget* getWidget() override;
+  FrameViewBase* getWidget() override;
   CompositorAnimationHost* compositorAnimationHost() const override;
   CompositorAnimationTimeline* compositorAnimationTimeline() const override;
   LayoutBox* layoutBox() const override;
@@ -459,12 +459,12 @@
   // and repaints to the host window in the window's coordinate space.
   HostWindow* getHostWindow() const;
 
-  typedef HeapHashSet<Member<Widget>> ChildrenWidgetSet;
+  typedef HeapHashSet<Member<FrameViewBase>> ChildrenWidgetSet;
 
   // Functions for child manipulation and inspection.
-  void setParent(Widget*) override;
-  void removeChild(Widget*);
-  void addChild(Widget*);
+  void setParent(FrameViewBase*) override;
+  void removeChild(FrameViewBase*);
+  void addChild(FrameViewBase*);
   const ChildrenWidgetSet* children() const { return &m_children; }
 
   // If the scroll view does not use a native widget, then it will have
@@ -609,7 +609,7 @@
   // event handlers (like Win32).
   Scrollbar* scrollbarAtFramePoint(const IntPoint&);
 
-  IntPoint convertChildToSelf(const Widget* child,
+  IntPoint convertChildToSelf(const FrameViewBase* child,
                               const IntPoint& point) const override {
     IntPoint newPoint = point;
     if (!isFrameViewScrollbar(child))
@@ -618,7 +618,7 @@
     return newPoint;
   }
 
-  IntPoint convertSelfToChild(const Widget* child,
+  IntPoint convertSelfToChild(const FrameViewBase* child,
                               const IntPoint& point) const override {
     IntPoint newPoint = point;
     if (!isFrameViewScrollbar(child))
@@ -627,16 +627,16 @@
     return newPoint;
   }
 
-  // Widget override. Handles painting of the contents of the view as well as
-  // the scrollbars.
+  // FrameViewBase override. Handles painting of the contents of the view as
+  // well as the scrollbars.
   void paint(GraphicsContext&, const CullRect&) const override;
   void paint(GraphicsContext&, const GlobalPaintFlags, const CullRect&) const;
   void paintContents(GraphicsContext&,
                      const GlobalPaintFlags,
                      const IntRect& damageRect) const;
 
-  // Widget overrides to ensure that our children's visibility status is kept up
-  // to date when we get shown and hidden.
+  // FrameViewBase overrides to ensure that our children's visibility status is
+  // kept up to date when we get shown and hidden.
   void show() override;
   void hide() override;
   void setParentVisible(bool) override;
@@ -951,8 +951,8 @@
   void contentsResized() override;
   void scrollbarExistenceDidChange();
 
-  // Override Widget methods to do point conversion via layoutObjects, in order
-  // to take transforms into account.
+  // Override FrameViewBase methods to do point conversion via layoutObjects, in
+  // order to take transforms into account.
   IntRect convertToContainingWidget(const IntRect&) const override;
   IntRect convertFromContainingWidget(const IntRect&) const override;
   IntPoint convertToContainingWidget(const IntPoint&) const override;
@@ -1007,7 +1007,7 @@
   void adjustScrollOffsetFromUpdateScrollbars();
   bool visualViewportSuppliesScrollbars();
 
-  bool isFrameViewScrollbar(const Widget* child) const {
+  bool isFrameViewScrollbar(const FrameViewBase* child) const {
     return horizontalScrollbar() == child || verticalScrollbar() == child;
   }
 
@@ -1054,7 +1054,7 @@
   EmbeddedObjectSet m_partUpdateSet;
 
   // FIXME: These are just "children" of the FrameView and should be
-  // Member<Widget> instead.
+  // Member<FrameViewBase> instead.
   HashSet<RefPtr<LayoutPart>> m_parts;
 
   Member<LocalFrame> m_frame;
@@ -1159,7 +1159,7 @@
 
   // Paint properties for SPv2 Only.
   // The hierarchy of transform subtree created by a FrameView.
-  // [ preTranslation ]               The offset from Widget::frameRect.
+  // [ preTranslation ]               The offset from FrameViewBase::frameRect.
   //     |                            Establishes viewport.
   //     +---[ scrollTranslation ]    Frame scrolling.
   // TODO(trchen): These will not be needed once settings->rootLayerScrolls() is
@@ -1253,10 +1253,10 @@
 }
 
 DEFINE_TYPE_CASTS(FrameView,
-                  Widget,
-                  widget,
-                  widget->isFrameView(),
-                  widget.isFrameView());
+                  FrameViewBase,
+                  frameViewBase,
+                  frameViewBase->isFrameView(),
+                  frameViewBase.isFrameView());
 DEFINE_TYPE_CASTS(FrameView,
                   ScrollableArea,
                   scrollableArea,
diff --git a/third_party/WebKit/Source/core/frame/LocalFrameClient.h b/third_party/WebKit/Source/core/frame/LocalFrameClient.h
index 43826ec..3cf25b4 100644
--- a/third_party/WebKit/Source/core/frame/LocalFrameClient.h
+++ b/third_party/WebKit/Source/core/frame/LocalFrameClient.h
@@ -194,12 +194,12 @@
   };
   virtual bool canCreatePluginWithoutRenderer(const String& mimeType) const = 0;
   virtual FrameViewBase* createPlugin(HTMLPlugInElement*,
-                               const KURL&,
-                               const Vector<String>&,
-                               const Vector<String>&,
-                               const String&,
-                               bool loadManually,
-                               DetachedPluginPolicy) = 0;
+                                      const KURL&,
+                                      const Vector<String>&,
+                                      const Vector<String>&,
+                                      const String&,
+                                      bool loadManually,
+                                      DetachedPluginPolicy) = 0;
 
   virtual std::unique_ptr<WebMediaPlayer> createWebMediaPlayer(
       HTMLMediaElement&,
diff --git a/third_party/WebKit/Source/core/frame/RemoteFrameView.cpp b/third_party/WebKit/Source/core/frame/RemoteFrameView.cpp
index fb2ad9df..8c48a72 100644
--- a/third_party/WebKit/Source/core/frame/RemoteFrameView.cpp
+++ b/third_party/WebKit/Source/core/frame/RemoteFrameView.cpp
@@ -22,8 +22,8 @@
 
 RemoteFrameView::~RemoteFrameView() {}
 
-void RemoteFrameView::setParent(Widget* parent) {
-  Widget::setParent(parent);
+void RemoteFrameView::setParent(FrameViewBase* parent) {
+  FrameViewBase::setParent(parent);
   frameRectsChanged();
 }
 
@@ -74,7 +74,7 @@
   // RemoteFrameView is disconnected before detachment.
   if (ownerElement && ownerElement->ownedWidget() == this)
     ownerElement->setWidget(nullptr);
-  Widget::dispose();
+  FrameViewBase::dispose();
 }
 
 void RemoteFrameView::invalidateRect(const IntRect& rect) {
@@ -94,7 +94,7 @@
   if (newRect == oldRect)
     return;
 
-  Widget::setFrameRect(newRect);
+  FrameViewBase::setFrameRect(newRect);
 
   frameRectsChanged();
 }
@@ -115,7 +115,7 @@
 void RemoteFrameView::hide() {
   setSelfVisible(false);
 
-  Widget::hide();
+  FrameViewBase::hide();
 
   m_remoteFrame->client()->visibilityChanged(false);
 }
@@ -123,7 +123,7 @@
 void RemoteFrameView::show() {
   setSelfVisible(true);
 
-  Widget::show();
+  FrameViewBase::show();
 
   m_remoteFrame->client()->visibilityChanged(true);
 }
@@ -132,7 +132,7 @@
   if (isParentVisible() == visible)
     return;
 
-  Widget::setParentVisible(visible);
+  FrameViewBase::setParentVisible(visible);
   if (!isSelfVisible())
     return;
 
@@ -141,7 +141,7 @@
 
 DEFINE_TRACE(RemoteFrameView) {
   visitor->trace(m_remoteFrame);
-  Widget::trace(visitor);
+  FrameViewBase::trace(visitor);
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/frame/RemoteFrameView.h b/third_party/WebKit/Source/core/frame/RemoteFrameView.h
index c117abb..9e48431 100644
--- a/third_party/WebKit/Source/core/frame/RemoteFrameView.h
+++ b/third_party/WebKit/Source/core/frame/RemoteFrameView.h
@@ -5,7 +5,7 @@
 #ifndef RemoteFrameView_h
 #define RemoteFrameView_h
 
-#include "platform/Widget.h"
+#include "platform/FrameViewBase.h"
 #include "platform/geometry/IntRect.h"
 #include "platform/heap/Handle.h"
 
@@ -13,14 +13,14 @@
 
 class RemoteFrame;
 
-class RemoteFrameView final : public Widget {
+class RemoteFrameView final : public FrameViewBase {
  public:
   static RemoteFrameView* create(RemoteFrame*);
 
   ~RemoteFrameView() override;
 
   bool isRemoteFrameView() const override { return true; }
-  void setParent(Widget*) override;
+  void setParent(FrameViewBase*) override;
 
   RemoteFrame& frame() const {
     ASSERT(m_remoteFrame);
@@ -53,10 +53,10 @@
 };
 
 DEFINE_TYPE_CASTS(RemoteFrameView,
-                  Widget,
-                  widget,
-                  widget->isRemoteFrameView(),
-                  widget.isRemoteFrameView());
+                  FrameViewBase,
+                  frameViewBase,
+                  frameViewBase->isRemoteFrameView(),
+                  frameViewBase.isRemoteFrameView());
 
 }  // namespace blink
 
diff --git a/third_party/WebKit/Source/core/frame/RootFrameViewport.cpp b/third_party/WebKit/Source/core/frame/RootFrameViewport.cpp
index 1f46321..558bc5e9 100644
--- a/third_party/WebKit/Source/core/frame/RootFrameViewport.cpp
+++ b/third_party/WebKit/Source/core/frame/RootFrameViewport.cpp
@@ -448,7 +448,7 @@
   visualViewport().cancelProgrammaticScrollAnimation();
 }
 
-Widget* RootFrameViewport::getWidget() {
+FrameViewBase* RootFrameViewport::getWidget() {
   return visualViewport().getWidget();
 }
 
diff --git a/third_party/WebKit/Source/core/frame/RootFrameViewport.h b/third_party/WebKit/Source/core/frame/RootFrameViewport.h
index 5c9cb153..7cbadcc 100644
--- a/third_party/WebKit/Source/core/frame/RootFrameViewport.h
+++ b/third_party/WebKit/Source/core/frame/RootFrameViewport.h
@@ -96,7 +96,7 @@
   void updateCompositorScrollAnimations() override;
   void cancelProgrammaticScrollAnimation() override;
   ScrollBehavior scrollBehaviorStyle() const override;
-  Widget* getWidget() override;
+  FrameViewBase* getWidget() override;
   void clearScrollableArea() override;
   LayoutBox* layoutBox() const override;
   FloatQuad localToVisibleContentQuad(const FloatQuad&,
diff --git a/third_party/WebKit/Source/core/frame/VisualViewport.cpp b/third_party/WebKit/Source/core/frame/VisualViewport.cpp
index 9be42a68..ae6c4e6 100644
--- a/third_party/WebKit/Source/core/frame/VisualViewport.cpp
+++ b/third_party/WebKit/Source/core/frame/VisualViewport.cpp
@@ -681,7 +681,7 @@
              : 0;
 }
 
-Widget* VisualViewport::getWidget() {
+FrameViewBase* VisualViewport::getWidget() {
   return mainFrame()->view();
 }
 
diff --git a/third_party/WebKit/Source/core/frame/VisualViewport.h b/third_party/WebKit/Source/core/frame/VisualViewport.h
index 5168e769..0e8ee55 100644
--- a/third_party/WebKit/Source/core/frame/VisualViewport.h
+++ b/third_party/WebKit/Source/core/frame/VisualViewport.h
@@ -191,7 +191,7 @@
   GraphicsLayer* layerForScrolling() const override;
   GraphicsLayer* layerForHorizontalScrollbar() const override;
   GraphicsLayer* layerForVerticalScrollbar() const override;
-  Widget* getWidget() override;
+  FrameViewBase* getWidget() override;
   CompositorAnimationHost* compositorAnimationHost() const override;
   CompositorAnimationTimeline* compositorAnimationTimeline() const override;
   IntRect visibleContentRect(
diff --git a/third_party/WebKit/Source/core/html/HTMLFrameOwnerElement.cpp b/third_party/WebKit/Source/core/html/HTMLFrameOwnerElement.cpp
index 2ce38adc..0efebb76 100644
--- a/third_party/WebKit/Source/core/html/HTMLFrameOwnerElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLFrameOwnerElement.cpp
@@ -38,22 +38,24 @@
 
 namespace blink {
 
-typedef HeapHashMap<Member<Widget>, Member<FrameView>> WidgetToParentMap;
-static WidgetToParentMap& widgetNewParentMap() {
-  DEFINE_STATIC_LOCAL(WidgetToParentMap, map, (new WidgetToParentMap));
+typedef HeapHashMap<Member<FrameViewBase>, Member<FrameView>>
+    FrameViewBaseToParentMap;
+static FrameViewBaseToParentMap& widgetNewParentMap() {
+  DEFINE_STATIC_LOCAL(FrameViewBaseToParentMap, map,
+                      (new FrameViewBaseToParentMap));
   return map;
 }
 
-using WidgetSet = HeapHashSet<Member<Widget>>;
-static WidgetSet& widgetsPendingTemporaryRemovalFromParent() {
-  // Widgets in this set will not leak because it will be cleared in
+using FrameViewBaseSet = HeapHashSet<Member<FrameViewBase>>;
+static FrameViewBaseSet& widgetsPendingTemporaryRemovalFromParent() {
+  // FrameViewBases in this set will not leak because it will be cleared in
   // HTMLFrameOwnerElement::UpdateSuspendScope::performDeferredWidgetTreeOperations.
-  DEFINE_STATIC_LOCAL(WidgetSet, set, (new WidgetSet));
+  DEFINE_STATIC_LOCAL(FrameViewBaseSet, set, (new FrameViewBaseSet));
   return set;
 }
 
-static WidgetSet& widgetsPendingDispose() {
-  DEFINE_STATIC_LOCAL(WidgetSet, set, (new WidgetSet));
+static FrameViewBaseSet& widgetsPendingDispose() {
+  DEFINE_STATIC_LOCAL(FrameViewBaseSet, set, (new FrameViewBaseSet));
   return set;
 }
 
@@ -71,12 +73,12 @@
 
 void HTMLFrameOwnerElement::UpdateSuspendScope::
     performDeferredWidgetTreeOperations() {
-  WidgetToParentMap map;
+  FrameViewBaseToParentMap map;
   widgetNewParentMap().swap(map);
-  for (const auto& widget : map) {
-    Widget* child = widget.key.get();
+  for (const auto& frameViewBase : map) {
+    FrameViewBase* child = frameViewBase.key.get();
     FrameView* currentParent = toFrameView(child->parent());
-    FrameView* newParent = widget.value;
+    FrameView* newParent = frameViewBase.value;
     if (newParent != currentParent) {
       if (currentParent)
         currentParent->removeChild(child);
@@ -88,20 +90,20 @@
   }
 
   {
-    WidgetSet set;
+    FrameViewBaseSet set;
     widgetsPendingTemporaryRemovalFromParent().swap(set);
-    for (const auto& widget : set) {
-      FrameView* currentParent = toFrameView(widget->parent());
+    for (const auto& frameViewBase : set) {
+      FrameView* currentParent = toFrameView(frameViewBase->parent());
       if (currentParent)
-        currentParent->removeChild(widget.get());
+        currentParent->removeChild(frameViewBase.get());
     }
   }
 
   {
-    WidgetSet set;
+    FrameViewBaseSet set;
     widgetsPendingDispose().swap(set);
-    for (const auto& widget : set) {
-      widget->dispose();
+    for (const auto& frameViewBase : set) {
+      frameViewBase->dispose();
     }
   }
 }
@@ -114,16 +116,16 @@
 }
 
 // Unlike moveWidgetToParentSoon, this will not call dispose the Widget.
-void temporarilyRemoveWidgetFromParentSoon(Widget* widget) {
+void temporarilyRemoveWidgetFromParentSoon(FrameViewBase* frameViewBase) {
   if (s_updateSuspendCount) {
-    widgetsPendingTemporaryRemovalFromParent().insert(widget);
+    widgetsPendingTemporaryRemovalFromParent().insert(frameViewBase);
   } else {
-    if (toFrameView(widget->parent()))
-      toFrameView(widget->parent())->removeChild(widget);
+    if (toFrameView(frameViewBase->parent()))
+      toFrameView(frameViewBase->parent())->removeChild(frameViewBase);
   }
 }
 
-void moveWidgetToParentSoon(Widget* child, FrameView* parent) {
+void moveWidgetToParentSoon(FrameViewBase* child, FrameView* parent) {
   if (!s_updateSuspendCount) {
     if (parent) {
       parent->addChild(child);
@@ -213,12 +215,12 @@
   return m_contentFrame && HTMLElement::isKeyboardFocusable();
 }
 
-void HTMLFrameOwnerElement::disposeWidgetSoon(Widget* widget) {
+void HTMLFrameOwnerElement::disposeWidgetSoon(FrameViewBase* frameViewBase) {
   if (s_updateSuspendCount) {
-    widgetsPendingDispose().insert(widget);
+    widgetsPendingDispose().insert(frameViewBase);
     return;
   }
-  widget->dispose();
+  frameViewBase->dispose();
 }
 
 void HTMLFrameOwnerElement::dispatchLoad() {
@@ -245,8 +247,8 @@
   return nullptr;
 }
 
-void HTMLFrameOwnerElement::setWidget(Widget* widget) {
-  if (widget == m_widget)
+void HTMLFrameOwnerElement::setWidget(FrameViewBase* frameViewBase) {
+  if (frameViewBase == m_widget)
     return;
 
   if (m_widget) {
@@ -255,7 +257,7 @@
     m_widget = nullptr;
   }
 
-  m_widget = widget;
+  m_widget = frameViewBase;
 
   LayoutPart* layoutPart = toLayoutPart(layoutObject());
   LayoutPartItem layoutPartItem = LayoutPartItem(layoutPart);
@@ -274,7 +276,7 @@
     cache->childrenChanged(layoutPart);
 }
 
-Widget* HTMLFrameOwnerElement::releaseWidget() {
+FrameViewBase* HTMLFrameOwnerElement::releaseWidget() {
   if (!m_widget)
     return nullptr;
   if (m_widget->parent())
@@ -287,7 +289,7 @@
   return m_widget.release();
 }
 
-Widget* HTMLFrameOwnerElement::ownedWidget() const {
+FrameViewBase* HTMLFrameOwnerElement::ownedWidget() const {
   return m_widget.get();
 }
 
diff --git a/third_party/WebKit/Source/core/html/HTMLObjectElement.cpp b/third_party/WebKit/Source/core/html/HTMLObjectElement.cpp
index afa08e86..a545e4b0 100644
--- a/third_party/WebKit/Source/core/html/HTMLObjectElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLObjectElement.cpp
@@ -41,7 +41,7 @@
 #include "core/html/parser/HTMLParserIdioms.h"
 #include "core/layout/api/LayoutEmbeddedItem.h"
 #include "core/plugins/PluginView.h"
-#include "platform/Widget.h"
+#include "platform/FrameViewBase.h"
 #include "platform/network/mime/MIMETypeRegistry.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/html/HTMLPlugInElement.cpp b/third_party/WebKit/Source/core/html/HTMLPlugInElement.cpp
index 123c9140..d8f485b 100644
--- a/third_party/WebKit/Source/core/html/HTMLPlugInElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLPlugInElement.cpp
@@ -46,8 +46,8 @@
 #include "core/page/Page.h"
 #include "core/page/scrolling/ScrollingCoordinator.h"
 #include "core/plugins/PluginView.h"
+#include "platform/FrameViewBase.h"
 #include "platform/Histogram.h"
-#include "platform/Widget.h"
 #include "platform/network/ResourceRequest.h"
 #include "platform/network/mime/MIMETypeFromURL.h"
 #include "platform/network/mime/MIMETypeRegistry.h"
@@ -78,7 +78,7 @@
     : HTMLFrameOwnerElement(tagName, doc),
       m_isDelayingLoadEvent(false),
       // m_needsWidgetUpdate(!createdByParser) allows HTMLObjectElement to delay
-      // widget updates until after all children are parsed. For
+      // FrameViewBase updates until after all children are parsed. For
       // HTMLEmbedElement this delay is unnecessary, but it is simpler to make
       // both classes share the same codepath in this class.
       m_needsWidgetUpdate(!createdByParser),
@@ -96,8 +96,8 @@
   HTMLFrameOwnerElement::trace(visitor);
 }
 
-void HTMLPlugInElement::setPersistedPluginWidget(Widget* widget) {
-  if (m_persistedPluginWidget == widget)
+void HTMLPlugInElement::setPersistedPluginWidget(FrameViewBase* frameViewBase) {
+  if (m_persistedPluginWidget == frameViewBase)
     return;
   if (m_persistedPluginWidget) {
     if (m_persistedPluginWidget->isPluginView()) {
@@ -108,7 +108,7 @@
              m_persistedPluginWidget->isRemoteFrameView());
     }
   }
-  m_persistedPluginWidget = widget;
+  m_persistedPluginWidget = frameViewBase;
 }
 
 bool HTMLPlugInElement::requestObjectInternal(
@@ -131,8 +131,8 @@
                        useFallback)) {
     // If the plugin element already contains a subframe,
     // loadOrRedirectSubframe will re-use it. Otherwise, it will create a
-    // new frame and set it as the LayoutPart's widget, causing what was
-    // previously in the widget to be torn down.
+    // new frame and set it as the LayoutPart's FrameViewBase, causing what was
+    // previously in the FrameViewBase to be torn down.
     return loadOrRedirectSubframe(completedURL, getNameAttribute(), true);
   }
 
@@ -159,8 +159,8 @@
 void HTMLPlugInElement::removeAllEventListeners() {
   HTMLFrameOwnerElement::removeAllEventListeners();
   if (LayoutPart* layoutObject = existingLayoutPart()) {
-    if (Widget* widget = layoutObject->widget())
-      widget->eventListenersRemoved();
+    if (FrameViewBase* frameViewBase = layoutObject->widget())
+      frameViewBase->eventListenersRemoved();
   }
 }
 
@@ -252,13 +252,16 @@
 }
 
 bool HTMLPlugInElement::shouldAccelerate() const {
-  if (Widget* widget = ownedWidget())
-    return widget->isPluginView() && toPluginView(widget)->platformLayer();
+  if (FrameViewBase* frameViewBase = ownedWidget()) {
+    return frameViewBase->isPluginView() &&
+           toPluginView(frameViewBase)->platformLayer();
+  }
   return false;
 }
 
 void HTMLPlugInElement::detachLayoutTree(const AttachContext& context) {
-  // Update the widget the next time we attach (detaching destroys the plugin).
+  // Update the FrameViewBase the next time we attach (detaching destroys the
+  // plugin).
   // FIXME: None of this "needsWidgetUpdate" related code looks right.
   if (layoutObject() && !useFallbackContent())
     setNeedsWidgetUpdate(true);
@@ -267,12 +270,12 @@
     document().decrementLoadEventDelayCount();
   }
 
-  // Only try to persist a plugin widget we actually own.
-  Widget* plugin = ownedWidget();
+  // Only try to persist a plugin FrameViewBase we actually own.
+  FrameViewBase* plugin = ownedWidget();
   if (plugin && context.performingReattach) {
     setPersistedPluginWidget(releaseWidget());
   } else {
-    // Clear the widget; will trigger disposal of it with Oilpan.
+    // Clear the FrameViewBase; will trigger disposal of it with Oilpan.
     setWidget(nullptr);
   }
 
@@ -322,7 +325,7 @@
   // return the cached allocated Bindings::Instance. Not supporting this
   // edge-case is OK.
   if (!m_pluginWrapper) {
-    Widget* plugin;
+    FrameViewBase* plugin;
 
     if (m_persistedPluginWidget)
       plugin = m_persistedPluginWidget.get();
@@ -335,7 +338,7 @@
   return m_pluginWrapper.get();
 }
 
-Widget* HTMLPlugInElement::pluginWidget() const {
+FrameViewBase* HTMLPlugInElement::pluginWidget() const {
   if (LayoutPart* layoutPart = layoutPartForJSBindings())
     return layoutPart->widget();
   return nullptr;
@@ -390,10 +393,10 @@
             .showsUnavailablePluginIndicator())
       return;
   }
-  Widget* widget = toLayoutPart(r)->widget();
-  if (!widget)
+  FrameViewBase* frameViewBase = toLayoutPart(r)->widget();
+  if (!frameViewBase)
     return;
-  widget->handleEvent(event);
+  frameViewBase->handleEvent(event);
   if (event->defaultHandled())
     return;
   HTMLFrameOwnerElement::defaultEventHandler(event);
@@ -528,9 +531,9 @@
     LocalFrameClient::DetachedPluginPolicy policy =
         requireLayoutObject ? LocalFrameClient::FailOnDetachedPlugin
                             : LocalFrameClient::AllowDetachedPlugin;
-    Widget* widget = frame->loader().client()->createPlugin(
+    FrameViewBase* frameViewBase = frame->loader().client()->createPlugin(
         this, url, paramNames, paramValues, mimeType, loadManually, policy);
-    if (!widget) {
+    if (!frameViewBase) {
       if (!layoutItem.isNull() &&
           !layoutItem.showsUnavailablePluginIndicator()) {
         m_pluginIsAvailable = false;
@@ -540,9 +543,9 @@
     }
 
     if (!layoutItem.isNull())
-      setWidget(widget);
+      setWidget(frameViewBase);
     else
-      setPersistedPluginWidget(widget);
+      setPersistedPluginWidget(frameViewBase);
   }
 
   document().setContainsPlugins();
diff --git a/third_party/WebKit/Source/core/html/PluginDocument.cpp b/third_party/WebKit/Source/core/html/PluginDocument.cpp
index 6d61570..6675c6b 100644
--- a/third_party/WebKit/Source/core/html/PluginDocument.cpp
+++ b/third_party/WebKit/Source/core/html/PluginDocument.cpp
@@ -158,9 +158,10 @@
 }
 
 PluginView* PluginDocumentParser::pluginView() const {
-  if (Widget* widget = toPluginDocument(document())->pluginWidget()) {
-    SECURITY_DCHECK(widget->isPluginContainer());
-    return toPluginView(widget);
+  if (FrameViewBase* frameViewBase =
+          toPluginDocument(document())->pluginWidget()) {
+    SECURITY_DCHECK(frameViewBase->isPluginContainer());
+    return toPluginView(frameViewBase);
   }
   return 0;
 }
@@ -178,14 +179,14 @@
   return PluginDocumentParser::create(this);
 }
 
-Widget* PluginDocument::pluginWidget() {
+FrameViewBase* PluginDocument::pluginWidget() {
   if (m_pluginNode && m_pluginNode->layoutObject()) {
     CHECK(m_pluginNode->layoutObject()->isEmbeddedObject());
-    Widget* widget =
+    FrameViewBase* frameViewBase =
         toLayoutEmbeddedObject(m_pluginNode->layoutObject())->widget();
-    if (!widget || !widget->isPluginContainer())
+    if (!frameViewBase || !frameViewBase->isPluginContainer())
       return nullptr;
-    return widget;
+    return frameViewBase;
   }
   return 0;
 }
diff --git a/third_party/WebKit/Source/core/input/EventHandler.cpp b/third_party/WebKit/Source/core/input/EventHandler.cpp
index 39d1f5e2..0135b65 100644
--- a/third_party/WebKit/Source/core/input/EventHandler.cpp
+++ b/third_party/WebKit/Source/core/input/EventHandler.cpp
@@ -108,9 +108,9 @@
 
 // Refetch the event target node if it is removed or currently is the shadow
 // node inside an <input> element.  If a mouse event handler changes the input
-// element type to one that has a widget associated, we'd like to
-// EventHandler::handleMousePressEvent to pass the event to the widget and thus
-// the event target node can't still be the shadow node.
+// element type to one that has a FrameViewBase associated, we'd like to
+// EventHandler::handleMousePressEvent to pass the event to the FrameViewBase
+// and thus the event target node can't still be the shadow node.
 bool shouldRefetchEventTarget(const MouseEventWithHitTestResults& mev) {
   Node* targetNode = mev.innerNode();
   if (!targetNode || !targetNode->parentNode())
@@ -319,11 +319,11 @@
   if (!layoutObject || !layoutObject->isLayoutPart())
     return nullptr;
 
-  Widget* widget = toLayoutPart(layoutObject)->widget();
-  if (!widget || !widget->isFrameView())
+  FrameViewBase* frameViewBase = toLayoutPart(layoutObject)->widget();
+  if (!frameViewBase || !frameViewBase->isFrameView())
     return nullptr;
 
-  return &toFrameView(widget)->frame();
+  return &toFrameView(frameViewBase)->frame();
 }
 
 static LocalFrame* subframeForHitTestResult(
@@ -609,8 +609,8 @@
     WebInputEventResult result = passMousePressEventToSubframe(mev, subframe);
     // Start capturing future events for this frame.  We only do this if we
     // didn't clear the m_mousePressed flag, which may happen if an AppKit
-    // widget entered a modal event loop.  The capturing should be done only
-    // when the result indicates it has been handled. See crbug.com/269917
+    // FrameViewBase entered a modal event loop.  The capturing should be done
+    // only when the result indicates it has been handled. See crbug.com/269917
     m_mouseEventManager->setCapturesDragging(
         subframe->eventHandler().m_mouseEventManager->capturesDragging());
     if (m_mouseEventManager->mousePressed() &&
@@ -693,8 +693,8 @@
       eventResult == WebInputEventResult::NotHandled || mev.scrollbar());
 
   // If the hit testing originally determined the event was in a scrollbar,
-  // refetch the MouseEventWithHitTestResults in case the scrollbar widget was
-  // destroyed when the mouse event was handled.
+  // refetch the MouseEventWithHitTestResults in case the scrollbar
+  // FrameViewBase was destroyed when the mouse event was handled.
   if (mev.scrollbar()) {
     const bool wasLastScrollBar =
         mev.scrollbar() == m_lastScrollbarUnderMouse.get();
diff --git a/third_party/WebKit/Source/core/input/ScrollManager.cpp b/third_party/WebKit/Source/core/input/ScrollManager.cpp
index 99c3fbd..5ddbc2d 100644
--- a/third_party/WebKit/Source/core/input/ScrollManager.cpp
+++ b/third_party/WebKit/Source/core/input/ScrollManager.cpp
@@ -361,13 +361,15 @@
       !layoutObject->isLayoutPart())
     return WebInputEventResult::NotHandled;
 
-  Widget* widget = toLayoutPart(layoutObject)->widget();
+  FrameViewBase* frameViewBase = toLayoutPart(layoutObject)->widget();
 
-  if (!widget || !widget->isFrameView())
+  if (!frameViewBase || !frameViewBase->isFrameView())
     return WebInputEventResult::NotHandled;
 
-  return toFrameView(widget)->frame().eventHandler().handleGestureScrollEvent(
-      gestureEvent);
+  return toFrameView(frameViewBase)
+      ->frame()
+      .eventHandler()
+      .handleGestureScrollEvent(gestureEvent);
 }
 
 bool ScrollManager::isViewportScrollingElement(const Element& element) const {
diff --git a/third_party/WebKit/Source/core/layout/LayoutEmbeddedObject.cpp b/third_party/WebKit/Source/core/layout/LayoutEmbeddedObject.cpp
index ae3e692e..4fca252 100644
--- a/third_party/WebKit/Source/core/layout/LayoutEmbeddedObject.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutEmbeddedObject.cpp
@@ -135,8 +135,8 @@
 
   updateLayerTransformAfterLayout();
 
-  Widget* widget = this->widget();
-  if (!widget && frameView())
+  FrameViewBase* frameViewBase = this->widget();
+  if (!frameViewBase && frameView())
     frameView()->addPartToUpdate(*this);
 
   clearNeedsLayout();
diff --git a/third_party/WebKit/Source/core/layout/LayoutPart.cpp b/third_party/WebKit/Source/core/layout/LayoutPart.cpp
index 5d6eba6..a8894f28 100644
--- a/third_party/WebKit/Source/core/layout/LayoutPart.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutPart.cpp
@@ -41,7 +41,8 @@
 LayoutPart::LayoutPart(Element* element)
     : LayoutReplaced(element),
       // Reference counting is used to prevent the part from being destroyed
-      // while inside the Widget code, which might not be able to handle that.
+      // while inside the FrameViewBase code, which might not be able to handle
+      // that.
       m_refCount(1) {
   ASSERT(element);
   frameView()->addPart(this);
@@ -87,8 +88,8 @@
   ASSERT(m_refCount <= 0);
 }
 
-Widget* LayoutPart::widget() const {
-  // Plugin widgets are stored in their DOM node.
+FrameViewBase* LayoutPart::widget() const {
+  // Plugin FrameViewBases are stored in their DOM node.
   Element* element = toElement(node());
 
   if (element && element->isFrameOwnerElement())
@@ -144,8 +145,8 @@
   bool inside = LayoutReplaced::nodeAtPoint(result, locationInContainer,
                                             accumulatedOffset, action);
 
-  // Check to see if we are really over the widget itself (and not just in the
-  // border/padding area).
+  // Check to see if we are really over the FrameViewBase itself (and not just
+  // in the border/padding area).
   if ((inside || result.isRectBasedTest()) && !hadResult &&
       result.innerNode() == node())
     result.setIsOverWidget(contentBoxRect().contains(result.localPoint()));
@@ -233,19 +234,19 @@
 void LayoutPart::styleDidChange(StyleDifference diff,
                                 const ComputedStyle* oldStyle) {
   LayoutReplaced::styleDidChange(diff, oldStyle);
-  Widget* widget = this->widget();
+  FrameViewBase* frameViewBase = this->widget();
 
-  if (!widget)
+  if (!frameViewBase)
     return;
 
   // If the iframe has custom scrollbars, recalculate their style.
-  if (widget && widget->isFrameView())
-    toFrameView(widget)->recalculateCustomScrollbarStyle();
+  if (frameViewBase && frameViewBase->isFrameView())
+    toFrameView(frameViewBase)->recalculateCustomScrollbarStyle();
 
   if (style()->visibility() != EVisibility::kVisible) {
-    widget->hide();
+    frameViewBase->hide();
   } else {
-    widget->show();
+    frameViewBase->show();
   }
 }
 
@@ -286,8 +287,8 @@
 }
 
 void LayoutPart::updateOnWidgetChange() {
-  Widget* widget = this->widget();
-  if (!widget)
+  FrameViewBase* frameViewBase = this->widget();
+  if (!frameViewBase)
     return;
 
   if (!style())
@@ -297,9 +298,9 @@
     updateWidgetGeometryInternal();
 
   if (style()->visibility() != EVisibility::kVisible) {
-    widget->hide();
+    frameViewBase->hide();
   } else {
-    widget->show();
+    frameViewBase->show();
     // FIXME: Why do we issue a full paint invalidation in this case, but not
     // the other?
     setShouldDoFullPaintInvalidation();
@@ -307,16 +308,18 @@
 }
 
 void LayoutPart::updateWidgetGeometry() {
-  Widget* widget = this->widget();
-  if (!widget || !node())  // Check the node in case destroy() has been called.
+  FrameViewBase* frameViewBase = this->widget();
+  if (!frameViewBase ||
+      !node())  // Check the node in case destroy() has been called.
     return;
 
   LayoutRect newFrame = replacedContentRect();
   DCHECK(newFrame.size() == roundedIntSize(newFrame.size()));
   bool boundsWillChange =
-      LayoutSize(widget->frameRect().size()) != newFrame.size();
+      LayoutSize(frameViewBase->frameRect().size()) != newFrame.size();
 
-  FrameView* frameView = widget->isFrameView() ? toFrameView(widget) : nullptr;
+  FrameView* frameView =
+      frameViewBase->isFrameView() ? toFrameView(frameViewBase) : nullptr;
 
   // If frame bounds are changing mark the view for layout. Also check the
   // frame's page to make sure that the frame isn't in the process of being
@@ -330,16 +333,16 @@
 
   // If view needs layout, either because bounds have changed or possibly
   // indicating content size is wrong, we have to do a layout to set the right
-  // widget size.
+  // FrameViewBase size.
   if (frameView && frameView->needsLayout() && frameView->frame().page())
     frameView->layout();
 
-  widget->widgetGeometryMayHaveChanged();
+  frameViewBase->widgetGeometryMayHaveChanged();
 }
 
 void LayoutPart::updateWidgetGeometryInternal() {
-  Widget* widget = this->widget();
-  ASSERT(widget);
+  FrameViewBase* frameViewBase = this->widget();
+  DCHECK(frameViewBase);
 
   // Ignore transform here, as we only care about the sub-pixel accumulation.
   // TODO(trchen): What about multicol? Need a LayoutBox function to query
@@ -352,10 +355,9 @@
                     pixelSnappedIntRect(absoluteReplacedRect).size());
   // Normally the location of the frame rect is ignored by the painter, but
   // currently it is still used by a family of coordinate conversion function in
-  // Widget/FrameView. This is incorrect because coordinate conversion needs to
-  // take transform and into account.
-  // A few callers still use the family of conversion function, including but
-  // not exhaustive:
+  // FrameViewBase/FrameView. This is incorrect because coordinate conversion
+  // needs to take transform and into account. A few callers still use the
+  // family of conversion function, including but not exhaustive:
   // FrameView::updateViewportIntersectionIfNeeded()
   // RemoteFrameView::frameRectsChanged().
   // WebPluginContainerImpl::reportGeometry()
@@ -366,7 +368,7 @@
 
   // Why is the protector needed?
   RefPtr<LayoutPart> protector(this);
-  widget->setFrameRect(frameRect);
+  frameViewBase->setFrameRect(frameRect);
 }
 
 void LayoutPart::invalidatePaintOfSubtreesIfNeeded(
diff --git a/third_party/WebKit/Source/core/layout/LayoutPart.h b/third_party/WebKit/Source/core/layout/LayoutPart.h
index 4859011..e44d8e73 100644
--- a/third_party/WebKit/Source/core/layout/LayoutPart.h
+++ b/third_party/WebKit/Source/core/layout/LayoutPart.h
@@ -25,7 +25,7 @@
 
 #include "core/CoreExport.h"
 #include "core/layout/LayoutReplaced.h"
-#include "platform/Widget.h"
+#include "platform/FrameViewBase.h"
 
 namespace blink {
 
@@ -48,7 +48,7 @@
   void ref() { ++m_refCount; }
   void deref();
 
-  Widget* widget() const;
+  FrameViewBase* widget() const;
 
   LayoutRect replacedContentRect() const final;
 
diff --git a/third_party/WebKit/Source/core/layout/LayoutScrollbar.cpp b/third_party/WebKit/Source/core/layout/LayoutScrollbar.cpp
index 90db9aa..d5b5bac7 100644
--- a/third_party/WebKit/Source/core/layout/LayoutScrollbar.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutScrollbar.cpp
@@ -99,7 +99,7 @@
              : 0;
 }
 
-void LayoutScrollbar::setParent(Widget* parent) {
+void LayoutScrollbar::setParent(FrameViewBase* parent) {
   Scrollbar::setParent(parent);
   if (!parent) {
     // Destroy all of the scrollbar's LayoutBoxes.
diff --git a/third_party/WebKit/Source/core/layout/LayoutScrollbar.h b/third_party/WebKit/Source/core/layout/LayoutScrollbar.h
index be6748ff..f0526cb 100644
--- a/third_party/WebKit/Source/core/layout/LayoutScrollbar.h
+++ b/third_party/WebKit/Source/core/layout/LayoutScrollbar.h
@@ -77,7 +77,7 @@
  private:
   friend class Scrollbar;
 
-  void setParent(Widget*) override;
+  void setParent(FrameViewBase*) override;
   void setEnabled(bool) override;
 
   void setHoveredPart(ScrollbarPart) override;
diff --git a/third_party/WebKit/Source/core/layout/LayoutTreeAsText.cpp b/third_party/WebKit/Source/core/layout/LayoutTreeAsText.cpp
index dc3c3d7c..0ccaf12 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTreeAsText.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTreeAsText.cpp
@@ -526,9 +526,9 @@
   }
 
   if (o.isLayoutPart()) {
-    Widget* widget = toLayoutPart(o).widget();
-    if (widget && widget->isFrameView()) {
-      FrameView* view = toFrameView(widget);
+    FrameViewBase* frameViewBase = toLayoutPart(o).widget();
+    if (frameViewBase && frameViewBase->isFrameView()) {
+      FrameView* view = toFrameView(frameViewBase);
       LayoutViewItem rootItem = view->layoutViewItem();
       if (!rootItem.isNull()) {
         rootItem.updateStyleAndLayout();
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
index 9328460..84f64b1 100644
--- a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
+++ b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
@@ -151,10 +151,10 @@
 static WebLayer* platformLayerForPlugin(LayoutObject& layoutObject) {
   if (!layoutObject.isEmbeddedObject())
     return nullptr;
-  Widget* widget = toLayoutEmbeddedObject(layoutObject).widget();
-  if (!widget || !widget->isPluginView())
+  FrameViewBase* frameViewBase = toLayoutEmbeddedObject(layoutObject).widget();
+  if (!frameViewBase || !frameViewBase->isPluginView())
     return nullptr;
-  return toPluginView(widget)->platformLayer();
+  return toPluginView(frameViewBase)->platformLayer();
 }
 
 static inline bool isAcceleratedContents(LayoutObject& layoutObject) {
diff --git a/third_party/WebKit/Source/core/loader/EmptyClients.cpp b/third_party/WebKit/Source/core/loader/EmptyClients.cpp
index 308465ad..fc9747e0 100644
--- a/third_party/WebKit/Source/core/loader/EmptyClients.cpp
+++ b/third_party/WebKit/Source/core/loader/EmptyClients.cpp
@@ -27,6 +27,7 @@
 
 #include "core/loader/EmptyClients.h"
 
+#include <memory>
 #include "core/frame/FrameHost.h"
 #include "core/frame/LocalFrame.h"
 #include "core/frame/VisualViewport.h"
@@ -35,14 +36,13 @@
 #include "core/html/forms/DateTimeChooser.h"
 #include "core/loader/DocumentLoader.h"
 #include "platform/FileChooser.h"
-#include "platform/Widget.h"
+#include "platform/FrameViewBase.h"
 #include "public/platform/Platform.h"
 #include "public/platform/WebApplicationCacheHost.h"
 #include "public/platform/WebMediaPlayer.h"
 #include "public/platform/modules/serviceworker/WebServiceWorkerProvider.h"
 #include "public/platform/modules/serviceworker/WebServiceWorkerProviderClient.h"
 #include "wtf/PtrUtil.h"
-#include <memory>
 
 namespace blink {
 
@@ -159,13 +159,13 @@
   return nullptr;
 }
 
-Widget* EmptyLocalFrameClient::createPlugin(HTMLPlugInElement*,
-                                            const KURL&,
-                                            const Vector<String>&,
-                                            const Vector<String>&,
-                                            const String&,
-                                            bool,
-                                            DetachedPluginPolicy) {
+FrameViewBase* EmptyLocalFrameClient::createPlugin(HTMLPlugInElement*,
+                                                   const KURL&,
+                                                   const Vector<String>&,
+                                                   const Vector<String>&,
+                                                   const String&,
+                                                   bool,
+                                                   DetachedPluginPolicy) {
   return nullptr;
 }
 
diff --git a/third_party/WebKit/Source/core/loader/EmptyClients.h b/third_party/WebKit/Source/core/loader/EmptyClients.h
index 71531ea..354c8eb 100644
--- a/third_party/WebKit/Source/core/loader/EmptyClients.h
+++ b/third_party/WebKit/Source/core/loader/EmptyClients.h
@@ -168,9 +168,10 @@
   bool tabsToLinks() override { return false; }
 
   void invalidateRect(const IntRect&) override {}
-  void scheduleAnimation(Widget*) override {}
+  void scheduleAnimation(FrameViewBase*) override {}
 
-  IntRect viewportToScreen(const IntRect& r, const Widget*) const override {
+  IntRect viewportToScreen(const IntRect& r,
+                           const FrameViewBase*) const override {
     return r;
   }
   float windowToViewportScalar(const float s) const override { return s; }
@@ -322,13 +323,13 @@
   LocalFrame* createFrame(const FrameLoadRequest&,
                           const AtomicString&,
                           HTMLFrameOwnerElement*) override;
-  Widget* createPlugin(HTMLPlugInElement*,
-                       const KURL&,
-                       const Vector<String>&,
-                       const Vector<String>&,
-                       const String&,
-                       bool,
-                       DetachedPluginPolicy) override;
+  FrameViewBase* createPlugin(HTMLPlugInElement*,
+                              const KURL&,
+                              const Vector<String>&,
+                              const Vector<String>&,
+                              const String&,
+                              bool,
+                              DetachedPluginPolicy) override;
   bool canCreatePluginWithoutRenderer(const String& mimeType) const override {
     return false;
   }
diff --git a/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp b/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp
index da9c42af..0c72123 100644
--- a/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp
+++ b/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp
@@ -990,7 +990,7 @@
   }
 
   if (const FrameView::ChildrenWidgetSet* children = frameView->children()) {
-    for (const Member<Widget>& child : *children) {
+    for (const Member<FrameViewBase>& child : *children) {
       if (!(*child).isPluginView())
         continue;
 
diff --git a/third_party/WebKit/Source/core/paint/EmbeddedObjectPaintInvalidator.cpp b/third_party/WebKit/Source/core/paint/EmbeddedObjectPaintInvalidator.cpp
index 438f86a..fadf49ee 100644
--- a/third_party/WebKit/Source/core/paint/EmbeddedObjectPaintInvalidator.cpp
+++ b/third_party/WebKit/Source/core/paint/EmbeddedObjectPaintInvalidator.cpp
@@ -16,9 +16,9 @@
       BoxPaintInvalidator(m_embeddedObject, m_context)
           .invalidatePaintIfNeeded();
 
-  Widget* widget = m_embeddedObject.widget();
-  if (widget && widget->isPluginView())
-    toPluginView(widget)->invalidatePaintIfNeeded();
+  FrameViewBase* frameViewBase = m_embeddedObject.widget();
+  if (frameViewBase && frameViewBase->isPluginView())
+    toPluginView(frameViewBase)->invalidatePaintIfNeeded();
 
   return reason;
 }
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
index c10ec79..5e1cd751 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
@@ -1884,7 +1884,7 @@
              controller.globalRootScroller()) == this;
 }
 
-Widget* PaintLayerScrollableArea::getWidget() {
+FrameViewBase* PaintLayerScrollableArea::getWidget() {
   return box().frame()->view();
 }
 
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.h b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.h
index 87bb281..2af6606 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.h
+++ b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.h
@@ -419,7 +419,7 @@
   IntRect rectForHorizontalScrollbar(const IntRect& borderBoxRect) const;
   IntRect rectForVerticalScrollbar(const IntRect& borderBoxRect) const;
 
-  Widget* getWidget() override;
+  FrameViewBase* getWidget() override;
   bool shouldPerformScrollAnchoring() const override;
   ScrollAnchor* scrollAnchor() override { return &m_scrollAnchor; }
   bool isPaintLayerScrollableArea() const override { return true; }
diff --git a/third_party/WebKit/Source/core/paint/PartPainter.cpp b/third_party/WebKit/Source/core/paint/PartPainter.cpp
index e7f27a16..9f31767 100644
--- a/third_party/WebKit/Source/core/paint/PartPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/PartPainter.cpp
@@ -118,23 +118,24 @@
                                 const LayoutPoint& paintOffset) {
   LayoutPoint adjustedPaintOffset = paintOffset + m_layoutPart.location();
 
-  Widget* widget = m_layoutPart.widget();
-  CHECK(widget);
+  FrameViewBase* frameViewBase = m_layoutPart.widget();
+  CHECK(frameViewBase);
 
   IntPoint paintLocation(roundedIntPoint(
       adjustedPaintOffset + m_layoutPart.replacedContentRect().location()));
 
-  // Widgets don't support painting with a paint offset, but instead offset
-  // themselves using the frame rect location. To paint widgets at our desired
-  // location, we need to apply paint offset as a transform, with the frame rect
-  // neutralized.
-  IntSize widgetPaintOffset = paintLocation - widget->frameRect().location();
+  // FrameViewBases don't support painting with a paint offset, but instead
+  // offset themselves using the frame rect location. To paint widgets at our
+  // desired location, we need to apply paint offset as a transform, with the
+  // frame rect neutralized.
+  IntSize widgetPaintOffset =
+      paintLocation - frameViewBase->frameRect().location();
   TransformRecorder transform(
       paintInfo.context, m_layoutPart,
       AffineTransform::translation(widgetPaintOffset.width(),
                                    widgetPaintOffset.height()));
   CullRect adjustedCullRect(paintInfo.cullRect(), -widgetPaintOffset);
-  widget->paint(paintInfo.context, adjustedCullRect);
+  frameViewBase->paint(paintInfo.context, adjustedCullRect);
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/paint/PrePaintTreeWalk.cpp b/third_party/WebKit/Source/core/paint/PrePaintTreeWalk.cpp
index ebef0f74..8a9a8d3 100644
--- a/third_party/WebKit/Source/core/paint/PrePaintTreeWalk.cpp
+++ b/third_party/WebKit/Source/core/paint/PrePaintTreeWalk.cpp
@@ -250,14 +250,14 @@
 
   if (object.isLayoutPart()) {
     const LayoutPart& layoutPart = toLayoutPart(object);
-    Widget* widget = layoutPart.widget();
-    if (widget && widget->isFrameView()) {
+    FrameViewBase* frameViewBase = layoutPart.widget();
+    if (frameViewBase && frameViewBase->isFrameView()) {
       context.treeBuilderContext.current.paintOffset +=
           layoutPart.replacedContentRect().location() -
-          widget->frameRect().location();
+          frameViewBase->frameRect().location();
       context.treeBuilderContext.current.paintOffset =
           roundedIntPoint(context.treeBuilderContext.current.paintOffset);
-      walk(*toFrameView(widget), context);
+      walk(*toFrameView(frameViewBase), context);
     }
     // TODO(pdr): Investigate RemoteFrameView (crbug.com/579281).
   }
diff --git a/third_party/WebKit/Source/core/plugins/PluginView.h b/third_party/WebKit/Source/core/plugins/PluginView.h
index 0f799cb..97f23618 100644
--- a/third_party/WebKit/Source/core/plugins/PluginView.h
+++ b/third_party/WebKit/Source/core/plugins/PluginView.h
@@ -29,7 +29,7 @@
 #define PluginView_h
 
 #include "core/CoreExport.h"
-#include "platform/Widget.h"
+#include "platform/FrameViewBase.h"
 #include "platform/scroll/ScrollTypes.h"
 #include "v8/include/v8.h"
 #include "wtf/text/WTFString.h"
@@ -42,7 +42,7 @@
 
 class ResourceResponse;
 
-class CORE_EXPORT PluginView : public Widget {
+class CORE_EXPORT PluginView : public FrameViewBase {
  public:
   bool isPluginView() const final { return true; }
 
@@ -62,14 +62,14 @@
   virtual void invalidatePaintIfNeeded() {}
 
  protected:
-  PluginView() : Widget() {}
+  PluginView() : FrameViewBase() {}
 };
 
 DEFINE_TYPE_CASTS(PluginView,
-                  Widget,
-                  widget,
-                  widget->isPluginView(),
-                  widget.isPluginView());
+                  FrameViewBase,
+                  frameViewBase,
+                  frameViewBase->isPluginView(),
+                  frameViewBase.isPluginView());
 
 }  // namespace blink
 
diff --git a/third_party/WebKit/Source/core/svg/graphics/SVGImageChromeClient.cpp b/third_party/WebKit/Source/core/svg/graphics/SVGImageChromeClient.cpp
index d9bffe4..653832f 100644
--- a/third_party/WebKit/Source/core/svg/graphics/SVGImageChromeClient.cpp
+++ b/third_party/WebKit/Source/core/svg/graphics/SVGImageChromeClient.cpp
@@ -82,7 +82,7 @@
   scheduleAnimation(nullptr);
 }
 
-void SVGImageChromeClient::scheduleAnimation(Widget*) {
+void SVGImageChromeClient::scheduleAnimation(FrameViewBase*) {
   // Because a single SVGImage can be shared by multiple pages, we can't key
   // our svg image layout on the page's real animation frame. Therefore, we
   // run this fake animation timer to trigger layout in SVGImages. The name,
diff --git a/third_party/WebKit/Source/core/svg/graphics/SVGImageChromeClient.h b/third_party/WebKit/Source/core/svg/graphics/SVGImageChromeClient.h
index 313561df..eea10b5 100644
--- a/third_party/WebKit/Source/core/svg/graphics/SVGImageChromeClient.h
+++ b/third_party/WebKit/Source/core/svg/graphics/SVGImageChromeClient.h
@@ -56,7 +56,7 @@
 
   void chromeDestroyed() override;
   void invalidateRect(const IntRect&) override;
-  void scheduleAnimation(Widget*) override;
+  void scheduleAnimation(FrameViewBase*) override;
 
   void setTimer(std::unique_ptr<TimerBase>);
   void animationTimerFired(TimerBase*);
diff --git a/third_party/WebKit/Source/modules/credentialmanager/PasswordCredential.cpp b/third_party/WebKit/Source/modules/credentialmanager/PasswordCredential.cpp
index 17cc39a..381369ed 100644
--- a/third_party/WebKit/Source/modules/credentialmanager/PasswordCredential.cpp
+++ b/third_party/WebKit/Source/modules/credentialmanager/PasswordCredential.cpp
@@ -103,7 +103,7 @@
   if (form->enctype() == "multipart/form-data") {
     additionalData.setFormData(formData);
   } else {
-    URLSearchParams* params = URLSearchParams::create(URLSearchParamsInit());
+    URLSearchParams* params = URLSearchParams::create(String());
     for (const FormData::Entry* entry : formData->entries()) {
       if (entry->isString())
         params->append(entry->name().data(), entry->value().data());
@@ -135,7 +135,7 @@
   if (m_additionalData.isURLSearchParams()) {
     // If |additionalData| is a 'URLSearchParams' object, build a urlencoded
     // response.
-    URLSearchParams* params = URLSearchParams::create(URLSearchParamsInit());
+    URLSearchParams* params = URLSearchParams::create(String());
     URLSearchParams* additionalData = m_additionalData.getAsURLSearchParams();
     for (const auto& param : additionalData->params()) {
       const String& name = param.first;
diff --git a/third_party/WebKit/Source/modules/plugins/PluginOcclusionSupport.cpp b/third_party/WebKit/Source/modules/plugins/PluginOcclusionSupport.cpp
index 55c60c4..d5724ec 100644
--- a/third_party/WebKit/Source/modules/plugins/PluginOcclusionSupport.cpp
+++ b/third_party/WebKit/Source/modules/plugins/PluginOcclusionSupport.cpp
@@ -38,7 +38,7 @@
 #include "core/html/HTMLFrameOwnerElement.h"
 #include "core/layout/LayoutBox.h"
 #include "core/layout/LayoutObject.h"
-#include "platform/Widget.h"
+#include "platform/FrameViewBase.h"
 #include "wtf/HashSet.h"
 
 // This file provides a utility function to support rendering certain elements
@@ -153,7 +153,7 @@
 // page. In a nutshell, iframe elements should occlude plugins when
 // they occur higher in the stacking order.
 void getPluginOcclusions(Element* element,
-                         Widget* parentWidget,
+                         FrameViewBase* parentFrameViewBase,
                          const IntRect& frameRect,
                          Vector<IntRect>& occlusions) {
   LayoutObject* pluginNode = element->layoutObject();
@@ -164,10 +164,10 @@
   Vector<const LayoutObject*> iframeZstack;
   getObjectStack(pluginNode, &pluginZstack);
 
-  if (!parentWidget->isFrameView())
+  if (!parentFrameViewBase->isFrameView())
     return;
 
-  FrameView* parentFrameView = toFrameView(parentWidget);
+  FrameView* parentFrameView = toFrameView(parentFrameViewBase);
 
   // Occlusions by iframes.
   const FrameView::ChildrenWidgetSet* children = parentFrameView->children();
diff --git a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5 b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5
index 41000ca..ec378cd 100644
--- a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5
+++ b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5
@@ -790,7 +790,6 @@
     },
     {
       name: "SetRootScroller",
-      origin_trial_feature_name: "RootScroller",
       status: "experimental",
     },
     {
diff --git a/third_party/WebKit/Source/web/ChromeClientImpl.cpp b/third_party/WebKit/Source/web/ChromeClientImpl.cpp
index e017d44a..a5721cf 100644
--- a/third_party/WebKit/Source/web/ChromeClientImpl.cpp
+++ b/third_party/WebKit/Source/web/ChromeClientImpl.cpp
@@ -545,9 +545,9 @@
     m_webView->invalidateRect(updateRect);
 }
 
-void ChromeClientImpl::scheduleAnimation(Widget* widget) {
-  DCHECK(widget->isFrameView());
-  FrameView* view = toFrameView(widget);
+void ChromeClientImpl::scheduleAnimation(FrameViewBase* frameViewBase) {
+  DCHECK(frameViewBase->isFrameView());
+  FrameView* view = toFrameView(frameViewBase);
   LocalFrame* frame = view->frame().localFrameRoot();
 
   // If the frame is still being created, it might not yet have a WebWidget.
@@ -559,12 +559,13 @@
     WebLocalFrameImpl::fromFrame(frame)->frameWidget()->scheduleAnimation();
 }
 
-IntRect ChromeClientImpl::viewportToScreen(const IntRect& rectInViewport,
-                                           const Widget* widget) const {
+IntRect ChromeClientImpl::viewportToScreen(
+    const IntRect& rectInViewport,
+    const FrameViewBase* frameViewBase) const {
   WebRect screenRect(rectInViewport);
 
-  DCHECK(widget->isFrameView());
-  const FrameView* view = toFrameView(widget);
+  DCHECK(frameViewBase->isFrameView());
+  const FrameView* view = toFrameView(frameViewBase);
   LocalFrame* frame = view->frame().localFrameRoot();
 
   WebWidgetClient* client =
@@ -639,9 +640,10 @@
                 isHTMLEmbedElement(*result.innerNode()))) {
       LayoutObject* object = result.innerNode()->layoutObject();
       if (object && object->isLayoutPart()) {
-        Widget* widget = toLayoutPart(object)->widget();
-        if (widget && widget->isPluginContainer()) {
-          WebPluginContainerImpl* plugin = toWebPluginContainerImpl(widget);
+        FrameViewBase* frameViewBase = toLayoutPart(object)->widget();
+        if (frameViewBase && frameViewBase->isPluginContainer()) {
+          WebPluginContainerImpl* plugin =
+              toWebPluginContainerImpl(frameViewBase);
           url = plugin->plugin()->linkAtPosition(
               result.roundedPointInInnerNodeFrame());
         }
diff --git a/third_party/WebKit/Source/web/ContextMenuClientImpl.cpp b/third_party/WebKit/Source/web/ContextMenuClientImpl.cpp
index a2116796..81c14acd 100644
--- a/third_party/WebKit/Source/web/ContextMenuClientImpl.cpp
+++ b/third_party/WebKit/Source/web/ContextMenuClientImpl.cpp
@@ -59,7 +59,7 @@
 #include "core/page/ContextMenuController.h"
 #include "core/page/Page.h"
 #include "platform/ContextMenu.h"
-#include "platform/Widget.h"
+#include "platform/FrameViewBase.h"
 #include "platform/exported/WrappedResourceResponse.h"
 #include "platform/text/TextBreakIterator.h"
 #include "platform/weborigin/KURL.h"
@@ -250,10 +250,11 @@
              isHTMLEmbedElement(*r.innerNode())) {
     LayoutObject* object = r.innerNode()->layoutObject();
     if (object && object->isLayoutPart()) {
-      Widget* widget = toLayoutPart(object)->widget();
-      if (widget && widget->isPluginContainer()) {
+      FrameViewBase* frameViewBase = toLayoutPart(object)->widget();
+      if (frameViewBase && frameViewBase->isPluginContainer()) {
         data.mediaType = WebContextMenuData::MediaTypePlugin;
-        WebPluginContainerImpl* plugin = toWebPluginContainerImpl(widget);
+        WebPluginContainerImpl* plugin =
+            toWebPluginContainerImpl(frameViewBase);
         WebString text = plugin->plugin()->selectionAsText();
         if (!text.isEmpty()) {
           data.selectedText = text;
diff --git a/third_party/WebKit/Source/web/InspectorOverlay.cpp b/third_party/WebKit/Source/web/InspectorOverlay.cpp
index 8faf981d..5516808 100644
--- a/third_party/WebKit/Source/web/InspectorOverlay.cpp
+++ b/third_party/WebKit/Source/web/InspectorOverlay.cpp
@@ -35,6 +35,7 @@
 #include "bindings/core/v8/V8InspectorOverlayHost.h"
 #include "core/dom/Node.h"
 #include "core/dom/StaticNodeList.h"
+#include "core/dom/TaskRunnerHelper.h"
 #include "core/frame/FrameHost.h"
 #include "core/frame/FrameView.h"
 #include "core/frame/LocalFrame.h"
@@ -161,11 +162,11 @@
 
   void invalidateRect(const IntRect&) override { m_overlay->invalidate(); }
 
-  void scheduleAnimation(Widget* widget) override {
+  void scheduleAnimation(FrameViewBase* frameViewBase) override {
     if (m_overlay->m_inLayout)
       return;
 
-    m_client->scheduleAnimation(widget);
+    m_client->scheduleAnimation(frameViewBase);
   }
 
  private:
@@ -182,7 +183,10 @@
       m_drawViewSize(false),
       m_resizeTimerActive(false),
       m_omitTooltip(false),
-      m_timer(this, &InspectorOverlay::onTimer),
+      m_timer(
+          TaskRunnerHelper::get(TaskType::UnspecedTimer, frameImpl->frame()),
+          this,
+          &InspectorOverlay::onTimer),
       m_suspended(false),
       m_showReloadingBlanket(false),
       m_inLayout(false),
diff --git a/third_party/WebKit/Source/web/InspectorOverlay.h b/third_party/WebKit/Source/web/InspectorOverlay.h
index 7276894c..341fd36 100644
--- a/third_party/WebKit/Source/web/InspectorOverlay.h
+++ b/third_party/WebKit/Source/web/InspectorOverlay.h
@@ -150,7 +150,7 @@
   bool m_drawViewSize;
   bool m_resizeTimerActive;
   bool m_omitTooltip;
-  Timer<InspectorOverlay> m_timer;
+  TaskRunnerTimer<InspectorOverlay> m_timer;
   bool m_suspended;
   bool m_showReloadingBlanket;
   bool m_inLayout;
diff --git a/third_party/WebKit/Source/web/LocalFrameClientImpl.cpp b/third_party/WebKit/Source/web/LocalFrameClientImpl.cpp
index 88f3598d..73c1b65e 100644
--- a/third_party/WebKit/Source/web/LocalFrameClientImpl.cpp
+++ b/third_party/WebKit/Source/web/LocalFrameClientImpl.cpp
@@ -748,13 +748,14 @@
   return m_webFrame->client()->canCreatePluginWithoutRenderer(mimeType);
 }
 
-Widget* LocalFrameClientImpl::createPlugin(HTMLPlugInElement* element,
-                                           const KURL& url,
-                                           const Vector<String>& paramNames,
-                                           const Vector<String>& paramValues,
-                                           const String& mimeType,
-                                           bool loadManually,
-                                           DetachedPluginPolicy policy) {
+FrameViewBase* LocalFrameClientImpl::createPlugin(
+    HTMLPlugInElement* element,
+    const KURL& url,
+    const Vector<String>& paramNames,
+    const Vector<String>& paramValues,
+    const String& mimeType,
+    bool loadManually,
+    DetachedPluginPolicy policy) {
   if (!m_webFrame->client())
     return nullptr;
 
diff --git a/third_party/WebKit/Source/web/LocalFrameClientImpl.h b/third_party/WebKit/Source/web/LocalFrameClientImpl.h
index bef391d3..203a6cb 100644
--- a/third_party/WebKit/Source/web/LocalFrameClientImpl.h
+++ b/third_party/WebKit/Source/web/LocalFrameClientImpl.h
@@ -143,13 +143,13 @@
                           const WTF::AtomicString& name,
                           HTMLFrameOwnerElement*) override;
   virtual bool canCreatePluginWithoutRenderer(const String& mimeType) const;
-  Widget* createPlugin(HTMLPlugInElement*,
-                       const KURL&,
-                       const Vector<WTF::String>&,
-                       const Vector<WTF::String>&,
-                       const WTF::String&,
-                       bool loadManually,
-                       DetachedPluginPolicy) override;
+  FrameViewBase* createPlugin(HTMLPlugInElement*,
+                              const KURL&,
+                              const Vector<WTF::String>&,
+                              const Vector<WTF::String>&,
+                              const WTF::String&,
+                              bool loadManually,
+                              DetachedPluginPolicy) override;
   std::unique_ptr<WebMediaPlayer> createWebMediaPlayer(
       HTMLMediaElement&,
       const WebMediaPlayerSource&,
diff --git a/third_party/WebKit/Source/web/WebInputEventConversion.cpp b/third_party/WebKit/Source/web/WebInputEventConversion.cpp
index f1a7f26..819d696 100644
--- a/third_party/WebKit/Source/web/WebInputEventConversion.cpp
+++ b/third_party/WebKit/Source/web/WebInputEventConversion.cpp
@@ -43,30 +43,30 @@
 #include "core/layout/api/LayoutItem.h"
 #include "core/page/ChromeClient.h"
 #include "core/page/Page.h"
+#include "platform/FrameViewBase.h"
 #include "platform/KeyboardCodes.h"
-#include "platform/Widget.h"
 #include "public/platform/Platform.h"
 
 namespace blink {
 
 namespace {
-float frameScale(const Widget* widget) {
+float frameScale(const FrameViewBase* frameViewBase) {
   float scale = 1;
-  if (widget) {
-    FrameView* rootView = toFrameView(widget->root());
+  if (frameViewBase) {
+    FrameView* rootView = toFrameView(frameViewBase->root());
     if (rootView)
       scale = rootView->inputEventsScaleFactor();
   }
   return scale;
 }
 
-FloatPoint frameTranslation(const Widget* widget) {
+FloatPoint frameTranslation(const FrameViewBase* frameViewBase) {
   float scale = 1;
   FloatSize offset;
   IntPoint visualViewport;
   FloatSize overscrollOffset;
-  if (widget) {
-    FrameView* rootView = toFrameView(widget->root());
+  if (frameViewBase) {
+    FrameView* rootView = toFrameView(frameViewBase->root());
     if (rootView) {
       scale = rootView->inputEventsScaleFactor();
       offset = FloatSize(rootView->inputEventsOffsetForEmulation());
@@ -97,16 +97,16 @@
       convertAbsoluteLocationForLayoutObjectFloat(location, layoutItem));
 }
 
-// FIXME: Change |widget| to const Widget& after RemoteFrames get
+// FIXME: Change |FrameViewBase| to const FrameViewBase& after RemoteFrames get
 // RemoteFrameViews.
 void updateWebMouseEventFromCoreMouseEvent(const MouseEvent& event,
-                                           const Widget* widget,
+                                           const FrameViewBase* frameViewBase,
                                            const LayoutItem layoutItem,
                                            WebMouseEvent& webEvent) {
   webEvent.setTimeStampSeconds(event.platformTimeStamp().InSeconds());
   webEvent.setModifiers(event.modifiers());
 
-  FrameView* view = widget ? toFrameView(widget->parent()) : 0;
+  FrameView* view = frameViewBase ? toFrameView(frameViewBase->parent()) : 0;
   // TODO(bokan): If view == nullptr, pointInRootFrame will really be
   // pointInRootContent.
   IntPoint pointInRootFrame(event.absoluteLocation().x(),
@@ -136,7 +136,7 @@
 
 }  // namespace
 
-WebMouseEvent TransformWebMouseEvent(Widget* widget,
+WebMouseEvent TransformWebMouseEvent(FrameViewBase* frameViewBase,
                                      const WebMouseEvent& event) {
   WebMouseEvent result = event;
 
@@ -154,25 +154,25 @@
     result.setModifiers(event.modifiers() &
                         ~toWebInputEventModifierFrom(event.button));
   }
-  result.setFrameScale(frameScale(widget));
-  result.setFrameTranslate(frameTranslation(widget));
+  result.setFrameScale(frameScale(frameViewBase));
+  result.setFrameTranslate(frameTranslation(frameViewBase));
   return result;
 }
 
 WebMouseWheelEvent TransformWebMouseWheelEvent(
-    Widget* widget,
+    FrameViewBase* frameViewBase,
     const WebMouseWheelEvent& event) {
   WebMouseWheelEvent result = event;
-  result.setFrameScale(frameScale(widget));
-  result.setFrameTranslate(frameTranslation(widget));
+  result.setFrameScale(frameScale(frameViewBase));
+  result.setFrameTranslate(frameTranslation(frameViewBase));
   return result;
 }
 
-WebGestureEvent TransformWebGestureEvent(Widget* widget,
+WebGestureEvent TransformWebGestureEvent(FrameViewBase* frameViewBase,
                                          const WebGestureEvent& event) {
   WebGestureEvent result = event;
-  result.setFrameScale(frameScale(widget));
-  result.setFrameTranslate(frameTranslation(widget));
+  result.setFrameScale(frameScale(frameViewBase));
+  result.setFrameTranslate(frameTranslation(frameViewBase));
   return result;
 }
 
@@ -189,13 +189,13 @@
   return result;
 }
 
-WebTouchEvent TransformWebTouchEvent(Widget* widget,
+WebTouchEvent TransformWebTouchEvent(FrameViewBase* frameViewBase,
                                      const WebTouchEvent& event) {
-  return TransformWebTouchEvent(frameScale(widget), frameTranslation(widget),
-                                event);
+  return TransformWebTouchEvent(frameScale(frameViewBase),
+                                frameTranslation(frameViewBase), event);
 }
 
-WebMouseEventBuilder::WebMouseEventBuilder(const Widget* widget,
+WebMouseEventBuilder::WebMouseEventBuilder(const FrameViewBase* frameViewBase,
                                            const LayoutItem layoutItem,
                                            const MouseEvent& event) {
   if (event.nativeEvent()) {
@@ -230,7 +230,8 @@
 
   m_timeStampSeconds = event.platformTimeStamp().InSeconds();
   m_modifiers = event.modifiers();
-  updateWebMouseEventFromCoreMouseEvent(event, widget, layoutItem, *this);
+  updateWebMouseEventFromCoreMouseEvent(event, frameViewBase, layoutItem,
+                                        *this);
 
   switch (event.button()) {
     case short(WebPointerProperties::Button::Left):
@@ -267,7 +268,7 @@
 
 // Generate a synthetic WebMouseEvent given a TouchEvent (eg. for emulating a
 // mouse with touch input for plugins that don't support touch input).
-WebMouseEventBuilder::WebMouseEventBuilder(const Widget* widget,
+WebMouseEventBuilder::WebMouseEventBuilder(const FrameViewBase* frameViewBase,
                                            const LayoutItem layoutItem,
                                            const TouchEvent& event) {
   if (!event.touches())
@@ -300,7 +301,7 @@
 
   // The mouse event co-ordinates should be generated from the co-ordinates of
   // the touch point.
-  FrameView* view = toFrameView(widget->parent());
+  FrameView* view = toFrameView(frameViewBase->parent());
   // FIXME: if view == nullptr, pointInRootFrame will really be
   // pointInRootContent.
   IntPoint pointInRootFrame = roundedIntPoint(touch->absoluteLocation());
@@ -350,22 +351,22 @@
 }
 
 Vector<WebMouseEvent> TransformWebMouseEventVector(
-    Widget* widget,
+    FrameViewBase* frameViewBase,
     const std::vector<const WebInputEvent*>& coalescedEvents) {
   Vector<WebMouseEvent> result;
   for (const auto& event : coalescedEvents) {
     DCHECK(WebInputEvent::isMouseEventType(event->type()));
     result.push_back(TransformWebMouseEvent(
-        widget, static_cast<const WebMouseEvent&>(*event)));
+        frameViewBase, static_cast<const WebMouseEvent&>(*event)));
   }
   return result;
 }
 
 Vector<WebTouchEvent> TransformWebTouchEventVector(
-    Widget* widget,
+    FrameViewBase* frameViewBase,
     const std::vector<const WebInputEvent*>& coalescedEvents) {
-  float scale = frameScale(widget);
-  FloatPoint translation = frameTranslation(widget);
+  float scale = frameScale(frameViewBase);
+  FloatPoint translation = frameTranslation(frameViewBase);
   Vector<WebTouchEvent> result;
   for (const auto& event : coalescedEvents) {
     DCHECK(WebInputEvent::isTouchEventType(event->type()));
diff --git a/third_party/WebKit/Source/web/WebInputEventConversion.h b/third_party/WebKit/Source/web/WebInputEventConversion.h
index 182e581..546b841 100644
--- a/third_party/WebKit/Source/web/WebInputEventConversion.h
+++ b/third_party/WebKit/Source/web/WebInputEventConversion.h
@@ -61,8 +61,12 @@
   // NOTE: This is only implemented for mousemove, mouseover, mouseout,
   // mousedown and mouseup. If the event mapping fails, the event type will
   // be set to Undefined.
-  WebMouseEventBuilder(const FrameViewBase*, const LayoutItem, const MouseEvent&);
-  WebMouseEventBuilder(const FrameViewBase*, const LayoutItem, const TouchEvent&);
+  WebMouseEventBuilder(const FrameViewBase*,
+                       const LayoutItem,
+                       const MouseEvent&);
+  WebMouseEventBuilder(const FrameViewBase*,
+                       const LayoutItem,
+                       const TouchEvent&);
 };
 
 // Converts a KeyboardEvent to a corresponding WebKeyboardEvent.
@@ -88,17 +92,21 @@
 // and translation.
 WEB_EXPORT WebGestureEvent TransformWebGestureEvent(FrameViewBase*,
                                                     const WebGestureEvent&);
-WEB_EXPORT WebMouseEvent TransformWebMouseEvent(FrameViewBase*, const WebMouseEvent&);
+WEB_EXPORT WebMouseEvent TransformWebMouseEvent(FrameViewBase*,
+                                                const WebMouseEvent&);
 
 WEB_EXPORT WebMouseWheelEvent
 TransformWebMouseWheelEvent(FrameViewBase*, const WebMouseWheelEvent&);
 
-WEB_EXPORT WebTouchEvent TransformWebTouchEvent(FrameViewBase*, const WebTouchEvent&);
+WEB_EXPORT WebTouchEvent TransformWebTouchEvent(FrameViewBase*,
+                                                const WebTouchEvent&);
 
 Vector<WebMouseEvent> WEB_EXPORT
-TransformWebMouseEventVector(FrameViewBase*, const std::vector<const WebInputEvent*>&);
+TransformWebMouseEventVector(FrameViewBase*,
+                             const std::vector<const WebInputEvent*>&);
 Vector<WebTouchEvent> WEB_EXPORT
-TransformWebTouchEventVector(FrameViewBase*, const std::vector<const WebInputEvent*>&);
+TransformWebTouchEventVector(FrameViewBase*,
+                             const std::vector<const WebInputEvent*>&);
 
 }  // namespace blink
 
diff --git a/third_party/WebKit/Source/web/WebNode.cpp b/third_party/WebKit/Source/web/WebNode.cpp
index 3d45d875..c866548 100644
--- a/third_party/WebKit/Source/web/WebNode.cpp
+++ b/third_party/WebKit/Source/web/WebNode.cpp
@@ -47,7 +47,7 @@
 #include "core/layout/LayoutPart.h"
 #include "modules/accessibility/AXObject.h"
 #include "modules/accessibility/AXObjectCacheImpl.h"
-#include "platform/Widget.h"
+#include "platform/FrameViewBase.h"
 #include "public/platform/WebString.h"
 #include "public/web/WebAXObject.h"
 #include "public/web/WebDOMEvent.h"
@@ -186,9 +186,9 @@
 
   LayoutObject* object = node->layoutObject();
   if (object && object->isLayoutPart()) {
-    Widget* widget = toLayoutPart(object)->widget();
-    if (widget && widget->isPluginContainer())
-      return toWebPluginContainerImpl(widget);
+    FrameViewBase* frameViewBase = toLayoutPart(object)->widget();
+    if (frameViewBase && frameViewBase->isPluginContainer())
+      return toWebPluginContainerImpl(frameViewBase);
   }
 
   return nullptr;
diff --git a/third_party/WebKit/Source/web/WebPagePopupImpl.cpp b/third_party/WebKit/Source/web/WebPagePopupImpl.cpp
index 148cd0e..2751595e 100644
--- a/third_party/WebKit/Source/web/WebPagePopupImpl.cpp
+++ b/third_party/WebKit/Source/web/WebPagePopupImpl.cpp
@@ -90,7 +90,7 @@
   IntRect rootWindowRect() override { return m_popup->windowRectInScreen(); }
 
   IntRect viewportToScreen(const IntRect& rect,
-                           const Widget* widget) const override {
+                           const FrameViewBase* frameViewBase) const override {
     WebRect rectInScreen(rect);
     WebRect windowRect = m_popup->windowRectInScreen();
     m_popup->widgetClient()->convertViewportToWindow(&rectInScreen);
@@ -123,7 +123,7 @@
       m_popup->widgetClient()->didInvalidateRect(paintRect);
   }
 
-  void scheduleAnimation(Widget*) override {
+  void scheduleAnimation(FrameViewBase*) override {
     // Calling scheduleAnimation on m_webView so WebViewTestProxy will call
     // beginFrame.
     if (LayoutTestSupport::isRunningLayoutTest())
diff --git a/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp b/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp
index e6ab6199..cc943a8 100644
--- a/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp
+++ b/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp
@@ -112,7 +112,7 @@
 // Public methods --------------------------------------------------------------
 
 void WebPluginContainerImpl::setFrameRect(const IntRect& frameRect) {
-  Widget::setFrameRect(frameRect);
+  FrameViewBase::setFrameRect(frameRect);
 }
 
 void WebPluginContainerImpl::updateAllLifecyclePhases() {
@@ -185,7 +185,7 @@
 }
 
 void WebPluginContainerImpl::setFocused(bool focused, WebFocusType focusType) {
-  Widget::setFocused(focused, focusType);
+  FrameViewBase::setFocused(focused, focusType);
   m_webPlugin->updateFocus(focused, focusType);
 }
 
@@ -193,14 +193,14 @@
   setSelfVisible(true);
   m_webPlugin->updateVisibility(true);
 
-  Widget::show();
+  FrameViewBase::show();
 }
 
 void WebPluginContainerImpl::hide() {
   setSelfVisible(false);
   m_webPlugin->updateVisibility(false);
 
-  Widget::hide();
+  FrameViewBase::hide();
 }
 
 void WebPluginContainerImpl::handleEvent(Event* event) {
@@ -221,19 +221,20 @@
   else if (event->isDragEvent() && m_webPlugin->canProcessDrag())
     handleDragEvent(toDragEvent(event));
 
-  // FIXME: it would be cleaner if Widget::handleEvent returned true/false and
-  // HTMLPluginElement called setDefaultHandled or defaultEventHandler.
+  // FIXME: it would be cleaner if FrameViewBase::handleEvent returned
+  // true/false and HTMLPluginElement called setDefaultHandled or
+  // defaultEventHandler.
   if (!event->defaultHandled())
     m_element->Node::defaultEventHandler(event);
 }
 
 void WebPluginContainerImpl::frameRectsChanged() {
-  Widget::frameRectsChanged();
+  FrameViewBase::frameRectsChanged();
   reportGeometry();
 }
 
 void WebPluginContainerImpl::widgetGeometryMayHaveChanged() {
-  Widget::widgetGeometryMayHaveChanged();
+  FrameViewBase::widgetGeometryMayHaveChanged();
   reportGeometry();
 }
 
@@ -253,7 +254,7 @@
   if (isParentVisible() == parentVisible)
     return;  // No change.
 
-  Widget::setParentVisible(parentVisible);
+  FrameViewBase::setParentVisible(parentVisible);
   if (!isSelfVisible())
     return;  // This widget has explicitely been marked as not visible.
 
@@ -411,7 +412,7 @@
 }
 
 void WebPluginContainerImpl::invalidate() {
-  Widget::invalidate();
+  FrameViewBase::invalidate();
 }
 
 void WebPluginContainerImpl::invalidateRect(const WebRect& rect) {
diff --git a/third_party/WebKit/Source/web/WebPluginContainerImpl.h b/third_party/WebKit/Source/web/WebPluginContainerImpl.h
index fbf8d77..c033f7f4 100644
--- a/third_party/WebKit/Source/web/WebPluginContainerImpl.h
+++ b/third_party/WebKit/Source/web/WebPluginContainerImpl.h
@@ -34,7 +34,7 @@
 
 #include "core/dom/ContextLifecycleObserver.h"
 #include "core/plugins/PluginView.h"
-#include "platform/Widget.h"
+#include "platform/FrameViewBase.h"
 #include "public/web/WebPluginContainer.h"
 #include "web/WebExport.h"
 #include "wtf/Compiler.h"
@@ -81,7 +81,7 @@
   void updateAllLifecyclePhases() override;
   void invalidatePaintIfNeeded() override { issuePaintInvalidations(); }
 
-  // Widget methods
+  // FrameViewBase methods
   void setFrameRect(const IntRect&) override;
   void paint(GraphicsContext&, const CullRect&) const override;
   void invalidateRect(const IntRect&) override;
@@ -220,11 +220,11 @@
 };
 
 DEFINE_TYPE_CASTS(WebPluginContainerImpl,
-                  Widget,
-                  widget,
-                  widget->isPluginContainer(),
-                  widget.isPluginContainer());
-// Unlike Widget, we need not worry about object type for container.
+                  FrameViewBase,
+                  frameViewBase,
+                  frameViewBase->isPluginContainer(),
+                  frameViewBase.isPluginContainer());
+// Unlike FrameViewBase, we need not worry about object type for container.
 // WebPluginContainerImpl is the only subclass of WebPluginContainer.
 DEFINE_TYPE_CASTS(WebPluginContainerImpl,
                   WebPluginContainer,
diff --git a/third_party/WebKit/Source/web/WebViewImpl.cpp b/third_party/WebKit/Source/web/WebViewImpl.cpp
index 945f27e..8a38208 100644
--- a/third_party/WebKit/Source/web/WebViewImpl.cpp
+++ b/third_party/WebKit/Source/web/WebViewImpl.cpp
@@ -1157,9 +1157,11 @@
         if (event.windowsKeyCode == VKEY_TAB) {
           // If the plugin supports keyboard focus then we should not send a tab
           // keypress event.
-          Widget* widget = toLayoutPart(element->layoutObject())->widget();
-          if (widget && widget->isPluginContainer()) {
-            WebPluginContainerImpl* plugin = toWebPluginContainerImpl(widget);
+          FrameViewBase* frameViewBase =
+              toLayoutPart(element->layoutObject())->widget();
+          if (frameViewBase && frameViewBase->isPluginContainer()) {
+            WebPluginContainerImpl* plugin =
+                toWebPluginContainerImpl(frameViewBase);
             if (plugin && plugin->supportsKeyboardFocus())
               m_suppressNextKeypressEvent = true;
           }
@@ -3336,9 +3338,10 @@
 
   LayoutObject* object = node->layoutObject();
   if (object && object->isLayoutPart()) {
-    Widget* widget = toLayoutPart(object)->widget();
-    if (widget && widget->isPluginContainer()) {
-      WebPluginContainerImpl* plugin = toWebPluginContainerImpl(widget);
+    FrameViewBase* frameViewWidget = toLayoutPart(object)->widget();
+    if (frameViewWidget && frameViewWidget->isPluginContainer()) {
+      WebPluginContainerImpl* plugin =
+          toWebPluginContainerImpl(frameViewWidget);
       switch (action.type) {
         case WebPluginAction::Rotate90Clockwise:
           plugin->plugin()->rotateView(WebPlugin::RotationType90Clockwise);
diff --git a/third_party/freetype2/.clang-format b/third_party/freetype-android/.clang-format
similarity index 100%
rename from third_party/freetype2/.clang-format
rename to third_party/freetype-android/.clang-format
diff --git a/third_party/freetype-android/BUILD.gn b/third_party/freetype-android/BUILD.gn
index acca85a..c8828e99 100644
--- a/third_party/freetype-android/BUILD.gn
+++ b/third_party/freetype-android/BUILD.gn
@@ -4,9 +4,6 @@
 
 import("//build/config/chromecast_build.gni")
 
-assert(is_android || is_chromecast,
-       "This library is only used on Android or Chromecast")
-
 config("freetype_config") {
   include_dirs = [
     "include",
@@ -14,10 +11,23 @@
   ]
 }
 
-source_set("freetype") {
+config("freetype-warnings") {
+  cflags = []
+
+  # The reduction of FreeType files to a minimum triggers -Wunused-function
+  # warnings in ftbase.c
+  cflags += [ "-Wno-unused-function" ]
+}
+
+config("freetype-visibility") {
+  cflags = []
+  cflags += [ "-fvisibility=default" ]
+}
+
+component("freetype") {
+  output_name = "freetype"
+  output_extension = "so.6"
   sources = [
-    # The following files are not sorted alphabetically, but in the
-    # same order as in Android.mk to ease maintenance.
     "src/src/autofit/autofit.c",
     "src/src/base/ftbase.c",
     "src/src/base/ftbbox.c",
@@ -42,7 +52,8 @@
     "src/src/truetype/truetype.c",
   ]
 
-  if (is_chromecast) {
+  if (is_linux || is_chromecast) {
+    # Needed for content_shell on Linux and Chromecast, since fontconfig requires FT_Get_BDF_Property.
     sources += [ "src/src/base/ftbdf.c" ]
   }
 
@@ -57,7 +68,11 @@
 
   public_configs = [ ":freetype_config" ]
   configs -= [ "//build/config/compiler:chromium_code" ]
-  configs += [ "//build/config/compiler:no_chromium_code" ]
+  configs += [
+    "//build/config/compiler:no_chromium_code",
+    ":freetype-warnings",
+    ":freetype-visibility"
+  ]
 
   deps = [
     "//third_party/libpng",
diff --git a/third_party/freetype-android/OWNERS b/third_party/freetype-android/OWNERS
index a5ce419f..480c869 100644
--- a/third_party/freetype-android/OWNERS
+++ b/third_party/freetype-android/OWNERS
@@ -1,3 +1,4 @@
 wangxianzhu@chromium.org
 michaelbai@chromium.org
 bungeman@chromium.org
+drott@chromium.org
diff --git a/third_party/freetype-android/include/freetype-android-config/ftoption.h b/third_party/freetype-android/include/freetype-android-config/ftoption.h
index f419cc1..e2d22a87 100644
--- a/third_party/freetype-android/include/freetype-android-config/ftoption.h
+++ b/third_party/freetype-android/include/freetype-android-config/ftoption.h
@@ -366,7 +366,7 @@
   /*                                                                       */
   /*   Note that the `FOND' resource isn't checked.                        */
   /*                                                                       */
-#define FT_CONFIG_OPTION_MAC_FONTS
+/* #define FT_CONFIG_OPTION_MAC_FONTS */
 
 
   /*************************************************************************/
@@ -722,7 +722,7 @@
   /* Define TT_CONFIG_OPTION_BDF if you want to include support for        */
   /* an embedded `BDF ' table within SFNT-based bitmap formats.            */
   /*                                                                       */
-#define TT_CONFIG_OPTION_BDF
+/* #define TT_CONFIG_OPTION_BDF */
 
 
   /*************************************************************************/
diff --git a/third_party/freetype2/BUILD.gn b/third_party/freetype2/BUILD.gn
deleted file mode 100644
index 2627827..0000000
--- a/third_party/freetype2/BUILD.gn
+++ /dev/null
@@ -1,75 +0,0 @@
-# Copyright (c) 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-assert(is_linux, "This file should only be depended on from Linux.")
-
-config("freetype2_config") {
-  include_dirs = [
-    "include",
-    "src/include",
-  ]
-}
-
-shared_library("freetype2") {
-  output_name = "freetype"
-  output_extension = "so.6"
-
-  sources = [
-    "src/src/autofit/autofit.c",
-    "src/src/base/ftbase.c",
-    "src/src/base/ftbbox.c",
-    "src/src/base/ftbdf.c",
-    "src/src/base/ftbitmap.c",
-    "src/src/base/ftcid.c",
-    "src/src/base/ftdebug.c",
-    "src/src/base/ftfntfmt.c",
-    "src/src/base/ftfstype.c",
-    "src/src/base/ftgasp.c",
-    "src/src/base/ftglyph.c",
-    "src/src/base/ftgxval.c",
-    "src/src/base/ftinit.c",
-    "src/src/base/ftlcdfil.c",
-    "src/src/base/ftmm.c",
-    "src/src/base/ftstroke.c",
-    "src/src/base/ftsynth.c",
-    "src/src/base/ftsystem.c",
-    "src/src/base/fttype1.c",
-    "src/src/bdf/bdf.c",
-    "src/src/cff/cff.c",
-    "src/src/gzip/ftgzip.c",
-    "src/src/lzw/ftlzw.c",
-    "src/src/psaux/psaux.c",
-    "src/src/pshinter/pshinter.c",
-    "src/src/psnames/psnames.c",
-    "src/src/raster/raster.c",
-    "src/src/sfnt/sfnt.c",
-    "src/src/smooth/smooth.c",
-    "src/src/truetype/truetype.c",
-    "src/src/type1/type1.c",
-  ]
-
-  defines = [
-    "FT_CONFIG_OPTION_SYSTEM_ZLIB",
-
-    # TODO: Enable this option and figure out a way to address the cyclic
-    # dependency with HarfBuzz. crbug.com/617168
-    # "FT_CONFIG_OPTION_USE_HARFBUZZ",
-    "FT2_BUILD_LIBRARY",
-    "FT_CONFIG_CONFIG_H=<freetype-custom-config/ftconfig.h>",  # See comments in README.chromium.
-    "FT_CONFIG_MODULES_H=<freetype-custom-config/ftmodule.h>",  # See comments in README.chromium.
-    "FT_CONFIG_OPTION_H=<freetype-custom-config/ftoption.h>",  # See comments in README.chromium.
-  ]
-
-  configs -= [ "//build/config/compiler:chromium_code" ]
-  configs += [ "//build/config/compiler:no_chromium_code" ]
-  configs += [ ":freetype2_config" ]
-
-  public_configs = [ ":freetype2_config" ]
-
-  deps = [
-    "//build/config/sanitizers:deps",
-    "//third_party/libpng",
-    "//third_party/zlib",
-  ]
-}
diff --git a/third_party/freetype2/OWNERS b/third_party/freetype2/OWNERS
deleted file mode 100644
index f8ec284..0000000
--- a/third_party/freetype2/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-dpranke@chromium.org
diff --git a/third_party/freetype2/README.chromium b/third_party/freetype2/README.chromium
deleted file mode 100644
index 3815184..0000000
--- a/third_party/freetype2/README.chromium
+++ /dev/null
@@ -1,53 +0,0 @@
-Name: freetype2
-URL: git://git.sv.nongnu.org/freetype/freetype2.git
-Version: VER-2-7-1-updates
-Revision: e432ebf2e2c96e75f674af41f062d8b210de8491
-Security Critical: yes
-License: Custom license "inspired by the BSD, Artistic, and IJG (Independent
-         JPEG Group) licenses"
-License File: src/docs/FTL.TXT
-License Android Compatible: yes
-
-Description:
-
-This version of Freetype is updated by checking out freetype from the above git
-URL, using the hash from "Revision:". Versions from 2.7.1 contain the level of
-OpenType font variations support that we require.
-
-The build files should approximate the output of
-
-make -Bn | rev | cut -d ' ' -f 1 | rev | grep "\.c$" | sort
-
-Currently the cache, patent checker (no longer used), bzip2 are excluded, as
-well as the following modules:
-t1cid_driver_class
-pfr_driver_class
-t42_driver_class
-winfnt_driver_class
-pcf_driver_class
-
-base/ftotval.c
-base/ftpfr.c
-base/ftwinfnt.c
-cid/type1cid.c
-pcf/pcf.c
-pfr/pfr.c
-type42/type42.c
-winfonts/winfnt.c
-
-Freetype depends on two header files to be supplied by the user to specify
-how to build the library, ftconfig.h and ftmodule.h (or equivalent filenames
-as defined by the FT_CONFIG_CONFIG_H and FT_CONFIG_MODULES_H #defines).
-
-The versions in include/ were generated as follows:
-
-  % cd <dir-where-you-cloned-freetype-to>
-  % bash autogen.sh
-  % ./configure
-  % cp objs/ftmodule.h ../include
-  % cp builds/unix/ftconfig.h ../include
-  % git apply patches/freetype2_symbols_visbility.patch
-
-Then we disable modules in include/ftmodule.h, then apply the symbols visibility
-patch to define the FT_EXPORT and FT_EXPORT_DEF macros to work properly when
-building a linux shared lib.
diff --git a/third_party/freetype2/include/freetype-custom-config/ftconfig.h b/third_party/freetype2/include/freetype-custom-config/ftconfig.h
deleted file mode 100644
index 80e7940..0000000
--- a/third_party/freetype2/include/freetype-custom-config/ftconfig.h
+++ /dev/null
@@ -1,504 +0,0 @@
-/* ftconfig.h.  Generated from ftconfig.in by configure.  */
-/***************************************************************************/
-/*                                                                         */
-/*  ftconfig.in                                                            */
-/*                                                                         */
-/*    UNIX-specific configuration file (specification only).               */
-/*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
-/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
-/*                                                                         */
-/*  This file is part of the FreeType project, and may only be used,       */
-/*  modified, and distributed under the terms of the FreeType project      */
-/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
-/*  this file you indicate that you have read the license and              */
-/*  understand and accept it fully.                                        */
-/*                                                                         */
-/***************************************************************************/
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* This header file contains a number of macro definitions that are used */
-  /* by the rest of the engine.  Most of the macros here are automatically */
-  /* determined at compile time, and you should not need to change it to   */
-  /* port FreeType, except to compile the library with a non-ANSI          */
-  /* compiler.                                                             */
-  /*                                                                       */
-  /* Note however that if some specific modifications are needed, we       */
-  /* advise you to place a modified copy in your build directory.          */
-  /*                                                                       */
-  /* The build directory is usually `builds/<system>', and contains        */
-  /* system-specific files that are always included first when building    */
-  /* the library.                                                          */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-#ifndef FTCONFIG_H_
-#define FTCONFIG_H_
-
-#include <ft2build.h>
-#include FT_CONFIG_OPTIONS_H
-#include FT_CONFIG_STANDARD_LIBRARY_H
-
-
-FT_BEGIN_HEADER
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /*               PLATFORM-SPECIFIC CONFIGURATION MACROS                  */
-  /*                                                                       */
-  /* These macros can be toggled to suit a specific system.  The current   */
-  /* ones are defaults used to compile FreeType in an ANSI C environment   */
-  /* (16bit compilers are also supported).  Copy this file to your own     */
-  /* `builds/<system>' directory, and edit it to port the engine.          */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-#define HAVE_UNISTD_H 1
-#define HAVE_FCNTL_H 1
-#define HAVE_STDINT_H 1
-
-
-  /* There are systems (like the Texas Instruments 'C54x) where a `char' */
-  /* has 16 bits.  ANSI C says that sizeof(char) is always 1.  Since an  */
-  /* `int' has 16 bits also for this system, sizeof(int) gives 1 which   */
-  /* is probably unexpected.                                             */
-  /*                                                                     */
-  /* `CHAR_BIT' (defined in limits.h) gives the number of bits in a      */
-  /* `char' type.                                                        */
-
-#ifndef FT_CHAR_BIT
-#define FT_CHAR_BIT  CHAR_BIT
-#endif
-
-
-/* #undef FT_USE_AUTOCONF_SIZEOF_TYPES */
-#ifdef FT_USE_AUTOCONF_SIZEOF_TYPES
-
-#define SIZEOF_INT 4
-#define SIZEOF_LONG 8
-#define FT_SIZEOF_INT  SIZEOF_INT
-#define FT_SIZEOF_LONG SIZEOF_LONG
-
-#else /* !FT_USE_AUTOCONF_SIZEOF_TYPES */
-
-  /* Following cpp computation of the bit length of int and long */
-  /* is copied from default include/freetype/config/ftconfig.h.  */
-  /* If any improvement is required for this file, it should be  */
-  /* applied to the original header file for the builders that   */
-  /* do not use configure script.                                */
-
-  /* The size of an `int' type.  */
-#if                                 FT_UINT_MAX == 0xFFFFUL
-#define FT_SIZEOF_INT  (16 / FT_CHAR_BIT)
-#elif                               FT_UINT_MAX == 0xFFFFFFFFUL
-#define FT_SIZEOF_INT  (32 / FT_CHAR_BIT)
-#elif FT_UINT_MAX > 0xFFFFFFFFUL && FT_UINT_MAX == 0xFFFFFFFFFFFFFFFFUL
-#define FT_SIZEOF_INT  (64 / FT_CHAR_BIT)
-#else
-#error "Unsupported size of `int' type!"
-#endif
-
-  /* The size of a `long' type.  A five-byte `long' (as used e.g. on the */
-  /* DM642) is recognized but avoided.                                   */
-#if                                  FT_ULONG_MAX == 0xFFFFFFFFUL
-#define FT_SIZEOF_LONG  (32 / FT_CHAR_BIT)
-#elif FT_ULONG_MAX > 0xFFFFFFFFUL && FT_ULONG_MAX == 0xFFFFFFFFFFUL
-#define FT_SIZEOF_LONG  (32 / FT_CHAR_BIT)
-#elif FT_ULONG_MAX > 0xFFFFFFFFUL && FT_ULONG_MAX == 0xFFFFFFFFFFFFFFFFUL
-#define FT_SIZEOF_LONG  (64 / FT_CHAR_BIT)
-#else
-#error "Unsupported size of `long' type!"
-#endif
-
-#endif /* !FT_USE_AUTOCONF_SIZEOF_TYPES */
-
-
-  /* FT_UNUSED is a macro used to indicate that a given parameter is not  */
-  /* used -- this is only used to get rid of unpleasant compiler warnings */
-#ifndef FT_UNUSED
-#define FT_UNUSED( arg )  ( (arg) = (arg) )
-#endif
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /*                     AUTOMATIC CONFIGURATION MACROS                    */
-  /*                                                                       */
-  /* These macros are computed from the ones defined above.  Don't touch   */
-  /* their definition, unless you know precisely what you are doing.  No   */
-  /* porter should need to mess with them.                                 */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Mac support                                                           */
-  /*                                                                       */
-  /*   This is the only necessary change, so it is defined here instead    */
-  /*   providing a new configuration file.                                 */
-  /*                                                                       */
-#if defined( __APPLE__ ) || ( defined( __MWERKS__ ) && defined( macintosh ) )
-  /* no Carbon frameworks for 64bit 10.4.x */
-  /* AvailabilityMacros.h is available since Mac OS X 10.2,        */
-  /* so guess the system version by maximum errno before inclusion */
-#include <errno.h>
-#ifdef ECANCELED /* defined since 10.2 */
-#include "AvailabilityMacros.h"
-#endif
-#if defined( __LP64__ ) && \
-    ( MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 )
-#undef FT_MACINTOSH
-#endif
-
-#elif defined( __SC__ ) || defined( __MRC__ )
-  /* Classic MacOS compilers */
-#include "ConditionalMacros.h"
-#if TARGET_OS_MAC
-#define FT_MACINTOSH 1
-#endif
-
-#endif
-
-
-  /* Fix compiler warning with sgi compiler */
-#if defined( __sgi ) && !defined( __GNUC__ )
-#if defined( _COMPILER_VERSION ) && ( _COMPILER_VERSION >= 730 )
-#pragma set woff 3505
-#endif
-#endif
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Section>                                                             */
-  /*    basic_types                                                        */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    FT_Int16                                                           */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A typedef for a 16bit signed integer type.                         */
-  /*                                                                       */
-  typedef signed short  FT_Int16;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    FT_UInt16                                                          */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A typedef for a 16bit unsigned integer type.                       */
-  /*                                                                       */
-  typedef unsigned short  FT_UInt16;
-
-  /* */
-
-
-  /* this #if 0 ... #endif clause is for documentation purposes */
-#if 0
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    FT_Int32                                                           */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A typedef for a 32bit signed integer type.  The size depends on    */
-  /*    the configuration.                                                 */
-  /*                                                                       */
-  typedef signed XXX  FT_Int32;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    FT_UInt32                                                          */
-  /*                                                                       */
-  /*    A typedef for a 32bit unsigned integer type.  The size depends on  */
-  /*    the configuration.                                                 */
-  /*                                                                       */
-  typedef unsigned XXX  FT_UInt32;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    FT_Int64                                                           */
-  /*                                                                       */
-  /*    A typedef for a 64bit signed integer type.  The size depends on    */
-  /*    the configuration.  Only defined if there is real 64bit support;   */
-  /*    otherwise, it gets emulated with a structure (if necessary).       */
-  /*                                                                       */
-  typedef signed XXX  FT_Int64;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    FT_UInt64                                                          */
-  /*                                                                       */
-  /*    A typedef for a 64bit unsigned integer type.  The size depends on  */
-  /*    the configuration.  Only defined if there is real 64bit support;   */
-  /*    otherwise, it gets emulated with a structure (if necessary).       */
-  /*                                                                       */
-  typedef unsigned XXX  FT_UInt64;
-
-  /* */
-
-#endif
-
-#if FT_SIZEOF_INT == 4
-
-  typedef signed int      FT_Int32;
-  typedef unsigned int    FT_UInt32;
-
-#elif FT_SIZEOF_LONG == 4
-
-  typedef signed long     FT_Int32;
-  typedef unsigned long   FT_UInt32;
-
-#else
-#error "no 32bit type found -- please check your configuration files"
-#endif
-
-
-  /* look up an integer type that is at least 32 bits */
-#if FT_SIZEOF_INT >= 4
-
-  typedef int            FT_Fast;
-  typedef unsigned int   FT_UFast;
-
-#elif FT_SIZEOF_LONG >= 4
-
-  typedef long           FT_Fast;
-  typedef unsigned long  FT_UFast;
-
-#endif
-
-
-  /* determine whether we have a 64-bit int type for platforms without */
-  /* Autoconf                                                          */
-#if FT_SIZEOF_LONG == 8
-
-  /* FT_LONG64 must be defined if a 64-bit type is available */
-#define FT_LONG64
-#define FT_INT64   long
-#define FT_UINT64  unsigned long
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* A 64-bit data type may create compilation problems if you compile     */
-  /* in strict ANSI mode.  To avoid them, we disable other 64-bit data     */
-  /* types if __STDC__ is defined.  You can however ignore this rule       */
-  /* by defining the FT_CONFIG_OPTION_FORCE_INT64 configuration macro.     */
-  /*                                                                       */
-#elif !defined( __STDC__ ) || defined( FT_CONFIG_OPTION_FORCE_INT64 )
-
-#if defined( __STDC_VERSION__ ) && __STDC_VERSION__ >= 199901L
-
-#define FT_LONG64
-#define FT_INT64   long long int
-#define FT_UINT64  unsigned long long int
-
-#elif defined( _MSC_VER ) && _MSC_VER >= 900  /* Visual C++ (and Intel C++) */
-
-  /* this compiler provides the __int64 type */
-#define FT_LONG64
-#define FT_INT64   __int64
-#define FT_UINT64  unsigned __int64
-
-#elif defined( __BORLANDC__ )  /* Borland C++ */
-
-  /* XXXX: We should probably check the value of __BORLANDC__ in order */
-  /*       to test the compiler version.                               */
-
-  /* this compiler provides the __int64 type */
-#define FT_LONG64
-#define FT_INT64   __int64
-#define FT_UINT64  unsigned __int64
-
-#elif defined( __WATCOMC__ )   /* Watcom C++ */
-
-  /* Watcom doesn't provide 64-bit data types */
-
-#elif defined( __MWERKS__ )    /* Metrowerks CodeWarrior */
-
-#define FT_LONG64
-#define FT_INT64   long long int
-#define FT_UINT64  unsigned long long int
-
-#elif defined( __GNUC__ )
-
-  /* GCC provides the `long long' type */
-#define FT_LONG64
-#define FT_INT64   long long int
-#define FT_UINT64  unsigned long long int
-
-#endif /* __STDC_VERSION__ >= 199901L */
-
-#endif /* FT_SIZEOF_LONG == 8 */
-
-#ifdef FT_LONG64
-  typedef FT_INT64   FT_Int64;
-  typedef FT_UINT64  FT_UInt64;
-#endif
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* miscellaneous                                                         */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-#define FT_BEGIN_STMNT  do {
-#define FT_END_STMNT    } while ( 0 )
-#define FT_DUMMY_STMNT  FT_BEGIN_STMNT FT_END_STMNT
-
-
-  /* typeof condition taken from gnulib's `intprops.h' header file */
-#if ( __GNUC__ >= 2                         || \
-      defined( __IBM__TYPEOF__ )            || \
-      ( __SUNPRO_C >= 0x5110 && !__STDC__ ) )
-#define FT_TYPEOF( type )  (__typeof__ (type))
-#else
-#define FT_TYPEOF( type )  /* empty */
-#endif
-
-
-#ifdef FT_MAKE_OPTION_SINGLE_OBJECT
-
-#define FT_LOCAL( x )      static  x
-#define FT_LOCAL_DEF( x )  static  x
-
-#else
-
-#ifdef __cplusplus
-#define FT_LOCAL( x )      extern "C"  x
-#define FT_LOCAL_DEF( x )  extern "C"  x
-#else
-#define FT_LOCAL( x )      extern  x
-#define FT_LOCAL_DEF( x )  x
-#endif
-
-#endif /* FT_MAKE_OPTION_SINGLE_OBJECT */
-
-#define FT_LOCAL_ARRAY( x )      extern const  x
-#define FT_LOCAL_ARRAY_DEF( x )  const  x
-
-
-#ifndef FT_BASE
-
-#ifdef __cplusplus
-#define FT_BASE( x )  extern "C"  x
-#else
-#define FT_BASE( x )  extern  x
-#endif
-
-#endif /* !FT_BASE */
-
-
-#ifndef FT_BASE_DEF
-
-#ifdef __cplusplus
-#define FT_BASE_DEF( x )  x
-#else
-#define FT_BASE_DEF( x )  x
-#endif
-
-#endif /* !FT_BASE_DEF */
-
-
-#ifndef FT_EXPORT
-
-#ifdef __cplusplus
-#define FT_EXPORT( x )  __attribute__ ((visibility ("default"))) extern "C"  x
-#else
-#define FT_EXPORT( x )  __attribute__ ((visibility ("default"))) extern  x
-#endif
-
-#endif /* !FT_EXPORT */
-
-
-#ifndef FT_EXPORT_DEF
-
-#ifdef __cplusplus
-#define FT_EXPORT_DEF( x )  __attribute__((visibility("default"))) extern "C"  x
-#else
-#define FT_EXPORT_DEF( x )  __attribute__((visibility("default"))) extern  x
-#endif
-
-#endif /* !FT_EXPORT_DEF */
-
-
-#ifndef FT_EXPORT_VAR
-
-#ifdef __cplusplus
-#define FT_EXPORT_VAR( x )  extern "C"  x
-#else
-#define FT_EXPORT_VAR( x )  extern  x
-#endif
-
-#endif /* !FT_EXPORT_VAR */
-
-  /* The following macros are needed to compile the library with a   */
-  /* C++ compiler and with 16bit compilers.                          */
-  /*                                                                 */
-
-  /* This is special.  Within C++, you must specify `extern "C"' for */
-  /* functions which are used via function pointers, and you also    */
-  /* must do that for structures which contain function pointers to  */
-  /* assure C linkage -- it's not possible to have (local) anonymous */
-  /* functions which are accessed by (global) function pointers.     */
-  /*                                                                 */
-  /*                                                                 */
-  /* FT_CALLBACK_DEF is used to _define_ a callback function.        */
-  /*                                                                 */
-  /* FT_CALLBACK_TABLE is used to _declare_ a constant variable that */
-  /* contains pointers to callback functions.                        */
-  /*                                                                 */
-  /* FT_CALLBACK_TABLE_DEF is used to _define_ a constant variable   */
-  /* that contains pointers to callback functions.                   */
-  /*                                                                 */
-  /*                                                                 */
-  /* Some 16bit compilers have to redefine these macros to insert    */
-  /* the infamous `_cdecl' or `__fastcall' declarations.             */
-  /*                                                                 */
-#ifndef FT_CALLBACK_DEF
-#ifdef __cplusplus
-#define FT_CALLBACK_DEF( x )  extern "C"  x
-#else
-#define FT_CALLBACK_DEF( x )  static  x
-#endif
-#endif /* FT_CALLBACK_DEF */
-
-#ifndef FT_CALLBACK_TABLE
-#ifdef __cplusplus
-#define FT_CALLBACK_TABLE      extern "C"
-#define FT_CALLBACK_TABLE_DEF  extern "C"
-#else
-#define FT_CALLBACK_TABLE      extern
-#define FT_CALLBACK_TABLE_DEF  /* nothing */
-#endif
-#endif /* FT_CALLBACK_TABLE */
-
-
-FT_END_HEADER
-
-
-#endif /* FTCONFIG_H_ */
-
-
-/* END */
diff --git a/third_party/freetype2/include/freetype-custom-config/ftmodule.h b/third_party/freetype2/include/freetype-custom-config/ftmodule.h
deleted file mode 100644
index 8ec70b80..0000000
--- a/third_party/freetype2/include/freetype-custom-config/ftmodule.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/***************************************************************************/
-/*                                                                         */
-/*  ftmodule.h                                                             */
-/*                                                                         */
-/*    User-selectable module macros.                                       */
-/*                                                                         */
-/*  Copyright 1996-2015 by                                                 */
-/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
-/*                                                                         */
-/*  This file is part of the FreeType project, and may only be used,       */
-/*  modified, and distributed under the terms of the FreeType project      */
-/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
-/*  this file you indicate that you have read the license and              */
-/*  understand and accept it fully.                                        */
-/*                                                                         */
-/***************************************************************************/
-
-FT_USE_MODULE( FT_Module_Class, autofit_module_class )
-FT_USE_MODULE( FT_Driver_ClassRec, tt_driver_class )
-FT_USE_MODULE( FT_Driver_ClassRec, cff_driver_class )
-FT_USE_MODULE( FT_Module_Class, psnames_module_class )
-FT_USE_MODULE( FT_Module_Class, pshinter_module_class )
-FT_USE_MODULE( FT_Renderer_Class, ft_raster1_renderer_class )
-FT_USE_MODULE( FT_Module_Class, sfnt_module_class )
-FT_USE_MODULE( FT_Renderer_Class, ft_smooth_renderer_class )
-FT_USE_MODULE( FT_Renderer_Class, ft_smooth_lcd_renderer_class )
-FT_USE_MODULE( FT_Renderer_Class, ft_smooth_lcdv_renderer_class )
-
-/*
-FT_USE_MODULE( FT_Driver_ClassRec, t1_driver_class )
-FT_USE_MODULE( FT_Driver_ClassRec, t1cid_driver_class )
-FT_USE_MODULE( FT_Driver_ClassRec, pfr_driver_class )
-FT_USE_MODULE( FT_Driver_ClassRec, t42_driver_class )
-FT_USE_MODULE( FT_Driver_ClassRec, winfnt_driver_class )
-FT_USE_MODULE( FT_Driver_ClassRec, pcf_driver_class )
-FT_USE_MODULE( FT_Driver_ClassRec, bdf_driver_class )
-FT_USE_MODULE( FT_Module_Class, psaux_module_class )
-*/
diff --git a/third_party/freetype2/include/freetype-custom-config/ftoption.h b/third_party/freetype2/include/freetype-custom-config/ftoption.h
deleted file mode 100644
index e2d22a87..0000000
--- a/third_party/freetype2/include/freetype-custom-config/ftoption.h
+++ /dev/null
@@ -1,969 +0,0 @@
-/***************************************************************************/
-/*                                                                         */
-/*  ftoption.h                                                             */
-/*                                                                         */
-/*    User-selectable configuration macros (specification only).           */
-/*                                                                         */
-/*  Copyright 1996-2017 by                                                 */
-/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
-/*                                                                         */
-/*  This file is part of the FreeType project, and may only be used,       */
-/*  modified, and distributed under the terms of the FreeType project      */
-/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
-/*  this file you indicate that you have read the license and              */
-/*  understand and accept it fully.                                        */
-/*                                                                         */
-/***************************************************************************/
-
-
-#ifndef FTOPTION_H_
-#define FTOPTION_H_
-
-
-#include <ft2build.h>
-
-
-FT_BEGIN_HEADER
-
-  /*************************************************************************/
-  /*                                                                       */
-  /*                 USER-SELECTABLE CONFIGURATION MACROS                  */
-  /*                                                                       */
-  /* This file contains the default configuration macro definitions for    */
-  /* a standard build of the FreeType library.  There are three ways to    */
-  /* use this file to build project-specific versions of the library:      */
-  /*                                                                       */
-  /*  - You can modify this file by hand, but this is not recommended in   */
-  /*    cases where you would like to build several versions of the        */
-  /*    library from a single source directory.                            */
-  /*                                                                       */
-  /*  - You can put a copy of this file in your build directory, more      */
-  /*    precisely in `$BUILD/freetype/config/ftoption.h', where `$BUILD'   */
-  /*    is the name of a directory that is included _before_ the FreeType  */
-  /*    include path during compilation.                                   */
-  /*                                                                       */
-  /*    The default FreeType Makefiles and Jamfiles use the build          */
-  /*    directory `builds/<system>' by default, but you can easily change  */
-  /*    that for your own projects.                                        */
-  /*                                                                       */
-  /*  - Copy the file <ft2build.h> to `$BUILD/ft2build.h' and modify it    */
-  /*    slightly to pre-define the macro FT_CONFIG_OPTIONS_H used to       */
-  /*    locate this file during the build.  For example,                   */
-  /*                                                                       */
-  /*      #define FT_CONFIG_OPTIONS_H  <myftoptions.h>                     */
-  /*      #include <freetype/config/ftheader.h>                            */
-  /*                                                                       */
-  /*    will use `$BUILD/myftoptions.h' instead of this file for macro     */
-  /*    definitions.                                                       */
-  /*                                                                       */
-  /*    Note also that you can similarly pre-define the macro              */
-  /*    FT_CONFIG_MODULES_H used to locate the file listing of the modules */
-  /*    that are statically linked to the library at compile time.  By     */
-  /*    default, this file is <freetype/config/ftmodule.h>.                */
-  /*                                                                       */
-  /* We highly recommend using the third method whenever possible.         */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /****                                                                 ****/
-  /**** G E N E R A L   F R E E T Y P E   2   C O N F I G U R A T I O N ****/
-  /****                                                                 ****/
-  /*************************************************************************/
-  /*************************************************************************/
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* If you enable this configuration option, FreeType recognizes an       */
-  /* environment variable called `FREETYPE_PROPERTIES', which can be used  */
-  /* to control the various font drivers and modules.  The controllable    */
-  /* properties are listed in the section `Controlling FreeType Modules'   */
-  /* in the reference's table of contents; currently there are properties  */
-  /* for the auto-hinter (file `ftautoh.h'), CFF (file `ftcffdrv.h'),      */
-  /* TrueType (file `ftttdrv.h'), and PCF (file `ftpcfdrv.h').             */
-  /*                                                                       */
-  /* `FREETYPE_PROPERTIES' has the following syntax form (broken here into */
-  /* multiple lines for better readability).                               */
-  /*                                                                       */
-  /*   <optional whitespace>                                               */
-  /*   <module-name1> ':'                                                  */
-  /*   <property-name1> '=' <property-value1>                              */
-  /*   <whitespace>                                                        */
-  /*   <module-name2> ':'                                                  */
-  /*   <property-name2> '=' <property-value2>                              */
-  /*   ...                                                                 */
-  /*                                                                       */
-  /* Example:                                                              */
-  /*                                                                       */
-  /*   FREETYPE_PROPERTIES=truetype:interpreter-version=35 \               */
-  /*                       cff:no-stem-darkening=1 \                       */
-  /*                       autofitter:warping=1                            */
-  /*                                                                       */
-/*#define FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES*/
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Uncomment the line below if you want to activate sub-pixel rendering  */
-  /* (a.k.a. LCD rendering, or ClearType) in this build of the library.    */
-  /*                                                                       */
-  /* Note that this feature is covered by several Microsoft patents        */
-  /* and should not be activated in any default build of the library.      */
-  /*                                                                       */
-  /* This macro has no impact on the FreeType API, only on its             */
-  /* _implementation_.  For example, using FT_RENDER_MODE_LCD when calling */
-  /* FT_Render_Glyph still generates a bitmap that is 3 times wider than   */
-  /* the original size in case this macro isn't defined; however, each     */
-  /* triplet of subpixels has R=G=B.                                       */
-  /*                                                                       */
-  /* This is done to allow FreeType clients to run unmodified, forcing     */
-  /* them to display normal gray-level anti-aliased glyphs.                */
-  /*                                                                       */
-/* #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Many compilers provide a non-ANSI 64-bit data type that can be used   */
-  /* by FreeType to speed up some computations.  However, this will create */
-  /* some problems when compiling the library in strict ANSI mode.         */
-  /*                                                                       */
-  /* For this reason, the use of 64-bit integers is normally disabled when */
-  /* the __STDC__ macro is defined.  You can however disable this by       */
-  /* defining the macro FT_CONFIG_OPTION_FORCE_INT64 here.                 */
-  /*                                                                       */
-  /* For most compilers, this will only create compilation warnings when   */
-  /* building the library.                                                 */
-  /*                                                                       */
-  /* ObNote: The compiler-specific 64-bit integers are detected in the     */
-  /*         file `ftconfig.h' either statically or through the            */
-  /*         `configure' script on supported platforms.                    */
-  /*                                                                       */
-#undef FT_CONFIG_OPTION_FORCE_INT64
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* If this macro is defined, do not try to use an assembler version of   */
-  /* performance-critical functions (e.g. FT_MulFix).  You should only do  */
-  /* that to verify that the assembler function works properly, or to      */
-  /* execute benchmark tests of the various implementations.               */
-/* #define FT_CONFIG_OPTION_NO_ASSEMBLER */
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* If this macro is defined, try to use an inlined assembler version of  */
-  /* the `FT_MulFix' function, which is a `hotspot' when loading and       */
-  /* hinting glyphs, and which should be executed as fast as possible.     */
-  /*                                                                       */
-  /* Note that if your compiler or CPU is not supported, this will default */
-  /* to the standard and portable implementation found in `ftcalc.c'.      */
-  /*                                                                       */
-#define FT_CONFIG_OPTION_INLINE_MULFIX
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* LZW-compressed file support.                                          */
-  /*                                                                       */
-  /*   FreeType now handles font files that have been compressed with the  */
-  /*   `compress' program.  This is mostly used to parse many of the PCF   */
-  /*   files that come with various X11 distributions.  The implementation */
-  /*   uses NetBSD's `zopen' to partially uncompress the file on the fly   */
-  /*   (see src/lzw/ftgzip.c).                                             */
-  /*                                                                       */
-  /*   Define this macro if you want to enable this `feature'.             */
-  /*                                                                       */
-#define FT_CONFIG_OPTION_USE_LZW
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Gzip-compressed file support.                                         */
-  /*                                                                       */
-  /*   FreeType now handles font files that have been compressed with the  */
-  /*   `gzip' program.  This is mostly used to parse many of the PCF files */
-  /*   that come with XFree86.  The implementation uses `zlib' to          */
-  /*   partially uncompress the file on the fly (see src/gzip/ftgzip.c).   */
-  /*                                                                       */
-  /*   Define this macro if you want to enable this `feature'.  See also   */
-  /*   the macro FT_CONFIG_OPTION_SYSTEM_ZLIB below.                       */
-  /*                                                                       */
-#define FT_CONFIG_OPTION_USE_ZLIB
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* ZLib library selection                                                */
-  /*                                                                       */
-  /*   This macro is only used when FT_CONFIG_OPTION_USE_ZLIB is defined.  */
-  /*   It allows FreeType's `ftgzip' component to link to the system's     */
-  /*   installation of the ZLib library.  This is useful on systems like   */
-  /*   Unix or VMS where it generally is already available.                */
-  /*                                                                       */
-  /*   If you let it undefined, the component will use its own copy        */
-  /*   of the zlib sources instead.  These have been modified to be        */
-  /*   included directly within the component and *not* export external    */
-  /*   function names.  This allows you to link any program with FreeType  */
-  /*   _and_ ZLib without linking conflicts.                               */
-  /*                                                                       */
-  /*   Do not #undef this macro here since the build system might define   */
-  /*   it for certain configurations only.                                 */
-  /*                                                                       */
-/* #define FT_CONFIG_OPTION_SYSTEM_ZLIB */
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Bzip2-compressed file support.                                        */
-  /*                                                                       */
-  /*   FreeType now handles font files that have been compressed with the  */
-  /*   `bzip2' program.  This is mostly used to parse many of the PCF      */
-  /*   files that come with XFree86.  The implementation uses `libbz2' to  */
-  /*   partially uncompress the file on the fly (see src/bzip2/ftbzip2.c). */
-  /*   Contrary to gzip, bzip2 currently is not included and need to use   */
-  /*   the system available bzip2 implementation.                          */
-  /*                                                                       */
-  /*   Define this macro if you want to enable this `feature'.             */
-  /*                                                                       */
-/* #define FT_CONFIG_OPTION_USE_BZIP2 */
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Define to disable the use of file stream functions and types, FILE,   */
-  /* fopen() etc.  Enables the use of smaller system libraries on embedded */
-  /* systems that have multiple system libraries, some with or without     */
-  /* file stream support, in the cases where file stream support is not    */
-  /* necessary such as memory loading of font files.                       */
-  /*                                                                       */
-/* #define FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT */
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* PNG bitmap support.                                                   */
-  /*                                                                       */
-  /*   FreeType now handles loading color bitmap glyphs in the PNG format. */
-  /*   This requires help from the external libpng library.  Uncompressed  */
-  /*   color bitmaps do not need any external libraries and will be        */
-  /*   supported regardless of this configuration.                         */
-  /*                                                                       */
-  /*   Define this macro if you want to enable this `feature'.             */
-  /*                                                                       */
-#define FT_CONFIG_OPTION_USE_PNG
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* HarfBuzz support.                                                     */
-  /*                                                                       */
-  /*   FreeType uses the HarfBuzz library to improve auto-hinting of       */
-  /*   OpenType fonts.  If available, many glyphs not directly addressable */
-  /*   by a font's character map will be hinted also.                      */
-  /*                                                                       */
-  /*   Define this macro if you want to enable this `feature'.             */
-  /*                                                                       */
-/* #define FT_CONFIG_OPTION_USE_HARFBUZZ */
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* DLL export compilation                                                */
-  /*                                                                       */
-  /*   When compiling FreeType as a DLL, some systems/compilers need a     */
-  /*   special keyword in front OR after the return type of function       */
-  /*   declarations.                                                       */
-  /*                                                                       */
-  /*   Two macros are used within the FreeType source code to define       */
-  /*   exported library functions: FT_EXPORT and FT_EXPORT_DEF.            */
-  /*                                                                       */
-  /*     FT_EXPORT( return_type )                                          */
-  /*                                                                       */
-  /*       is used in a function declaration, as in                        */
-  /*                                                                       */
-  /*         FT_EXPORT( FT_Error )                                         */
-  /*         FT_Init_FreeType( FT_Library*  alibrary );                    */
-  /*                                                                       */
-  /*                                                                       */
-  /*     FT_EXPORT_DEF( return_type )                                      */
-  /*                                                                       */
-  /*       is used in a function definition, as in                         */
-  /*                                                                       */
-  /*         FT_EXPORT_DEF( FT_Error )                                     */
-  /*         FT_Init_FreeType( FT_Library*  alibrary )                     */
-  /*         {                                                             */
-  /*           ... some code ...                                           */
-  /*           return FT_Err_Ok;                                           */
-  /*         }                                                             */
-  /*                                                                       */
-  /*   You can provide your own implementation of FT_EXPORT and            */
-  /*   FT_EXPORT_DEF here if you want.  If you leave them undefined, they  */
-  /*   will be later automatically defined as `extern return_type' to      */
-  /*   allow normal compilation.                                           */
-  /*                                                                       */
-  /*   Do not #undef these macros here since the build system might define */
-  /*   them for certain configurations only.                               */
-  /*                                                                       */
-/* #define FT_EXPORT(x)      extern x */
-/* #define FT_EXPORT_DEF(x)  x */
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Glyph Postscript Names handling                                       */
-  /*                                                                       */
-  /*   By default, FreeType 2 is compiled with the `psnames' module.  This */
-  /*   module is in charge of converting a glyph name string into a        */
-  /*   Unicode value, or return a Macintosh standard glyph name for the    */
-  /*   use with the TrueType `post' table.                                 */
-  /*                                                                       */
-  /*   Undefine this macro if you do not want `psnames' compiled in your   */
-  /*   build of FreeType.  This has the following effects:                 */
-  /*                                                                       */
-  /*   - The TrueType driver will provide its own set of glyph names,      */
-  /*     if you build it to support postscript names in the TrueType       */
-  /*     `post' table.                                                     */
-  /*                                                                       */
-  /*   - The Type 1 driver will not be able to synthesize a Unicode        */
-  /*     charmap out of the glyphs found in the fonts.                     */
-  /*                                                                       */
-  /*   You would normally undefine this configuration macro when building  */
-  /*   a version of FreeType that doesn't contain a Type 1 or CFF driver.  */
-  /*                                                                       */
-#define FT_CONFIG_OPTION_POSTSCRIPT_NAMES
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Postscript Names to Unicode Values support                            */
-  /*                                                                       */
-  /*   By default, FreeType 2 is built with the `PSNames' module compiled  */
-  /*   in.  Among other things, the module is used to convert a glyph name */
-  /*   into a Unicode value.  This is especially useful in order to        */
-  /*   synthesize on the fly a Unicode charmap from the CFF/Type 1 driver  */
-  /*   through a big table named the `Adobe Glyph List' (AGL).             */
-  /*                                                                       */
-  /*   Undefine this macro if you do not want the Adobe Glyph List         */
-  /*   compiled in your `PSNames' module.  The Type 1 driver will not be   */
-  /*   able to synthesize a Unicode charmap out of the glyphs found in the */
-  /*   fonts.                                                              */
-  /*                                                                       */
-#define FT_CONFIG_OPTION_ADOBE_GLYPH_LIST
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Support for Mac fonts                                                 */
-  /*                                                                       */
-  /*   Define this macro if you want support for outline fonts in Mac      */
-  /*   format (mac dfont, mac resource, macbinary containing a mac         */
-  /*   resource) on non-Mac platforms.                                     */
-  /*                                                                       */
-  /*   Note that the `FOND' resource isn't checked.                        */
-  /*                                                                       */
-/* #define FT_CONFIG_OPTION_MAC_FONTS */
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Guessing methods to access embedded resource forks                    */
-  /*                                                                       */
-  /*   Enable extra Mac fonts support on non-Mac platforms (e.g.           */
-  /*   GNU/Linux).                                                         */
-  /*                                                                       */
-  /*   Resource forks which include fonts data are stored sometimes in     */
-  /*   locations which users or developers don't expected.  In some cases, */
-  /*   resource forks start with some offset from the head of a file.  In  */
-  /*   other cases, the actual resource fork is stored in file different   */
-  /*   from what the user specifies.  If this option is activated,         */
-  /*   FreeType tries to guess whether such offsets or different file      */
-  /*   names must be used.                                                 */
-  /*                                                                       */
-  /*   Note that normal, direct access of resource forks is controlled via */
-  /*   the FT_CONFIG_OPTION_MAC_FONTS option.                              */
-  /*                                                                       */
-#ifdef FT_CONFIG_OPTION_MAC_FONTS
-#define FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK
-#endif
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Allow the use of FT_Incremental_Interface to load typefaces that      */
-  /* contain no glyph data, but supply it via a callback function.         */
-  /* This is required by clients supporting document formats which         */
-  /* supply font data incrementally as the document is parsed, such        */
-  /* as the Ghostscript interpreter for the PostScript language.           */
-  /*                                                                       */
-/* #define FT_CONFIG_OPTION_INCREMENTAL */
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* The size in bytes of the render pool used by the scan-line converter  */
-  /* to do all of its work.                                                */
-  /*                                                                       */
-#define FT_RENDER_POOL_SIZE  16384L
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* FT_MAX_MODULES                                                        */
-  /*                                                                       */
-  /*   The maximum number of modules that can be registered in a single    */
-  /*   FreeType library object.  32 is the default.                        */
-  /*                                                                       */
-#define FT_MAX_MODULES  32
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Debug level                                                           */
-  /*                                                                       */
-  /*   FreeType can be compiled in debug or trace mode.  In debug mode,    */
-  /*   errors are reported through the `ftdebug' component.  In trace      */
-  /*   mode, additional messages are sent to the standard output during    */
-  /*   execution.                                                          */
-  /*                                                                       */
-  /*   Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode.     */
-  /*   Define FT_DEBUG_LEVEL_TRACE to build it in trace mode.              */
-  /*                                                                       */
-  /*   Don't define any of these macros to compile in `release' mode!      */
-  /*                                                                       */
-  /*   Do not #undef these macros here since the build system might define */
-  /*   them for certain configurations only.                               */
-  /*                                                                       */
-/* #define FT_DEBUG_LEVEL_ERROR */
-/* #define FT_DEBUG_LEVEL_TRACE */
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Autofitter debugging                                                  */
-  /*                                                                       */
-  /*   If FT_DEBUG_AUTOFIT is defined, FreeType provides some means to     */
-  /*   control the autofitter behaviour for debugging purposes with global */
-  /*   boolean variables (consequently, you should *never* enable this     */
-  /*   while compiling in `release' mode):                                 */
-  /*                                                                       */
-  /*     _af_debug_disable_horz_hints                                      */
-  /*     _af_debug_disable_vert_hints                                      */
-  /*     _af_debug_disable_blue_hints                                      */
-  /*                                                                       */
-  /*   Additionally, the following functions provide dumps of various      */
-  /*   internal autofit structures to stdout (using `printf'):             */
-  /*                                                                       */
-  /*     af_glyph_hints_dump_points                                        */
-  /*     af_glyph_hints_dump_segments                                      */
-  /*     af_glyph_hints_dump_edges                                         */
-  /*     af_glyph_hints_get_num_segments                                   */
-  /*     af_glyph_hints_get_segment_offset                                 */
-  /*                                                                       */
-  /*   As an argument, they use another global variable:                   */
-  /*                                                                       */
-  /*     _af_debug_hints                                                   */
-  /*                                                                       */
-  /*   Please have a look at the `ftgrid' demo program to see how those    */
-  /*   variables and macros should be used.                                */
-  /*                                                                       */
-  /*   Do not #undef these macros here since the build system might define */
-  /*   them for certain configurations only.                               */
-  /*                                                                       */
-/* #define FT_DEBUG_AUTOFIT */
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Memory Debugging                                                      */
-  /*                                                                       */
-  /*   FreeType now comes with an integrated memory debugger that is       */
-  /*   capable of detecting simple errors like memory leaks or double      */
-  /*   deletes.  To compile it within your build of the library, you       */
-  /*   should define FT_DEBUG_MEMORY here.                                 */
-  /*                                                                       */
-  /*   Note that the memory debugger is only activated at runtime when     */
-  /*   when the _environment_ variable `FT2_DEBUG_MEMORY' is defined also! */
-  /*                                                                       */
-  /*   Do not #undef this macro here since the build system might define   */
-  /*   it for certain configurations only.                                 */
-  /*                                                                       */
-/* #define FT_DEBUG_MEMORY */
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Module errors                                                         */
-  /*                                                                       */
-  /*   If this macro is set (which is _not_ the default), the higher byte  */
-  /*   of an error code gives the module in which the error has occurred,  */
-  /*   while the lower byte is the real error code.                        */
-  /*                                                                       */
-  /*   Setting this macro makes sense for debugging purposes only, since   */
-  /*   it would break source compatibility of certain programs that use    */
-  /*   FreeType 2.                                                         */
-  /*                                                                       */
-  /*   More details can be found in the files ftmoderr.h and fterrors.h.   */
-  /*                                                                       */
-#undef FT_CONFIG_OPTION_USE_MODULE_ERRORS
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Position Independent Code                                             */
-  /*                                                                       */
-  /*   If this macro is set (which is _not_ the default), FreeType2 will   */
-  /*   avoid creating constants that require address fixups.  Instead the  */
-  /*   constants will be moved into a struct and additional intialization  */
-  /*   code will be used.                                                  */
-  /*                                                                       */
-  /*   Setting this macro is needed for systems that prohibit address      */
-  /*   fixups, such as BREW.  [Note that standard compilers like gcc or    */
-  /*   clang handle PIC generation automatically; you don't have to set    */
-  /*   FT_CONFIG_OPTION_PIC, which is only necessary for very special      */
-  /*   compilers.]                                                         */
-  /*                                                                       */
-  /*   Note that FT_CONFIG_OPTION_PIC support is not available for all     */
-  /*   modules (see `modules.cfg' for a complete list).  For building with */
-  /*   FT_CONFIG_OPTION_PIC support, do the following.                     */
-  /*                                                                       */
-  /*     0. Clone the repository.                                          */
-  /*     1. Define FT_CONFIG_OPTION_PIC.                                   */
-  /*     2. Remove all subdirectories in `src' that don't have             */
-  /*        FT_CONFIG_OPTION_PIC support.                                  */
-  /*     3. Comment out the corresponding modules in `modules.cfg'.        */
-  /*     4. Compile.                                                       */
-  /*                                                                       */
-/* #define FT_CONFIG_OPTION_PIC */
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /****                                                                 ****/
-  /****        S F N T   D R I V E R    C O N F I G U R A T I O N       ****/
-  /****                                                                 ****/
-  /*************************************************************************/
-  /*************************************************************************/
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Define TT_CONFIG_OPTION_EMBEDDED_BITMAPS if you want to support       */
-  /* embedded bitmaps in all formats using the SFNT module (namely         */
-  /* TrueType & OpenType).                                                 */
-  /*                                                                       */
-#define TT_CONFIG_OPTION_EMBEDDED_BITMAPS
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Define TT_CONFIG_OPTION_POSTSCRIPT_NAMES if you want to be able to    */
-  /* load and enumerate the glyph Postscript names in a TrueType or        */
-  /* OpenType file.                                                        */
-  /*                                                                       */
-  /* Note that when you do not compile the `PSNames' module by undefining  */
-  /* the above FT_CONFIG_OPTION_POSTSCRIPT_NAMES, the `sfnt' module will   */
-  /* contain additional code used to read the PS Names table from a font.  */
-  /*                                                                       */
-  /* (By default, the module uses `PSNames' to extract glyph names.)       */
-  /*                                                                       */
-#define TT_CONFIG_OPTION_POSTSCRIPT_NAMES
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Define TT_CONFIG_OPTION_SFNT_NAMES if your applications need to       */
-  /* access the internal name table in a SFNT-based format like TrueType   */
-  /* or OpenType.  The name table contains various strings used to         */
-  /* describe the font, like family name, copyright, version, etc.  It     */
-  /* does not contain any glyph name though.                               */
-  /*                                                                       */
-  /* Accessing SFNT names is done through the functions declared in        */
-  /* `ftsnames.h'.                                                         */
-  /*                                                                       */
-#define TT_CONFIG_OPTION_SFNT_NAMES
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* TrueType CMap support                                                 */
-  /*                                                                       */
-  /*   Here you can fine-tune which TrueType CMap table format shall be    */
-  /*   supported.                                                          */
-#define TT_CONFIG_CMAP_FORMAT_0
-#define TT_CONFIG_CMAP_FORMAT_2
-#define TT_CONFIG_CMAP_FORMAT_4
-#define TT_CONFIG_CMAP_FORMAT_6
-#define TT_CONFIG_CMAP_FORMAT_8
-#define TT_CONFIG_CMAP_FORMAT_10
-#define TT_CONFIG_CMAP_FORMAT_12
-#define TT_CONFIG_CMAP_FORMAT_13
-#define TT_CONFIG_CMAP_FORMAT_14
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /****                                                                 ****/
-  /****    T R U E T Y P E   D R I V E R    C O N F I G U R A T I O N   ****/
-  /****                                                                 ****/
-  /*************************************************************************/
-  /*************************************************************************/
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Define TT_CONFIG_OPTION_BYTECODE_INTERPRETER if you want to compile   */
-  /* a bytecode interpreter in the TrueType driver.                        */
-  /*                                                                       */
-  /* By undefining this, you will only compile the code necessary to load  */
-  /* TrueType glyphs without hinting.                                      */
-  /*                                                                       */
-  /*   Do not #undef this macro here, since the build system might         */
-  /*   define it for certain configurations only.                          */
-  /*                                                                       */
-#define TT_CONFIG_OPTION_BYTECODE_INTERPRETER
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Define TT_CONFIG_OPTION_SUBPIXEL_HINTING if you want to compile       */
-  /* subpixel hinting support into the TrueType driver.  This modifies the */
-  /* TrueType hinting mechanism when anything but FT_RENDER_MODE_MONO is   */
-  /* requested.                                                            */
-  /*                                                                       */
-  /* In particular, it modifies the bytecode interpreter to interpret (or  */
-  /* not) instructions in a certain way so that all TrueType fonts look    */
-  /* like they do in a Windows ClearType (DirectWrite) environment.  See   */
-  /* [1] for a technical overview on what this means.  See `ttinterp.h'    */
-  /* for more details on the LEAN option.                                  */
-  /*                                                                       */
-  /* There are three possible values.                                      */
-  /*                                                                       */
-  /* Value 1:                                                              */
-  /*    This value is associated with the `Infinality' moniker,            */
-  /*    contributed by an individual nicknamed Infinality with the goal of */
-  /*    making TrueType fonts render better than on Windows.  A high       */
-  /*    amount of configurability and flexibility, down to rules for       */
-  /*    single glyphs in fonts, but also very slow.  Its experimental and  */
-  /*    slow nature and the original developer losing interest meant that  */
-  /*    this option was never enabled in default builds.                   */
-  /*                                                                       */
-  /*    The corresponding interpreter version is v38.                      */
-  /*                                                                       */
-  /* Value 2:                                                              */
-  /*    The new default mode for the TrueType driver.  The Infinality code */
-  /*    base was stripped to the bare minimum and all configurability      */
-  /*    removed in the name of speed and simplicity.  The configurability  */
-  /*    was mainly aimed at legacy fonts like Arial, Times New Roman, or   */
-  /*    Courier.  Legacy fonts are fonts that modify vertical stems to     */
-  /*    achieve clean black-and-white bitmaps.  The new mode focuses on    */
-  /*    applying a minimal set of rules to all fonts indiscriminately so   */
-  /*    that modern and web fonts render well while legacy fonts render    */
-  /*    okay.                                                              */
-  /*                                                                       */
-  /*    The corresponding interpreter version is v40.                      */
-  /*                                                                       */
-  /* Value 3:                                                              */
-  /*    Compile both, making both v38 and v40 available (the latter is the */
-  /*    default).                                                          */
-  /*                                                                       */
-  /* By undefining these, you get rendering behavior like on Windows       */
-  /* without ClearType, i.e., Windows XP without ClearType enabled and     */
-  /* Win9x (interpreter version v35).  Or not, depending on how much       */
-  /* hinting blood and testing tears the font designer put into a given    */
-  /* font.  If you define one or both subpixel hinting options, you can    */
-  /* switch between between v35 and the ones you define (using             */
-  /* `FT_Property_Set').                                                   */
-  /*                                                                       */
-  /* This option requires TT_CONFIG_OPTION_BYTECODE_INTERPRETER to be      */
-  /* defined.                                                              */
-  /*                                                                       */
-  /* [1] http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx */
-  /*                                                                       */
-/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING  1         */
-#define TT_CONFIG_OPTION_SUBPIXEL_HINTING  2
-/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING  ( 1 | 2 ) */
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Define TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED to compile the        */
-  /* TrueType glyph loader to use Apple's definition of how to handle      */
-  /* component offsets in composite glyphs.                                */
-  /*                                                                       */
-  /* Apple and MS disagree on the default behavior of component offsets    */
-  /* in composites.  Apple says that they should be scaled by the scaling  */
-  /* factors in the transformation matrix (roughly, it's more complex)     */
-  /* while MS says they should not.  OpenType defines two bits in the      */
-  /* composite flags array which can be used to disambiguate, but old      */
-  /* fonts will not have them.                                             */
-  /*                                                                       */
-  /*   http://www.microsoft.com/typography/otspec/glyf.htm                 */
-  /*   https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6glyf.html */
-  /*                                                                       */
-#undef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Define TT_CONFIG_OPTION_GX_VAR_SUPPORT if you want to include         */
-  /* support for Apple's distortable font technology (fvar, gvar, cvar,    */
-  /* and avar tables).  This has many similarities to Type 1 Multiple      */
-  /* Masters support.                                                      */
-  /*                                                                       */
-#define TT_CONFIG_OPTION_GX_VAR_SUPPORT
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Define TT_CONFIG_OPTION_BDF if you want to include support for        */
-  /* an embedded `BDF ' table within SFNT-based bitmap formats.            */
-  /*                                                                       */
-/* #define TT_CONFIG_OPTION_BDF */
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Option TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES controls the maximum     */
-  /* number of bytecode instructions executed for a single run of the      */
-  /* bytecode interpreter, needed to prevent infinite loops.  You don't    */
-  /* want to change this except for very special situations (e.g., making  */
-  /* a library fuzzer spend less time to handle broken fonts).             */
-  /*                                                                       */
-  /* It is not expected that this value is ever modified by a configuring  */
-  /* script; instead, it gets surrounded with #ifndef ... #endif so that   */
-  /* the value can be set as a preprocessor option on the compiler's       */
-  /* command line.                                                         */
-  /*                                                                       */
-#ifndef TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES
-#define TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES  1000000L
-#endif
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /****                                                                 ****/
-  /****      T Y P E 1   D R I V E R    C O N F I G U R A T I O N       ****/
-  /****                                                                 ****/
-  /*************************************************************************/
-  /*************************************************************************/
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* T1_MAX_DICT_DEPTH is the maximum depth of nest dictionaries and       */
-  /* arrays in the Type 1 stream (see t1load.c).  A minimum of 4 is        */
-  /* required.                                                             */
-  /*                                                                       */
-#define T1_MAX_DICT_DEPTH  5
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* T1_MAX_SUBRS_CALLS details the maximum number of nested sub-routine   */
-  /* calls during glyph loading.                                           */
-  /*                                                                       */
-#define T1_MAX_SUBRS_CALLS  16
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* T1_MAX_CHARSTRING_OPERANDS is the charstring stack's capacity.  A     */
-  /* minimum of 16 is required.                                            */
-  /*                                                                       */
-  /* The Chinese font MingTiEG-Medium (CNS 11643 character set) needs 256. */
-  /*                                                                       */
-#define T1_MAX_CHARSTRINGS_OPERANDS  256
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Define this configuration macro if you want to prevent the            */
-  /* compilation of `t1afm', which is in charge of reading Type 1 AFM      */
-  /* files into an existing face.  Note that if set, the T1 driver will be */
-  /* unable to produce kerning distances.                                  */
-  /*                                                                       */
-#undef T1_CONFIG_OPTION_NO_AFM
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Define this configuration macro if you want to prevent the            */
-  /* compilation of the Multiple Masters font support in the Type 1        */
-  /* driver.                                                               */
-  /*                                                                       */
-#undef T1_CONFIG_OPTION_NO_MM_SUPPORT
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /****                                                                 ****/
-  /****         C F F   D R I V E R    C O N F I G U R A T I O N        ****/
-  /****                                                                 ****/
-  /*************************************************************************/
-  /*************************************************************************/
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Using CFF_CONFIG_OPTION_DARKENING_PARAMETER_{X,Y}{1,2,3,4} it is      */
-  /* possible to set up the default values of the four control points that */
-  /* define the stem darkening behaviour of the (new) CFF engine.  For     */
-  /* more details please read the documentation of the                     */
-  /* `darkening-parameters' property of the cff driver module (file        */
-  /* `ftcffdrv.h'), which allows the control at run-time.                  */
-  /*                                                                       */
-  /* Do *not* undefine these macros!                                       */
-  /*                                                                       */
-#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1   500
-#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1   400
-
-#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2  1000
-#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2   275
-
-#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3  1667
-#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3   275
-
-#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4  2333
-#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4     0
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* CFF_CONFIG_OPTION_OLD_ENGINE controls whether the pre-Adobe CFF       */
-  /* engine gets compiled into FreeType.  If defined, it is possible to    */
-  /* switch between the two engines using the `hinting-engine' property of */
-  /* the cff driver module.                                                */
-  /*                                                                       */
-/* #define CFF_CONFIG_OPTION_OLD_ENGINE */
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /****                                                                 ****/
-  /****         P C F   D R I V E R    C O N F I G U R A T I O N        ****/
-  /****                                                                 ****/
-  /*************************************************************************/
-  /*************************************************************************/
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* There are many PCF fonts just called `Fixed' which look completely    */
-  /* different, and which have nothing to do with each other.  When        */
-  /* selecting `Fixed' in KDE or Gnome one gets results that appear rather */
-  /* random, the style changes often if one changes the size and one       */
-  /* cannot select some fonts at all.  This option makes the PCF module    */
-  /* prepend the foundry name (plus a space) to the family name.           */
-  /*                                                                       */
-  /* We also check whether we have `wide' characters; all put together, we */
-  /* get family names like `Sony Fixed' or `Misc Fixed Wide'.              */
-  /*                                                                       */
-  /* If this option is activated, it can be controlled with the            */
-  /* `no-long-family-names' property of the pcf driver module.             */
-  /*                                                                       */
-/* #define PCF_CONFIG_OPTION_LONG_FAMILY_NAMES */
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /****                                                                 ****/
-  /****    A U T O F I T   M O D U L E    C O N F I G U R A T I O N     ****/
-  /****                                                                 ****/
-  /*************************************************************************/
-  /*************************************************************************/
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Compile autofit module with CJK (Chinese, Japanese, Korean) script    */
-  /* support.                                                              */
-  /*                                                                       */
-#define AF_CONFIG_OPTION_CJK
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Compile autofit module with Indic script support.                     */
-  /*                                                                       */
-#define AF_CONFIG_OPTION_INDIC
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Compile autofit module with warp hinting.  The idea of the warping    */
-  /* code is to slightly scale and shift a glyph within a single dimension */
-  /* so that as much of its segments are aligned (more or less) on the     */
-  /* grid.  To find out the optimal scaling and shifting value, various    */
-  /* parameter combinations are tried and scored.                          */
-  /*                                                                       */
-  /* This experimental option is active only if the rendering mode is      */
-  /* FT_RENDER_MODE_LIGHT; you can switch warping on and off with the      */
-  /* `warping' property of the auto-hinter (see file `ftautoh.h' for more  */
-  /* information; by default it is switched off).                          */
-  /*                                                                       */
-/*#define AF_CONFIG_OPTION_USE_WARPER*/
-
-  /* */
-
-
-  /*
-   * This macro is obsolete.  Support has been removed in FreeType
-   * version 2.5.
-   */
-/* #define FT_CONFIG_OPTION_OLD_INTERNALS */
-
-
-  /*
-   * This macro is defined if native TrueType hinting is requested by the
-   * definitions above.
-   */
-#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
-#define  TT_USE_BYTECODE_INTERPRETER
-
-#if TT_CONFIG_OPTION_SUBPIXEL_HINTING & 1
-#define  TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-#endif
-
-#if TT_CONFIG_OPTION_SUBPIXEL_HINTING & 2
-#define  TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
-#endif
-#endif
-
-
-  /*
-   * Check CFF darkening parameters.  The checks are the same as in function
-   * `cff_property_set' in file `cffdrivr.c'.
-   */
-#if CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1 < 0   || \
-    CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 < 0   || \
-    CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3 < 0   || \
-    CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4 < 0   || \
-                                                      \
-    CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1 < 0   || \
-    CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2 < 0   || \
-    CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3 < 0   || \
-    CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4 < 0   || \
-                                                      \
-    CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1 >        \
-      CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2     || \
-    CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 >        \
-      CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3     || \
-    CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3 >        \
-      CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4     || \
-                                                      \
-    CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1 > 500 || \
-    CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2 > 500 || \
-    CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3 > 500 || \
-    CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4 > 500
-#error "Invalid CFF darkening parameters!"
-#endif
-
-FT_END_HEADER
-
-
-#endif /* FTOPTION_H_ */
-
-
-/* END */
diff --git a/third_party/freetype2/patches/freetype2_symbols_visibility.patch b/third_party/freetype2/patches/freetype2_symbols_visibility.patch
deleted file mode 100644
index e8c3232..0000000
--- a/third_party/freetype2/patches/freetype2_symbols_visibility.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-diff --git a/third_party/freetype2/include/freetype-custom-config/ftconfig.h b/third_party/freetype2/include/freetype-custom-config/ftconfig.h
-index 0e1945b..80e7940 100644
---- a/third_party/freetype2/include/freetype-custom-config/ftconfig.h
-+++ b/third_party/freetype2/include/freetype-custom-config/ftconfig.h
-@@ -424,9 +424,9 @@ FT_BEGIN_HEADER
- #ifndef FT_EXPORT
-
- #ifdef __cplusplus
--#define FT_EXPORT( x )  extern "C"  x
-+#define FT_EXPORT( x )  __attribute__ ((visibility ("default"))) extern "C"  x
- #else
--#define FT_EXPORT( x )  extern  x
-+#define FT_EXPORT( x )  __attribute__ ((visibility ("default"))) extern  x
- #endif
-
- #endif /* !FT_EXPORT */
-@@ -435,9 +435,9 @@ FT_BEGIN_HEADER
- #ifndef FT_EXPORT_DEF
-
- #ifdef __cplusplus
--#define FT_EXPORT_DEF( x )  extern "C"  x
-+#define FT_EXPORT_DEF( x )  __attribute__((visibility("default"))) extern "C"  x
- #else
--#define FT_EXPORT_DEF( x )  extern  x
-+#define FT_EXPORT_DEF( x )  __attribute__((visibility("default"))) extern  x
- #endif
-
- #endif /* !FT_EXPORT_DEF */
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 704c29d..4696764 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -31219,6 +31219,25 @@
   </summary>
 </histogram>
 
+<histogram name="Net.CertificateTransparency.DnsQueryDuration" units="ms">
+  <owner>robpercival@chromium.org</owner>
+  <summary>
+    The time taken to obtain an inclusion proof from a Certificate Transparency
+    log over DNS. This includes the time taken to obtain the leaf index first.
+    Emitted at the end of an attempt.
+  </summary>
+</histogram>
+
+<histogram name="Net.CertificateTransparency.DnsQueryStatus"
+    enum="CertificateTransparencyDnsQueryStatus">
+  <owner>robpercival@chromium.org</owner>
+  <summary>
+    The status of each attempt to obtain an inclusion proof from a Certificate
+    Transparency log over DNS. This can consist of more than one DNS request.
+    Emitted at the end of an attempt.
+  </summary>
+</histogram>
+
 <histogram name="Net.CertificateTransparency.InclusionCheckResult"
     enum="CTLogEntryInclusionCheckResult">
   <owner>eranm@chromium.org</owner>
@@ -82453,6 +82472,14 @@
   <int value="0" label="Root Certificate"/>
 </enum>
 
+<enum name="CertificateTransparencyDnsQueryStatus" type="int">
+  <int value="0" label="SUCCESS"/>
+  <int value="1" label="FAILED_UNKNOWN"/>
+  <int value="2" label="FAILED_NAME_RESOLUTION"/>
+  <int value="3" label="FAILED_LEAF_INDEX_MALFORMED"/>
+  <int value="4" label="FAILED_INCLUSION_PROOF_MALFORMED"/>
+</enum>
+
 <enum name="ChannelLayout" type="int">
   <int value="0" label="CHANNEL_LAYOUT_NONE"/>
   <int value="1" label="CHANNEL_LAYOUT_UNSUPPORTED"/>
diff --git a/ui/file_manager/image_loader/piex_loader.js b/ui/file_manager/image_loader/piex_loader.js
index d4bb42e..e667692 100644
--- a/ui/file_manager/image_loader/piex_loader.js
+++ b/ui/file_manager/image_loader/piex_loader.js
@@ -54,60 +54,65 @@
 }
 
 /**
+ * Creates a PiexLoader for loading RAW files using a Piex NaCl module.
+ *
+ * All of the arguments are optional and used for tests only. If not passed,
+ * then default implementations and values will be used.
+ *
+ * @param {function()=} opt_createModule Creates a NaCl module.
+ * @param {function(!Element)=} opt_destroyModule Destroys a NaCl module.
+ * @param {number=} opt_idleTimeout Idle timeout to destroy NaCl module.
  * @constructor
  * @struct
  */
-function PiexLoader() {
+function PiexLoader(opt_createModule, opt_destroyModule, opt_idleTimeout) {
   /**
-   * @private {!Element}
-   * @const
+   * @private {function():!Element}
    */
-  this.naclModule_ = document.createElement('embed');
+  this.createModule_ = opt_createModule || this.defaultCreateModule_.bind(this);
 
   /**
-   * @private {!Promise<boolean>}
-   * @const
+   * @private {function():!Element}
    */
-  this.naclPromise_ = new Promise(function(fulfill) {
-    chrome.fileManagerPrivate.isPiexLoaderEnabled(fulfill);
-  }).then(function(enabled) {
-    if (!enabled)
-      return false;
-    return new Promise(function(fulfill, reject) {
-      var embed = this.naclModule_;
-      embed.setAttribute('type', 'application/x-pnacl');
-      // The extension nmf is not allowed to load. We uses .nmf.js instead.
-      embed.setAttribute('src', '/piex/piex.nmf.txt');
-      embed.width = 0;
-      embed.height = 0;
+  this.destroyModule_ =
+      opt_destroyModule || this.defaultDestroyModule_.bind(this);
 
-      // The <EMBED> element is wrapped inside a <DIV>, which has both a 'load'
-      // and a 'message' event listener attached.  This wrapping method is used
-      // instead of attaching the event listeners directly to the <EMBED>
-      // element to ensure that the listeners are active before the NaCl module
-      // 'load' event fires.
-      var listenerContainer = document.createElement('div');
-      listenerContainer.appendChild(embed);
-      listenerContainer.addEventListener(
-          'load', fulfill.bind(null, true), true);
-      listenerContainer.addEventListener(
-          'message', this.onMessage_.bind(this), true);
-      listenerContainer.addEventListener('error', function() {
-        reject(embed['lastError']);
-      }.bind(this), true);
-      listenerContainer.addEventListener('crash', function() {
-        reject('PiexLoader crashed.');
-      }.bind(this), true);
-      listenerContainer.style.height = '0px';
-      document.body.appendChild(listenerContainer);
-    }.bind(this));
-  }.bind(this)).catch(function (error) {
-    console.error(error);
-    return false;
-  });
+  this.idleTimeoutMs_ = opt_idleTimeout !== undefined ?
+      opt_idleTimeout :
+      PiexLoader.DEFAULT_IDLE_TIMEOUT_MS;
 
   /**
-   * @private {!Object<number, PiexRequestCallbacks>}
+   * @private {Element}
+   */
+  this.naclModule_ = null;
+
+  /**
+   * @private {Element}
+   */
+  this.containerElement_ = null;
+
+  /**
+   * @private {number}
+   */
+  this.unloadTimer_ = 0;
+
+  /**
+   * @private {Promise<boolean>}
+   */
+  this.naclPromise_ = null;
+
+  /**
+   * @private {?function(boolean)}
+   */
+  this.naclPromiseFulfill_ = null;
+
+  /**
+   * @private {?function(string=)}
+   */
+  this.naclPromiseReject_ = null;
+
+  /**
+   * @private {!Object<number, ?PiexRequestCallbacks>}
    * @const
    */
   this.requests_ = {};
@@ -116,21 +121,187 @@
    * @private {number}
    */
   this.requestIdCount_ = 0;
+
+  // Bound function so the listeners can be unregistered.
+  this.onNaclLoadBound_ = this.onNaclLoad_.bind(this);
+  this.onNaclMessageBound_ = this.onNaclMessage_.bind(this);
+  this.onNaclErrorBound_ = this.onNaclError_.bind(this);
+  this.onNaclCrashBound_ = this.onNaclCrash_.bind(this);
 }
 
 /**
+ * Idling time before the NaCl module is unloaded. This lets the image loader
+ * extension close when inactive.
+ *
+ * @const {number}
+ */
+PiexLoader.DEFAULT_IDLE_TIMEOUT_MS = 3000;  // 3 seconds.
+
+/**
+ * Creates a NaCl module element.
+ *
+ * Do not call directly. Use this.loadModule_ instead to support
+ * tests.
+ *
+ * @return {!Element}
+ * @private
+ */
+PiexLoader.prototype.defaultCreateModule_ = function() {
+  var embed = document.createElement('embed');
+  embed.setAttribute('type', 'application/x-pnacl');
+  // The extension nmf is not allowed to load. We uses .nmf.js instead.
+  embed.setAttribute('src', '/piex/piex.nmf.txt');
+  embed.width = 0;
+  embed.height = 0;
+  return embed;
+};
+
+PiexLoader.prototype.defaultDestroyModule_ = function(module) {
+  // The module is destroyed by removing it from DOM in loadNaclModule_().
+};
+
+/**
+ * @return {!Promise<boolean>}
+ * @private
+ */
+PiexLoader.prototype.loadNaclModule_ = function() {
+  if (this.naclPromise_) {
+    return this.naclPromise_;
+  }
+
+  this.naclPromise_ = new Promise(function(fulfill) {
+    chrome.fileManagerPrivate.isPiexLoaderEnabled(fulfill);
+  }).then(function(enabled) {
+    if (!enabled)
+      return false;
+    return new Promise(function(fulfill, reject) {
+      this.naclPromiseFulfill_ = fulfill;
+      this.naclPromiseReject_ = reject;
+      this.naclModule_ = this.createModule_();
+
+      // The <EMBED> element is wrapped inside a <DIV>, which has both a 'load'
+      // and a 'message' event listener attached.  This wrapping method is used
+      // instead of attaching the event listeners directly to the <EMBED>
+      // element to ensure that the listeners are active before the NaCl module
+      // 'load' event fires.
+      var listenerContainer = document.createElement('div');
+      listenerContainer.appendChild(this.naclModule_);
+      listenerContainer.addEventListener('load', this.onNaclLoadBound_, true);
+      listenerContainer.addEventListener(
+          'message', this.onNaclMessageBound_, true);
+      listenerContainer.addEventListener('error', this.onNaclErrorBound_, true);
+      listenerContainer.addEventListener('crash', this.onNaclCrashBound_, true);
+      listenerContainer.style.height = '0px';
+      this.containerElement_ = listenerContainer;
+      document.body.appendChild(listenerContainer);
+    }.bind(this));
+  }.bind(this)).catch(function (error) {
+    console.error(error);
+    return false;
+  });
+
+  return this.naclPromise_;
+};
+
+/**
+ * @private
+ */
+PiexLoader.prototype.unloadNaclModule_ = function() {
+  this.containerElement_.removeEventListener('load', this.onNaclLoadBound_);
+  this.containerElement_.removeEventListener(
+      'message', this.onNaclMessageBound_);
+  this.containerElement_.removeEventListener('error', this.onNaclErrorBound_);
+  this.containerElement_.removeEventListener('crash', this.onNaclCrashBound_);
+  this.containerElement_.parentNode.removeChild(this.containerElement_);
+  this.containerElement_ = null;
+
+  this.destroyModule_();
+  this.naclModule_ = null;
+  this.naclPromise_ = null;
+  this.naclPromiseFulfill_ = null;
+  this.naclPromiseReject_ = null;
+};
+
+/**
  * @param {Event} event
  * @private
  */
-PiexLoader.prototype.onMessage_ = function(event) {
+PiexLoader.prototype.onNaclLoad_ = function(event) {
+  console.assert(this.naclPromiseFulfill_);
+  this.naclPromiseFulfill_(true);
+};
+
+/**
+ * @param {Event} event
+ * @private
+ */
+PiexLoader.prototype.onNaclMessage_ = function(event) {
   var id = event.data.id;
   if (!event.data.error) {
     var response = new PiexLoaderResponse(event.data);
+    console.assert(this.requests_[id]);
     this.requests_[id].fulfill(response);
   } else {
+    console.assert(this.requests_[id]);
     this.requests_[id].reject(event.data.error);
   }
   delete this.requests_[id];
+  if (Object.keys(this.requests_).length === 0)
+    this.scheduleUnloadOnIdle_();
+};
+
+/**
+ * @param {Event} event
+ * @private
+ */
+PiexLoader.prototype.onNaclError_ = function(event) {
+  console.assert(this.naclPromiseReject_);
+  this.naclPromiseReject_(this.naclModule_['lastError']);
+};
+
+/**
+ * @param {Event} event
+ * @private
+ */
+PiexLoader.prototype.onNaclCrash_ = function(event) {
+  console.assert(this.naclPromiseReject_);
+  this.naclPromiseReject_('PiexLoader crashed.');
+};
+
+/**
+ * Schedules unloading the NaCl module after IDLE_TIMEOUT_MS passes.
+ * @private
+ */
+PiexLoader.prototype.scheduleUnloadOnIdle_ = function() {
+  if (this.unloadTimer_)
+    clearTimeout(this.unloadTimer_);
+  this.unloadTimer_ =
+      setTimeout(this.onIdleTimeout_.bind(this), this.idleTimeoutMs_);
+};
+
+/**
+ * @private
+ */
+PiexLoader.prototype.onIdleTimeout_ = function() {
+  this.unloadNaclModule_();
+};
+
+/**
+ * Simulates time passed required to fire the closure enqueued with setTimeout.
+ *
+ * Note, that if there is no active timer set with setTimeout earlier, then
+ * nothing will happen.
+ *
+ * This method is used to avoid waiting for DEFAULT_IDLE_TIMEOUT_MS in tests.
+ * Also, it allows to avoid flakyness by effectively removing any dependency
+ * on execution speed of the test (tests set the timeout to a very large value
+ * and only rely on this method to simulate passed time).
+ */
+PiexLoader.prototype.simulateIdleTimeoutPassedForTests = function() {
+  if (this.unloadTimer_) {
+    clearTimeout(this.unloadTimer_);
+    this.onIdleTimeout_();
+  }
 };
 
 /**
@@ -139,20 +310,29 @@
  * @return {!Promise<!PiexLoaderResponse>}
  */
 PiexLoader.prototype.load = function(url) {
-  return this.naclPromise_.then(function(loaded) {
+  var requestId = this.requestIdCount_++;
+
+  if (this.unloadTimer_) {
+    clearTimeout(this.unloadTimer_);
+    this.unloadTimer_ = 0;
+  }
+
+  // Prevents unloading the NaCl module during handling the promises below.
+  this.requests_[requestId] = null;
+
+  return this.loadNaclModule_().then(function(loaded) {
     if (!loaded)
       return Promise.reject('Piex is not loaded');
-    var message = {
-      id: this.requestIdCount_++,
-      name: 'loadThumbnail',
-      url: url
-    };
+    var message = {id: requestId, name: 'loadThumbnail', url: url};
     this.naclModule_.postMessage(message);
     return new Promise(function(fulfill, reject) {
-      this.requests_[message.id] = {fulfill: fulfill, reject: reject};
-    }.bind(this)).catch(function(error) {
-      console.error('PiexLoaderError: ', error);
-      return Promise.reject(error);
-    });
+             delete this.requests_[requestId];
+             this.requests_[message.id] = {fulfill: fulfill, reject: reject};
+           }.bind(this))
+        .catch(function(error) {
+          delete this.requests_[requestId];
+          console.error('PiexLoaderError: ', error);
+          return Promise.reject(error);
+        });
   }.bind(this));
 };
diff --git a/ui/file_manager/image_loader/piex_loader_unittest.html b/ui/file_manager/image_loader/piex_loader_unittest.html
new file mode 100644
index 0000000..def61cc
--- /dev/null
+++ b/ui/file_manager/image_loader/piex_loader_unittest.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<!-- 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.
+  -->
+
+<script src="../../webui/resources/js/assert.js"></script>
+<script src="../../webui/resources/js/cr.js"></script>
+<script src="../../webui/resources/js/cr/ui.js"></script>
+<script src="../file_manager/common/js/unittest_util.js"></script>
+<script src="../file_manager/foreground/js/metadata/image_orientation.js"></script>
+
+<script src="piex_loader.js"></script>
+<script src="piex_loader_unittest.js"></script>
diff --git a/ui/file_manager/image_loader/piex_loader_unittest.js b/ui/file_manager/image_loader/piex_loader_unittest.js
new file mode 100644
index 0000000..240f31a
--- /dev/null
+++ b/ui/file_manager/image_loader/piex_loader_unittest.js
@@ -0,0 +1,100 @@
+// 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.
+
+chrome.fileManagerPrivate = {
+  isPiexLoaderEnabled: function(callback) {
+    callback(true);
+  }
+};
+
+var MockModule = cr.ui.define('div');
+MockModule.prototype = Object.create(HTMLDivElement.prototype);
+MockModule.prototype.constructor = MockModule;
+
+MockModule.prototype.setBeforeMessageCallback = function(callback) {
+  this.onBeforeMessageCallback_ = callback;
+};
+
+MockModule.prototype.decorate = function() {
+  this.onBeforeMessageCallback_ = null;
+  setTimeout(function() {
+    this.dispatchEvent(new Event('load', {bubbles: true}));
+  }.bind(this));
+};
+
+MockModule.prototype.postMessage = function(message) {
+  setTimeout(function() {
+    this.dispatchEvent(new Event('load', {bubbles: true}));
+    if (this.onBeforeMessageCallback_)
+      this.onBeforeMessageCallback_();
+
+    var e = new CustomEvent('message', {bubbles: true});
+    e.data = {id: message.id, thumbnail: 'thumbnail-data', orientation: 1};
+    this.dispatchEvent(e);
+  }.bind(this));
+};
+
+function testUnloadingAfterTimeout(callback) {
+  var loadCount = 0;
+  var unloadCount = 0;
+
+  var unloadPromiseFulfill = null;
+  var unloadPromise = new Promise(function(onFulfill, onReject) {
+    unloadPromiseFulfill = onFulfill;
+  });
+
+  var mockModule;
+  var loader = new PiexLoader(
+      function() {
+        loadCount++;
+        mockModule = new MockModule();
+        mockModule.setBeforeMessageCallback(function() {
+          // Simulate slow NaCl module response taking more than the idle
+          // timeout.
+          loader.simulateIdleTimeoutPassedForTests();
+        });
+        return mockModule;
+      },
+      function(module) {
+        unloadCount++;
+        unloadPromiseFulfill();
+      },
+      60 * 1000);
+
+  reportPromise(
+      Promise.all([
+        loader.load('http://foobar/test.raw')
+            .then(function(data) {
+              assertEquals(0, data.id);
+              assertEquals('thumbnail-data', data.thumbnail);
+              assertEquals(0, unloadCount);
+              assertEquals(1, loadCount);
+              return loader.load('http://foobar/another.raw')
+            })
+            .then(function(data) {
+              // The NaCl module is not unloaded, as the next request came
+              // before the idling timeout passed.
+              assertEquals(1, data.id);
+              assertEquals('thumbnail-data', data.thumbnail);
+              assertEquals(0, unloadCount);
+              assertEquals(1, loadCount);
+            })
+            .then(function() {
+              // Simulate idling while no request are in progress. It should
+              // unload the NaCl module.
+              loader.simulateIdleTimeoutPassedForTests();
+              assertEquals(1, unloadCount);
+              return loader.load('http://foobar/chocolate.raw')
+            })
+            .then(function(data) {
+              // Following requests should reload the NaCl module.
+              assertEquals(2, data.id);
+              assertEquals('thumbnail-data', data.thumbnail);
+              assertEquals(1, unloadCount);
+              assertEquals(2, loadCount);
+            }),
+        unloadPromise
+      ]),
+      callback);
+};