diff --git a/.gitignore b/.gitignore
index 42847de..d12ac93b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -439,6 +439,7 @@
 /third_party/retrolambda/*.jar
 /third_party/robolectric/lib/*.jar
 /third_party/robolectric/robolectric
+/third_party/scan-build/src
 /third_party/scons-2.0.1
 /third_party/sfntly/src
 /third_party/shaderc/src
diff --git a/.gn b/.gn
index 264ffac..be1fb72 100644
--- a/.gn
+++ b/.gn
@@ -31,8 +31,10 @@
     "//third_party/WebKit/Source/core/streams/CountQueuingStrategy.js",
     "//third_party/WebKit/Source/core/streams/ReadableStream.js",
   ]
-  v8_experimental_extra_library_files =
-      [ "//third_party/WebKit/Source/core/streams/WritableStream.js" ]
+  v8_experimental_extra_library_files = [
+    "//third_party/WebKit/Source/core/streams/ReadableStreamExperimentalPipeTo.js",
+    "//third_party/WebKit/Source/core/streams/WritableStream.js",
+  ]
   v8_enable_inspector = true
   v8_enable_gdbjit = false
   v8_imminent_deprecation_warnings = false
diff --git a/DEPS b/DEPS
index 23ba0d55..b7ac0c8 100644
--- a/DEPS
+++ b/DEPS
@@ -40,11 +40,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': 'd6016013bdf843013f7fb8648fc5a64ce7e77005',
+  'skia_revision': '964dec3948721808491b21b4ff4ff41a466443ec',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'v8_revision': 'f1c62827c0ce39bdef8c4e6dc7b5dc4df5397dd6',
+  'v8_revision': '9b59b4b58270e9f5009b124e450cca2bd95ce6c7',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling swarming_client
   # and whatever else without interference from each other.
@@ -64,7 +64,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
-  'pdfium_revision': '5c1673db6deae2e1858c4ffc3b3a0b79901dd827',
+  'pdfium_revision': '98909bf9f458614abc1bb7f4df34a319a1d5ce3f',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling openmax_dl
   # and whatever else without interference from each other.
@@ -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' + '@' + 'd68fcc42256f0f6483d562aa69531091560ff9f2', # commit position 16134
+    Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + 'eed2ae257f91a209b6fbe313903aec83250a6a63', # commit position 16296
 
   'src/third_party/openmax_dl':
     Var('chromium_git') + '/external/webrtc/deps/third_party/openmax.git' + '@' +  Var('openmax_dl_revision'),
diff --git a/base/BUILD.gn b/base/BUILD.gn
index 7f46e71..fa5e369d 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -149,8 +149,6 @@
     "allocator/allocator_check.h",
     "allocator/allocator_extension.cc",
     "allocator/allocator_extension.h",
-    "allocator/allocator_interception_mac.h",
-    "allocator/allocator_interception_mac.mm",
     "allocator/allocator_shim.h",
     "allocator/oom.h",
     "android/animation_frame_time_histogram.cc",
diff --git a/base/allocator/allocator_interception_mac.h b/base/allocator/allocator_interception_mac.h
deleted file mode 100644
index 87cbf489..0000000
--- a/base/allocator/allocator_interception_mac.h
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_ALLOCATOR_ALLOCATOR_INTERCEPTION_MAC_H_
-#define BASE_ALLOCATOR_ALLOCATOR_INTERCEPTION_MAC_H_
-
-#include <malloc/malloc.h>
-#include <stddef.h>
-
-#include "third_party/apple_apsl/malloc.h"
-
-namespace base {
-namespace allocator {
-
-typedef void* (*malloc_type)(struct _malloc_zone_t* zone, size_t size);
-typedef void* (*calloc_type)(struct _malloc_zone_t* zone,
-                             size_t num_items,
-                             size_t size);
-typedef void* (*valloc_type)(struct _malloc_zone_t* zone, size_t size);
-typedef void (*free_type)(struct _malloc_zone_t* zone, void* ptr);
-typedef void* (*realloc_type)(struct _malloc_zone_t* zone,
-                              void* ptr,
-                              size_t size);
-typedef void* (*memalign_type)(struct _malloc_zone_t* zone,
-                               size_t alignment,
-                               size_t size);
-
-struct MallocZoneFunctions {
-  malloc_type malloc = nullptr;
-  calloc_type calloc = nullptr;
-  valloc_type valloc = nullptr;
-  free_type free = nullptr;
-  realloc_type realloc = nullptr;
-  memalign_type memalign = nullptr;
-};
-
-// Saves the function pointers currently used by |zone| into |functions|.
-void StoreZoneFunctions(ChromeMallocZone* zone, MallocZoneFunctions* functions);
-
-// Updates the malloc zone to use the functions specified by |functions|.
-void ReplaceZoneFunctions(ChromeMallocZone* zone,
-                          const MallocZoneFunctions* functions);
-
-// Calls the original implementation of malloc/calloc prior to interception.
-bool UncheckedMallocMac(size_t size, void** result);
-bool UncheckedCallocMac(size_t num_items, size_t size, void** result);
-
-// Intercepts calls to default and purgeable malloc zones. Intercepts Core
-// Foundation and Objective-C allocations.
-void InterceptAllocationsMac();
-}  // namespace allocator
-}  // namespace base
-
-#endif  // BASE_ALLOCATOR_ALLOCATOR_INTERCEPTION_MAC_H_
diff --git a/base/allocator/allocator_interception_mac.mm b/base/allocator/allocator_interception_mac.mm
deleted file mode 100644
index 941c5b4a..0000000
--- a/base/allocator/allocator_interception_mac.mm
+++ /dev/null
@@ -1,471 +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.
-
-// This file contains all the logic necessary to intercept allocations on
-// macOS. "malloc zones" are an abstraction that allows the process to intercept
-// all malloc-related functions.  There is no good mechanism [short of
-// interposition] to determine new malloc zones are added, so there's no clean
-// mechanism to intercept all malloc zones. This file contains logic to
-// intercept the default and purgeable zones, which always exist. A cursory
-// review of Chrome seems to imply that non-default zones are almost never used.
-//
-// This file also contains logic to intercept Core Foundation and Objective-C
-// allocations. The implementations forward to the default malloc zone, so the
-// only reason to intercept these calls is to re-label OOM crashes with slightly
-// more details.
-
-#include "base/allocator/allocator_interception_mac.h"
-
-#include <CoreFoundation/CoreFoundation.h>
-#import <Foundation/Foundation.h>
-#include <errno.h>
-#include <mach/mach.h>
-#include <mach/mach_vm.h>
-#import <objc/runtime.h>
-#include <stddef.h>
-
-#include <new>
-
-#include "base/logging.h"
-#include "base/mac/mac_util.h"
-#include "base/mac/mach_logging.h"
-#include "base/process/memory.h"
-#include "base/scoped_clear_errno.h"
-#include "build/build_config.h"
-#include "third_party/apple_apsl/CFBase.h"
-
-namespace base {
-namespace allocator {
-
-namespace {
-
-bool g_oom_killer_enabled;
-
-#if !defined(ADDRESS_SANITIZER)
-
-// Starting with Mac OS X 10.7, the zone allocators set up by the system are
-// read-only, to prevent them from being overwritten in an attack. However,
-// blindly unprotecting and reprotecting the zone allocators fails with
-// GuardMalloc because GuardMalloc sets up its zone allocator using a block of
-// memory in its bss. Explicit saving/restoring of the protection is required.
-//
-// This function takes a pointer to a malloc zone, de-protects it if necessary,
-// and returns (in the out parameters) a region of memory (if any) to be
-// re-protected when modifications are complete. This approach assumes that
-// there is no contention for the protection of this memory.
-void DeprotectMallocZone(ChromeMallocZone* default_zone,
-                         mach_vm_address_t* reprotection_start,
-                         mach_vm_size_t* reprotection_length,
-                         vm_prot_t* reprotection_value) {
-  mach_port_t unused;
-  *reprotection_start = reinterpret_cast<mach_vm_address_t>(default_zone);
-  struct vm_region_basic_info_64 info;
-  mach_msg_type_number_t count = VM_REGION_BASIC_INFO_COUNT_64;
-  kern_return_t result = mach_vm_region(
-      mach_task_self(), reprotection_start, reprotection_length,
-      VM_REGION_BASIC_INFO_64, reinterpret_cast<vm_region_info_t>(&info),
-      &count, &unused);
-  MACH_CHECK(result == KERN_SUCCESS, result) << "mach_vm_region";
-
-  // The kernel always returns a null object for VM_REGION_BASIC_INFO_64, but
-  // balance it with a deallocate in case this ever changes. See 10.9.2
-  // xnu-2422.90.20/osfmk/vm/vm_map.c vm_map_region.
-  mach_port_deallocate(mach_task_self(), unused);
-
-  // Does the region fully enclose the zone pointers? Possibly unwarranted
-  // simplification used: using the size of a full version 8 malloc zone rather
-  // than the actual smaller size if the passed-in zone is not version 8.
-  CHECK(*reprotection_start <=
-        reinterpret_cast<mach_vm_address_t>(default_zone));
-  mach_vm_size_t zone_offset =
-      reinterpret_cast<mach_vm_size_t>(default_zone) -
-      reinterpret_cast<mach_vm_size_t>(*reprotection_start);
-  CHECK(zone_offset + sizeof(ChromeMallocZone) <= *reprotection_length);
-
-  if (info.protection & VM_PROT_WRITE) {
-    // No change needed; the zone is already writable.
-    *reprotection_start = 0;
-    *reprotection_length = 0;
-    *reprotection_value = VM_PROT_NONE;
-  } else {
-    *reprotection_value = info.protection;
-    result = mach_vm_protect(mach_task_self(), *reprotection_start,
-                             *reprotection_length, false,
-                             info.protection | VM_PROT_WRITE);
-    MACH_CHECK(result == KERN_SUCCESS, result) << "mach_vm_protect";
-  }
-}
-
-MallocZoneFunctions g_old_zone;
-MallocZoneFunctions g_old_purgeable_zone;
-
-void* oom_killer_malloc(struct _malloc_zone_t* zone, size_t size) {
-  void* result = g_old_zone.malloc(zone, size);
-  if (!result && size)
-    TerminateBecauseOutOfMemory(size);
-  return result;
-}
-
-void* oom_killer_calloc(struct _malloc_zone_t* zone,
-                        size_t num_items,
-                        size_t size) {
-  void* result = g_old_zone.calloc(zone, num_items, size);
-  if (!result && num_items && size)
-    TerminateBecauseOutOfMemory(num_items * size);
-  return result;
-}
-
-void* oom_killer_valloc(struct _malloc_zone_t* zone, size_t size) {
-  void* result = g_old_zone.valloc(zone, size);
-  if (!result && size)
-    TerminateBecauseOutOfMemory(size);
-  return result;
-}
-
-void oom_killer_free(struct _malloc_zone_t* zone, void* ptr) {
-  g_old_zone.free(zone, ptr);
-}
-
-void* oom_killer_realloc(struct _malloc_zone_t* zone, void* ptr, size_t size) {
-  void* result = g_old_zone.realloc(zone, ptr, size);
-  if (!result && size)
-    TerminateBecauseOutOfMemory(size);
-  return result;
-}
-
-void* oom_killer_memalign(struct _malloc_zone_t* zone,
-                          size_t alignment,
-                          size_t size) {
-  void* result = g_old_zone.memalign(zone, alignment, size);
-  // Only die if posix_memalign would have returned ENOMEM, since there are
-  // other reasons why NULL might be returned (see
-  // http://opensource.apple.com/source/Libc/Libc-583/gen/malloc.c ).
-  if (!result && size && alignment >= sizeof(void*) &&
-      (alignment & (alignment - 1)) == 0) {
-    TerminateBecauseOutOfMemory(size);
-  }
-  return result;
-}
-
-void* oom_killer_malloc_purgeable(struct _malloc_zone_t* zone, size_t size) {
-  void* result = g_old_purgeable_zone.malloc(zone, size);
-  if (!result && size)
-    TerminateBecauseOutOfMemory(size);
-  return result;
-}
-
-void* oom_killer_calloc_purgeable(struct _malloc_zone_t* zone,
-                                  size_t num_items,
-                                  size_t size) {
-  void* result = g_old_purgeable_zone.calloc(zone, num_items, size);
-  if (!result && num_items && size)
-    TerminateBecauseOutOfMemory(num_items * size);
-  return result;
-}
-
-void* oom_killer_valloc_purgeable(struct _malloc_zone_t* zone, size_t size) {
-  void* result = g_old_purgeable_zone.valloc(zone, size);
-  if (!result && size)
-    TerminateBecauseOutOfMemory(size);
-  return result;
-}
-
-void oom_killer_free_purgeable(struct _malloc_zone_t* zone, void* ptr) {
-  g_old_purgeable_zone.free(zone, ptr);
-}
-
-void* oom_killer_realloc_purgeable(struct _malloc_zone_t* zone,
-                                   void* ptr,
-                                   size_t size) {
-  void* result = g_old_purgeable_zone.realloc(zone, ptr, size);
-  if (!result && size)
-    TerminateBecauseOutOfMemory(size);
-  return result;
-}
-
-void* oom_killer_memalign_purgeable(struct _malloc_zone_t* zone,
-                                    size_t alignment,
-                                    size_t size) {
-  void* result = g_old_purgeable_zone.memalign(zone, alignment, size);
-  // Only die if posix_memalign would have returned ENOMEM, since there are
-  // other reasons why NULL might be returned (see
-  // http://opensource.apple.com/source/Libc/Libc-583/gen/malloc.c ).
-  if (!result && size && alignment >= sizeof(void*) &&
-      (alignment & (alignment - 1)) == 0) {
-    TerminateBecauseOutOfMemory(size);
-  }
-  return result;
-}
-
-#endif  // !defined(ADDRESS_SANITIZER)
-
-// === C++ operator new ===
-
-void oom_killer_new() {
-  TerminateBecauseOutOfMemory(0);
-}
-
-#if !defined(ADDRESS_SANITIZER)
-
-// === Core Foundation CFAllocators ===
-
-bool CanGetContextForCFAllocator() {
-  return !base::mac::IsOSLaterThan10_12_DontCallThis();
-}
-
-CFAllocatorContext* ContextForCFAllocator(CFAllocatorRef allocator) {
-  ChromeCFAllocatorLions* our_allocator = const_cast<ChromeCFAllocatorLions*>(
-      reinterpret_cast<const ChromeCFAllocatorLions*>(allocator));
-  return &our_allocator->_context;
-}
-
-CFAllocatorAllocateCallBack g_old_cfallocator_system_default;
-CFAllocatorAllocateCallBack g_old_cfallocator_malloc;
-CFAllocatorAllocateCallBack g_old_cfallocator_malloc_zone;
-
-void* oom_killer_cfallocator_system_default(CFIndex alloc_size,
-                                            CFOptionFlags hint,
-                                            void* info) {
-  void* result = g_old_cfallocator_system_default(alloc_size, hint, info);
-  if (!result)
-    TerminateBecauseOutOfMemory(alloc_size);
-  return result;
-}
-
-void* oom_killer_cfallocator_malloc(CFIndex alloc_size,
-                                    CFOptionFlags hint,
-                                    void* info) {
-  void* result = g_old_cfallocator_malloc(alloc_size, hint, info);
-  if (!result)
-    TerminateBecauseOutOfMemory(alloc_size);
-  return result;
-}
-
-void* oom_killer_cfallocator_malloc_zone(CFIndex alloc_size,
-                                         CFOptionFlags hint,
-                                         void* info) {
-  void* result = g_old_cfallocator_malloc_zone(alloc_size, hint, info);
-  if (!result)
-    TerminateBecauseOutOfMemory(alloc_size);
-  return result;
-}
-
-#endif  // !defined(ADDRESS_SANITIZER)
-
-// === Cocoa NSObject allocation ===
-
-typedef id (*allocWithZone_t)(id, SEL, NSZone*);
-allocWithZone_t g_old_allocWithZone;
-
-id oom_killer_allocWithZone(id self, SEL _cmd, NSZone* zone) {
-  id result = g_old_allocWithZone(self, _cmd, zone);
-  if (!result)
-    TerminateBecauseOutOfMemory(0);
-  return result;
-}
-
-}  // namespace
-
-bool UncheckedMallocMac(size_t size, void** result) {
-#if defined(ADDRESS_SANITIZER)
-  *result = malloc(size);
-#else
-  if (g_old_zone.malloc) {
-    *result = g_old_zone.malloc(malloc_default_zone(), size);
-  } else {
-    *result = malloc(size);
-  }
-#endif  // defined(ADDRESS_SANITIZER)
-
-  return *result != NULL;
-}
-
-bool UncheckedCallocMac(size_t num_items, size_t size, void** result) {
-#if defined(ADDRESS_SANITIZER)
-  *result = calloc(num_items, size);
-#else
-  if (g_old_zone.calloc) {
-    *result = g_old_zone.calloc(malloc_default_zone(), num_items, size);
-  } else {
-    *result = calloc(num_items, size);
-  }
-#endif  // defined(ADDRESS_SANITIZER)
-
-  return *result != NULL;
-}
-
-void StoreZoneFunctions(ChromeMallocZone* zone,
-                        MallocZoneFunctions* functions) {
-  functions->malloc = zone->malloc;
-  functions->calloc = zone->calloc;
-  functions->valloc = zone->valloc;
-  functions->free = zone->free;
-  functions->realloc = zone->realloc;
-  CHECK(functions->malloc && functions->calloc && functions->valloc &&
-        functions->free && functions->realloc);
-
-  if (zone->version >= 5) {
-    functions->memalign = zone->memalign;
-    CHECK(functions->memalign);
-  }
-}
-
-void ReplaceZoneFunctions(ChromeMallocZone* zone,
-                          const MallocZoneFunctions* functions) {
-  // Remove protection.
-  mach_vm_address_t reprotection_start = 0;
-  mach_vm_size_t reprotection_length = 0;
-  vm_prot_t reprotection_value = VM_PROT_NONE;
-  DeprotectMallocZone(zone, &reprotection_start, &reprotection_length,
-                      &reprotection_value);
-
-  zone->malloc = functions->malloc;
-  zone->calloc = functions->calloc;
-  zone->valloc = functions->valloc;
-  zone->free = functions->free;
-  zone->realloc = functions->realloc;
-  if (zone->version >= 5) {
-    zone->memalign = functions->memalign;
-  }
-
-  // Restore protection if it was active.
-  if (reprotection_start) {
-    kern_return_t result =
-        mach_vm_protect(mach_task_self(), reprotection_start,
-                        reprotection_length, false, reprotection_value);
-    MACH_CHECK(result == KERN_SUCCESS, result) << "mach_vm_protect";
-  }
-}
-
-void InterceptAllocationsMac() {
-  if (g_oom_killer_enabled)
-    return;
-
-  g_oom_killer_enabled = true;
-
-// === C malloc/calloc/valloc/realloc/posix_memalign ===
-
-// This approach is not perfect, as requests for amounts of memory larger than
-// MALLOC_ABSOLUTE_MAX_SIZE (currently SIZE_T_MAX - (2 * PAGE_SIZE)) will
-// still fail with a NULL rather than dying (see
-// http://opensource.apple.com/source/Libc/Libc-583/gen/malloc.c for details).
-// Unfortunately, it's the best we can do. Also note that this does not affect
-// allocations from non-default zones.
-
-#if !defined(ADDRESS_SANITIZER)
-  // Don't do anything special on OOM for the malloc zones replaced by
-  // AddressSanitizer, as modifying or protecting them may not work correctly.
-  ChromeMallocZone* default_zone =
-      reinterpret_cast<ChromeMallocZone*>(malloc_default_zone());
-  StoreZoneFunctions(default_zone, &g_old_zone);
-  MallocZoneFunctions new_functions;
-  new_functions.malloc = oom_killer_malloc;
-  new_functions.calloc = oom_killer_calloc;
-  new_functions.valloc = oom_killer_valloc;
-  new_functions.free = oom_killer_free;
-  new_functions.realloc = oom_killer_realloc;
-  new_functions.memalign = oom_killer_memalign;
-  ReplaceZoneFunctions(default_zone, &new_functions);
-
-  ChromeMallocZone* purgeable_zone =
-      reinterpret_cast<ChromeMallocZone*>(malloc_default_purgeable_zone());
-  if (purgeable_zone) {
-    StoreZoneFunctions(purgeable_zone, &g_old_purgeable_zone);
-    MallocZoneFunctions new_functions;
-    new_functions.malloc = oom_killer_malloc_purgeable;
-    new_functions.calloc = oom_killer_calloc_purgeable;
-    new_functions.valloc = oom_killer_valloc_purgeable;
-    new_functions.free = oom_killer_free_purgeable;
-    new_functions.realloc = oom_killer_realloc_purgeable;
-    new_functions.memalign = oom_killer_memalign_purgeable;
-    ReplaceZoneFunctions(purgeable_zone, &new_functions);
-  }
-#endif
-
-  // === C malloc_zone_batch_malloc ===
-
-  // batch_malloc is omitted because the default malloc zone's implementation
-  // only supports batch_malloc for "tiny" allocations from the free list. It
-  // will fail for allocations larger than "tiny", and will only allocate as
-  // many blocks as it's able to from the free list. These factors mean that it
-  // can return less than the requested memory even in a non-out-of-memory
-  // situation. There's no good way to detect whether a batch_malloc failure is
-  // due to these other factors, or due to genuine memory or address space
-  // exhaustion. The fact that it only allocates space from the "tiny" free list
-  // means that it's likely that a failure will not be due to memory exhaustion.
-  // Similarly, these constraints on batch_malloc mean that callers must always
-  // be expecting to receive less memory than was requested, even in situations
-  // where memory pressure is not a concern. Finally, the only public interface
-  // to batch_malloc is malloc_zone_batch_malloc, which is specific to the
-  // system's malloc implementation. It's unlikely that anyone's even heard of
-  // it.
-
-  // === C++ operator new ===
-
-  // Yes, operator new does call through to malloc, but this will catch failures
-  // that our imperfect handling of malloc cannot.
-
-  std::set_new_handler(oom_killer_new);
-
-#ifndef ADDRESS_SANITIZER
-  // === Core Foundation CFAllocators ===
-
-  // This will not catch allocation done by custom allocators, but will catch
-  // all allocation done by system-provided ones.
-
-  CHECK(!g_old_cfallocator_system_default && !g_old_cfallocator_malloc &&
-        !g_old_cfallocator_malloc_zone)
-      << "Old allocators unexpectedly non-null";
-
-  bool cf_allocator_internals_known = CanGetContextForCFAllocator();
-
-  if (cf_allocator_internals_known) {
-    CFAllocatorContext* context =
-        ContextForCFAllocator(kCFAllocatorSystemDefault);
-    CHECK(context) << "Failed to get context for kCFAllocatorSystemDefault.";
-    g_old_cfallocator_system_default = context->allocate;
-    CHECK(g_old_cfallocator_system_default)
-        << "Failed to get kCFAllocatorSystemDefault allocation function.";
-    context->allocate = oom_killer_cfallocator_system_default;
-
-    context = ContextForCFAllocator(kCFAllocatorMalloc);
-    CHECK(context) << "Failed to get context for kCFAllocatorMalloc.";
-    g_old_cfallocator_malloc = context->allocate;
-    CHECK(g_old_cfallocator_malloc)
-        << "Failed to get kCFAllocatorMalloc allocation function.";
-    context->allocate = oom_killer_cfallocator_malloc;
-
-    context = ContextForCFAllocator(kCFAllocatorMallocZone);
-    CHECK(context) << "Failed to get context for kCFAllocatorMallocZone.";
-    g_old_cfallocator_malloc_zone = context->allocate;
-    CHECK(g_old_cfallocator_malloc_zone)
-        << "Failed to get kCFAllocatorMallocZone allocation function.";
-    context->allocate = oom_killer_cfallocator_malloc_zone;
-  } else {
-    DLOG(WARNING) << "Internals of CFAllocator not known; out-of-memory "
-                     "failures via CFAllocator will not result in termination. "
-                     "http://crbug.com/45650";
-  }
-#endif
-
-  // === Cocoa NSObject allocation ===
-
-  // Note that both +[NSObject new] and +[NSObject alloc] call through to
-  // +[NSObject allocWithZone:].
-
-  CHECK(!g_old_allocWithZone) << "Old allocator unexpectedly non-null";
-
-  Class nsobject_class = [NSObject class];
-  Method orig_method =
-      class_getClassMethod(nsobject_class, @selector(allocWithZone:));
-  g_old_allocWithZone =
-      reinterpret_cast<allocWithZone_t>(method_getImplementation(orig_method));
-  CHECK(g_old_allocWithZone)
-      << "Failed to get allocWithZone allocation function.";
-  method_setImplementation(orig_method,
-                           reinterpret_cast<IMP>(oom_killer_allocWithZone));
-}
-
-}  // namespace allocator
-}  // namespace base
diff --git a/base/debug/activity_analyzer.cc b/base/debug/activity_analyzer.cc
index 6a483f3..7c421e9 100644
--- a/base/debug/activity_analyzer.cc
+++ b/base/debug/activity_analyzer.cc
@@ -31,7 +31,7 @@
     : ThreadActivityAnalyzer(allocator->GetAsArray<char>(
                                  reference,
                                  GlobalActivityTracker::kTypeIdActivityTracker,
-                                 1),
+                                 PersistentMemoryAllocator::kSizeAny),
                              allocator->GetAllocSize(reference)) {}
 
 ThreadActivityAnalyzer::~ThreadActivityAnalyzer() {}
@@ -159,6 +159,26 @@
   return messages;
 }
 
+std::vector<GlobalActivityTracker::ModuleInfo>
+GlobalActivityAnalyzer::GetModules() {
+  std::vector<GlobalActivityTracker::ModuleInfo> modules;
+
+  PersistentMemoryAllocator::Iterator iter(allocator_.get());
+  const GlobalActivityTracker::ModuleInfoRecord* record;
+  while (
+      (record =
+           iter.GetNextOfObject<GlobalActivityTracker::ModuleInfoRecord>()) !=
+      nullptr) {
+    GlobalActivityTracker::ModuleInfo info;
+    if (record->DecodeTo(&info, allocator_->GetAllocSize(
+                                    allocator_->GetAsReference(record)))) {
+      modules.push_back(std::move(info));
+    }
+  }
+
+  return modules;
+}
+
 GlobalActivityAnalyzer::ProgramLocation
 GlobalActivityAnalyzer::GetProgramLocationFromAddress(uint64_t address) {
   // TODO(bcwhite): Implement this.
diff --git a/base/debug/activity_analyzer.h b/base/debug/activity_analyzer.h
index 48efd85..95df69fd 100644
--- a/base/debug/activity_analyzer.h
+++ b/base/debug/activity_analyzer.h
@@ -155,6 +155,9 @@
   // Gets all log messages stored within.
   std::vector<std::string> GetLogMessages();
 
+  // Gets all the known modules.
+  std::vector<GlobalActivityTracker::ModuleInfo> GetModules();
+
   // Gets the corresponding "program location" for a given "program counter".
   // This will return {0,0} if no mapping could be found.
   ProgramLocation GetProgramLocationFromAddress(uint64_t address);
diff --git a/base/debug/activity_analyzer_unittest.cc b/base/debug/activity_analyzer_unittest.cc
index 08ed85c..7f1bce9 100644
--- a/base/debug/activity_analyzer_unittest.cc
+++ b/base/debug/activity_analyzer_unittest.cc
@@ -321,6 +321,82 @@
   EXPECT_EQ(strlen(string2), snapshot.at("sref").GetStringReference().size());
 }
 
+TEST_F(ActivityAnalyzerTest, GlobalModulesTest) {
+  GlobalActivityTracker::CreateWithLocalMemory(kMemorySize, 0, "", 3);
+
+  PersistentMemoryAllocator* allocator =
+      GlobalActivityTracker::Get()->allocator();
+  GlobalActivityAnalyzer global_analyzer(MakeUnique<PersistentMemoryAllocator>(
+      const_cast<void*>(allocator->data()), allocator->size(), 0, 0, "", true));
+
+  GlobalActivityTracker::ModuleInfo info1;
+  info1.is_loaded = true;
+  info1.address = 0x12345678;
+  info1.load_time = 1111;
+  info1.size = 0xABCDEF;
+  info1.timestamp = 111;
+  info1.age = 11;
+  info1.identifier[0] = 1;
+  info1.file = "anything";
+  info1.debug_file = "elsewhere";
+
+  GlobalActivityTracker::Get()->RecordModuleInfo(info1);
+  std::vector<GlobalActivityTracker::ModuleInfo> modules1;
+  modules1 = global_analyzer.GetModules();
+  ASSERT_EQ(1U, modules1.size());
+  GlobalActivityTracker::ModuleInfo& stored1a = modules1[0];
+  EXPECT_EQ(info1.is_loaded, stored1a.is_loaded);
+  EXPECT_EQ(info1.address, stored1a.address);
+  EXPECT_NE(info1.load_time, stored1a.load_time);
+  EXPECT_EQ(info1.size, stored1a.size);
+  EXPECT_EQ(info1.timestamp, stored1a.timestamp);
+  EXPECT_EQ(info1.age, stored1a.age);
+  EXPECT_EQ(info1.identifier[0], stored1a.identifier[0]);
+  EXPECT_EQ(info1.file, stored1a.file);
+  EXPECT_EQ(info1.debug_file, stored1a.debug_file);
+
+  info1.is_loaded = false;
+  GlobalActivityTracker::Get()->RecordModuleInfo(info1);
+  modules1 = global_analyzer.GetModules();
+  ASSERT_EQ(1U, modules1.size());
+  GlobalActivityTracker::ModuleInfo& stored1b = modules1[0];
+  EXPECT_EQ(info1.is_loaded, stored1b.is_loaded);
+  EXPECT_EQ(info1.address, stored1b.address);
+  EXPECT_NE(info1.load_time, stored1b.load_time);
+  EXPECT_EQ(info1.size, stored1b.size);
+  EXPECT_EQ(info1.timestamp, stored1b.timestamp);
+  EXPECT_EQ(info1.age, stored1b.age);
+  EXPECT_EQ(info1.identifier[0], stored1b.identifier[0]);
+  EXPECT_EQ(info1.file, stored1b.file);
+  EXPECT_EQ(info1.debug_file, stored1b.debug_file);
+
+  GlobalActivityTracker::ModuleInfo info2;
+  info2.is_loaded = true;
+  info2.address = 0x87654321;
+  info2.load_time = 2222;
+  info2.size = 0xFEDCBA;
+  info2.timestamp = 222;
+  info2.age = 22;
+  info2.identifier[0] = 2;
+  info2.file = "nothing";
+  info2.debug_file = "farewell";
+
+  GlobalActivityTracker::Get()->RecordModuleInfo(info2);
+  std::vector<GlobalActivityTracker::ModuleInfo> modules2;
+  modules2 = global_analyzer.GetModules();
+  ASSERT_EQ(2U, modules2.size());
+  GlobalActivityTracker::ModuleInfo& stored2 = modules2[1];
+  EXPECT_EQ(info2.is_loaded, stored2.is_loaded);
+  EXPECT_EQ(info2.address, stored2.address);
+  EXPECT_NE(info2.load_time, stored2.load_time);
+  EXPECT_EQ(info2.size, stored2.size);
+  EXPECT_EQ(info2.timestamp, stored2.timestamp);
+  EXPECT_EQ(info2.age, stored2.age);
+  EXPECT_EQ(info2.identifier[0], stored2.identifier[0]);
+  EXPECT_EQ(info2.file, stored2.file);
+  EXPECT_EQ(info2.debug_file, stored2.debug_file);
+}
+
 TEST_F(ActivityAnalyzerTest, GlobalLogMessages) {
   GlobalActivityTracker::CreateWithLocalMemory(kMemorySize, 0, "", 3);
 
diff --git a/base/debug/activity_tracker.cc b/base/debug/activity_tracker.cc
index c728fa05..deb1717 100644
--- a/base/debug/activity_tracker.cc
+++ b/base/debug/activity_tracker.cc
@@ -17,6 +17,7 @@
 #include "base/metrics/field_trial.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/pending_task.h"
+#include "base/pickle.h"
 #include "base/process/process.h"
 #include "base/process/process_handle.h"
 #include "base/stl_util.h"
@@ -44,6 +45,9 @@
 const size_t kMaxUserDataNameLength =
     static_cast<size_t>(std::numeric_limits<uint8_t>::max());
 
+// A constant used to indicate that module information is changing.
+const uint32_t kModuleInformationChanging = 0x80000000;
+
 union ThreadRef {
   int64_t as_id;
 #if defined(OS_WIN)
@@ -478,6 +482,10 @@
 // the very first time the thread is seen. All fields must be of exact sizes
 // so there is no issue moving between 32 and 64-bit builds.
 struct ThreadActivityTracker::Header {
+  // Defined in .h for analyzer access. Increment this if structure changes!
+  static constexpr uint32_t kPersistentTypeId =
+      GlobalActivityTracker::kTypeIdActivityTracker;
+
   // Expected size for 32/64-bit check.
   static constexpr size_t kExpectedInstanceSize = 80;
 
@@ -894,6 +902,119 @@
 
 GlobalActivityTracker* GlobalActivityTracker::g_tracker_ = nullptr;
 
+GlobalActivityTracker::ModuleInfo::ModuleInfo() {}
+GlobalActivityTracker::ModuleInfo::ModuleInfo(ModuleInfo&& rhs) = default;
+GlobalActivityTracker::ModuleInfo::ModuleInfo(const ModuleInfo& rhs) = default;
+GlobalActivityTracker::ModuleInfo::~ModuleInfo() {}
+
+GlobalActivityTracker::ModuleInfo& GlobalActivityTracker::ModuleInfo::operator=(
+    ModuleInfo&& rhs) = default;
+GlobalActivityTracker::ModuleInfo& GlobalActivityTracker::ModuleInfo::operator=(
+    const ModuleInfo& rhs) = default;
+
+GlobalActivityTracker::ModuleInfoRecord::ModuleInfoRecord() {}
+GlobalActivityTracker::ModuleInfoRecord::~ModuleInfoRecord() {}
+
+bool GlobalActivityTracker::ModuleInfoRecord::DecodeTo(
+    GlobalActivityTracker::ModuleInfo* info,
+    size_t record_size) const {
+  // Get the current "changes" indicator, acquiring all the other values.
+  uint32_t current_changes = changes.load(std::memory_order_acquire);
+
+  // Copy out the dynamic information.
+  info->is_loaded = loaded != 0;
+  info->address = static_cast<uintptr_t>(address);
+  info->load_time = load_time;
+
+  // Check to make sure no information changed while being read. A "seq-cst"
+  // operation is expensive but is only done during analysis and it's the only
+  // way to ensure this occurs after all the accesses above. If changes did
+  // occur then return a "not loaded" result so that |size| and |address|
+  // aren't expected to be accurate.
+  if ((current_changes & kModuleInformationChanging) != 0 ||
+      changes.load(std::memory_order_seq_cst) != current_changes) {
+    info->is_loaded = false;
+  }
+
+  // Copy out the static information. These never change so don't have to be
+  // protected by the atomic |current_changes| operations.
+  info->size = static_cast<size_t>(size);
+  info->timestamp = timestamp;
+  info->age = age;
+  memcpy(info->identifier, identifier, sizeof(info->identifier));
+
+  if (offsetof(ModuleInfoRecord, pickle) + pickle_size > record_size)
+    return false;
+  Pickle pickler(pickle, pickle_size);
+  PickleIterator iter(pickler);
+  return iter.ReadString(&info->file) && iter.ReadString(&info->debug_file);
+}
+
+bool GlobalActivityTracker::ModuleInfoRecord::EncodeFrom(
+    const GlobalActivityTracker::ModuleInfo& info,
+    size_t record_size) {
+  Pickle pickler;
+  bool okay =
+      pickler.WriteString(info.file) && pickler.WriteString(info.debug_file);
+  if (!okay) {
+    NOTREACHED();
+    return false;
+  }
+  if (offsetof(ModuleInfoRecord, pickle) + pickler.size() > record_size) {
+    NOTREACHED();
+    return false;
+  }
+
+  // These fields never changes and are done before the record is made
+  // iterable so no thread protection is necessary.
+  size = info.size;
+  timestamp = info.timestamp;
+  age = info.age;
+  memcpy(identifier, info.identifier, sizeof(identifier));
+  memcpy(pickle, pickler.data(), pickler.size());
+  pickle_size = pickler.size();
+  changes.store(0, std::memory_order_relaxed);
+
+  // Now set those fields that can change.
+  return UpdateFrom(info);
+}
+
+bool GlobalActivityTracker::ModuleInfoRecord::UpdateFrom(
+    const GlobalActivityTracker::ModuleInfo& info) {
+  // Updates can occur after the record is made visible so make changes atomic.
+  // A "strong" exchange ensures no false failures.
+  uint32_t old_changes = changes.load(std::memory_order_relaxed);
+  uint32_t new_changes = old_changes | kModuleInformationChanging;
+  if ((old_changes & kModuleInformationChanging) != 0 ||
+      !changes.compare_exchange_strong(old_changes, new_changes,
+                                       std::memory_order_acquire,
+                                       std::memory_order_acquire)) {
+    NOTREACHED() << "Multiple sources are updating module information.";
+    return false;
+  }
+
+  loaded = info.is_loaded ? 1 : 0;
+  address = info.address;
+  load_time = Time::Now().ToInternalValue();
+
+  bool success = changes.compare_exchange_strong(new_changes, old_changes + 1,
+                                                 std::memory_order_release,
+                                                 std::memory_order_relaxed);
+  DCHECK(success);
+  return true;
+}
+
+// static
+size_t GlobalActivityTracker::ModuleInfoRecord::EncodedSize(
+    const GlobalActivityTracker::ModuleInfo& info) {
+  PickleSizer sizer;
+  sizer.AddString(info.file);
+  sizer.AddString(info.debug_file);
+
+  return offsetof(ModuleInfoRecord, pickle) + sizeof(Pickle::Header) +
+         sizer.payload_size();
+}
+
 GlobalActivityTracker::ScopedThreadActivity::ScopedThreadActivity(
     const void* program_counter,
     const void* origin,
@@ -1022,13 +1143,8 @@
   // TODO(bcwhite): Review this after major compiler releases.
   DCHECK(mem_reference);
   void* mem_base;
-#if 0  // TODO(bcwhite): Update this for new GetAsObject functionality.
-  mem_base = allocator_->GetAsObject<ThreadActivityTracker::Header>(
-      mem_reference, kTypeIdActivityTracker);
-#else
-  mem_base = allocator_->GetAsArray<char>(mem_reference, kTypeIdActivityTracker,
-                                          PersistentMemoryAllocator::kSizeAny);
-#endif
+  mem_base =
+      allocator_->GetAsObject<ThreadActivityTracker::Header>(mem_reference);
 
   DCHECK(mem_base);
   DCHECK_LE(stack_memory_size_, allocator_->GetAllocSize(mem_reference));
@@ -1066,6 +1182,33 @@
   }
 }
 
+void GlobalActivityTracker::RecordModuleInfo(const ModuleInfo& info) {
+  AutoLock lock(modules_lock_);
+  auto found = modules_.find(info.file);
+  if (found != modules_.end()) {
+    ModuleInfoRecord* record = found->second;
+    DCHECK(record);
+
+    // Update the basic state of module information that has been already
+    // recorded. It is assumed that the string information (identifier,
+    // version, etc.) remain unchanged which means that there's no need
+    // to create a new record to accommodate a possibly longer length.
+    record->UpdateFrom(info);
+    return;
+  }
+
+  size_t required_size = ModuleInfoRecord::EncodedSize(info);
+  ModuleInfoRecord* record =
+      allocator_->AllocateObject<ModuleInfoRecord>(required_size);
+  if (!record)
+    return;
+
+  bool success = record->EncodeFrom(info, required_size);
+  DCHECK(success);
+  allocator_->MakeIterable(record);
+  modules_.insert(std::make_pair(info.file, record));
+}
+
 GlobalActivityTracker::GlobalActivityTracker(
     std::unique_ptr<PersistentMemoryAllocator> allocator,
     int stack_depth)
@@ -1099,8 +1242,7 @@
   DCHECK(!g_tracker_);
   g_tracker_ = this;
 
-  // The global user-data record must be iterable in order to be found by an
-  // analyzer.
+  // The global records must be iterable in order to be found by an analyzer.
   allocator_->MakeIterable(allocator_->GetAsReference(
       user_data_.GetBaseAddress(), kTypeIdGlobalDataRecord));
 }
diff --git a/base/debug/activity_tracker.h b/base/debug/activity_tracker.h
index 62f983b..2d3c2bc7 100644
--- a/base/debug/activity_tracker.h
+++ b/base/debug/activity_tracker.h
@@ -646,6 +646,32 @@
     kTypeIdUserDataRecordFree = ~kTypeIdUserDataRecord,
   };
 
+  // This structure contains information about a loaded module, as shown to
+  // users of the tracker.
+  struct BASE_EXPORT ModuleInfo {
+    ModuleInfo();
+    ModuleInfo(ModuleInfo&& rhs);
+    ModuleInfo(const ModuleInfo& rhs);
+    ~ModuleInfo();
+
+    ModuleInfo& operator=(ModuleInfo&& rhs);
+    ModuleInfo& operator=(const ModuleInfo& rhs);
+
+    // Information about where and when the module was loaded/unloaded.
+    bool is_loaded = false;  // Was the last operation a load or unload?
+    uintptr_t address = 0;   // Address of the last load operation.
+    int64_t load_time = 0;   // Time of last change; set automatically.
+
+    // Information about the module itself. These never change no matter how
+    // many times a module may be loaded and unloaded.
+    size_t size = 0;         // The size of the loaded module.
+    uint32_t timestamp = 0;  // Opaque "timestamp" for the module.
+    uint32_t age = 0;        // Opaque "age" for the module.
+    uint8_t identifier[16];  // Opaque identifier (GUID, etc.) for the module.
+    std::string file;        // The full path to the file. (UTF-8)
+    std::string debug_file;  // The full path to the debug file.
+  };
+
   // This is a thin wrapper around the thread-tracker's ScopedActivity that
   // accesses the global tracker to provide some of the information, notably
   // which thread-tracker to use. It is safe to create even if activity
@@ -749,10 +775,15 @@
   // only store critical messages such as FATAL ones.
   void RecordLogMessage(StringPiece message);
 
+  // Records a module load/unload event. This is safe to call multiple times
+  // even with the same information.
+  void RecordModuleInfo(const ModuleInfo& info);
+
   // Accesses the global data record for storing arbitrary key/value pairs.
   ActivityUserData& user_data() { return user_data_; }
 
  private:
+  friend class GlobalActivityAnalyzer;
   friend class ScopedThreadActivity;
   friend class ActivityTrackerTest;
 
@@ -764,6 +795,51 @@
     kCachedUserDataMemories = 10,
   };
 
+  // State of a module as stored in persistent memory. This supports a single
+  // loading of a module only. If modules are loaded multiple times at
+  // different addresses, only the last will be recorded and an unload will
+  // not revert to the information of any other addresses.
+  struct BASE_EXPORT ModuleInfoRecord {
+    // SHA1(ModuleInfoRecord): Increment this if structure changes!
+    static constexpr uint32_t kPersistentTypeId = 0x05DB5F41 + 1;
+
+    // Expected size for 32/64-bit check by PersistentMemoryAllocator.
+    static constexpr size_t kExpectedInstanceSize = 56;
+
+    // The atomic unfortunately makes this a "complex" class on some compilers
+    // and thus requires an out-of-line constructor & destructor even though
+    // they do nothing.
+    ModuleInfoRecord();
+    ~ModuleInfoRecord();
+
+    uint64_t address;               // The base address of the module.
+    uint64_t load_time;             // Time of last load/unload.
+    uint64_t size;                  // The size of the module in bytes.
+    uint32_t timestamp;             // Opaque timestamp of the module.
+    uint32_t age;                   // Opaque "age" associated with the module.
+    uint8_t identifier[16];         // Opaque identifier for the module.
+    std::atomic<uint32_t> changes;  // Number load/unload actions.
+    uint16_t pickle_size;           // The size of the following pickle.
+    uint8_t loaded;                 // Flag if module is loaded or not.
+    char pickle[1];                 // Other strings; may allocate larger.
+
+    // Decodes/encodes storage structure from more generic info structure.
+    bool DecodeTo(GlobalActivityTracker::ModuleInfo* info,
+                  size_t record_size) const;
+    bool EncodeFrom(const GlobalActivityTracker::ModuleInfo& info,
+                    size_t record_size);
+
+    // Updates the core information without changing the encoded strings. This
+    // is useful when a known module changes state (i.e. new load or unload).
+    bool UpdateFrom(const GlobalActivityTracker::ModuleInfo& info);
+
+    // Determines the required memory size for the encoded storage.
+    static size_t EncodedSize(const GlobalActivityTracker::ModuleInfo& info);
+
+   private:
+    DISALLOW_COPY_AND_ASSIGN(ModuleInfoRecord);
+  };
+
   // A thin wrapper around the main thread-tracker that keeps additional
   // information that the global tracker needs to handle joined threads.
   class ManagedActivityTracker : public ThreadActivityTracker {
@@ -825,6 +901,10 @@
   // be written from the main UI thread.
   ActivityUserData user_data_;
 
+  // A map of global module information, keyed by module path.
+  std::map<const std::string, ModuleInfoRecord*> modules_;
+  base::Lock modules_lock_;
+
   // The active global activity tracker.
   static GlobalActivityTracker* g_tracker_;
 
diff --git a/base/process/memory_mac.mm b/base/process/memory_mac.mm
index 155004dc..4c1b120 100644
--- a/base/process/memory_mac.mm
+++ b/base/process/memory_mac.mm
@@ -4,8 +4,25 @@
 
 #include "base/process/memory.h"
 
-#include "base/allocator/allocator_interception_mac.h"
+#include <CoreFoundation/CoreFoundation.h>
+#import <Foundation/Foundation.h>
+#include <errno.h>
+#include <mach/mach.h>
+#include <mach/mach_vm.h>
+#include <malloc/malloc.h>
+#import <objc/runtime.h>
+#include <stddef.h>
+
+#include <new>
+
+#include "base/lazy_instance.h"
+#include "base/logging.h"
+#include "base/mac/mac_util.h"
+#include "base/mac/mach_logging.h"
+#include "base/scoped_clear_errno.h"
 #include "build/build_config.h"
+#include "third_party/apple_apsl/CFBase.h"
+#include "third_party/apple_apsl/malloc.h"
 
 namespace base {
 
@@ -15,16 +32,521 @@
 #endif
 }
 
+// ------------------------------------------------------------------------
+
+namespace {
+
+bool g_oom_killer_enabled;
+
+#if !defined(ADDRESS_SANITIZER)
+
+// Starting with Mac OS X 10.7, the zone allocators set up by the system are
+// read-only, to prevent them from being overwritten in an attack. However,
+// blindly unprotecting and reprotecting the zone allocators fails with
+// GuardMalloc because GuardMalloc sets up its zone allocator using a block of
+// memory in its bss. Explicit saving/restoring of the protection is required.
+//
+// This function takes a pointer to a malloc zone, de-protects it if necessary,
+// and returns (in the out parameters) a region of memory (if any) to be
+// re-protected when modifications are complete. This approach assumes that
+// there is no contention for the protection of this memory.
+void DeprotectMallocZone(ChromeMallocZone* default_zone,
+                         mach_vm_address_t* reprotection_start,
+                         mach_vm_size_t* reprotection_length,
+                         vm_prot_t* reprotection_value) {
+  mach_port_t unused;
+  *reprotection_start = reinterpret_cast<mach_vm_address_t>(default_zone);
+  struct vm_region_basic_info_64 info;
+  mach_msg_type_number_t count = VM_REGION_BASIC_INFO_COUNT_64;
+  kern_return_t result =
+      mach_vm_region(mach_task_self(),
+                     reprotection_start,
+                     reprotection_length,
+                     VM_REGION_BASIC_INFO_64,
+                     reinterpret_cast<vm_region_info_t>(&info),
+                     &count,
+                     &unused);
+  MACH_CHECK(result == KERN_SUCCESS, result) << "mach_vm_region";
+
+  // The kernel always returns a null object for VM_REGION_BASIC_INFO_64, but
+  // balance it with a deallocate in case this ever changes. See 10.9.2
+  // xnu-2422.90.20/osfmk/vm/vm_map.c vm_map_region.
+  mach_port_deallocate(mach_task_self(), unused);
+
+  // Does the region fully enclose the zone pointers? Possibly unwarranted
+  // simplification used: using the size of a full version 8 malloc zone rather
+  // than the actual smaller size if the passed-in zone is not version 8.
+  CHECK(*reprotection_start <=
+            reinterpret_cast<mach_vm_address_t>(default_zone));
+  mach_vm_size_t zone_offset = reinterpret_cast<mach_vm_size_t>(default_zone) -
+      reinterpret_cast<mach_vm_size_t>(*reprotection_start);
+  CHECK(zone_offset + sizeof(ChromeMallocZone) <= *reprotection_length);
+
+  if (info.protection & VM_PROT_WRITE) {
+    // No change needed; the zone is already writable.
+    *reprotection_start = 0;
+    *reprotection_length = 0;
+    *reprotection_value = VM_PROT_NONE;
+  } else {
+    *reprotection_value = info.protection;
+    result = mach_vm_protect(mach_task_self(),
+                             *reprotection_start,
+                             *reprotection_length,
+                             false,
+                             info.protection | VM_PROT_WRITE);
+    MACH_CHECK(result == KERN_SUCCESS, result) << "mach_vm_protect";
+  }
+}
+
+// === C malloc/calloc/valloc/realloc/posix_memalign ===
+
+typedef void* (*malloc_type)(struct _malloc_zone_t* zone,
+                             size_t size);
+typedef void* (*calloc_type)(struct _malloc_zone_t* zone,
+                             size_t num_items,
+                             size_t size);
+typedef void* (*valloc_type)(struct _malloc_zone_t* zone,
+                             size_t size);
+typedef void (*free_type)(struct _malloc_zone_t* zone,
+                          void* ptr);
+typedef void* (*realloc_type)(struct _malloc_zone_t* zone,
+                              void* ptr,
+                              size_t size);
+typedef void* (*memalign_type)(struct _malloc_zone_t* zone,
+                               size_t alignment,
+                               size_t size);
+
+malloc_type g_old_malloc;
+calloc_type g_old_calloc;
+valloc_type g_old_valloc;
+free_type g_old_free;
+realloc_type g_old_realloc;
+memalign_type g_old_memalign;
+
+malloc_type g_old_malloc_purgeable;
+calloc_type g_old_calloc_purgeable;
+valloc_type g_old_valloc_purgeable;
+free_type g_old_free_purgeable;
+realloc_type g_old_realloc_purgeable;
+memalign_type g_old_memalign_purgeable;
+
+void* oom_killer_malloc(struct _malloc_zone_t* zone,
+                        size_t size) {
+  void* result = g_old_malloc(zone, size);
+  if (!result && size)
+    TerminateBecauseOutOfMemory(size);
+  return result;
+}
+
+void* oom_killer_calloc(struct _malloc_zone_t* zone,
+                        size_t num_items,
+                        size_t size) {
+  void* result = g_old_calloc(zone, num_items, size);
+  if (!result && num_items && size)
+    TerminateBecauseOutOfMemory(num_items * size);
+  return result;
+}
+
+void* oom_killer_valloc(struct _malloc_zone_t* zone,
+                        size_t size) {
+  void* result = g_old_valloc(zone, size);
+  if (!result && size)
+    TerminateBecauseOutOfMemory(size);
+  return result;
+}
+
+void oom_killer_free(struct _malloc_zone_t* zone,
+                     void* ptr) {
+  g_old_free(zone, ptr);
+}
+
+void* oom_killer_realloc(struct _malloc_zone_t* zone,
+                         void* ptr,
+                         size_t size) {
+  void* result = g_old_realloc(zone, ptr, size);
+  if (!result && size)
+    TerminateBecauseOutOfMemory(size);
+  return result;
+}
+
+void* oom_killer_memalign(struct _malloc_zone_t* zone,
+                          size_t alignment,
+                          size_t size) {
+  void* result = g_old_memalign(zone, alignment, size);
+  // Only die if posix_memalign would have returned ENOMEM, since there are
+  // other reasons why NULL might be returned (see
+  // http://opensource.apple.com/source/Libc/Libc-583/gen/malloc.c ).
+  if (!result && size && alignment >= sizeof(void*) &&
+      (alignment & (alignment - 1)) == 0) {
+    TerminateBecauseOutOfMemory(size);
+  }
+  return result;
+}
+
+void* oom_killer_malloc_purgeable(struct _malloc_zone_t* zone,
+                                  size_t size) {
+  void* result = g_old_malloc_purgeable(zone, size);
+  if (!result && size)
+    TerminateBecauseOutOfMemory(size);
+  return result;
+}
+
+void* oom_killer_calloc_purgeable(struct _malloc_zone_t* zone,
+                                  size_t num_items,
+                                  size_t size) {
+  void* result = g_old_calloc_purgeable(zone, num_items, size);
+  if (!result && num_items && size)
+    TerminateBecauseOutOfMemory(num_items * size);
+  return result;
+}
+
+void* oom_killer_valloc_purgeable(struct _malloc_zone_t* zone,
+                                  size_t size) {
+  void* result = g_old_valloc_purgeable(zone, size);
+  if (!result && size)
+    TerminateBecauseOutOfMemory(size);
+  return result;
+}
+
+void oom_killer_free_purgeable(struct _malloc_zone_t* zone,
+                               void* ptr) {
+  g_old_free_purgeable(zone, ptr);
+}
+
+void* oom_killer_realloc_purgeable(struct _malloc_zone_t* zone,
+                                   void* ptr,
+                                   size_t size) {
+  void* result = g_old_realloc_purgeable(zone, ptr, size);
+  if (!result && size)
+    TerminateBecauseOutOfMemory(size);
+  return result;
+}
+
+void* oom_killer_memalign_purgeable(struct _malloc_zone_t* zone,
+                                    size_t alignment,
+                                    size_t size) {
+  void* result = g_old_memalign_purgeable(zone, alignment, size);
+  // Only die if posix_memalign would have returned ENOMEM, since there are
+  // other reasons why NULL might be returned (see
+  // http://opensource.apple.com/source/Libc/Libc-583/gen/malloc.c ).
+  if (!result && size && alignment >= sizeof(void*)
+      && (alignment & (alignment - 1)) == 0) {
+    TerminateBecauseOutOfMemory(size);
+  }
+  return result;
+}
+
+#endif  // !defined(ADDRESS_SANITIZER)
+
+// === C++ operator new ===
+
+void oom_killer_new() {
+  TerminateBecauseOutOfMemory(0);
+}
+
+#if !defined(ADDRESS_SANITIZER)
+
+// === Core Foundation CFAllocators ===
+
+bool CanGetContextForCFAllocator() {
+  return !base::mac::IsOSLaterThan10_12_DontCallThis();
+}
+
+CFAllocatorContext* ContextForCFAllocator(CFAllocatorRef allocator) {
+  ChromeCFAllocatorLions* our_allocator =
+      const_cast<ChromeCFAllocatorLions*>(
+          reinterpret_cast<const ChromeCFAllocatorLions*>(allocator));
+  return &our_allocator->_context;
+}
+
+CFAllocatorAllocateCallBack g_old_cfallocator_system_default;
+CFAllocatorAllocateCallBack g_old_cfallocator_malloc;
+CFAllocatorAllocateCallBack g_old_cfallocator_malloc_zone;
+
+void* oom_killer_cfallocator_system_default(CFIndex alloc_size,
+                                            CFOptionFlags hint,
+                                            void* info) {
+  void* result = g_old_cfallocator_system_default(alloc_size, hint, info);
+  if (!result)
+    TerminateBecauseOutOfMemory(alloc_size);
+  return result;
+}
+
+void* oom_killer_cfallocator_malloc(CFIndex alloc_size,
+                                    CFOptionFlags hint,
+                                    void* info) {
+  void* result = g_old_cfallocator_malloc(alloc_size, hint, info);
+  if (!result)
+    TerminateBecauseOutOfMemory(alloc_size);
+  return result;
+}
+
+void* oom_killer_cfallocator_malloc_zone(CFIndex alloc_size,
+                                         CFOptionFlags hint,
+                                         void* info) {
+  void* result = g_old_cfallocator_malloc_zone(alloc_size, hint, info);
+  if (!result)
+    TerminateBecauseOutOfMemory(alloc_size);
+  return result;
+}
+
+#endif  // !defined(ADDRESS_SANITIZER)
+
+// === Cocoa NSObject allocation ===
+
+typedef id (*allocWithZone_t)(id, SEL, NSZone*);
+allocWithZone_t g_old_allocWithZone;
+
+id oom_killer_allocWithZone(id self, SEL _cmd, NSZone* zone)
+{
+  id result = g_old_allocWithZone(self, _cmd, zone);
+  if (!result)
+    TerminateBecauseOutOfMemory(0);
+  return result;
+}
+
+}  // namespace
+
 bool UncheckedMalloc(size_t size, void** result) {
-  return allocator::UncheckedMallocMac(size, result);
+#if defined(ADDRESS_SANITIZER)
+  *result = malloc(size);
+#else
+  if (g_old_malloc) {
+    *result = g_old_malloc(malloc_default_zone(), size);
+  } else {
+    *result = malloc(size);
+  }
+#endif  // defined(ADDRESS_SANITIZER)
+
+  return *result != NULL;
 }
 
 bool UncheckedCalloc(size_t num_items, size_t size, void** result) {
-  return allocator::UncheckedCallocMac(num_items, size, result);
+#if defined(ADDRESS_SANITIZER)
+  *result = calloc(num_items, size);
+#else
+  if (g_old_calloc) {
+    *result = g_old_calloc(malloc_default_zone(), num_items, size);
+  } else {
+    *result = calloc(num_items, size);
+  }
+#endif  // defined(ADDRESS_SANITIZER)
+
+  return *result != NULL;
+}
+
+void* UncheckedMalloc(size_t size) {
+  void* address;
+  return UncheckedMalloc(size, &address) ? address : NULL;
+}
+
+void* UncheckedCalloc(size_t num_items, size_t size) {
+  void* address;
+  return UncheckedCalloc(num_items, size, &address) ? address : NULL;
 }
 
 void EnableTerminationOnOutOfMemory() {
-  allocator::InterceptAllocationsMac();
+  if (g_oom_killer_enabled)
+    return;
+
+  g_oom_killer_enabled = true;
+
+  // === C malloc/calloc/valloc/realloc/posix_memalign ===
+
+  // This approach is not perfect, as requests for amounts of memory larger than
+  // MALLOC_ABSOLUTE_MAX_SIZE (currently SIZE_T_MAX - (2 * PAGE_SIZE)) will
+  // still fail with a NULL rather than dying (see
+  // http://opensource.apple.com/source/Libc/Libc-583/gen/malloc.c for details).
+  // Unfortunately, it's the best we can do. Also note that this does not affect
+  // allocations from non-default zones.
+
+#if !defined(ADDRESS_SANITIZER)
+  // Don't do anything special on OOM for the malloc zones replaced by
+  // AddressSanitizer, as modifying or protecting them may not work correctly.
+
+  CHECK(!g_old_malloc && !g_old_calloc && !g_old_valloc && !g_old_realloc &&
+        !g_old_memalign) << "Old allocators unexpectedly non-null";
+
+  CHECK(!g_old_malloc_purgeable && !g_old_calloc_purgeable &&
+        !g_old_valloc_purgeable && !g_old_realloc_purgeable &&
+        !g_old_memalign_purgeable) << "Old allocators unexpectedly non-null";
+
+  ChromeMallocZone* default_zone =
+      reinterpret_cast<ChromeMallocZone*>(malloc_default_zone());
+  ChromeMallocZone* purgeable_zone =
+      reinterpret_cast<ChromeMallocZone*>(malloc_default_purgeable_zone());
+
+  mach_vm_address_t default_reprotection_start = 0;
+  mach_vm_size_t default_reprotection_length = 0;
+  vm_prot_t default_reprotection_value = VM_PROT_NONE;
+  DeprotectMallocZone(default_zone,
+                      &default_reprotection_start,
+                      &default_reprotection_length,
+                      &default_reprotection_value);
+
+  mach_vm_address_t purgeable_reprotection_start = 0;
+  mach_vm_size_t purgeable_reprotection_length = 0;
+  vm_prot_t purgeable_reprotection_value = VM_PROT_NONE;
+  if (purgeable_zone) {
+    DeprotectMallocZone(purgeable_zone,
+                        &purgeable_reprotection_start,
+                        &purgeable_reprotection_length,
+                        &purgeable_reprotection_value);
+  }
+
+  // Default zone
+
+  g_old_malloc = default_zone->malloc;
+  g_old_calloc = default_zone->calloc;
+  g_old_valloc = default_zone->valloc;
+  g_old_free = default_zone->free;
+  g_old_realloc = default_zone->realloc;
+  CHECK(g_old_malloc && g_old_calloc && g_old_valloc && g_old_free &&
+        g_old_realloc)
+      << "Failed to get system allocation functions.";
+
+  default_zone->malloc = oom_killer_malloc;
+  default_zone->calloc = oom_killer_calloc;
+  default_zone->valloc = oom_killer_valloc;
+  default_zone->free = oom_killer_free;
+  default_zone->realloc = oom_killer_realloc;
+
+  if (default_zone->version >= 5) {
+    g_old_memalign = default_zone->memalign;
+    if (g_old_memalign)
+      default_zone->memalign = oom_killer_memalign;
+  }
+
+  // Purgeable zone (if it exists)
+
+  if (purgeable_zone) {
+    g_old_malloc_purgeable = purgeable_zone->malloc;
+    g_old_calloc_purgeable = purgeable_zone->calloc;
+    g_old_valloc_purgeable = purgeable_zone->valloc;
+    g_old_free_purgeable = purgeable_zone->free;
+    g_old_realloc_purgeable = purgeable_zone->realloc;
+    CHECK(g_old_malloc_purgeable && g_old_calloc_purgeable &&
+          g_old_valloc_purgeable && g_old_free_purgeable &&
+          g_old_realloc_purgeable)
+        << "Failed to get system allocation functions.";
+
+    purgeable_zone->malloc = oom_killer_malloc_purgeable;
+    purgeable_zone->calloc = oom_killer_calloc_purgeable;
+    purgeable_zone->valloc = oom_killer_valloc_purgeable;
+    purgeable_zone->free = oom_killer_free_purgeable;
+    purgeable_zone->realloc = oom_killer_realloc_purgeable;
+
+    if (purgeable_zone->version >= 5) {
+      g_old_memalign_purgeable = purgeable_zone->memalign;
+      if (g_old_memalign_purgeable)
+        purgeable_zone->memalign = oom_killer_memalign_purgeable;
+    }
+  }
+
+  // Restore protection if it was active.
+
+  if (default_reprotection_start) {
+    kern_return_t result = mach_vm_protect(mach_task_self(),
+                                           default_reprotection_start,
+                                           default_reprotection_length,
+                                           false,
+                                           default_reprotection_value);
+    MACH_CHECK(result == KERN_SUCCESS, result) << "mach_vm_protect";
+  }
+
+  if (purgeable_reprotection_start) {
+    kern_return_t result = mach_vm_protect(mach_task_self(),
+                                           purgeable_reprotection_start,
+                                           purgeable_reprotection_length,
+                                           false,
+                                           purgeable_reprotection_value);
+    MACH_CHECK(result == KERN_SUCCESS, result) << "mach_vm_protect";
+  }
+#endif
+
+  // === C malloc_zone_batch_malloc ===
+
+  // batch_malloc is omitted because the default malloc zone's implementation
+  // only supports batch_malloc for "tiny" allocations from the free list. It
+  // will fail for allocations larger than "tiny", and will only allocate as
+  // many blocks as it's able to from the free list. These factors mean that it
+  // can return less than the requested memory even in a non-out-of-memory
+  // situation. There's no good way to detect whether a batch_malloc failure is
+  // due to these other factors, or due to genuine memory or address space
+  // exhaustion. The fact that it only allocates space from the "tiny" free list
+  // means that it's likely that a failure will not be due to memory exhaustion.
+  // Similarly, these constraints on batch_malloc mean that callers must always
+  // be expecting to receive less memory than was requested, even in situations
+  // where memory pressure is not a concern. Finally, the only public interface
+  // to batch_malloc is malloc_zone_batch_malloc, which is specific to the
+  // system's malloc implementation. It's unlikely that anyone's even heard of
+  // it.
+
+  // === C++ operator new ===
+
+  // Yes, operator new does call through to malloc, but this will catch failures
+  // that our imperfect handling of malloc cannot.
+
+  std::set_new_handler(oom_killer_new);
+
+#ifndef ADDRESS_SANITIZER
+  // === Core Foundation CFAllocators ===
+
+  // This will not catch allocation done by custom allocators, but will catch
+  // all allocation done by system-provided ones.
+
+  CHECK(!g_old_cfallocator_system_default && !g_old_cfallocator_malloc &&
+        !g_old_cfallocator_malloc_zone)
+      << "Old allocators unexpectedly non-null";
+
+  bool cf_allocator_internals_known = CanGetContextForCFAllocator();
+
+  if (cf_allocator_internals_known) {
+    CFAllocatorContext* context =
+        ContextForCFAllocator(kCFAllocatorSystemDefault);
+    CHECK(context) << "Failed to get context for kCFAllocatorSystemDefault.";
+    g_old_cfallocator_system_default = context->allocate;
+    CHECK(g_old_cfallocator_system_default)
+        << "Failed to get kCFAllocatorSystemDefault allocation function.";
+    context->allocate = oom_killer_cfallocator_system_default;
+
+    context = ContextForCFAllocator(kCFAllocatorMalloc);
+    CHECK(context) << "Failed to get context for kCFAllocatorMalloc.";
+    g_old_cfallocator_malloc = context->allocate;
+    CHECK(g_old_cfallocator_malloc)
+        << "Failed to get kCFAllocatorMalloc allocation function.";
+    context->allocate = oom_killer_cfallocator_malloc;
+
+    context = ContextForCFAllocator(kCFAllocatorMallocZone);
+    CHECK(context) << "Failed to get context for kCFAllocatorMallocZone.";
+    g_old_cfallocator_malloc_zone = context->allocate;
+    CHECK(g_old_cfallocator_malloc_zone)
+        << "Failed to get kCFAllocatorMallocZone allocation function.";
+    context->allocate = oom_killer_cfallocator_malloc_zone;
+  } else {
+    DLOG(WARNING) << "Internals of CFAllocator not known; out-of-memory "
+                     "failures via CFAllocator will not result in termination. "
+                     "http://crbug.com/45650";
+  }
+#endif
+
+  // === Cocoa NSObject allocation ===
+
+  // Note that both +[NSObject new] and +[NSObject alloc] call through to
+  // +[NSObject allocWithZone:].
+
+  CHECK(!g_old_allocWithZone)
+      << "Old allocator unexpectedly non-null";
+
+  Class nsobject_class = [NSObject class];
+  Method orig_method = class_getClassMethod(nsobject_class,
+                                            @selector(allocWithZone:));
+  g_old_allocWithZone = reinterpret_cast<allocWithZone_t>(
+      method_getImplementation(orig_method));
+  CHECK(g_old_allocWithZone)
+      << "Failed to get allocWithZone allocation function.";
+  method_setImplementation(orig_method,
+                           reinterpret_cast<IMP>(oom_killer_allocWithZone));
 }
 
 }  // namespace base
diff --git a/base/time/time.cc b/base/time/time.cc
index 93a6195c..f5cefd4 100644
--- a/base/time/time.cc
+++ b/base/time/time.cc
@@ -191,6 +191,10 @@
 }
 
 double Time::ToJsTime() const {
+  if (is_null()) {
+    // Preserve 0 so the invalid result doesn't depend on the platform.
+    return 0;
+  }
   if (is_max()) {
     // Preserve max without offset to prevent overflow.
     return std::numeric_limits<double>::infinity();
diff --git a/base/time/time_unittest.cc b/base/time/time_unittest.cc
index f25315f..8906c3b 100644
--- a/base/time/time_unittest.cc
+++ b/base/time/time_unittest.cc
@@ -159,15 +159,6 @@
   EXPECT_EQ(700.0003, t.ToDoubleT());
   t = Time::FromDoubleT(800.73);
   EXPECT_EQ(800730.0, t.ToJsTime());
-
-  // Correctly convert |- epoch offset| which is valid time in javascript.
-  Time minusEpoch = Time::FromJsTime(-11644473600000.0);
-  EXPECT_EQ(-11644473600000, minusEpoch.ToJsTime());
-
-  // Check conversion of boundary javascript time values.
-  // See http://www.ecma-international.org/ecma-262/6.0/#sec-timeclip
-  EXPECT_EQ(-8.46e15, Time::FromJsTime(-8.46e15).ToJsTime());
-  EXPECT_EQ(8.46e15, Time::FromJsTime(8.46e15).ToJsTime());
 }
 
 #if defined(OS_POSIX)
diff --git a/base/trace_event/memory_infra_background_whitelist.cc b/base/trace_event/memory_infra_background_whitelist.cc
index ea37739..d6e9f5d16 100644
--- a/base/trace_event/memory_infra_background_whitelist.cc
+++ b/base/trace_event/memory_infra_background_whitelist.cc
@@ -88,6 +88,42 @@
     "winheap/allocated_objects",
     "sync/0x?/kernel",
     "sync/0x?/store",
+    "sync/0x?/model_type/APP",
+    "sync/0x?/model_type/APP_LIST",
+    "sync/0x?/model_type/APP_NOTIFICATION",
+    "sync/0x?/model_type/APP_SETTING",
+    "sync/0x?/model_type/ARC_PACKAGE",
+    "sync/0x?/model_type/ARTICLE",
+    "sync/0x?/model_type/AUTOFILL",
+    "sync/0x?/model_type/AUTOFILL_PROFILE",
+    "sync/0x?/model_type/AUTOFILL_WALLET",
+    "sync/0x?/model_type/BOOKMARK",
+    "sync/0x?/model_type/DEVICE_INFO",
+    "sync/0x?/model_type/DICTIONARY",
+    "sync/0x?/model_type/EXPERIMENTS",
+    "sync/0x?/model_type/EXTENSION",
+    "sync/0x?/model_type/EXTENSION_SETTING",
+    "sync/0x?/model_type/FAVICON_IMAGE",
+    "sync/0x?/model_type/FAVICON_TRACKING",
+    "sync/0x?/model_type/HISTORY_DELETE_DIRECTIVE",
+    "sync/0x?/model_type/MANAGED_USER",
+    "sync/0x?/model_type/MANAGED_USER_SETTING",
+    "sync/0x?/model_type/MANAGED_USER_SHARED_SETTING",
+    "sync/0x?/model_type/MANAGED_USER_WHITELIST",
+    "sync/0x?/model_type/NIGORI",
+    "sync/0x?/model_type/PASSWORD",
+    "sync/0x?/model_type/PREFERENCE",
+    "sync/0x?/model_type/PRINTER",
+    "sync/0x?/model_type/PRIORITY_PREFERENCE",
+    "sync/0x?/model_type/READING_LIST",
+    "sync/0x?/model_type/SEARCH_ENGINE",
+    "sync/0x?/model_type/SESSION",
+    "sync/0x?/model_type/SYNCED_NOTIFICATION",
+    "sync/0x?/model_type/SYNCED_NOTIFICATION_APP_INFO",
+    "sync/0x?/model_type/THEME",
+    "sync/0x?/model_type/TYPED_URL",
+    "sync/0x?/model_type/WALLET_METADATA",
+    "sync/0x?/model_type/WIFI_CREDENTIAL",
     nullptr  // End of list marker.
 };
 
diff --git a/build/mac_toolchain.py b/build/mac_toolchain.py
index c4de86f9..123e5e0d3 100755
--- a/build/mac_toolchain.py
+++ b/build/mac_toolchain.py
@@ -28,8 +28,8 @@
 MAC_TOOLCHAIN_SUB_REVISION = 3
 MAC_TOOLCHAIN_VERSION = '%s-%s' % (MAC_TOOLCHAIN_VERSION,
                                    MAC_TOOLCHAIN_SUB_REVISION)
-IOS_TOOLCHAIN_VERSION = '8A218a'
-IOS_TOOLCHAIN_SUB_REVISION = 2
+IOS_TOOLCHAIN_VERSION = '8C1002'
+IOS_TOOLCHAIN_SUB_REVISION = 1
 IOS_TOOLCHAIN_VERSION = '%s-%s' % (IOS_TOOLCHAIN_VERSION,
                                    IOS_TOOLCHAIN_SUB_REVISION)
 
diff --git a/cc/test/ordered_simple_task_runner.cc b/cc/test/ordered_simple_task_runner.cc
index 9dc4bbcd..161704f 100644
--- a/cc/test/ordered_simple_task_runner.cc
+++ b/cc/test/ordered_simple_task_runner.cc
@@ -137,6 +137,8 @@
 }
 
 base::TimeTicks OrderedSimpleTaskRunner::NextTaskTime() {
+  RemoveCancelledTasks();
+
   if (pending_tasks_.size() <= 0) {
     return AbsoluteMaxNow();
   }
@@ -146,6 +148,7 @@
 
 base::TimeDelta OrderedSimpleTaskRunner::DelayToNextTaskTime() {
   DCHECK(thread_checker_.CalledOnValidThread());
+  RemoveCancelledTasks();
 
   if (pending_tasks_.size() <= 0) {
     return AbsoluteMaxNow() - base::TimeTicks();
@@ -198,6 +201,11 @@
   }
 
   while (pending_tasks_.size() > 0) {
+    // Skip canceled tasks.
+    if (pending_tasks_.begin()->task.IsCancelled()) {
+      pending_tasks_.erase(pending_tasks_.begin());
+      continue;
+    }
     // Check if we should continue to run pending tasks.
     bool condition_success = true;
     for (std::vector<base::Callback<bool(void)>>::iterator it =
@@ -344,4 +352,15 @@
   return true;
 }
 
+void OrderedSimpleTaskRunner::RemoveCancelledTasks() {
+  std::set<TestOrderablePendingTask>::iterator it = pending_tasks_.begin();
+  while (it != pending_tasks_.end()) {
+    if (it->task.IsCancelled()) {
+      it = pending_tasks_.erase(it);
+    } else {
+      it++;
+    }
+  }
+}
+
 }  // namespace cc
diff --git a/cc/test/ordered_simple_task_runner.h b/cc/test/ordered_simple_task_runner.h
index 9620a960..1ba8e95 100644
--- a/cc/test/ordered_simple_task_runner.h
+++ b/cc/test/ordered_simple_task_runner.h
@@ -130,6 +130,9 @@
   // Advance Now() to the next task to run.
   base::Callback<bool(void)> AdvanceNow();
 
+  // Removes all tasks whose weak pointer has been revoked.
+  void RemoveCancelledTasks();
+
  protected:
   static bool TaskRunCountBelowCallback(size_t max_tasks, size_t* task_run);
   bool TaskExistedInitiallyCallback(
diff --git a/cc/trees/layer_tree.cc b/cc/trees/layer_tree.cc
index 5f5e551..c545a12 100644
--- a/cc/trees/layer_tree.cc
+++ b/cc/trees/layer_tree.cc
@@ -18,27 +18,8 @@
 
 namespace cc {
 
-LayerTree::Inputs::Inputs()
-    : top_controls_height(0.f),
-      top_controls_shown_ratio(0.f),
-      browser_controls_shrink_blink_size(false),
-      bottom_controls_height(0.f),
-      device_scale_factor(1.f),
-      painted_device_scale_factor(1.f),
-      page_scale_factor(1.f),
-      min_page_scale_factor(1.f),
-      max_page_scale_factor(1.f),
-      background_color(SK_ColorWHITE),
-      has_transparent_background(false),
-      have_scroll_event_handlers(false),
-      event_listener_properties() {}
-
-LayerTree::Inputs::~Inputs() = default;
-
 LayerTree::LayerTree(MutatorHost* mutator_host, LayerTreeHost* layer_tree_host)
-    : needs_full_tree_sync_(true),
-      needs_meta_info_recomputation_(true),
-      in_paint_layer_contents_(false),
+    : event_listener_properties_(),
       mutator_host_(mutator_host),
       layer_tree_host_(layer_tree_host) {
   DCHECK(mutator_host_);
@@ -52,26 +33,26 @@
   // We must clear any pointers into the layer tree prior to destroying it.
   RegisterViewportLayers(nullptr, nullptr, nullptr, nullptr);
 
-  if (inputs_.root_layer) {
-    inputs_.root_layer->SetLayerTreeHost(nullptr);
+  if (root_layer_) {
+    root_layer_->SetLayerTreeHost(nullptr);
 
     // The root layer must be destroyed before the layer tree. We've made a
     // contract with our animation controllers that the animation_host will
     // outlive them, and we must make good.
-    inputs_.root_layer = nullptr;
+    root_layer_ = nullptr;
   }
 }
 
 void LayerTree::SetRootLayer(scoped_refptr<Layer> root_layer) {
-  if (inputs_.root_layer.get() == root_layer.get())
+  if (root_layer_.get() == root_layer.get())
     return;
 
-  if (inputs_.root_layer.get())
-    inputs_.root_layer->SetLayerTreeHost(nullptr);
-  inputs_.root_layer = root_layer;
-  if (inputs_.root_layer.get()) {
-    DCHECK(!inputs_.root_layer->parent());
-    inputs_.root_layer->SetLayerTreeHost(layer_tree_host_);
+  if (root_layer_.get())
+    root_layer_->SetLayerTreeHost(nullptr);
+  root_layer_ = root_layer;
+  if (root_layer_.get()) {
+    DCHECK(!root_layer_->parent());
+    root_layer_->SetLayerTreeHost(layer_tree_host_);
   }
 
   if (hud_layer_.get())
@@ -91,85 +72,85 @@
     scoped_refptr<Layer> outer_viewport_scroll_layer) {
   DCHECK(!inner_viewport_scroll_layer ||
          inner_viewport_scroll_layer != outer_viewport_scroll_layer);
-  inputs_.overscroll_elasticity_layer = overscroll_elasticity_layer;
-  inputs_.page_scale_layer = page_scale_layer;
-  inputs_.inner_viewport_scroll_layer = inner_viewport_scroll_layer;
-  inputs_.outer_viewport_scroll_layer = outer_viewport_scroll_layer;
+  overscroll_elasticity_layer_ = overscroll_elasticity_layer;
+  page_scale_layer_ = page_scale_layer;
+  inner_viewport_scroll_layer_ = inner_viewport_scroll_layer;
+  outer_viewport_scroll_layer_ = outer_viewport_scroll_layer;
 }
 
 void LayerTree::RegisterSelection(const LayerSelection& selection) {
-  if (inputs_.selection == selection)
+  if (selection_ == selection)
     return;
 
-  inputs_.selection = selection;
+  selection_ = selection;
   SetNeedsCommit();
 }
 
 void LayerTree::SetHaveScrollEventHandlers(bool have_event_handlers) {
-  if (inputs_.have_scroll_event_handlers == have_event_handlers)
+  if (have_scroll_event_handlers_ == have_event_handlers)
     return;
 
-  inputs_.have_scroll_event_handlers = have_event_handlers;
+  have_scroll_event_handlers_ = have_event_handlers;
   SetNeedsCommit();
 }
 
 void LayerTree::SetEventListenerProperties(EventListenerClass event_class,
                                            EventListenerProperties properties) {
   const size_t index = static_cast<size_t>(event_class);
-  if (inputs_.event_listener_properties[index] == properties)
+  if (event_listener_properties_[index] == properties)
     return;
 
-  inputs_.event_listener_properties[index] = properties;
+  event_listener_properties_[index] = properties;
   SetNeedsCommit();
 }
 
 void LayerTree::SetViewportSize(const gfx::Size& device_viewport_size) {
-  if (inputs_.device_viewport_size == device_viewport_size)
+  if (device_viewport_size_ == device_viewport_size)
     return;
 
-  inputs_.device_viewport_size = device_viewport_size;
+  device_viewport_size_ = device_viewport_size;
 
   SetPropertyTreesNeedRebuild();
   SetNeedsCommit();
 }
 
 void LayerTree::SetBrowserControlsHeight(float height, bool shrink) {
-  if (inputs_.top_controls_height == height &&
-      inputs_.browser_controls_shrink_blink_size == shrink)
+  if (top_controls_height_ == height &&
+      browser_controls_shrink_blink_size_ == shrink)
     return;
 
-  inputs_.top_controls_height = height;
-  inputs_.browser_controls_shrink_blink_size = shrink;
+  top_controls_height_ = height;
+  browser_controls_shrink_blink_size_ = shrink;
   SetNeedsCommit();
 }
 
 void LayerTree::SetBrowserControlsShownRatio(float ratio) {
-  if (inputs_.top_controls_shown_ratio == ratio)
+  if (top_controls_shown_ratio_ == ratio)
     return;
 
-  inputs_.top_controls_shown_ratio = ratio;
+  top_controls_shown_ratio_ = ratio;
   SetNeedsCommit();
 }
 
 void LayerTree::SetBottomControlsHeight(float height) {
-  if (inputs_.bottom_controls_height == height)
+  if (bottom_controls_height_ == height)
     return;
 
-  inputs_.bottom_controls_height = height;
+  bottom_controls_height_ = height;
   SetNeedsCommit();
 }
 
 void LayerTree::SetPageScaleFactorAndLimits(float page_scale_factor,
                                             float min_page_scale_factor,
                                             float max_page_scale_factor) {
-  if (inputs_.page_scale_factor == page_scale_factor &&
-      inputs_.min_page_scale_factor == min_page_scale_factor &&
-      inputs_.max_page_scale_factor == max_page_scale_factor)
+  if (page_scale_factor_ == page_scale_factor &&
+      min_page_scale_factor_ == min_page_scale_factor &&
+      max_page_scale_factor_ == max_page_scale_factor)
     return;
 
-  inputs_.page_scale_factor = page_scale_factor;
-  inputs_.min_page_scale_factor = min_page_scale_factor;
-  inputs_.max_page_scale_factor = max_page_scale_factor;
+  page_scale_factor_ = page_scale_factor;
+  min_page_scale_factor_ = min_page_scale_factor;
+  max_page_scale_factor_ = max_page_scale_factor;
   SetPropertyTreesNeedRebuild();
   SetNeedsCommit();
 }
@@ -178,37 +159,37 @@
                                         bool use_anchor,
                                         float scale,
                                         base::TimeDelta duration) {
-  inputs_.pending_page_scale_animation.reset(new PendingPageScaleAnimation(
+  pending_page_scale_animation_.reset(new PendingPageScaleAnimation(
       target_offset, use_anchor, scale, duration));
 
   SetNeedsCommit();
 }
 
 bool LayerTree::HasPendingPageScaleAnimation() const {
-  return !!inputs_.pending_page_scale_animation.get();
+  return !!pending_page_scale_animation_.get();
 }
 
 void LayerTree::SetDeviceScaleFactor(float device_scale_factor) {
-  if (inputs_.device_scale_factor == device_scale_factor)
+  if (device_scale_factor_ == device_scale_factor)
     return;
-  inputs_.device_scale_factor = device_scale_factor;
+  device_scale_factor_ = device_scale_factor;
 
   property_trees_.needs_rebuild = true;
   SetNeedsCommit();
 }
 
 void LayerTree::SetPaintedDeviceScaleFactor(float painted_device_scale_factor) {
-  if (inputs_.painted_device_scale_factor == painted_device_scale_factor)
+  if (painted_device_scale_factor_ == painted_device_scale_factor)
     return;
-  inputs_.painted_device_scale_factor = painted_device_scale_factor;
+  painted_device_scale_factor_ = painted_device_scale_factor;
 
   SetNeedsCommit();
 }
 
 void LayerTree::SetDeviceColorSpace(const gfx::ColorSpace& device_color_space) {
-  if (inputs_.device_color_space == device_color_space)
+  if (device_color_space_ == device_color_space)
     return;
-  inputs_.device_color_space = device_color_space;
+  device_color_space_ = device_color_space;
   LayerTreeHostCommon::CallFunctionForEveryLayer(
       this, [](Layer* layer) { layer->SetNeedsDisplay(); });
 }
@@ -277,7 +258,7 @@
 
 void LayerTree::SetPageScaleFromImplSide(float page_scale) {
   DCHECK(layer_tree_host_->CommitRequested());
-  inputs_.page_scale_factor = page_scale;
+  page_scale_factor_ = page_scale;
   SetPropertyTreesNeedRebuild();
 }
 
@@ -293,8 +274,8 @@
       hud_layer_ = HeadsUpDisplayLayer::Create();
     }
 
-    if (inputs_.root_layer.get() && !hud_layer_->parent())
-      inputs_.root_layer->AddChild(hud_layer_);
+    if (root_layer_.get() && !hud_layer_->parent())
+      root_layer_->AddChild(hud_layer_);
   } else if (hud_layer_.get()) {
     hud_layer_->RemoveFromParent();
     hud_layer_ = nullptr;
@@ -333,9 +314,9 @@
     tree_impl->set_hud_layer(nullptr);
   }
 
-  tree_impl->set_background_color(inputs_.background_color);
-  tree_impl->set_has_transparent_background(inputs_.has_transparent_background);
-  tree_impl->set_have_scroll_event_handlers(inputs_.have_scroll_event_handlers);
+  tree_impl->set_background_color(background_color_);
+  tree_impl->set_has_transparent_background(has_transparent_background_);
+  tree_impl->set_have_scroll_event_handlers(have_scroll_event_handlers_);
   tree_impl->set_event_listener_properties(
       EventListenerClass::kTouchStartOrMove,
       event_listener_properties(EventListenerClass::kTouchStartOrMove));
@@ -346,30 +327,26 @@
       EventListenerClass::kTouchEndOrCancel,
       event_listener_properties(EventListenerClass::kTouchEndOrCancel));
 
-  if (inputs_.page_scale_layer && inputs_.inner_viewport_scroll_layer) {
+  if (page_scale_layer_ && inner_viewport_scroll_layer_) {
     tree_impl->SetViewportLayersFromIds(
-        inputs_.overscroll_elasticity_layer
-            ? inputs_.overscroll_elasticity_layer->id()
-            : Layer::INVALID_ID,
-        inputs_.page_scale_layer->id(),
-        inputs_.inner_viewport_scroll_layer->id(),
-        inputs_.outer_viewport_scroll_layer
-            ? inputs_.outer_viewport_scroll_layer->id()
-            : Layer::INVALID_ID);
-    DCHECK(inputs_.inner_viewport_scroll_layer
-               ->IsContainerForFixedPositionLayers());
+        overscroll_elasticity_layer_ ? overscroll_elasticity_layer_->id()
+                                     : Layer::INVALID_ID,
+        page_scale_layer_->id(), inner_viewport_scroll_layer_->id(),
+        outer_viewport_scroll_layer_ ? outer_viewport_scroll_layer_->id()
+                                     : Layer::INVALID_ID);
+    DCHECK(inner_viewport_scroll_layer_->IsContainerForFixedPositionLayers());
   } else {
     tree_impl->ClearViewportLayers();
   }
 
-  tree_impl->RegisterSelection(inputs_.selection);
+  tree_impl->RegisterSelection(selection_);
 
   bool property_trees_changed_on_active_tree =
       tree_impl->IsActiveTree() && tree_impl->property_trees()->changed;
   // Property trees may store damage status. We preserve the sync tree damage
   // status by pushing the damage status from sync tree property trees to main
   // thread property trees or by moving it onto the layers.
-  if (inputs_.root_layer && property_trees_changed_on_active_tree) {
+  if (root_layer_ && property_trees_changed_on_active_tree) {
     if (property_trees_.sequence_number ==
         tree_impl->property_trees()->sequence_number)
       tree_impl->property_trees()->PushChangeTrackingTo(&property_trees_);
@@ -379,28 +356,25 @@
   // Setting property trees must happen before pushing the page scale.
   tree_impl->SetPropertyTrees(&property_trees_);
 
-  tree_impl->PushPageScaleFromMainThread(inputs_.page_scale_factor,
-                                         inputs_.min_page_scale_factor,
-                                         inputs_.max_page_scale_factor);
+  tree_impl->PushPageScaleFromMainThread(
+      page_scale_factor_, min_page_scale_factor_, max_page_scale_factor_);
 
   tree_impl->set_browser_controls_shrink_blink_size(
-      inputs_.browser_controls_shrink_blink_size);
-  tree_impl->set_top_controls_height(inputs_.top_controls_height);
-  tree_impl->set_bottom_controls_height(inputs_.bottom_controls_height);
-  tree_impl->PushBrowserControlsFromMainThread(
-      inputs_.top_controls_shown_ratio);
+      browser_controls_shrink_blink_size_);
+  tree_impl->set_top_controls_height(top_controls_height_);
+  tree_impl->set_bottom_controls_height(bottom_controls_height_);
+  tree_impl->PushBrowserControlsFromMainThread(top_controls_shown_ratio_);
   tree_impl->elastic_overscroll()->PushFromMainThread(elastic_overscroll_);
   if (tree_impl->IsActiveTree())
     tree_impl->elastic_overscroll()->PushPendingToActive();
 
-  tree_impl->set_painted_device_scale_factor(
-      inputs_.painted_device_scale_factor);
+  tree_impl->set_painted_device_scale_factor(painted_device_scale_factor_);
 
-  tree_impl->SetDeviceColorSpace(inputs_.device_color_space);
+  tree_impl->SetDeviceColorSpace(device_color_space_);
 
-  if (inputs_.pending_page_scale_animation) {
+  if (pending_page_scale_animation_) {
     tree_impl->SetPendingPageScaleAnimation(
-        std::move(inputs_.pending_page_scale_animation));
+        std::move(pending_page_scale_animation_));
   }
 
   DCHECK(!tree_impl->ViewportSizeInvalid());
@@ -514,7 +488,7 @@
 }
 
 LayerListIterator<Layer> LayerTree::begin() const {
-  return LayerListIterator<Layer>(inputs_.root_layer.get());
+  return LayerListIterator<Layer>(root_layer_.get());
 }
 
 LayerListIterator<Layer> LayerTree::end() const {
@@ -522,7 +496,7 @@
 }
 
 LayerListReverseIterator<Layer> LayerTree::rbegin() {
-  return LayerListReverseIterator<Layer>(inputs_.root_layer.get());
+  return LayerListReverseIterator<Layer>(root_layer_.get());
 }
 
 LayerListReverseIterator<Layer> LayerTree::rend() {
diff --git a/cc/trees/layer_tree.h b/cc/trees/layer_tree.h
index 5ac3f69..7f874120 100644
--- a/cc/trees/layer_tree.h
+++ b/cc/trees/layer_tree.h
@@ -44,8 +44,8 @@
   virtual ~LayerTree();
 
   void SetRootLayer(scoped_refptr<Layer> root_layer);
-  Layer* root_layer() { return inputs_.root_layer.get(); }
-  const Layer* root_layer() const { return inputs_.root_layer.get(); }
+  Layer* root_layer() { return root_layer_.get(); }
+  const Layer* root_layer() const { return root_layer_.get(); }
 
   void RegisterViewportLayers(scoped_refptr<Layer> overscroll_elasticity_layer,
                               scoped_refptr<Layer> page_scale_layer,
@@ -53,35 +53,33 @@
                               scoped_refptr<Layer> outer_viewport_scroll_layer);
 
   Layer* overscroll_elasticity_layer() const {
-    return inputs_.overscroll_elasticity_layer.get();
+    return overscroll_elasticity_layer_.get();
   }
-  Layer* page_scale_layer() const { return inputs_.page_scale_layer.get(); }
+  Layer* page_scale_layer() const { return page_scale_layer_.get(); }
   Layer* inner_viewport_scroll_layer() const {
-    return inputs_.inner_viewport_scroll_layer.get();
+    return inner_viewport_scroll_layer_.get();
   }
   Layer* outer_viewport_scroll_layer() const {
-    return inputs_.outer_viewport_scroll_layer.get();
+    return outer_viewport_scroll_layer_.get();
   }
 
   void RegisterSelection(const LayerSelection& selection);
-  const LayerSelection& selection() const { return inputs_.selection; }
+  const LayerSelection& selection() const { return selection_; }
 
   void SetHaveScrollEventHandlers(bool have_event_handlers);
   bool have_scroll_event_handlers() const {
-    return inputs_.have_scroll_event_handlers;
+    return have_scroll_event_handlers_;
   }
 
   void SetEventListenerProperties(EventListenerClass event_class,
                                   EventListenerProperties event_properties);
   EventListenerProperties event_listener_properties(
       EventListenerClass event_class) const {
-    return inputs_.event_listener_properties[static_cast<size_t>(event_class)];
+    return event_listener_properties_[static_cast<size_t>(event_class)];
   }
 
   void SetViewportSize(const gfx::Size& device_viewport_size);
-  gfx::Size device_viewport_size() const {
-    return inputs_.device_viewport_size;
-  }
+  gfx::Size device_viewport_size() const { return device_viewport_size_; }
 
   void SetBrowserControlsHeight(float height, bool shrink);
   void SetBrowserControlsShownRatio(float ratio);
@@ -90,18 +88,18 @@
   void SetPageScaleFactorAndLimits(float page_scale_factor,
                                    float min_page_scale_factor,
                                    float max_page_scale_factor);
-  float page_scale_factor() const { return inputs_.page_scale_factor; }
-  float min_page_scale_factor() const { return inputs_.min_page_scale_factor; }
-  float max_page_scale_factor() const { return inputs_.max_page_scale_factor; }
+  float page_scale_factor() const { return page_scale_factor_; }
+  float min_page_scale_factor() const { return min_page_scale_factor_; }
+  float max_page_scale_factor() const { return max_page_scale_factor_; }
 
-  void set_background_color(SkColor color) { inputs_.background_color = color; }
-  SkColor background_color() const { return inputs_.background_color; }
+  void set_background_color(SkColor color) { background_color_ = color; }
+  SkColor background_color() const { return background_color_; }
 
   void set_has_transparent_background(bool transparent) {
-    inputs_.has_transparent_background = transparent;
+    has_transparent_background_ = transparent;
   }
   bool has_transparent_background() const {
-    return inputs_.has_transparent_background;
+    return has_transparent_background_;
   }
 
   void StartPageScaleAnimation(const gfx::Vector2d& target_offset,
@@ -111,16 +109,16 @@
   bool HasPendingPageScaleAnimation() const;
 
   void SetDeviceScaleFactor(float device_scale_factor);
-  float device_scale_factor() const { return inputs_.device_scale_factor; }
+  float device_scale_factor() const { return device_scale_factor_; }
 
   void SetPaintedDeviceScaleFactor(float painted_device_scale_factor);
   float painted_device_scale_factor() const {
-    return inputs_.painted_device_scale_factor;
+    return painted_device_scale_factor_;
   }
 
   void SetDeviceColorSpace(const gfx::ColorSpace& device_color_space);
   const gfx::ColorSpace& device_color_space() const {
-    return inputs_.device_color_space;
+    return device_color_space_;
   }
 
   // Used externally by blink for setting the PropertyTrees when
@@ -218,51 +216,43 @@
   gfx::ScrollOffset GetScrollOffsetForAnimation(
       ElementId element_id) const override;
 
-  // Encapsulates the data, callbacks, interfaces received from the embedder.
-  struct Inputs {
-    Inputs();
-    ~Inputs();
+  scoped_refptr<Layer> root_layer_;
 
-    scoped_refptr<Layer> root_layer;
+  scoped_refptr<Layer> overscroll_elasticity_layer_;
+  scoped_refptr<Layer> page_scale_layer_;
+  scoped_refptr<Layer> inner_viewport_scroll_layer_;
+  scoped_refptr<Layer> outer_viewport_scroll_layer_;
 
-    scoped_refptr<Layer> overscroll_elasticity_layer;
-    scoped_refptr<Layer> page_scale_layer;
-    scoped_refptr<Layer> inner_viewport_scroll_layer;
-    scoped_refptr<Layer> outer_viewport_scroll_layer;
+  float top_controls_height_ = 0.f;
+  float top_controls_shown_ratio_ = 0.f;
+  bool browser_controls_shrink_blink_size_ = false;
 
-    float top_controls_height;
-    float top_controls_shown_ratio;
-    bool browser_controls_shrink_blink_size;
+  float bottom_controls_height_ = 0.f;
 
-    float bottom_controls_height;
+  float device_scale_factor_ = 1.f;
+  float painted_device_scale_factor_ = 1.f;
+  float page_scale_factor_ = 1.f;
+  float min_page_scale_factor_ = 1.f;
+  float max_page_scale_factor_ = 1.f;
+  gfx::ColorSpace device_color_space_;
 
-    float device_scale_factor;
-    float painted_device_scale_factor;
-    float page_scale_factor;
-    float min_page_scale_factor;
-    float max_page_scale_factor;
-    gfx::ColorSpace device_color_space;
+  SkColor background_color_ = SK_ColorWHITE;
+  bool has_transparent_background_ = false;
 
-    SkColor background_color;
-    bool has_transparent_background;
+  LayerSelection selection_;
 
-    LayerSelection selection;
+  gfx::Size device_viewport_size_;
 
-    gfx::Size device_viewport_size;
+  bool have_scroll_event_handlers_ = false;
+  EventListenerProperties event_listener_properties_[static_cast<size_t>(
+      EventListenerClass::kNumClasses)];
 
-    bool have_scroll_event_handlers;
-    EventListenerProperties event_listener_properties[static_cast<size_t>(
-        EventListenerClass::kNumClasses)];
-
-    std::unique_ptr<PendingPageScaleAnimation> pending_page_scale_animation;
-  };
-
-  Inputs inputs_;
+  std::unique_ptr<PendingPageScaleAnimation> pending_page_scale_animation_;
 
   PropertyTrees property_trees_;
 
-  bool needs_full_tree_sync_;
-  bool needs_meta_info_recomputation_;
+  bool needs_full_tree_sync_ = true;
+  bool needs_meta_info_recomputation_ = true;
 
   gfx::Vector2dF elastic_overscroll_;
 
@@ -277,7 +267,7 @@
   using ElementLayersMap = std::unordered_map<ElementId, Layer*, ElementIdHash>;
   ElementLayersMap element_layers_map_;
 
-  bool in_paint_layer_contents_;
+  bool in_paint_layer_contents_ = false;
 
   MutatorHost* mutator_host_;
   LayerTreeHost* layer_tree_host_;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSection.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSection.java
index 4d8dee5..850fec8 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSection.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSection.java
@@ -6,7 +6,6 @@
 
 import org.chromium.base.Callback;
 import org.chromium.base.Log;
-import org.chromium.base.VisibleForTesting;
 import org.chromium.chrome.browser.ntp.NewTabPage.DestructionObserver;
 import org.chromium.chrome.browser.ntp.NewTabPageUma;
 import org.chromium.chrome.browser.ntp.snippets.CategoryInt;
@@ -152,7 +151,7 @@
             int itemCount = mSuggestions.size();
             if (itemCount > n) {
                 mSuggestions.subList(n, itemCount).clear();
-                notifyItemRangeRemoved(n, itemCount - 1);
+                notifyItemRangeRemoved(n, itemCount - n);
             }
         }
 
@@ -474,21 +473,11 @@
         return mHeader.getHeaderText();
     }
 
-    /**
-     * @return The progress indicator.
-     */
-    @VisibleForTesting
     ProgressItem getProgressItemForTesting() {
         return mProgressIndicator;
     }
 
-    @VisibleForTesting
-    ActionItem getActionItem() {
+    ActionItem getActionItemForTesting() {
         return mMoreButton;
     }
-
-    @VisibleForTesting
-    StatusItem getStatusItem() {
-        return mStatus;
-    }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShell.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShell.java
index ae07fda..8d1de1f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShell.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShell.java
@@ -19,6 +19,11 @@
     void initializeNative(Tab currentTab, VrShellDelegate delegate, boolean forWebVR);
 
     /**
+     * Swaps to the designated tab.
+     */
+    void swapTab(Tab currentTab);
+
+    /**
      * Pauses VrShell.
      */
     void pause();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java
index 70f379b..835a3c63 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java
@@ -30,6 +30,8 @@
 import org.chromium.chrome.browser.tab.EmptyTabObserver;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tab.TabObserver;
+import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver;
+import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -74,6 +76,7 @@
 
     private final ChromeTabbedActivity mActivity;
     private TabObserver mTabObserver;
+    private TabModelSelectorObserver mTabModelSelectorObserver;
     private Intent mEnterVRIntent;
 
     @VrSupportLevel
@@ -111,6 +114,7 @@
             mVrSupportLevel = VR_NOT_AVAILABLE;
             mEnterVRIntent = null;
             mTabObserver = null;
+            mTabModelSelectorObserver = null;
             return;
         }
 
@@ -147,6 +151,14 @@
                 }
             };
         }
+        if (mTabModelSelectorObserver == null) {
+            mTabModelSelectorObserver = new EmptyTabModelSelectorObserver() {
+                @Override
+                public void onChange() {
+                    swapToForegroundTab();
+                }
+            };
+        }
 
         mVrSupportLevel = mVrDaydreamApi.isDaydreamReadyDevice() ? VR_DAYDREAM : VR_CARDBOARD;
     }
@@ -250,6 +262,7 @@
         mVrShell.resume();
         mTab.updateFullscreenEnabledState();
         setEnterVRResult(true, requestedWebVR);
+        mActivity.getTabModelSelector().addObserver(mTabModelSelectorObserver);
     }
 
     private void setEnterVRResult(boolean success, boolean requestedWebVR) {
@@ -260,6 +273,22 @@
         mRequestedWebVR = false;
     }
 
+    private void swapToForegroundTab() {
+        Tab tab = mActivity.getActivityTab();
+        if (tab == mTab) return;
+        if (!canEnterVR(tab)) {
+            forceExitVr();
+            return;
+        }
+        mTab.removeObserver(mTabObserver);
+        mTab.updateFullscreenEnabledState();
+
+        mVrShell.swapTab(tab);
+        mTab = tab;
+        mTab.addObserver(mTabObserver);
+        mTab.updateFullscreenEnabledState();
+    }
+
     private boolean canEnterVR(Tab tab) {
         if (!LibraryLoader.isInitialized()) {
             return false;
@@ -511,6 +540,7 @@
             mVrClassesWrapper.setVrModeEnabled(false);
             mLastVRExit = SystemClock.uptimeMillis();
         }
+        mActivity.getTabModelSelector().removeObserver(mTabModelSelectorObserver);
         mActivity.setRequestedOrientation(mRestoreOrientation);
         mVrShell.pause();
         removeVrViews();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java
index fd53a659..4c73c02f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java
@@ -65,6 +65,7 @@
     private final CompositorViewHolder mCompositorViewHolder;
     private final VirtualDisplayAndroid mContentVirtualDisplay;
     private final VirtualDisplayAndroid mUiVirtualDisplay;
+    private final TabRedirectHandler mTabRedirectHandler;
 
     private long mNativeVrShell;
 
@@ -87,6 +88,9 @@
 
     private TabRedirectHandler mNonVrTabRedirectHandler;
     private TabModelSelector mTabModelSelector;
+    private float mLastContentWidth;
+    private float mLastContentHeight;
+    private float mLastContentDpr;
 
     public VrShellImpl(Activity activity, CompositorViewHolder compositorViewHolder) {
         super(activity);
@@ -123,6 +127,13 @@
         mContentVirtualDisplay.setTo(primaryDisplay);
         mUiVirtualDisplay = VirtualDisplayAndroid.createVirtualDisplay();
         mUiVirtualDisplay.setTo(primaryDisplay);
+
+        mTabRedirectHandler = new TabRedirectHandler(mActivity) {
+            @Override
+            public boolean shouldStayInChrome(boolean hasExternalProtocol) {
+                return true;
+            }
+        };
     }
 
     @Override
@@ -132,15 +143,6 @@
         mContentCVC = mTab.getContentViewCore();
         mContentVrWindowAndroid = new VrWindowAndroid(mActivity, mContentVirtualDisplay);
 
-        // Make sure we are not redirecting to another app, i.e. out of VR mode.
-        mNonVrTabRedirectHandler = mTab.getTabRedirectHandler();
-        mTab.setTabRedirectHandler(new TabRedirectHandler(mActivity) {
-            @Override
-            public boolean shouldStayInChrome(boolean hasExternalProtocol) {
-                return true;
-            }
-        });
-
         mUiVrWindowAndroid = new VrWindowAndroid(mActivity, mUiVirtualDisplay);
         mUiContents = WebContentsFactory.createWebContents(true, false);
         mUiCVC = new ContentViewCore(mActivity, ChromeVersionInfo.getProductVersion());
@@ -187,9 +189,35 @@
         mUiCVC.setTopControlsHeight(0, false);
         mUiVrWindowAndroid.onVisibilityChanged(true);
 
+        initializeTabForVR();
+    }
+
+    private void initializeTabForVR() {
         mOriginalWindowAndroid = mContentCVC.getWindowAndroid();
         mTab.updateWindowAndroid(mContentVrWindowAndroid);
         mContentCVC.onAttachedToWindow();
+
+        // Make sure we are not redirecting to another app, i.e. out of VR mode.
+        mNonVrTabRedirectHandler = mTab.getTabRedirectHandler();
+        mTab.setTabRedirectHandler(mTabRedirectHandler);
+    }
+
+    private void restoreTabFromVR() {
+        mTab.setTabRedirectHandler(mNonVrTabRedirectHandler);
+        mTab.updateWindowAndroid(mOriginalWindowAndroid);
+        mOriginalWindowAndroid = null;
+        mNonVrTabRedirectHandler = null;
+    }
+
+    @Override
+    public void swapTab(final Tab newTab) {
+        restoreTabFromVR();
+        mTab = newTab;
+        mContentCVC = mTab.getContentViewCore();
+        initializeTabForVR();
+
+        nativeSwapContents(mNativeVrShell, mContentCVC.getWebContents());
+        setContentCssSize(mLastContentWidth, mLastContentHeight, mLastContentDpr);
     }
 
     @CalledByNative
@@ -212,6 +240,9 @@
     @CalledByNative
     public void setContentCssSize(float width, float height, float dpr) {
         ThreadUtils.assertOnUiThread();
+        mLastContentWidth = width;
+        mLastContentHeight = height;
+        mLastContentDpr = dpr;
         int surfaceWidth = (int) Math.ceil(width * dpr);
         int surfaceHeight = (int) Math.ceil(height * dpr);
 
@@ -270,15 +301,12 @@
             nativeDestroy(mNativeVrShell);
             mNativeVrShell = 0;
         }
-        mCompositorViewHolder.onExitVR(mTabModelSelector);
-        mTab.setTabRedirectHandler(mNonVrTabRedirectHandler);
-        mTab.updateWindowAndroid(mOriginalWindowAndroid);
-        mContentCVC.onSizeChanged(mContentCVC.getContainerView().getWidth(),
-                mContentCVC.getContainerView().getHeight(), 0, 0);
+        restoreTabFromVR();
         mUiContents.destroy();
         mContentVirtualDisplay.destroy();
         mUiVirtualDisplay.destroy();
         super.shutdown();
+        mCompositorViewHolder.onExitVR(mTabModelSelector);
     }
 
     @Override
@@ -333,6 +361,7 @@
             long nativeContentWindowAndroid, WebContents uiWebContents, long nativeUiWindowAndroid,
             boolean forWebVR, VrShellDelegate delegate, long gvrApi, boolean reprojectedRendering);
     private native void nativeSetSurface(long nativeVrShell, Surface surface);
+    private native void nativeSwapContents(long nativeVrShell, WebContents webContents);
     private native void nativeLoadUIContent(long nativeVrShell);
     private native void nativeDestroy(long nativeVrShell);
     private native void nativeOnTriggerEvent(long nativeVrShell);
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni
index 38f2ca1..6d2105e 100644
--- a/chrome/android/java_sources.gni
+++ b/chrome/android/java_sources.gni
@@ -1396,6 +1396,7 @@
   "javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPaymentAppCanMakePaymentQueryTest.java",
   "javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPaymentAppAndCardsTest.java",
   "javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPaymentAppTest.java",
+  "javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPaymentAppUiSkipTest.java",
   "javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPhoneTest.java",
   "javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPhoneAndFreeShippingTest.java",
   "javatests/src/org/chromium/chrome/browser/payments/PaymentRequestRemoveBillingAddressTest.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPaymentAppUiSkipTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPaymentAppUiSkipTest.java
new file mode 100644
index 0000000..a158a26
--- /dev/null
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPaymentAppUiSkipTest.java
@@ -0,0 +1,80 @@
+// 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.payments;
+
+import android.support.test.filters.MediumTest;
+
+import org.chromium.base.test.util.Feature;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * A payment integration test for a merchant that requests payment via Bob Pay when performing the
+ * single payment app UI skip optimization.
+ */
+public class PaymentRequestPaymentAppUiSkipTest extends PaymentRequestTestBase {
+    public PaymentRequestPaymentAppUiSkipTest() {
+        super("payment_request_bobpay_ui_skip_test.html");
+    }
+
+    @Override
+    public void onMainActivityStarted()
+            throws InterruptedException, ExecutionException, TimeoutException {}
+
+    /**
+     * If Bob Pay is supported and installed, user should be able to pay with it. Here Bob Pay
+     * responds to Chrome immediately.
+     */
+    @MediumTest
+    @Feature({"Payments"})
+    public void testPayViaFastBobPay()
+            throws InterruptedException, ExecutionException, TimeoutException {
+        installPaymentApp(HAVE_INSTRUMENTS, IMMEDIATE_RESPONSE);
+        openPageAndClickBuyAndWait(mDismissed);
+        expectResultContains(new String[] {"https://bobpay.com", "\"transaction\"", "1337"});
+    }
+
+    /**
+     * If Bob Pay is supported and installed, user should be able to pay with it. Here Bob Pay
+     * responds to Chrome after a slight delay.
+     */
+    @MediumTest
+    @Feature({"Payments"})
+    public void testPayViaSlowBobPay()
+            throws InterruptedException, ExecutionException, TimeoutException {
+        installPaymentApp(HAVE_INSTRUMENTS, DELAYED_RESPONSE);
+        openPageAndClickBuyAndWait(mDismissed);
+        expectResultContains(new String[] {"https://bobpay.com", "\"transaction\"", "1337"});
+    }
+
+    /**
+     * Test payment with a Bob Pay that is created with a delay, but responds immediately
+     * to getInstruments.
+     */
+    @MediumTest
+    @Feature({"Payments"})
+    public void testPayViaDelayedFastBobPay()
+            throws InterruptedException, ExecutionException, TimeoutException {
+        installPaymentApp(
+                "https://bobpay.com", HAVE_INSTRUMENTS, IMMEDIATE_RESPONSE, DELAYED_CREATION);
+        openPageAndClickBuyAndWait(mDismissed);
+        expectResultContains(new String[] {"https://bobpay.com", "\"transaction\"", "1337"});
+    }
+
+    /**
+     * Test payment with a Bob Pay that is created with a delay, and responds slowly to
+     * getInstruments.
+     */
+    @MediumTest
+    @Feature({"Payments"})
+    public void testPayViaDelayedSlowBobPay()
+            throws InterruptedException, ExecutionException, TimeoutException {
+        installPaymentApp(
+                "https://bobpay.com", HAVE_INSTRUMENTS, DELAYED_RESPONSE, DELAYED_CREATION);
+        openPageAndClickBuyAndWait(mDismissed);
+        expectResultContains(new String[] {"https://bobpay.com", "\"transaction\"", "1337"});
+    }
+}
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/SectionListTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/SectionListTest.java
index 4d27499..e8d0cad 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/SectionListTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/SectionListTest.java
@@ -225,11 +225,11 @@
         bindViewHolders(sectionList);
 
         assertThat(sectionList.getSectionForTesting(KnownCategories.ARTICLES)
-                           .getActionItem()
+                           .getActionItemForTesting()
                            .getPerSectionRank(),
                 equalTo(0));
         assertThat(sectionList.getSectionForTesting(KnownCategories.DOWNLOADS)
-                           .getActionItem()
+                           .getActionItemForTesting()
                            .getPerSectionRank(),
                 equalTo(3));
     }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSectionTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSectionTest.java
index 678dd08..4450d7f 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSectionTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSectionTest.java
@@ -94,7 +94,7 @@
         SuggestionsSection section = createSectionWithReloadAction(true);
 
         section.setStatus(CategoryStatus.AVAILABLE);
-        assertNotNull(section.getActionItem());
+        assertNotNull(section.getActionItemForTesting());
 
         // Without snippets.
         assertEquals(ItemViewType.HEADER, section.getItemViewType(0));
@@ -120,7 +120,7 @@
         SuggestionsSection section = createSectionWithReloadAction(true);
 
         section.setStatus(CategoryStatus.AVAILABLE);
-        assertNotNull(section.getActionItem());
+        assertNotNull(section.getActionItemForTesting());
 
         // Without snippets.
         assertEquals(ItemViewType.HEADER, section.getItemViewType(0));
@@ -315,13 +315,13 @@
                         .build());
         SuggestionsSection section = createSection(info);
 
-        assertTrue(section.getActionItem().isVisible());
+        assertTrue(section.getActionItemForTesting().isVisible());
         verifyAction(section, ActionItem.ACTION_VIEW_ALL);
 
         section.setSuggestions(
                 createDummySuggestions(3), CategoryStatus.AVAILABLE, /* replaceExisting = */ true);
 
-        assertTrue(section.getActionItem().isVisible());
+        assertTrue(section.getActionItemForTesting().isVisible());
         verifyAction(section, ActionItem.ACTION_VIEW_ALL);
     }
 
@@ -340,13 +340,13 @@
                         .build());
         SuggestionsSection section = createSection(info);
 
-        assertTrue(section.getActionItem().isVisible());
+        assertTrue(section.getActionItemForTesting().isVisible());
         verifyAction(section, ActionItem.ACTION_RELOAD);
 
         section.setSuggestions(
                 createDummySuggestions(3), CategoryStatus.AVAILABLE, /* replaceExisting = */ true);
 
-        assertTrue(section.getActionItem().isVisible());
+        assertTrue(section.getActionItemForTesting().isVisible());
         verifyAction(section, ActionItem.ACTION_FETCH_MORE);
     }
 
@@ -360,13 +360,13 @@
                 new CategoryInfoBuilder(TEST_CATEGORY_ID).withReloadAction().showIfEmpty().build());
         SuggestionsSection section = createSection(info);
 
-        assertTrue(section.getActionItem().isVisible());
+        assertTrue(section.getActionItemForTesting().isVisible());
         verifyAction(section, ActionItem.ACTION_RELOAD);
 
         section.setSuggestions(
                 createDummySuggestions(3), CategoryStatus.AVAILABLE, /* replaceExisting = */ true);
 
-        assertFalse(section.getActionItem().isVisible());
+        assertFalse(section.getActionItemForTesting().isVisible());
         verifyAction(section, ActionItem.ACTION_NONE);
     }
 
@@ -380,13 +380,13 @@
                 new CategoryInfoBuilder(TEST_CATEGORY_ID).withMoreAction().showIfEmpty().build());
         SuggestionsSection section = createSection(info);
 
-        assertFalse(section.getActionItem().isVisible());
+        assertFalse(section.getActionItemForTesting().isVisible());
         verifyAction(section, ActionItem.ACTION_NONE);
 
         section.setSuggestions(
                 createDummySuggestions(3), CategoryStatus.AVAILABLE, /* replaceExisting = */ true);
 
-        assertTrue(section.getActionItem().isVisible());
+        assertTrue(section.getActionItemForTesting().isVisible());
         verifyAction(section, ActionItem.ACTION_FETCH_MORE);
     }
 
@@ -400,13 +400,13 @@
                 spy(new CategoryInfoBuilder(TEST_CATEGORY_ID).showIfEmpty().build());
         SuggestionsSection section = createSection(info);
 
-        assertFalse(section.getActionItem().isVisible());
+        assertFalse(section.getActionItemForTesting().isVisible());
         verifyAction(section, ActionItem.ACTION_NONE);
 
         section.setSuggestions(
                 createDummySuggestions(3), CategoryStatus.AVAILABLE, /* replaceExisting = */ true);
 
-        assertFalse(section.getActionItem().isVisible());
+        assertFalse(section.getActionItemForTesting().isVisible());
         verifyAction(section, ActionItem.ACTION_NONE);
     }
 
@@ -443,6 +443,8 @@
 
         section.setSuggestions(createDummySuggestions(3, TEST_CATEGORY_ID),
                 CategoryStatus.AVAILABLE, /* replaceExisting = */ true);
+        verify(mParent).onItemRangeRemoved(section, 1, 4);
+        verify(mParent).onItemRangeInserted(section, 1, 3);
         assertEquals(3, section.getSuggestionsCount());
     }
 
@@ -463,6 +465,8 @@
 
         section.setSuggestions(createDummySuggestions(3, TEST_CATEGORY_ID),
                 CategoryStatus.AVAILABLE, /* replaceExisting = */ true);
+        verify(mParent, never()).onItemRangeRemoved(any(TreeNode.class), anyInt(), anyInt());
+        verify(mParent, never()).onItemRangeInserted(any(TreeNode.class), anyInt(), anyInt());
         assertEquals(4, section.getSuggestionsCount());
     }
 
@@ -487,10 +491,14 @@
         // Copy the list when passing to the section - it may alter it but we later need it.
         section.setSuggestions(new ArrayList<>(newSnippets), CategoryStatus.AVAILABLE,
                 /* replaceExisting = */ true);
+        verify(mParent).onItemRangeRemoved(section, 2, 3);
+        verify(mParent).onItemRangeInserted(section, 2, 2);
         assertEquals(3, section.getSuggestionsCount());
         assertEquals(snippets.get(0), section.getSuggestionAt(1));
         assertNotEquals(snippets.get(1), section.getSuggestionAt(2));
         assertEquals(newSnippets.get(0), section.getSuggestionAt(2));
+        assertNotEquals(snippets.get(2), section.getSuggestionAt(3));
+        assertEquals(newSnippets.get(1), section.getSuggestionAt(3));
     }
 
     /**
@@ -515,6 +523,8 @@
         // Copy the list when passing to the section - it may alter it but we later need it.
         section.setSuggestions(new ArrayList<>(newSnippets), CategoryStatus.AVAILABLE,
                 /* replaceExisting = */ true);
+        verify(mParent).onItemRangeRemoved(section, 3, 2);
+        verify(mParent).onItemRangeInserted(section, 3, 1);
         assertEquals(3, section.getSuggestionsCount());
         assertEquals(snippets.get(0), section.getSuggestionAt(1));
         assertEquals(snippets.get(1), section.getSuggestionAt(2));
@@ -543,6 +553,8 @@
                 CategoryStatus.AVAILABLE, /* replaceExisting = */ true);
         // Even though the new list has just one suggestion, we need to keep the two seen ones
         // around.
+        verify(mParent).onItemRangeRemoved(section, 3, 2);
+        verify(mParent, never()).onItemRangeInserted(any(TreeNode.class), anyInt(), anyInt());
         assertEquals(2, section.getSuggestionsCount());
         assertEquals(snippets.get(0), section.getSuggestionAt(1));
         assertEquals(snippets.get(1), section.getSuggestionAt(2));
@@ -568,12 +580,15 @@
         // Remove last two items.
         section.removeSuggestionById(section.getSuggestionAt(3).mIdWithinCategory);
         section.removeSuggestionById(section.getSuggestionAt(2).mIdWithinCategory);
+        reset(mParent);
 
         assertEquals(1, section.getSuggestionsCount());
 
         section.setSuggestions(createDummySuggestions(4, TEST_CATEGORY_ID),
                 CategoryStatus.AVAILABLE, /* replaceExisting = */ true);
         // We do not touch the current list if all has been seen.
+        verify(mParent, never()).onItemRangeRemoved(any(TreeNode.class), anyInt(), anyInt());
+        verify(mParent, never()).onItemRangeInserted(any(TreeNode.class), anyInt(), anyInt());
         assertEquals(1, section.getSuggestionsCount());
         assertEquals(snippets.get(0), section.getSuggestionAt(1));
     }
@@ -593,6 +608,8 @@
 
         section.setSuggestions(createDummySuggestions(3, TEST_CATEGORY_ID),
                 CategoryStatus.AVAILABLE, /* replaceExisting = */ true);
+        verify(mParent, never()).onItemRangeRemoved(any(TreeNode.class), anyInt(), anyInt());
+        verify(mParent, never()).onItemRangeInserted(any(TreeNode.class), anyInt(), anyInt());
 
         // All old snippets should be in place.
         verifySnippets(section, snippets);
@@ -631,6 +648,10 @@
         SuggestionsSection section = createSectionWithReloadAction(true);
         section.setStatus(CategoryStatus.AVAILABLE);
         section.setSuggestions(snippets, CategoryStatus.AVAILABLE, /* replaceExisting = */ true);
+
+        // Reset any notification invocations on the parent from setting the initial list
+        // of suggestions.
+        reset(mParent);
         return section;
     }
 
@@ -667,7 +688,7 @@
         when(manager.getMetricsReporter()).thenReturn(mock(SuggestionsMetricsReporter.class));
 
         if (action != ActionItem.ACTION_NONE) {
-            section.getActionItem().performAction(manager);
+            section.getActionItemForTesting().performAction(manager);
         }
 
         verify(section.getCategoryInfo(),
diff --git a/chrome/app/resources/locale_settings_mac.grd b/chrome/app/resources/locale_settings_mac.grd
index 812c18b..3b49d1d4 100644
--- a/chrome/app/resources/locale_settings_mac.grd
+++ b/chrome/app/resources/locale_settings_mac.grd
@@ -215,7 +215,7 @@
       <!-- The default value for |WebPreference::serif_font_family_map| for
            Simplified Chinese script. -->
       <message name="IDS_SERIF_FONT_FAMILY_SIMPLIFIED_HAN" use_name_for_id="true">
-        STSong
+        Songti SC
       </message>
 
       <!-- The default value for |WebPreference::sans_serif_font_family_map| for
@@ -239,7 +239,7 @@
       <!-- The default value for |WebPreference::serif_font_family_map| for
            Traditional Chinese script. -->
       <message name="IDS_SERIF_FONT_FAMILY_TRADITIONAL_HAN" use_name_for_id="true">
-        LiSong Pro
+        Songti TC
       </message>
 
       <!-- The default value for |WebPreference::sans_serif_font_family_map| for
diff --git a/chrome/app/resources/platform_locale_settings/locale_settings_mac_zh-CN.xtb b/chrome/app/resources/platform_locale_settings/locale_settings_mac_zh-CN.xtb
index eaac82c..caa09d2 100644
--- a/chrome/app/resources/platform_locale_settings/locale_settings_mac_zh-CN.xtb
+++ b/chrome/app/resources/platform_locale_settings/locale_settings_mac_zh-CN.xtb
@@ -2,7 +2,7 @@
 <!DOCTYPE translationbundle>
 <translationbundle lang="zh-CN">
 <translation id="IDS_STANDARD_FONT_FAMILY">,PingFang SC,STHeiti</translation>
-<translation id="IDS_SERIF_FONT_FAMILY">STSong</translation>
+<translation id="IDS_SERIF_FONT_FAMILY">Songti SC</translation>
 <translation id="IDS_SANS_SERIF_FONT_FAMILY">,PingFang SC,STHeiti</translation>
 <translation id="IDS_CURSIVE_FONT_FAMILY">Kaiti SC</translation>
 <translation id="IDS_MINIMUM_FONT_SIZE">12</translation>
diff --git a/chrome/app/resources/platform_locale_settings/locale_settings_mac_zh-TW.xtb b/chrome/app/resources/platform_locale_settings/locale_settings_mac_zh-TW.xtb
index 0ea5a9d..664a81b 100644
--- a/chrome/app/resources/platform_locale_settings/locale_settings_mac_zh-TW.xtb
+++ b/chrome/app/resources/platform_locale_settings/locale_settings_mac_zh-TW.xtb
@@ -2,7 +2,7 @@
 <!DOCTYPE translationbundle>
 <translationbundle lang="zh-TW">
 <translation id="IDS_STANDARD_FONT_FAMILY">,PingFang TC,Heiti TC</translation>
-<translation id="IDS_SERIF_FONT_FAMILY">LiSong Pro</translation>
+<translation id="IDS_SERIF_FONT_FAMILY">Songti TC</translation>
 <translation id="IDS_SANS_SERIF_FONT_FAMILY">,PingFang TC,Heiti TC</translation>
 <translation id="IDS_CURSIVE_FONT_FAMILY">Kaiti TC</translation>
 <translation id="IDS_MINIMUM_FONT_SIZE">12</translation>
diff --git a/chrome/browser/android/chrome_feature_list.cc b/chrome/browser/android/chrome_feature_list.cc
index 8cbc9319..fb40a0d 100644
--- a/chrome/browser/android/chrome_feature_list.cc
+++ b/chrome/browser/android/chrome_feature_list.cc
@@ -147,7 +147,7 @@
                                           base::FEATURE_DISABLED_BY_DEFAULT};
 
 const base::Feature kWebPaymentsSingleAppUiSkip{
-    "WebPaymentsSingleAppUiSkip", base::FEATURE_DISABLED_BY_DEFAULT};
+    "WebPaymentsSingleAppUiSkip", base::FEATURE_ENABLED_BY_DEFAULT};
 
 static jboolean IsEnabled(JNIEnv* env,
                           const JavaParamRef<jclass>& clazz,
diff --git a/chrome/browser/android/omnibox/omnibox_prerender.cc b/chrome/browser/android/omnibox/omnibox_prerender.cc
index 2d4bd40..5342880 100644
--- a/chrome/browser/android/omnibox/omnibox_prerender.cc
+++ b/chrome/browser/android/omnibox/omnibox_prerender.cc
@@ -11,7 +11,6 @@
 #include "chrome/browser/predictors/autocomplete_action_predictor_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_android.h"
-#include "chrome/browser/ui/search/instant_search_prerenderer.h"
 #include "components/omnibox/browser/autocomplete_match.h"
 #include "components/omnibox/browser/autocomplete_result.h"
 #include "content/public/browser/web_contents.h"
@@ -91,26 +90,15 @@
   if (default_match == autocomplete_result->end())
     return;
 
-  AutocompleteActionPredictor::Action recommended_action =
-      AutocompleteActionPredictor::ACTION_NONE;
-  InstantSearchPrerenderer* prerenderer =
-      InstantSearchPrerenderer::GetForProfile(profile);
-  if (prerenderer &&
-      prerenderer->IsAllowed(*default_match, web_contents)) {
-    recommended_action = AutocompleteActionPredictor::ACTION_PRERENDER;
-  } else {
-    AutocompleteActionPredictor* action_predictor =
-        AutocompleteActionPredictorFactory::GetForProfile(profile);
-    if (!action_predictor)
-      return;
+  AutocompleteActionPredictor* action_predictor =
+      AutocompleteActionPredictorFactory::GetForProfile(profile);
+  if (!action_predictor)
+    return;
 
-    if (action_predictor) {
-      action_predictor->
-          RegisterTransitionalMatches(url_string, *autocomplete_result);
-      recommended_action =
-          action_predictor->RecommendAction(url_string, *default_match);
-    }
-  }
+  action_predictor->
+      RegisterTransitionalMatches(url_string, *autocomplete_result);
+  AutocompleteActionPredictor::Action recommended_action =
+      action_predictor->RecommendAction(url_string, *default_match);
 
   GURL current_url = GURL(current_url_string);
   switch (recommended_action) {
@@ -145,14 +133,6 @@
   if (!web_contents)
     return;
   gfx::Rect container_bounds = web_contents->GetContainerBounds();
-  InstantSearchPrerenderer* prerenderer =
-      InstantSearchPrerenderer::GetForProfile(profile);
-  if (prerenderer && prerenderer->IsAllowed(match, web_contents)) {
-    prerenderer->Init(
-        web_contents->GetController().GetDefaultSessionStorageNamespace(),
-        container_bounds.size());
-    return;
-  }
   predictors::AutocompleteActionPredictorFactory::GetForProfile(profile)->
       StartPrerendering(
           match.destination_url,
diff --git a/chrome/browser/android/vr_shell/vr_compositor.cc b/chrome/browser/android/vr_shell/vr_compositor.cc
index 882236f..e386d90 100644
--- a/chrome/browser/android/vr_shell/vr_compositor.cc
+++ b/chrome/browser/android/vr_shell/vr_compositor.cc
@@ -20,12 +20,8 @@
 }
 
 VrCompositor::~VrCompositor() {
-  if (layer_) {
-    layer_->SetBackgroundColor(background_color_);
-    if (layer_parent_) {
-      layer_parent_->AddChild(layer_);
-    }
-  }
+  if (layer_)
+    RestoreLayer();
 }
 
 void VrCompositor::UpdateLayerTreeHost() {}
@@ -33,7 +29,8 @@
 void VrCompositor::OnSwapBuffersCompleted(int pending_swap_buffers) {}
 
 void VrCompositor::SetLayer(content::WebContents* web_contents) {
-  assert(layer_ == nullptr);
+  if (layer_)
+    RestoreLayer();
   ui::ViewAndroid* view_android = web_contents->GetNativeView();
 
   // When we pass the layer for the ContentViewCore to the compositor it may be
@@ -50,6 +47,13 @@
   compositor_->SetRootLayer(layer_);
 }
 
+void VrCompositor::RestoreLayer() {
+  layer_->SetBackgroundColor(background_color_);
+  if (layer_parent_) {
+    layer_parent_->AddChild(layer_);
+  }
+}
+
 void VrCompositor::SurfaceDestroyed() {
   compositor_->SetSurface(nullptr);
 }
diff --git a/chrome/browser/android/vr_shell/vr_compositor.h b/chrome/browser/android/vr_shell/vr_compositor.h
index a0e87202..7238ad8 100644
--- a/chrome/browser/android/vr_shell/vr_compositor.h
+++ b/chrome/browser/android/vr_shell/vr_compositor.h
@@ -45,6 +45,8 @@
   void OnSwapBuffersCompleted(int pending_swap_buffers) override;
 
  private:
+  void RestoreLayer();
+
   std::unique_ptr<content::Compositor> compositor_;
   gfx::Size bounds_;
 
diff --git a/chrome/browser/android/vr_shell/vr_input_manager.cc b/chrome/browser/android/vr_shell/vr_input_manager.cc
index e8ceb40c..efb98cb 100644
--- a/chrome/browser/android/vr_shell/vr_input_manager.cc
+++ b/chrome/browser/android/vr_shell/vr_input_manager.cc
@@ -30,16 +30,11 @@
 }  // namespace
 
 VrInputManager::VrInputManager(content::WebContents* web_contents)
-    : web_contents_(web_contents),
-      weak_ptr_factory_(this) {
+    : web_contents_(web_contents) {
 }
 
 VrInputManager::~VrInputManager() = default;
 
-base::WeakPtr<VrInputManager> VrInputManager::GetWeakPtr() {
-  return weak_ptr_factory_.GetWeakPtr();
-}
-
 void VrInputManager::ProcessUpdatedGesture(
     std::unique_ptr<blink::WebInputEvent> event) {
   if (WebInputEvent::isMouseEventType(event->type())) {
diff --git a/chrome/browser/android/vr_shell/vr_input_manager.h b/chrome/browser/android/vr_shell/vr_input_manager.h
index f80b331..8e4e70d8 100644
--- a/chrome/browser/android/vr_shell/vr_input_manager.h
+++ b/chrome/browser/android/vr_shell/vr_input_manager.h
@@ -23,7 +23,6 @@
   explicit VrInputManager(content::WebContents* web_contents);
   ~VrInputManager();
 
-  base::WeakPtr<VrInputManager> GetWeakPtr();
   void ProcessUpdatedGesture(std::unique_ptr<blink::WebInputEvent> event);
 
  private:
@@ -33,8 +32,6 @@
 
   content::WebContents* web_contents_;
 
-  base::WeakPtrFactory<VrInputManager> weak_ptr_factory_;
-
   DISALLOW_COPY_AND_ASSIGN(VrInputManager);
 };
 
diff --git a/chrome/browser/android/vr_shell/vr_shell.cc b/chrome/browser/android/vr_shell/vr_shell.cc
index 2704107f..4cba25a 100644
--- a/chrome/browser/android/vr_shell/vr_shell.cc
+++ b/chrome/browser/android/vr_shell/vr_shell.cc
@@ -27,6 +27,7 @@
 #include "content/public/common/referrer.h"
 #include "device/vr/android/gvr/gvr_device_provider.h"
 #include "jni/VrShellImpl_jni.h"
+#include "third_party/WebKit/public/platform/WebInputEvent.h"
 #include "ui/android/view_android.h"
 #include "ui/android/window_android.h"
 #include "ui/base/page_transition_types.h"
@@ -46,16 +47,12 @@
 class GLThread : public base::Thread {
  public:
   GLThread(const base::WeakPtr<VrShell>& weak_vr_shell,
-           const base::WeakPtr<VrInputManager>& content_input_manager,
-           const base::WeakPtr<VrInputManager>& ui_input_manager,
            scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner,
            gvr_context* gvr_api,
            bool initially_web_vr,
            bool reprojected_rendering)
       : base::Thread("VrShellGL"),
         weak_vr_shell_(weak_vr_shell),
-        content_input_manager_(content_input_manager),
-        ui_input_manager_(ui_input_manager),
         main_thread_task_runner_(std::move(main_thread_task_runner)),
         gvr_api_(gvr_api),
         initially_web_vr_(initially_web_vr),
@@ -70,8 +67,6 @@
  protected:
   void Init() override {
     vr_shell_gl_.reset(new VrShellGl(std::move(weak_vr_shell_),
-                                     std::move(content_input_manager_),
-                                     std::move(ui_input_manager_),
                                      std::move(main_thread_task_runner_),
                                      gvr_api_,
                                      initially_web_vr_,
@@ -89,14 +84,17 @@
   base::WeakPtr<VrShellGl> weak_vr_shell_gl_;
 
   base::WeakPtr<VrShell> weak_vr_shell_;
-  base::WeakPtr<VrInputManager> content_input_manager_;
-  base::WeakPtr<VrInputManager> ui_input_manager_;
   scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
   gvr_context* gvr_api_;
   bool initially_web_vr_;
   bool reprojected_rendering_;
 };
 
+void SetIsInVR(content::WebContents* contents, bool is_in_vr) {
+  if (contents->GetRenderWidgetHostView())
+    contents->GetRenderWidgetHostView()->SetIsInVR(is_in_vr);
+}
+
 }  // namespace
 
 VrShell::VrShell(JNIEnv* env,
@@ -111,11 +109,12 @@
                  bool reprojected_rendering)
     : WebContentsObserver(ui_contents),
       main_contents_(main_contents),
-      content_compositor_(new VrCompositor(content_window, false)),
+      content_compositor_(
+          base::MakeUnique<VrCompositor>(content_window, false)),
       ui_contents_(ui_contents),
-      ui_compositor_(new VrCompositor(ui_window, true)),
+      ui_compositor_(base::MakeUnique<VrCompositor>(ui_window, true)),
       delegate_(delegate),
-      metrics_helper_(new VrMetricsHelper(main_contents_)),
+      metrics_helper_(base::MakeUnique<VrMetricsHelper>(main_contents_)),
       main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()),
       reprojected_rendering_(reprojected_rendering),
       weak_ptr_factory_(this) {
@@ -123,19 +122,15 @@
   g_instance = this;
   j_vr_shell_.Reset(env, obj);
 
-  content_input_manager_.reset(new VrInputManager(main_contents_));
-  ui_input_manager_.reset(new VrInputManager(ui_contents_));
+  content_input_manager_ = base::MakeUnique<VrInputManager>(main_contents_);
+  ui_input_manager_ = base::MakeUnique<VrInputManager>(ui_contents_);
 
   content_compositor_->SetLayer(main_contents_);
   ui_compositor_->SetLayer(ui_contents_);
 
-  gl_thread_.reset(new GLThread(weak_ptr_factory_.GetWeakPtr(),
-                                content_input_manager_->GetWeakPtr(),
-                                ui_input_manager_->GetWeakPtr(),
-                                main_thread_task_runner_,
-                                gvr_api,
-                                for_web_vr,
-                                reprojected_rendering_));
+  gl_thread_ = base::MakeUnique<GLThread>(weak_ptr_factory_.GetWeakPtr(),
+                                          main_thread_task_runner_, gvr_api,
+                                          for_web_vr, reprojected_rendering_);
 
   base::Thread::Options options(base::MessageLoop::TYPE_DEFAULT, 0);
   options.priority = base::ThreadPriority::DISPLAY;
@@ -143,19 +138,39 @@
 
   if (for_web_vr)
     metrics_helper_->SetWebVREnabled(true);
-  html_interface_.reset(new UiInterface(
+  html_interface_ = base::MakeUnique<UiInterface>(
       for_web_vr ? UiInterface::Mode::WEB_VR : UiInterface::Mode::STANDARD,
-      main_contents_->IsFullscreen()));
-  vr_web_contents_observer_.reset(new VrWebContentsObserver(
-      main_contents, html_interface_.get(), this));
+      main_contents_->IsFullscreen());
+  vr_web_contents_observer_ = base::MakeUnique<VrWebContentsObserver>(
+      main_contents_, html_interface_.get(), this);
 
-  SetIsInVR(true);
+  SetIsInVR(main_contents_, true);
 }
 
 void VrShell::Destroy(JNIEnv* env, const JavaParamRef<jobject>& obj) {
   delete this;
 }
 
+void VrShell::SwapContents(JNIEnv* env, const JavaParamRef<jobject>& obj,
+                           const JavaParamRef<jobject>& web_contents) {
+  SetIsInVR(main_contents_, false);
+  content::WebContents* contents =
+      content::WebContents::FromJavaWebContents(web_contents);
+  main_contents_ = contents;
+  content_input_manager_ = base::MakeUnique<VrInputManager>(main_contents_);
+  content_compositor_->SetLayer(main_contents_);
+  vr_web_contents_observer_ = base::MakeUnique<VrWebContentsObserver>(
+      main_contents_, html_interface_.get(), this);
+  SetIsInVR(main_contents_, true);
+
+  // TODO(billorr): Make VrMetricsHelper tab-aware and able to track multiple
+  // tabs. crbug.com/684661
+  metrics_helper_ = base::MakeUnique<VrMetricsHelper>(main_contents_);
+  metrics_helper_->SetVRActive(true);
+  metrics_helper_->SetWebVREnabled(
+      html_interface_->GetMode() == UiInterface::Mode::WEB_VR);
+}
+
 void VrShell::LoadUIContent(JNIEnv* env, const JavaParamRef<jobject>& obj) {
   GURL url(kVrShellUIURL);
   ui_contents_->GetController().LoadURL(
@@ -209,7 +224,7 @@
 
   // exit vr session
   metrics_helper_->SetVRActive(false);
-  SetIsInVR(false);
+  SetIsInVR(main_contents_, false);
 }
 
 void VrShell::OnResume(JNIEnv* env, const JavaParamRef<jobject>& obj) {
@@ -218,7 +233,7 @@
       FROM_HERE, base::Bind(&VrShellGl::OnResume, thread->GetVrShellGl()));
 
   metrics_helper_->SetVRActive(true);
-  SetIsInVR(true);
+  SetIsInVR(main_contents_, true);
 }
 
 void VrShell::SetSurface(JNIEnv* env,
@@ -233,10 +248,6 @@
                                      base::Unretained(window)));
 }
 
-void VrShell::SetIsInVR(bool is_in_vr) {
-  main_contents_->GetRenderWidgetHostView()->SetIsInVR(is_in_vr);
-}
-
 base::WeakPtr<VrShell> VrShell::GetWeakPtr(
     const content::WebContents* web_contents) {
   // Ensure that the WebContents requesting the VrShell instance is the one
@@ -448,9 +459,11 @@
 
 void VrShell::ContentWasHidden() {
   // Ensure we don't continue sending input to it.
-  content_input_manager_.reset();
-  // TODO(mthiesse): Handle web contents being hidden.
-  ForceExitVr();
+  content_input_manager_ = nullptr;
+}
+
+void VrShell::ContentWasShown() {
+  content_input_manager_ = base::MakeUnique<VrInputManager>(main_contents_);
 }
 
 void VrShell::ForceExitVr() {
@@ -468,6 +481,21 @@
   Java_VrShellImpl_setUiCssSize(env, j_vr_shell_.obj(), width, height, dpr);
 }
 
+void VrShell::ProcessUIGesture(std::unique_ptr<blink::WebInputEvent> event) {
+  if (ui_input_manager_) {
+    ui_input_manager_->ProcessUpdatedGesture(std::move(event));
+  }
+
+}
+
+void VrShell::ProcessContentGesture(
+    std::unique_ptr<blink::WebInputEvent> event) {
+  if (content_input_manager_) {
+    content_input_manager_->ProcessUpdatedGesture(std::move(event));
+  }
+}
+
+
 // ----------------------------------------------------------------------------
 // Native JNI methods
 // ----------------------------------------------------------------------------
diff --git a/chrome/browser/android/vr_shell/vr_shell.h b/chrome/browser/android/vr_shell/vr_shell.h
index 8b71dc0..f0e83ec 100644
--- a/chrome/browser/android/vr_shell/vr_shell.h
+++ b/chrome/browser/android/vr_shell/vr_shell.h
@@ -24,6 +24,10 @@
 class Thread;
 }
 
+namespace blink {
+class WebInputEvent;
+}
+
 namespace content {
 class WebContents;
 }
@@ -65,7 +69,9 @@
           VrShellDelegate* delegate,
           gvr_context* gvr_api,
           bool reprojected_rendering);
-
+  void SwapContents(JNIEnv* env,
+                    const base::android::JavaParamRef<jobject>& obj,
+                    const base::android::JavaParamRef<jobject>& web_contents);
   void LoadUIContent(JNIEnv* env,
                      const base::android::JavaParamRef<jobject>& obj);
   void Destroy(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj);
@@ -89,6 +95,7 @@
   // Called when our WebContents have been hidden. Usually a sign that something
   // like another tab placed in front of it.
   void ContentWasHidden();
+  void ContentWasShown();
 
   // html/js UI hooks.
   static base::WeakPtr<VrShell> GetWeakPtr(
@@ -136,9 +143,11 @@
 
   void ForceExitVr();
 
+  void ProcessUIGesture(std::unique_ptr<blink::WebInputEvent> event);
+  void ProcessContentGesture(std::unique_ptr<blink::WebInputEvent> event);
+
  private:
   ~VrShell() override;
-  void SetIsInVR(bool is_in_vr);
   void PostToGlThreadWhenReady(const base::Closure& task);
 
   // content::WebContentsObserver implementation. All called on UI thread.
diff --git a/chrome/browser/android/vr_shell/vr_shell_gl.cc b/chrome/browser/android/vr_shell/vr_shell_gl.cc
index 93ffa9ab..f9a0af1 100644
--- a/chrome/browser/android/vr_shell/vr_shell_gl.cc
+++ b/chrome/browser/android/vr_shell/vr_shell_gl.cc
@@ -12,11 +12,11 @@
 #include "chrome/browser/android/vr_shell/ui_scene.h"
 #include "chrome/browser/android/vr_shell/vr_controller.h"
 #include "chrome/browser/android/vr_shell/vr_gl_util.h"
-#include "chrome/browser/android/vr_shell/vr_input_manager.h"
 #include "chrome/browser/android/vr_shell/vr_math.h"
 #include "chrome/browser/android/vr_shell/vr_shell.h"
 #include "chrome/browser/android/vr_shell/vr_shell_renderer.h"
 #include "third_party/WebKit/public/platform/WebInputEvent.h"
+#include "third_party/WebKit/public/platform/WebMouseEvent.h"
 #include "ui/gfx/vsync_provider.h"
 #include "ui/gl/android/scoped_java_surface.h"
 #include "ui/gl/android/surface_texture.h"
@@ -180,8 +180,6 @@
 
 VrShellGl::VrShellGl(
     const base::WeakPtr<VrShell>& weak_vr_shell,
-    const base::WeakPtr<VrInputManager>& content_input_manager,
-    const base::WeakPtr<VrInputManager>& ui_input_manager,
     scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner,
     gvr_context* gvr_api,
     bool initially_web_vr,
@@ -190,8 +188,6 @@
         surfaceless_rendering_(reprojected_rendering),
         task_runner_(base::ThreadTaskRunnerHandle::Get()),
         weak_vr_shell_(weak_vr_shell),
-        content_input_manager_(content_input_manager),
-        ui_input_manager_(ui_input_manager),
         main_thread_task_runner_(std::move(main_thread_task_runner)),
         weak_ptr_factory_(this) {
   GvrInit(gvr_api);
@@ -580,13 +576,12 @@
 void VrShellGl::SendGesture(InputTarget input_target,
                             std::unique_ptr<blink::WebInputEvent> event) {
   DCHECK(input_target != InputTarget::NONE);
-  const base::WeakPtr<VrInputManager>& weak_ptr =
-      input_target == InputTarget::CONTENT ? content_input_manager_
-                                           : ui_input_manager_;
+  auto&& target = input_target == InputTarget::CONTENT
+                      ? &VrShell::ProcessContentGesture
+                      : &VrShell::ProcessUIGesture;
   main_thread_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&VrInputManager::ProcessUpdatedGesture, weak_ptr,
-                 base::Passed(std::move(event))));
+      base::Bind(target, weak_vr_shell_, base::Passed(std::move(event))));
 }
 
 void VrShellGl::SetGvrPoseForWebVr(const gvr::Mat4f& pose, uint32_t pose_num) {
diff --git a/chrome/browser/android/vr_shell/vr_shell_gl.h b/chrome/browser/android/vr_shell/vr_shell_gl.h
index c5dce100..f38164b 100644
--- a/chrome/browser/android/vr_shell/vr_shell_gl.h
+++ b/chrome/browser/android/vr_shell/vr_shell_gl.h
@@ -36,7 +36,6 @@
 
 class UiScene;
 class VrController;
-class VrInputManager;
 class VrShell;
 class VrShellRenderer;
 struct ContentRectangle;
@@ -53,8 +52,6 @@
 
   VrShellGl(
       const base::WeakPtr<VrShell>& weak_vr_shell,
-      const base::WeakPtr<VrInputManager>& content_input_manager,
-      const base::WeakPtr<VrInputManager>& ui_input_manager,
       scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner,
       gvr_context* gvr_api,
       bool initially_web_vr,
@@ -176,8 +173,6 @@
   base::TimeDelta vsync_interval_;
 
   base::WeakPtr<VrShell> weak_vr_shell_;
-  base::WeakPtr<VrInputManager> content_input_manager_;
-  base::WeakPtr<VrInputManager> ui_input_manager_;
   scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
 
   base::WeakPtrFactory<VrShellGl> weak_ptr_factory_;
diff --git a/chrome/browser/android/vr_shell/vr_web_contents_observer.cc b/chrome/browser/android/vr_shell/vr_web_contents_observer.cc
index 77979416..7d819ee 100644
--- a/chrome/browser/android/vr_shell/vr_web_contents_observer.cc
+++ b/chrome/browser/android/vr_shell/vr_web_contents_observer.cc
@@ -81,6 +81,11 @@
   vr_shell_->ContentWasHidden();
 }
 
+void VrWebContentsObserver::WasShown() {
+  vr_shell_->ContentWasShown();
+}
+
+
 void VrWebContentsObserver::MainFrameWasResized(bool width_changed) {
   vr_shell_->ContentFrameWasResized(width_changed);
 }
diff --git a/chrome/browser/android/vr_shell/vr_web_contents_observer.h b/chrome/browser/android/vr_shell/vr_web_contents_observer.h
index a3102e13..de2652a 100644
--- a/chrome/browser/android/vr_shell/vr_web_contents_observer.h
+++ b/chrome/browser/android/vr_shell/vr_web_contents_observer.h
@@ -42,6 +42,7 @@
   void DidChangeVisibleSecurityState() override;
   void WebContentsDestroyed() override;
   void WasHidden() override;
+  void WasShown() override;
   void MainFrameWasResized(bool width_changed) override;
   void RenderViewHostChanged(content::RenderViewHost* old_host,
                              content::RenderViewHost* new_host) override;
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc
index 4e89ac2c..950fbba 100644
--- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc
+++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc
@@ -38,6 +38,7 @@
 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
 #include "chrome/browser/search_engines/template_url_service_factory.h"
 #include "chrome/browser/sessions/tab_restore_service_factory.h"
+#include "chrome/browser/translate/language_model_factory.h"
 #include "chrome/browser/web_data_service_factory.h"
 #include "chrome/common/features.h"
 #include "chrome/common/pref_names.h"
@@ -63,6 +64,7 @@
 #include "components/previews/core/previews_ui_service.h"
 #include "components/search_engines/template_url_service.h"
 #include "components/sessions/core/tab_restore_service.h"
+#include "components/translate/core/browser/language_model.h"
 #include "content/public/browser/plugin_data_remover.h"
 #include "content/public/browser/ssl_host_state_delegate.h"
 #include "content/public/browser/storage_partition.h"
@@ -375,6 +377,12 @@
                                                   filter, bookmark_model);
     }
 
+    translate::LanguageModel* language_model =
+        LanguageModelFactory::GetInstance()->GetForBrowserContext(profile_);
+    if (language_model) {
+      language_model->ClearHistory(delete_begin_, delete_end_);
+    }
+
 #if BUILDFLAG(ENABLE_EXTENSIONS)
     // The extension activity log contains details of which websites extensions
     // were active on. It therefore indirectly stores details of websites a
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc
index 009376f..86871d8 100644
--- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc
+++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc
@@ -27,6 +27,7 @@
 #include "chrome/browser/permissions/permission_decision_auto_blocker.h"
 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
 #include "chrome/browser/storage/durable_storage_permission_context.h"
+#include "chrome/browser/translate/language_model_factory.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
@@ -54,6 +55,7 @@
 #include "components/password_manager/core/browser/password_manager_test_utils.h"
 #include "components/password_manager/core/browser/password_store_consumer.h"
 #include "components/prefs/testing_pref_service.h"
+#include "components/translate/core/browser/language_model.h"
 #include "content/public/test/mock_download_manager.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "content/public/test/test_utils.h"
@@ -91,6 +93,7 @@
 using testing::_;
 using testing::ByRef;
 using testing::Eq;
+using testing::FloatEq;
 using testing::Invoke;
 using testing::IsEmpty;
 using testing::Matcher;
@@ -1739,3 +1742,35 @@
   EXPECT_THAT(remaining_nodes, SizeIs(1));
   EXPECT_THAT(remaining_nodes[0]->url().spec(), Eq("http://foo-2.org/"));
 }
+
+// Test that the remover clears language model data (normally added by the
+// ChromeTranslateClient).
+TEST_F(ChromeBrowsingDataRemoverDelegateTest,
+       LanguageModelClearedOnClearingCompleteHistory) {
+  translate::LanguageModel* language_model =
+      LanguageModelFactory::GetInstance()->GetForBrowserContext(GetProfile());
+
+  // Simulate browsing.
+  for (int i = 0; i < 100; i++) {
+    language_model->OnPageVisited("en");
+    language_model->OnPageVisited("en");
+    language_model->OnPageVisited("en");
+    language_model->OnPageVisited("es");
+  }
+
+  // Clearing a part of the history has no effect.
+  BlockUntilBrowsingDataRemoved(AnHourAgo(), base::Time::Max(),
+                                BrowsingDataRemover::REMOVE_HISTORY, false);
+
+  EXPECT_THAT(language_model->GetTopLanguages(), SizeIs(2));
+  EXPECT_THAT(language_model->GetLanguageFrequency("en"), FloatEq(0.75));
+  EXPECT_THAT(language_model->GetLanguageFrequency("es"), FloatEq(0.25));
+
+  // Clearing the full history does the trick.
+  BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(),
+                                BrowsingDataRemover::REMOVE_HISTORY, false);
+
+  EXPECT_THAT(language_model->GetTopLanguages(), SizeIs(0));
+  EXPECT_THAT(language_model->GetLanguageFrequency("en"), FloatEq(0.0));
+  EXPECT_THAT(language_model->GetLanguageFrequency("es"), FloatEq(0.0));
+}
diff --git a/chrome/browser/prerender/prerender_browsertest.cc b/chrome/browser/prerender/prerender_browsertest.cc
index 4b830e7a..5de302c 100644
--- a/chrome/browser/prerender/prerender_browsertest.cc
+++ b/chrome/browser/prerender/prerender_browsertest.cc
@@ -3110,6 +3110,31 @@
                    FINAL_STATUS_NEW_NAVIGATION_ENTRY, 1);
 }
 
+// Checks that the prerendering of a page for ORIGIN_OFFLINE is not canceled
+// when the prerendered page tries to make a second navigation entry.
+IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
+                       PrerenderNewNavigationEntryForOffline) {
+  // Navigate to about:blank to get the session storage namespace.
+  ui_test_utils::NavigateToURL(current_browser(), GURL(url::kAboutBlankURL));
+  content::SessionStorageNamespace* storage_namespace =
+      GetActiveWebContents()
+          ->GetController()
+          .GetDefaultSessionStorageNamespace();
+
+  std::unique_ptr<TestPrerender> test_prerender =
+      prerender_contents_factory()->ExpectPrerenderContents(
+          FINAL_STATUS_APP_TERMINATING);
+
+  const GURL url =
+      src_server()->GetURL(MakeAbsolute("/prerender/prerender_new_entry.html"));
+  std::unique_ptr<PrerenderHandle> prerender_handle(
+      GetPrerenderManager()->AddPrerenderForOffline(url, storage_namespace,
+                                                    gfx::Size(640, 480)));
+  ASSERT_EQ(prerender_handle->contents(), test_prerender->contents());
+  test_prerender->WaitForLoads(2);
+  ASSERT_EQ(1, GetActiveWebContents()->GetController().GetEntryCount());
+}
+
 // Attempt a swap-in in a new tab. The session storage doesn't match, so it
 // should not swap.
 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPageNewTab) {
diff --git a/chrome/browser/prerender/prerender_contents.cc b/chrome/browser/prerender/prerender_contents.cc
index aea147d..cbff038 100644
--- a/chrome/browser/prerender/prerender_contents.cc
+++ b/chrome/browser/prerender/prerender_contents.cc
@@ -577,6 +577,13 @@
 void PrerenderContents::DidNavigateMainFrame(
     const content::LoadCommittedDetails& details,
     const content::FrameNavigateParams& params) {
+  // Prevent ORIGIN_OFFLINE prerenders from being destroyed on location.href
+  // change, since the history is never merged for offline prerenders. Also
+  // avoid adding aliases as they may potentially mark other valid requests to
+  // offline as duplicate.
+  if (origin() == ORIGIN_OFFLINE)
+    return;
+
   // If the prerender made a second navigation entry, abort the prerender. This
   // avoids having to correctly implement a complex history merging case (this
   // interacts with location.replace) and correctly synchronize with the
diff --git a/chrome/browser/prerender/prerender_tab_helper.cc b/chrome/browser/prerender/prerender_tab_helper.cc
index bb34ce2..e9e6018 100644
--- a/chrome/browser/prerender/prerender_tab_helper.cc
+++ b/chrome/browser/prerender/prerender_tab_helper.cc
@@ -11,6 +11,7 @@
 #include "chrome/browser/prerender/prerender_manager.h"
 #include "chrome/browser/prerender/prerender_manager_factory.h"
 #include "chrome/browser/profiles/profile.h"
+#include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/resource_request_details.h"
 #include "content/public/browser/web_contents.h"
@@ -37,19 +38,21 @@
   MainFrameUrlDidChange(details.new_url);
 }
 
-void PrerenderTabHelper::DidCommitProvisionalLoadForFrame(
-    content::RenderFrameHost* render_frame_host,
-    const GURL& validated_url,
-    ui::PageTransition transition_type) {
-  if (render_frame_host->GetParent())
+void PrerenderTabHelper::DidFinishNavigation(
+      content::NavigationHandle* navigation_handle) {
+  if (!navigation_handle->IsInMainFrame() ||
+      !navigation_handle->HasCommitted() ||
+      navigation_handle->IsErrorPage()) {
     return;
-  url_ = validated_url;
+  }
+
+  url_ = navigation_handle->GetURL();
   PrerenderManager* prerender_manager = MaybeGetPrerenderManager();
   if (!prerender_manager)
     return;
   if (prerender_manager->IsWebContentsPrerendering(web_contents(), NULL))
     return;
-  prerender_manager->RecordNavigation(validated_url);
+  prerender_manager->RecordNavigation(url_);
 }
 
 void PrerenderTabHelper::DidStopLoading() {
@@ -90,10 +93,11 @@
   actual_load_start_ = base::TimeTicks();
 }
 
-void PrerenderTabHelper::DidStartProvisionalLoadForFrame(
-    content::RenderFrameHost* render_frame_host,
-    const GURL& validated_url,
-    bool is_error_page) {
+void PrerenderTabHelper::DidStartNavigation(
+    content::NavigationHandle* navigation_handle) {
+  if (navigation_handle->IsSamePage())
+    return;
+
   // Determine the navigation type.
   PrerenderManager* prerender_manager = MaybeGetPrerenderManager();
   if (prerender_manager &&
@@ -103,14 +107,14 @@
     navigation_type_ = NAVIGATION_TYPE_NORMAL;
   }
 
-  if (render_frame_host->GetParent())
+  if (!navigation_handle->IsInMainFrame())
     return;
 
   // Record PPLT state for the beginning of a new navigation.
   pplt_load_start_ = GetTimeTicksFromPrerenderManager();
   actual_load_start_ = base::TimeTicks();
 
-  MainFrameUrlDidChange(validated_url);
+  MainFrameUrlDidChange(navigation_handle->GetURL());
 }
 
 void PrerenderTabHelper::MainFrameUrlDidChange(const GURL& url) {
diff --git a/chrome/browser/prerender/prerender_tab_helper.h b/chrome/browser/prerender/prerender_tab_helper.h
index 5f96be28..f944aa1 100644
--- a/chrome/browser/prerender/prerender_tab_helper.h
+++ b/chrome/browser/prerender/prerender_tab_helper.h
@@ -32,14 +32,10 @@
   void DidGetRedirectForResourceRequest(
       const content::ResourceRedirectDetails& details) override;
   void DidStopLoading() override;
-  void DidStartProvisionalLoadForFrame(
-      content::RenderFrameHost* render_frame_host,
-      const GURL& validated_url,
-      bool is_error_page) override;
-  void DidCommitProvisionalLoadForFrame(
-      content::RenderFrameHost* render_frame_host,
-      const GURL& validated_url,
-      ui::PageTransition transition_type) override;
+  void DidStartNavigation(
+      content::NavigationHandle* navigation_handle) override;
+  void DidFinishNavigation(
+      content::NavigationHandle* navigation_handle) override;
 
   // Called when the URL of the main frame changed, either when the load
   // commits, or a redirect happens.
diff --git a/chrome/browser/sync/profile_sync_service_factory.cc b/chrome/browser/sync/profile_sync_service_factory.cc
index f9c8481..10671f8 100644
--- a/chrome/browser/sync/profile_sync_service_factory.cc
+++ b/chrome/browser/sync/profile_sync_service_factory.cc
@@ -152,7 +152,12 @@
   init_params.url_request_context = profile->GetRequestContext();
   init_params.debug_identifier = profile->GetDebugName();
   init_params.channel = chrome::GetChannel();
-  init_params.blocking_pool = content::BrowserThread::GetBlockingPool();
+  base::SequencedWorkerPool* blocking_pool =
+      content::BrowserThread::GetBlockingPool();
+  init_params.blocking_task_runner =
+      blocking_pool->GetSequencedTaskRunnerWithShutdownBehavior(
+          blocking_pool->GetSequenceToken(),
+          base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
 
   bool local_sync_backend_enabled = false;
 
diff --git a/chrome/browser/sync/profile_sync_test_util.cc b/chrome/browser/sync/profile_sync_test_util.cc
index c06b04f..c59b3c0 100644
--- a/chrome/browser/sync/profile_sync_test_util.cc
+++ b/chrome/browser/sync/profile_sync_test_util.cc
@@ -55,7 +55,12 @@
   init_params.url_request_context = profile->GetRequestContext();
   init_params.debug_identifier = profile->GetDebugName();
   init_params.channel = chrome::GetChannel();
-  init_params.blocking_pool = content::BrowserThread::GetBlockingPool();
+  base::SequencedWorkerPool* blocking_pool =
+      content::BrowserThread::GetBlockingPool();
+  init_params.blocking_task_runner =
+      blocking_pool->GetSequencedTaskRunnerWithShutdownBehavior(
+          blocking_pool->GetSequenceToken(),
+          base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
 
   return init_params;
 }
diff --git a/chrome/browser/tracing/navigation_tracing.cc b/chrome/browser/tracing/navigation_tracing.cc
index e5c7332..510b6e9 100644
--- a/chrome/browser/tracing/navigation_tracing.cc
+++ b/chrome/browser/tracing/navigation_tracing.cc
@@ -15,6 +15,7 @@
 #include "content/public/browser/background_tracing_config.h"
 #include "content/public/browser/background_tracing_manager.h"
 #include "content/public/browser/browser_thread.h"
+#include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/render_frame_host.h"
 
 DEFINE_WEB_CONTENTS_USER_DATA_KEY(tracing::NavigationTracingObserver);
@@ -101,8 +102,8 @@
 NavigationTracingObserver::NavigationTracingObserver(
     content::WebContents* web_contents)
     : content::WebContentsObserver(web_contents) {
-  if (navigation_handle == -1) {
-    navigation_handle =
+  if (navigation_trigger_handle_ == -1) {
+    navigation_trigger_handle_ =
         content::BackgroundTracingManager::GetInstance()->RegisterTriggerType(
             kNavigationTracingConfig);
   }
@@ -111,18 +112,16 @@
 NavigationTracingObserver::~NavigationTracingObserver() {
 }
 
-void NavigationTracingObserver::DidStartProvisionalLoadForFrame(
-    content::RenderFrameHost* render_frame_host,
-    const GURL& validated_url,
-    bool is_error_page) {
-  if (!render_frame_host->GetParent() && !is_error_page) {
+void NavigationTracingObserver::DidStartNavigation(
+    content::NavigationHandle* navigation_handle) {
+  if (navigation_handle->IsInMainFrame()) {
     content::BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
-        navigation_handle,
+        navigation_trigger_handle_,
         content::BackgroundTracingManager::StartedFinalizingCallback());
   }
 }
 
 content::BackgroundTracingManager::TriggerHandle
-    NavigationTracingObserver::navigation_handle = -1;
+    NavigationTracingObserver::navigation_trigger_handle_ = -1;
 
 }  // namespace tracing
diff --git a/chrome/browser/tracing/navigation_tracing.h b/chrome/browser/tracing/navigation_tracing.h
index f26287e..709379d 100644
--- a/chrome/browser/tracing/navigation_tracing.h
+++ b/chrome/browser/tracing/navigation_tracing.h
@@ -28,12 +28,11 @@
   ~NavigationTracingObserver() override;
 
   // content::WebContentsObserver implementation.
-  void DidStartProvisionalLoadForFrame(
-      content::RenderFrameHost* render_frame_host,
-      const GURL& validated_url,
-      bool is_error_page) override;
+  void DidStartNavigation(
+      content::NavigationHandle* navigation_handle) override;
 
-  static content::BackgroundTracingManager::TriggerHandle navigation_handle;
+  static content::BackgroundTracingManager::TriggerHandle
+      navigation_trigger_handle_;
 
   DISALLOW_COPY_AND_ASSIGN(NavigationTracingObserver);
 };
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index 4e8f3cbd..9cba78d 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -1804,6 +1804,8 @@
         "views/payments/payment_request_views_util.h",
         "views/payments/payment_sheet_view_controller.cc",
         "views/payments/payment_sheet_view_controller.h",
+        "views/payments/shipping_list_view_controller.cc",
+        "views/payments/shipping_list_view_controller.h",
         "views/payments/view_stack.cc",
         "views/payments/view_stack.h",
         "views/process_singleton_dialog_linux.cc",
diff --git a/chrome/browser/ui/android/toolbar/toolbar_model_android.cc b/chrome/browser/ui/android/toolbar/toolbar_model_android.cc
index 8676af2..9368db5 100644
--- a/chrome/browser/ui/android/toolbar/toolbar_model_android.cc
+++ b/chrome/browser/ui/android/toolbar/toolbar_model_android.cc
@@ -5,17 +5,12 @@
 #include "chrome/browser/ui/android/toolbar/toolbar_model_android.h"
 
 #include "base/android/jni_string.h"
-#include "base/metrics/field_trial.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/search/search.h"
-#include "chrome/browser/search_engines/ui_thread_search_terms_data.h"
 #include "components/toolbar/toolbar_model_impl.h"
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/ssl_status.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/content_constants.h"
 #include "jni/ToolbarModel_jni.h"
-#include "net/cert/x509_certificate.h"
 
 using base::android::JavaParamRef;
 using base::android::ScopedJavaLocalRef;
diff --git a/chrome/browser/ui/cocoa/location_bar/zoom_decoration.mm b/chrome/browser/ui/cocoa/location_bar/zoom_decoration.mm
index 7e4c133a..5dfac1d 100644
--- a/chrome/browser/ui/cocoa/location_bar/zoom_decoration.mm
+++ b/chrome/browser/ui/cocoa/location_bar/zoom_decoration.mm
@@ -144,7 +144,7 @@
   if (bubble_)
     CloseBubble();
   else
-    ShowBubble(NO);
+    ShowBubble(YES);
   return true;
 }
 
diff --git a/chrome/browser/ui/views/payments/payment_request_dialog_view.cc b/chrome/browser/ui/views/payments/payment_request_dialog_view.cc
index 355a8a9..8abd360 100644
--- a/chrome/browser/ui/views/payments/payment_request_dialog_view.cc
+++ b/chrome/browser/ui/views/payments/payment_request_dialog_view.cc
@@ -11,10 +11,10 @@
 #include "chrome/browser/ui/views/payments/order_summary_view_controller.h"
 #include "chrome/browser/ui/views/payments/payment_method_view_controller.h"
 #include "chrome/browser/ui/views/payments/payment_sheet_view_controller.h"
+#include "chrome/browser/ui/views/payments/shipping_list_view_controller.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/constrained_window/constrained_window_views.h"
 #include "components/payments/payment_request.h"
-#include "components/payments/payment_request_dialog.h"
 #include "content/public/browser/browser_thread.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/views/layout/fill_layout.h"
@@ -101,13 +101,19 @@
 void PaymentRequestDialogView::ShowOrderSummary() {
   view_stack_.Push(CreateViewAndInstallController<OrderSummaryViewController>(
                        &controller_map_, request_, this),
-                   true);
+                   /* animate = */ true);
 }
 
 void PaymentRequestDialogView::ShowPaymentMethodSheet() {
   view_stack_.Push(CreateViewAndInstallController<PaymentMethodViewController>(
                        &controller_map_, request_, this),
-                   true);
+                   /* animate = */ true);
+}
+
+void PaymentRequestDialogView::ShowShippingListSheet() {
+  view_stack_.Push(CreateViewAndInstallController<ShippingListViewController>(
+                       &controller_map_, request_, this),
+                   /* animate = */ true);
 }
 
 void PaymentRequestDialogView::ShowDialog() {
@@ -122,7 +128,7 @@
 void PaymentRequestDialogView::ShowInitialPaymentSheet() {
   view_stack_.Push(CreateViewAndInstallController<PaymentSheetViewController>(
                        &controller_map_, request_, this),
-                   false);
+                   /* animate = */ false);
   if (observer_for_testing_)
     observer_for_testing_->OnDialogOpened();
 }
diff --git a/chrome/browser/ui/views/payments/payment_request_dialog_view.h b/chrome/browser/ui/views/payments/payment_request_dialog_view.h
index 4dc07950..1d35d2f 100644
--- a/chrome/browser/ui/views/payments/payment_request_dialog_view.h
+++ b/chrome/browser/ui/views/payments/payment_request_dialog_view.h
@@ -56,6 +56,7 @@
 
   void GoBack();
   void ShowOrderSummary();
+  void ShowShippingListSheet();
   void ShowPaymentMethodSheet();
 
  private:
diff --git a/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc b/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
index 87d3f2d..061d75fd 100644
--- a/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
+++ b/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
@@ -213,7 +213,7 @@
       break;
 
     case static_cast<int>(PaymentSheetViewControllerTags::SHOW_SHIPPING_BUTTON):
-      // TODO(tmartino): Transition to shipping page once it exists.
+      dialog()->ShowShippingListSheet();
       break;
 
     case static_cast<int>(
@@ -266,7 +266,7 @@
 
 std::unique_ptr<views::View>
 PaymentSheetViewController::CreateShippingSectionContent() {
-  auto profile = request()->GetCurrentlySelectedProfile();
+  auto profile = request()->selected_shipping_profile();
 
   // TODO(tmartino): Empty string param is app locale; this should be passed
   // at construct-time and stored as a member in a future CL.
@@ -351,7 +351,7 @@
 
 std::unique_ptr<views::View>
 PaymentSheetViewController::CreateContactInfoSectionContent() {
-  auto profile = request()->GetCurrentlySelectedProfile();
+  auto profile = request()->selected_contact_profile();
   // TODO(tmartino): Replace empty string with app locale.
   return profile ? payments::GetContactInfoLabel(AddressStyleType::SUMMARY,
                                                  std::string(), *profile, true,
diff --git a/chrome/browser/ui/views/payments/shipping_list_view_controller.cc b/chrome/browser/ui/views/payments/shipping_list_view_controller.cc
new file mode 100644
index 0000000..25b391f
--- /dev/null
+++ b/chrome/browser/ui/views/payments/shipping_list_view_controller.cc
@@ -0,0 +1,66 @@
+// 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 "chrome/browser/ui/views/payments/shipping_list_view_controller.h"
+
+#include <memory>
+#include <utility>
+
+#include "chrome/browser/ui/views/payments/payment_request_dialog_view.h"
+#include "chrome/browser/ui/views/payments/payment_request_views_util.h"
+#include "components/payments/payment_request.h"
+#include "components/strings/grit/components_strings.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/views/layout/box_layout.h"
+
+namespace payments {
+
+ShippingListViewController::ShippingListViewController(
+    PaymentRequest* request,
+    PaymentRequestDialogView* dialog)
+    : PaymentRequestSheetController(request, dialog) {}
+
+ShippingListViewController::~ShippingListViewController() {}
+
+std::unique_ptr<views::View> ShippingListViewController::CreateView() {
+  std::unique_ptr<views::View> content_view = base::MakeUnique<views::View>();
+
+  views::BoxLayout* layout =
+      new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0);
+  layout->set_main_axis_alignment(views::BoxLayout::MAIN_AXIS_ALIGNMENT_START);
+  layout->set_cross_axis_alignment(
+      views::BoxLayout::CROSS_AXIS_ALIGNMENT_STRETCH);
+  content_view->SetLayoutManager(layout);
+
+  for (auto& profile : request()->shipping_profiles()) {
+    // TODO(tmartino): Pass an actual locale in place of empty string.
+    content_view->AddChildView(
+        GetShippingAddressLabel(AddressStyleType::DETAILED, std::string(),
+                                *profile)
+            .release());
+  }
+
+  return CreatePaymentView(
+      CreateSheetHeaderView(
+          /* show_back_arrow = */ true,
+          l10n_util::GetStringUTF16(IDS_PAYMENT_REQUEST_SHIPPING_SECTION_NAME),
+          this),
+      std::move(content_view));
+}
+
+void ShippingListViewController::ButtonPressed(views::Button* sender,
+                                               const ui::Event& event) {
+  switch (sender->tag()) {
+    case static_cast<int>(PaymentRequestCommonTags::CLOSE_BUTTON_TAG):
+      dialog()->CloseDialog();
+      break;
+    case static_cast<int>(PaymentRequestCommonTags::BACK_BUTTON_TAG):
+      dialog()->GoBack();
+      break;
+    default:
+      NOTREACHED();
+  }
+}
+
+}  // namespace payments
diff --git a/chrome/browser/ui/views/payments/shipping_list_view_controller.h b/chrome/browser/ui/views/payments/shipping_list_view_controller.h
new file mode 100644
index 0000000..9b3d441
--- /dev/null
+++ b/chrome/browser/ui/views/payments/shipping_list_view_controller.h
@@ -0,0 +1,39 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_VIEWS_PAYMENTS_SHIPPING_LIST_VIEW_CONTROLLER_H_
+#define CHROME_BROWSER_UI_VIEWS_PAYMENTS_SHIPPING_LIST_VIEW_CONTROLLER_H_
+
+#include "base/macros.h"
+#include "chrome/browser/ui/views/payments/payment_request_sheet_controller.h"
+#include "ui/views/controls/button/vector_icon_button_delegate.h"
+
+namespace payments {
+
+class PaymentRequest;
+class PaymentRequestDialogView;
+
+// The PaymentRequestSheetController subtype for the Shipping address list
+// screen of the Payment Request flow.
+class ShippingListViewController : public PaymentRequestSheetController,
+                                   public views::VectorIconButtonDelegate {
+ public:
+  // Does not take ownership of the arguments, which should outlive this object.
+  ShippingListViewController(PaymentRequest* request,
+                             PaymentRequestDialogView* dialog);
+  ~ShippingListViewController() override;
+
+  // PaymentRequestSheetController:
+  std::unique_ptr<views::View> CreateView() override;
+
+ private:
+  // views::VectorIconButtonDelegate:
+  void ButtonPressed(views::Button* sender, const ui::Event& event) override;
+
+  DISALLOW_COPY_AND_ASSIGN(ShippingListViewController);
+};
+
+}  // namespace payments
+
+#endif  // CHROME_BROWSER_UI_VIEWS_PAYMENTS_SHIPPING_LIST_VIEW_CONTROLLER_H_
diff --git a/chrome/renderer/autofill/DEPS b/chrome/renderer/autofill/DEPS
deleted file mode 100644
index d7867aa1..0000000
--- a/chrome/renderer/autofill/DEPS
+++ /dev/null
@@ -1,7 +0,0 @@
-specific_include_rules = {
-  # TODO(estark): remove this when the Form-Not-Secure feature is fully
-  # launched. https://crbug.com/677295
-  "password_autofill_agent_browsertest\.cc" : [
-    "+components/security_state/core",
-  ],
-}
\ No newline at end of file
diff --git a/chrome/renderer/autofill/password_autofill_agent_browsertest.cc b/chrome/renderer/autofill/password_autofill_agent_browsertest.cc
index 55aa61a..ae056a5c 100644
--- a/chrome/renderer/autofill/password_autofill_agent_browsertest.cc
+++ b/chrome/renderer/autofill/password_autofill_agent_browsertest.cc
@@ -23,7 +23,6 @@
 #include "components/autofill/core/common/password_form.h"
 #include "components/autofill/core/common/password_form_field_prediction_map.h"
 #include "components/password_manager/core/common/password_manager_features.h"
-#include "components/security_state/core/security_state.h"
 #include "content/public/common/associated_interface_provider.h"
 #include "content/public/renderer/render_frame.h"
 #include "content/public/renderer/render_view.h"
@@ -352,11 +351,6 @@
         password_manager::features::kFillOnAccountSelect);
   }
 
-  void SetHttpFormWarning() {
-    scoped_feature_list_.InitAndEnableFeature(
-        security_state::kHttpFormWarningFeature);
-  }
-
   void UpdateOriginForHTML(const std::string& html) {
     std::string origin = "data:text/html;charset=utf-8," + html;
     fill_data_.origin = GURL(origin);
@@ -489,11 +483,6 @@
     return fake_driver_.called_show_pw_suggestions();
   }
 
-  bool GetCalledShowNotSecureWarning() {
-    base::RunLoop().RunUntilIdle();
-    return fake_driver_.called_show_not_secure_warning();
-  }
-
   void ExpectFormSubmittedWithUsernameAndPasswords(
       const std::string& username_value,
       const std::string& password_value,
@@ -1367,30 +1356,6 @@
   ClearUsernameAndPasswordFields();
 }
 
-// Tests that the Form Not Secure warning appears when a password form
-// is autofilled when the Form Not Secure feature is enabled.
-TEST_F(PasswordAutofillAgentTest, FormNotSecureWarningOnAutofill) {
-  SetHttpFormWarning();
-
-  fill_data_.show_form_not_secure_warning_on_autofill = true;
-
-  // Simulate the browser autofilling a password form.
-  SimulateOnFillPasswordForm(fill_data_);
-  EXPECT_TRUE(GetCalledShowNotSecureWarning());
-}
-
-// Tests that the Form Not Secure warning does not appear when the
-// PasswordFormFillData does not indicate that it should show.
-TEST_F(PasswordAutofillAgentTest, FormNotSecureWarningNotShownOnAutofill) {
-  SetHttpFormWarning();
-
-  fill_data_.show_form_not_secure_warning_on_autofill = false;
-
-  // Simulate the browser autofilling a password form.
-  SimulateOnFillPasswordForm(fill_data_);
-  EXPECT_FALSE(GetCalledShowNotSecureWarning());
-}
-
 // Tests that there is an autosuggestion from the password manager when the
 // user clicks on the password field when FillOnAccountSelect is enabled.
 TEST_F(PasswordAutofillAgentTest,
diff --git a/chrome/test/data/payments/bobpay.js b/chrome/test/data/payments/bobpay.js
index 0d24e9fc..9e4848c6 100644
--- a/chrome/test/data/payments/bobpay.js
+++ b/chrome/test/data/payments/bobpay.js
@@ -7,12 +7,13 @@
 /* global PaymentRequest:false */
 
 /**
- * Launches the PaymentRequest UI with Bob Pay as the only payment method.
+ * Launches the PaymentRequest UI with Bob Pay as one of multiple payment
+ * methods.
  */
 function buy() {  // eslint-disable-line no-unused-vars
   try {
     new PaymentRequest(
-        [{supportedMethods: ['https://bobpay.com']}],
+        [{supportedMethods: ['https://bobpay.com', 'https://alicepay.com']}],
         {total: {label: 'Total', amount: {currency: 'USD', value: '5.00'}}})
         .show()
         .then(function(resp) {
diff --git a/chrome/test/data/payments/bobpay_ui_skip.js b/chrome/test/data/payments/bobpay_ui_skip.js
new file mode 100644
index 0000000..62b4680
--- /dev/null
+++ b/chrome/test/data/payments/bobpay_ui_skip.js
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+/* global PaymentRequest:false */
+
+/**
+ * Launches the PaymentRequest UI with Bob Pay as the only payment method.
+ *
+ * <p>When the developer chooses a single payment method and requests no other
+ * data (no shipping, no email, no phone, ...), Payment Request will apply
+ * the UI skip optimization, skipping its own UI enterily and going directly to
+ * Bob Pay.
+ */
+function buy() {  // eslint-disable-line no-unused-vars
+  try {
+    new PaymentRequest(
+        [{supportedMethods: ['https://bobpay.com']}],
+        {total: {label: 'Total', amount: {currency: 'USD', value: '5.00'}}})
+        .show()
+        .then(function(resp) {
+          resp.complete('success')
+              .then(function() {
+                print(resp.methodName + '<br>' +
+                      JSON.stringify(resp.details, undefined, 2));
+              })
+              .catch(function(error) {
+                print('complete() rejected<br>' + error);
+              });
+        })
+        .catch(function(error) {
+          print('show() rejected<br>' + error);
+        });
+  } catch (error) {
+    print('exception thrown<br>' + error);
+  }
+}
diff --git a/chrome/test/data/payments/payment_request_bobpay_ui_skip_test.html b/chrome/test/data/payments/payment_request_bobpay_ui_skip_test.html
new file mode 100644
index 0000000..5d179cf7
--- /dev/null
+++ b/chrome/test/data/payments/payment_request_bobpay_ui_skip_test.html
@@ -0,0 +1,20 @@
+<!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.
+-->
+<html>
+<head>
+<title>Bob Pay UI skip Test</title>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
+<link rel="stylesheet" type="text/css" href="style.css">
+</head>
+<body>
+<button onclick="buy()" id="buy">Bob Pay Test</button><br>
+<pre id="result"></pre>
+<script src="util.js"></script>
+<script src="bobpay_ui_skip.js"></script>
+</body>
+</html>
diff --git a/chromeos/dbus/debug_daemon_client.cc b/chromeos/dbus/debug_daemon_client.cc
index 868a60f2..c007e2f 100644
--- a/chromeos/dbus/debug_daemon_client.cc
+++ b/chromeos/dbus/debug_daemon_client.cc
@@ -466,12 +466,13 @@
                    weak_ptr_factory_.GetWeakPtr(), callback));
   }
 
-  void CupsAddPrinter(const std::string& name,
-                      const std::string& uri,
-                      const std::string& ppd_path,
-                      bool ipp_everywhere,
-                      const DebugDaemonClient::CupsAddPrinterCallback& callback,
-                      const base::Closure& error_callback) override {
+  void CupsAddPrinter(
+      const std::string& name,
+      const std::string& uri,
+      const std::string& ppd_path,
+      bool ipp_everywhere,
+      const DebugDaemonClient::LegacyCupsAddPrinterCallback& callback,
+      const base::Closure& error_callback) override {
     dbus::MethodCall method_call(debugd::kDebugdInterface,
                                  debugd::kCupsAddPrinter);
     dbus::MessageWriter writer(&method_call);
@@ -482,6 +483,42 @@
 
     debugdaemon_proxy_->CallMethod(
         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
+        base::Bind(&DebugDaemonClientImpl::LegacyOnPrinterAdded,
+                   weak_ptr_factory_.GetWeakPtr(), callback, error_callback));
+  }
+
+  void CupsAddManuallyConfiguredPrinter(
+      const std::string& name,
+      const std::string& uri,
+      const std::string& ppd_contents,
+      const DebugDaemonClient::CupsAddPrinterCallback& callback,
+      const base::Closure& error_callback) override {
+    dbus::MethodCall method_call(debugd::kDebugdInterface,
+                                 debugd::kCupsAddManuallyConfiguredPrinter);
+    dbus::MessageWriter writer(&method_call);
+    writer.AppendString(name);
+    writer.AppendString(uri);
+    writer.AppendString(ppd_contents);
+
+    debugdaemon_proxy_->CallMethod(
+        &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
+        base::Bind(&DebugDaemonClientImpl::OnPrinterAdded,
+                   weak_ptr_factory_.GetWeakPtr(), callback, error_callback));
+  }
+
+  void CupsAddAutoConfiguredPrinter(
+      const std::string& name,
+      const std::string& uri,
+      const DebugDaemonClient::CupsAddPrinterCallback& callback,
+      const base::Closure& error_callback) override {
+    dbus::MethodCall method_call(debugd::kDebugdInterface,
+                                 debugd::kCupsAddAutoConfiguredPrinter);
+    dbus::MessageWriter writer(&method_call);
+    writer.AppendString(name);
+    writer.AppendString(uri);
+
+    debugdaemon_proxy_->CallMethod(
+        &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
         base::Bind(&DebugDaemonClientImpl::OnPrinterAdded,
                    weak_ptr_factory_.GetWeakPtr(), callback, error_callback));
   }
@@ -713,9 +750,9 @@
       callback.Run(false, "");
   }
 
-  void OnPrinterAdded(const CupsAddPrinterCallback& callback,
-                      const base::Closure& error_callback,
-                      dbus::Response* response) {
+  void LegacyOnPrinterAdded(const LegacyCupsAddPrinterCallback& callback,
+                            const base::Closure& error_callback,
+                            dbus::Response* response) {
     bool result = false;
     dbus::MessageReader reader(response);
     if (response && reader.PopBool(&result)) {
@@ -725,6 +762,18 @@
     }
   }
 
+  void OnPrinterAdded(const CupsAddPrinterCallback& callback,
+                      const base::Closure& error_callback,
+                      dbus::Response* response) {
+    int32_t result;
+    dbus::MessageReader reader(response);
+    if (response && reader.PopInt32(&result)) {
+      callback.Run(result);
+    } else {
+      error_callback.Run();
+    }
+  }
+
   void OnPrinterRemoved(const CupsRemovePrinterCallback& callback,
                         const base::Closure& error_callback,
                         dbus::Response* response) {
diff --git a/chromeos/dbus/debug_daemon_client.h b/chromeos/dbus/debug_daemon_client.h
index 2a7a3185..4d8541ae 100644
--- a/chromeos/dbus/debug_daemon_client.h
+++ b/chromeos/dbus/debug_daemon_client.h
@@ -210,7 +210,12 @@
       const SetOomScoreAdjCallback& callback) = 0;
 
   // A callback to handle the result of CupsAddPrinter.
-  using CupsAddPrinterCallback = base::Callback<void(bool success)>;
+  using LegacyCupsAddPrinterCallback = base::Callback<void(bool status)>;
+
+  // A callback to handle the result of CupsAdd[Auto|Manually]ConfiguredPrinter.
+  // A zero status means success, non-zero statuses are used to convey different
+  // errors.
+  using CupsAddPrinterCallback = base::Callback<void(int32_t status)>;
 
   // Calls CupsAddPrinter.  |name| is the printer name. |uri| is the device
   // uri. |ppd_path| is the absolute path to the PPD file. |ipp_everywhere|
@@ -218,13 +223,40 @@
   // true if adding the printer to CUPS was successful and false if there was an
   // error.  |error_callback| will be called if there was an error in
   // communicating with debugd.
+  //
+  // Obsoleted by CupsAddAutoConfiguredPrinter and
+  // CupsAddManuallyConfiguredPrinter.
   virtual void CupsAddPrinter(const std::string& name,
                               const std::string& uri,
                               const std::string& ppd_path,
                               bool ipp_everywhere,
-                              const CupsAddPrinterCallback& callback,
+                              const LegacyCupsAddPrinterCallback& callback,
                               const base::Closure& error_callback) = 0;
 
+  // Calls CupsAddManuallyConfiguredPrinter.  |name| is the printer
+  // name. |uri| is the device.  |ppd_contents| is the contents of the
+  // PPD file used to drive the device.  |callback| is called with
+  // true if adding the printer to CUPS was successful and false if
+  // there was an error.  |error_callback| will be called if there was
+  // an error in communicating with debugd.
+  virtual void CupsAddManuallyConfiguredPrinter(
+      const std::string& name,
+      const std::string& uri,
+      const std::string& ppd_contents,
+      const CupsAddPrinterCallback& callback,
+      const base::Closure& error_callback) = 0;
+
+  // Calls CupsAddAutoConfiguredPrinter.  |name| is the printer
+  // name. |uri| is the device.  |callback| is called with true if
+  // adding the printer to CUPS was successful and false if there was
+  // an error.  |error_callback| will be called if there was an error
+  // in communicating with debugd.
+  virtual void CupsAddAutoConfiguredPrinter(
+      const std::string& name,
+      const std::string& uri,
+      const CupsAddPrinterCallback& callback,
+      const base::Closure& error_callback) = 0;
+
   // A callback to handle the result of CupsRemovePrinter.
   using CupsRemovePrinterCallback = base::Callback<void(bool success)>;
 
diff --git a/chromeos/dbus/fake_debug_daemon_client.cc b/chromeos/dbus/fake_debug_daemon_client.cc
index a07b18e..20d7498 100644
--- a/chromeos/dbus/fake_debug_daemon_client.cc
+++ b/chromeos/dbus/fake_debug_daemon_client.cc
@@ -223,13 +223,34 @@
     const std::string& uri,
     const std::string& ppd_path,
     bool ipp_everywhere,
-    const DebugDaemonClient::CupsAddPrinterCallback& callback,
+    const DebugDaemonClient::LegacyCupsAddPrinterCallback& callback,
     const base::Closure& error_callback) {
   printers_.insert(name);
   base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
                                                 base::Bind(callback, true));
 }
 
+void FakeDebugDaemonClient::CupsAddManuallyConfiguredPrinter(
+    const std::string& name,
+    const std::string& uri,
+    const std::string& ppd_contents,
+    const DebugDaemonClient::CupsAddPrinterCallback& callback,
+    const base::Closure& error_callback) {
+  printers_.insert(name);
+  base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+                                                base::Bind(callback, 0));
+}
+
+void FakeDebugDaemonClient::CupsAddAutoConfiguredPrinter(
+    const std::string& name,
+    const std::string& uri,
+    const DebugDaemonClient::CupsAddPrinterCallback& callback,
+    const base::Closure& error_callback) {
+  printers_.insert(name);
+  base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+                                                base::Bind(callback, 0));
+}
+
 void FakeDebugDaemonClient::CupsRemovePrinter(
     const std::string& name,
     const DebugDaemonClient::CupsRemovePrinterCallback& callback,
diff --git a/chromeos/dbus/fake_debug_daemon_client.h b/chromeos/dbus/fake_debug_daemon_client.h
index d008880..00e8dce 100644
--- a/chromeos/dbus/fake_debug_daemon_client.h
+++ b/chromeos/dbus/fake_debug_daemon_client.h
@@ -76,8 +76,19 @@
                       const std::string& uri,
                       const std::string& ppd_path,
                       bool ipp_everywhere,
-                      const CupsAddPrinterCallback& callback,
+                      const LegacyCupsAddPrinterCallback& callback,
                       const base::Closure& error_callback) override;
+  void CupsAddManuallyConfiguredPrinter(
+      const std::string& name,
+      const std::string& uri,
+      const std::string& ppd_contents,
+      const CupsAddPrinterCallback& callback,
+      const base::Closure& error_callback) override;
+  void CupsAddAutoConfiguredPrinter(
+      const std::string& name,
+      const std::string& uri,
+      const CupsAddPrinterCallback& callback,
+      const base::Closure& error_callback) override;
   void CupsRemovePrinter(const std::string& name,
                          const CupsRemovePrinterCallback& callback,
                          const base::Closure& error_callback) override;
diff --git a/components/autofill/content/common/autofill_types.mojom b/components/autofill/content/common/autofill_types.mojom
index db88276..9142c617 100644
--- a/components/autofill/content/common/autofill_types.mojom
+++ b/components/autofill/content/common/autofill_types.mojom
@@ -140,7 +140,6 @@
   array<array<string>> other_possible_usernames_values;
   bool wait_for_username;
   bool is_possible_change_password_form;
-  bool show_form_not_secure_warning_on_autofill;
 };
 
 // autofill::PasswordFormGenerationData
diff --git a/components/autofill/content/common/autofill_types_struct_traits.cc b/components/autofill/content/common/autofill_types_struct_traits.cc
index d3214a1..dce12aa 100644
--- a/components/autofill/content/common/autofill_types_struct_traits.cc
+++ b/components/autofill/content/common/autofill_types_struct_traits.cc
@@ -463,8 +463,6 @@
   out->wait_for_username = data.wait_for_username();
   out->is_possible_change_password_form =
       data.is_possible_change_password_form();
-  out->show_form_not_secure_warning_on_autofill =
-      data.show_form_not_secure_warning_on_autofill();
 
   return true;
 }
diff --git a/components/autofill/content/common/autofill_types_struct_traits.h b/components/autofill/content/common/autofill_types_struct_traits.h
index a9785e3..ba126b37 100644
--- a/components/autofill/content/common/autofill_types_struct_traits.h
+++ b/components/autofill/content/common/autofill_types_struct_traits.h
@@ -355,11 +355,6 @@
     return r.is_possible_change_password_form;
   }
 
-  static bool show_form_not_secure_warning_on_autofill(
-      const autofill::PasswordFormFillData& r) {
-    return r.show_form_not_secure_warning_on_autofill;
-  }
-
   static bool Read(autofill::mojom::PasswordFormFillDataDataView data,
                    autofill::PasswordFormFillData* out);
 };
diff --git a/components/autofill/content/renderer/password_autofill_agent.cc b/components/autofill/content/renderer/password_autofill_agent.cc
index 1026178..2d8f6c91 100644
--- a/components/autofill/content/renderer/password_autofill_agent.cc
+++ b/components/autofill/content/renderer/password_autofill_agent.cc
@@ -1278,15 +1278,12 @@
         element.isPasswordField()
             ? element
             : web_input_to_password_info_[element].password_field;
-    if (FillFormOnPasswordReceived(
-            form_data, username_element, password_element,
-            &field_value_and_properties_map_,
-            base::Bind(&PasswordValueGatekeeper::RegisterElement,
-                       base::Unretained(&gatekeeper_)),
-            logger.get())) {
-      if (form_data.show_form_not_secure_warning_on_autofill)
-        autofill_agent_->ShowNotSecureWarning(element);
-    }
+    FillFormOnPasswordReceived(
+        form_data, username_element, password_element,
+        &field_value_and_properties_map_,
+        base::Bind(&PasswordValueGatekeeper::RegisterElement,
+                   base::Unretained(&gatekeeper_)),
+        logger.get());
   }
 }
 
diff --git a/components/autofill/core/common/password_form_fill_data.cc b/components/autofill/core/common/password_form_fill_data.cc
index 014a24e..9b138304 100644
--- a/components/autofill/core/common/password_form_fill_data.cc
+++ b/components/autofill/core/common/password_form_fill_data.cc
@@ -22,9 +22,7 @@
 }
 
 PasswordFormFillData::PasswordFormFillData()
-    : wait_for_username(false),
-      is_possible_change_password_form(false),
-      show_form_not_secure_warning_on_autofill(false) {}
+    : wait_for_username(false), is_possible_change_password_form(false) {}
 
 PasswordFormFillData::PasswordFormFillData(const PasswordFormFillData& other) =
     default;
diff --git a/components/autofill/core/common/password_form_fill_data.h b/components/autofill/core/common/password_form_fill_data.h
index 91798eda..fd0f64fe 100644
--- a/components/autofill/core/common/password_form_fill_data.h
+++ b/components/autofill/core/common/password_form_fill_data.h
@@ -75,10 +75,6 @@
   // True if this form is a change password form.
   bool is_possible_change_password_form;
 
-  // True if a "form not secure" warning should be shown when the form is
-  // autofilled.
-  bool show_form_not_secure_warning_on_autofill;
-
   PasswordFormFillData();
   PasswordFormFillData(const PasswordFormFillData& other);
   ~PasswordFormFillData();
diff --git a/components/browser_sync/profile_sync_service.cc b/components/browser_sync/profile_sync_service.cc
index b17acf44..6c7488b 100644
--- a/components/browser_sync/profile_sync_service.cc
+++ b/components/browser_sync/profile_sync_service.cc
@@ -69,7 +69,6 @@
 #include "components/sync/js/js_event_details.h"
 #include "components/sync/model/change_processor.h"
 #include "components/sync/model/model_type_change_processor.h"
-#include "components/sync/model/model_type_store.h"
 #include "components/sync/model/sync_error.h"
 #include "components/sync/protocol/sync.pb.h"
 #include "components/sync/syncable/directory.h"
@@ -193,7 +192,7 @@
       network_time_update_callback_(
           std::move(init_params.network_time_update_callback)),
       url_request_context_(init_params.url_request_context),
-      blocking_pool_(init_params.blocking_pool),
+      blocking_task_runner_(std::move(init_params.blocking_task_runner)),
       is_first_time_sync_configure_(false),
       engine_initialized_(false),
       sync_disabled_by_admin_(false),
@@ -274,19 +273,11 @@
                  syncer::ModelTypeSet(syncer::SESSIONS)));
 
   if (base::FeatureList::IsEnabled(switches::kSyncUSSDeviceInfo)) {
-    scoped_refptr<base::SequencedTaskRunner> blocking_task_runner(
-        blocking_pool_->GetSequencedTaskRunnerWithShutdownBehavior(
-            blocking_pool_->GetSequenceToken(),
-            base::SequencedWorkerPool::SKIP_ON_SHUTDOWN));
     // TODO(skym): Stop creating leveldb files when signed out.
     // TODO(skym): Verify using AsUTF8Unsafe is okay here. Should work as long
     // as the Local State file is guaranteed to be UTF-8.
     device_info_sync_bridge_ = base::MakeUnique<DeviceInfoSyncBridge>(
-        local_device_.get(),
-        base::Bind(&ModelTypeStore::CreateStore, syncer::DEVICE_INFO,
-                   sync_data_folder_.Append(base::FilePath(kLevelDBFolderName))
-                       .AsUTF8Unsafe(),
-                   blocking_task_runner),
+        local_device_.get(), GetModelTypeStoreFactory(syncer::DEVICE_INFO),
         base::BindRepeating(
             &ModelTypeChangeProcessor::Create,
             base::BindRepeating(&syncer::ReportUnrecoverableError, channel_)));
@@ -974,7 +965,7 @@
 
   // Initialize local device info.
   local_device_->Initialize(cache_guid, signin_scoped_device_id,
-                            blocking_pool_);
+                            blocking_task_runner_);
 
   if (protocol_event_observers_.might_have_observers()) {
     engine_->RequestBufferedProtocolEventsAndEnableForwarding();
@@ -1823,6 +1814,14 @@
   platform_sync_allowed_provider_ = platform_sync_allowed_provider;
 }
 
+syncer::ModelTypeStoreFactory ProfileSyncService::GetModelTypeStoreFactory(
+    ModelType type) {
+  return base::Bind(&ModelTypeStore::CreateStore, type,
+                    sync_data_folder_.Append(base::FilePath(kLevelDBFolderName))
+                        .AsUTF8Unsafe(),
+                    blocking_task_runner_);
+}
+
 void ProfileSyncService::ConfigureDataTypeManager() {
   // Don't configure datatypes if the setup UI is still on the screen - this
   // is to help multi-screen setting UIs (like iOS) where they don't want to
diff --git a/components/browser_sync/profile_sync_service.h b/components/browser_sync/profile_sync_service.h
index 43c8f8b..9d7c709 100644
--- a/components/browser_sync/profile_sync_service.h
+++ b/components/browser_sync/profile_sync_service.h
@@ -49,6 +49,7 @@
 #include "components/sync/engine/sync_engine_host.h"
 #include "components/sync/engine/sync_manager_factory.h"
 #include "components/sync/js/sync_js_controller.h"
+#include "components/sync/model/model_type_store.h"
 #include "components/sync/syncable/user_share.h"
 #include "components/version_info/version_info.h"
 #include "google_apis/gaia/google_service_auth_error.h"
@@ -244,7 +245,7 @@
     scoped_refptr<net::URLRequestContextGetter> url_request_context;
     std::string debug_identifier;
     version_info::Channel channel = version_info::Channel::UNKNOWN;
-    base::SequencedWorkerPool* blocking_pool = nullptr;
+    scoped_refptr<base::SequencedTaskRunner> blocking_task_runner;
     base::FilePath local_sync_backend_folder;
 
    private:
@@ -580,6 +581,11 @@
   void SetPlatformSyncAllowedProvider(
       const PlatformSyncAllowedProvider& platform_sync_allowed_provider);
 
+  // Returns a function for |type| that will create a ModelTypeStore that shares
+  // the sync LevelDB backend.
+  syncer::ModelTypeStoreFactory GetModelTypeStoreFactory(
+      syncer::ModelType type);
+
   // Needed to test whether the directory is deleted properly.
   base::FilePath GetDirectoryPathForTest() const;
 
@@ -793,8 +799,8 @@
   // The request context in which sync should operate.
   scoped_refptr<net::URLRequestContextGetter> url_request_context_;
 
-  // Threading context.
-  base::SequencedWorkerPool* blocking_pool_;
+  // The task runner to use for blocking IO operations.
+  scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_;
 
   // Indicates if this is the first time sync is being configured.  This value
   // is equal to !IsFirstSetupComplete() at the time of OnEngineInitialized().
diff --git a/components/browser_sync/profile_sync_test_util.cc b/components/browser_sync/profile_sync_test_util.cc
index f9f8355d..c6d34511 100644
--- a/components/browser_sync/profile_sync_test_util.cc
+++ b/components/browser_sync/profile_sync_test_util.cc
@@ -261,7 +261,10 @@
   init_params.url_request_context = url_request_context();
   init_params.debug_identifier = "dummyDebugName";
   init_params.channel = version_info::Channel::UNKNOWN;
-  init_params.blocking_pool = worker_pool_owner_.pool().get();
+  init_params.blocking_task_runner =
+      worker_pool_owner_.pool()->GetSequencedTaskRunnerWithShutdownBehavior(
+          worker_pool_owner_.pool()->GetSequenceToken(),
+          base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
 
   return init_params;
 }
diff --git a/components/password_manager/core/browser/password_form_manager_unittest.cc b/components/password_manager/core/browser/password_form_manager_unittest.cc
index a91c1822..be93b49 100644
--- a/components/password_manager/core/browser/password_form_manager_unittest.cc
+++ b/components/password_manager/core/browser/password_form_manager_unittest.cc
@@ -39,7 +39,6 @@
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
 #include "components/prefs/testing_pref_service.h"
-#include "components/security_state/core/security_state.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
@@ -2866,41 +2865,4 @@
   }
 }
 
-class PasswordFormManagerFormNotSecureTest : public PasswordFormManagerTest {
- public:
-  PasswordFormManagerFormNotSecureTest() {
-    scoped_feature_list_.InitAndEnableFeature(
-        security_state::kHttpFormWarningFeature);
-  }
-
-  base::test::ScopedFeatureList scoped_feature_list_;
-};
-
-// Tests that PasswordFormFillData's
-// |show_form_not_secure_warning_on_autofill| field is set correctly
-// when processing a frame.
-TEST_F(PasswordFormManagerFormNotSecureTest,
-       ProcessFrameSetsFormNotSecureFlag) {
-  autofill::PasswordFormFillData fill_data;
-  EXPECT_CALL(*client()->mock_driver(), FillPasswordForm(_))
-      .WillOnce(SaveArg<0>(&fill_data));
-  fake_form_fetcher()->SetNonFederated({saved_match()}, 0u);
-  EXPECT_TRUE(fill_data.show_form_not_secure_warning_on_autofill);
-}
-
-// Tests that PasswordFormFillData's
-// |show_form_not_secure_warning_on_autofill| field is *not* set when
-// the feature is not enabled.
-//
-// TODO(estark): remove this test when the feature is fully
-// launched. https://crbug.com/677295
-TEST_F(PasswordFormManagerTest,
-       ProcessFrameSetsFormNotSecureFlagWithoutFeature) {
-  autofill::PasswordFormFillData fill_data;
-  EXPECT_CALL(*client()->mock_driver(), FillPasswordForm(_))
-      .WillOnce(SaveArg<0>(&fill_data));
-  fake_form_fetcher()->SetNonFederated({saved_match()}, 0u);
-  EXPECT_FALSE(fill_data.show_form_not_secure_warning_on_autofill);
-}
-
 }  // namespace password_manager
diff --git a/components/password_manager/core/browser/password_manager.cc b/components/password_manager/core/browser/password_manager.cc
index a2bbaf12..acb0e8dc 100644
--- a/components/password_manager/core/browser/password_manager.cc
+++ b/components/password_manager/core/browser/password_manager.cc
@@ -16,7 +16,6 @@
 #include "base/threading/platform_thread.h"
 #include "build/build_config.h"
 #include "components/autofill/core/browser/autofill_field.h"
-#include "components/autofill/core/browser/autofill_manager.h"
 #include "components/autofill/core/browser/form_structure.h"
 #include "components/autofill/core/common/form_data_predictions.h"
 #include "components/autofill/core/common/password_form_field_prediction_map.h"
@@ -35,7 +34,6 @@
 #include "components/password_manager/core/common/password_manager_pref_names.h"
 #include "components/pref_registry/pref_registry_syncable.h"
 #include "components/prefs/pref_service.h"
-#include "components/security_state/core/security_state.h"
 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
 
 #if defined(OS_WIN)
@@ -782,16 +780,6 @@
   InitPasswordFormFillData(form_for_autofill, best_matches, &preferred_match,
                            wait_for_username, OtherPossibleUsernamesEnabled(),
                            &fill_data);
-  // Show a "Login not secure" warning if the experiment is enabled and the
-  // top-level page is not secure.
-  // TODO(estark): Verify that |origin| is the right URL to check here.
-  // https://crbug.com/676706
-  autofill::AutofillManager* autofill_manager =
-      client_->GetAutofillManagerForMainFrame();
-  fill_data.show_form_not_secure_warning_on_autofill =
-      security_state::IsHttpWarningInFormEnabled() && autofill_manager &&
-      !autofill_manager->client()->IsContextSecure(fill_data.origin);
-
   if (logger)
     logger->LogBoolean(Logger::STRING_WAIT_FOR_USERNAME, wait_for_username);
   UMA_HISTOGRAM_BOOLEAN(
diff --git a/components/payments/payment_request.cc b/components/payments/payment_request.cc
index 2fa4910..d7302df 100644
--- a/components/payments/payment_request.cc
+++ b/components/payments/payment_request.cc
@@ -22,7 +22,9 @@
     : web_contents_(web_contents),
       delegate_(std::move(delegate)),
       manager_(manager),
-      binding_(this, std::move(request)) {
+      binding_(this, std::move(request)),
+      selected_shipping_profile_(nullptr),
+      selected_contact_profile_(nullptr) {
   // OnConnectionTerminated will be called when the Mojo pipe is closed. This
   // will happen as a result of many renderer-side events (both successful and
   // erroneous in nature).
@@ -30,6 +32,7 @@
   // set_connection_error_with_reason_handler with Binding::CloseWithReason.
   binding_.set_connection_error_handler(base::Bind(
       &PaymentRequest::OnConnectionTerminated, base::Unretained(this)));
+
 }
 
 PaymentRequest::~PaymentRequest() {}
@@ -48,6 +51,8 @@
   }
   client_ = std::move(client);
   details_ = std::move(details);
+  PopulateProfileCache();
+  SetDefaultProfileSelections();
 }
 
 void PaymentRequest::Show() {
@@ -105,17 +110,14 @@
   return currency_formatter_.get();
 }
 
-autofill::AutofillProfile* PaymentRequest::GetCurrentlySelectedProfile() {
-  // TODO(tmartino): Implement more sophisticated algorithm for populating
-  // this when it starts empty.
-  if (!profile_) {
-    autofill::PersonalDataManager* data_manager =
-        delegate_->GetPersonalDataManager();
-    auto profiles = data_manager->GetProfiles();
-    if (!profiles.empty())
-      profile_ = base::MakeUnique<autofill::AutofillProfile>(*profiles[0]);
-  }
-  return profile_ ? profile_.get() : nullptr;
+const std::vector<autofill::AutofillProfile*>&
+    PaymentRequest::shipping_profiles() {
+  return shipping_profiles_;
+}
+
+const std::vector<autofill::AutofillProfile*>&
+    PaymentRequest::contact_profiles() {
+  return contact_profiles_;
 }
 
 autofill::CreditCard* PaymentRequest::GetCurrentlySelectedCreditCard() {
@@ -137,4 +139,32 @@
   return first_complete_card == cards.end() ? nullptr : *first_complete_card;
 }
 
+void PaymentRequest::PopulateProfileCache() {
+  autofill::PersonalDataManager* data_manager =
+      delegate_->GetPersonalDataManager();
+  std::vector<autofill::AutofillProfile*> profiles =
+      data_manager->GetProfilesToSuggest();
+
+  // PaymentRequest may outlive the Profiles returned by the Data Manager.
+  // Thus, we store copies, and return a vector of pointers to these copies
+  // whenever Profiles are requested.
+  for (size_t i = 0; i < profiles.size(); i++) {
+    profile_cache_.push_back(
+        base::MakeUnique<autofill::AutofillProfile>(*profiles[i]));
+
+    // TODO(tmartino): Implement deduplication rules specific to shipping and
+    // contact profiles.
+    shipping_profiles_.push_back(profile_cache_[i].get());
+    contact_profiles_.push_back(profile_cache_[i].get());
+  }
+}
+
+void PaymentRequest::SetDefaultProfileSelections() {
+  if (!shipping_profiles().empty())
+    set_selected_shipping_profile(shipping_profiles()[0]);
+
+  if (!contact_profiles().empty())
+    set_selected_contact_profile(contact_profiles()[0]);
+}
+
 }  // namespace payments
diff --git a/components/payments/payment_request.h b/components/payments/payment_request.h
index cbc9905..a2caab9 100644
--- a/components/payments/payment_request.h
+++ b/components/payments/payment_request.h
@@ -67,12 +67,28 @@
       const std::string& currency_system,
       const std::string& locale_name);
 
-  // Returns the Autofill Profile, representing the shipping address and contact
-  // information, currently selected for this PaymentRequest flow. If
-  // unpopulated, populates with and returns the 0th profile on record for this
-  // user, if it exists; or nullptr otherwise. Profile is owned by the request
-  // object, not the caller.
-  autofill::AutofillProfile* GetCurrentlySelectedProfile();
+  // Returns the appropriate Autofill Profiles for this user. On the first
+  // invocation of either getter, the profiles are fetched from the
+  // PersonalDataManager; on subsequent invocations, a cached version is
+  // returned. The profiles returned are owned by the request object.
+  const std::vector<autofill::AutofillProfile*>& shipping_profiles();
+  const std::vector<autofill::AutofillProfile*>& contact_profiles();
+
+  // Gets/sets the Autofill Profile representing the shipping address or contact
+  // information currently selected for this PaymentRequest flow. Can return
+  // null.
+  autofill::AutofillProfile* selected_shipping_profile() const {
+    return selected_shipping_profile_;
+  }
+  void set_selected_shipping_profile(autofill::AutofillProfile* profile) {
+    selected_shipping_profile_ = profile;
+  }
+  autofill::AutofillProfile* selected_contact_profile() const {
+    return selected_contact_profile_;
+  }
+  void set_selected_contact_profile(autofill::AutofillProfile* profile) {
+    selected_contact_profile_ = profile;
+  }
 
   // Returns the currently selected credit card for this PaymentRequest flow.
   // It's not guaranteed to be complete. Returns nullptr if there is no selected
@@ -83,6 +99,13 @@
   content::WebContents* web_contents() { return web_contents_; }
 
  private:
+  // Fetches the Autofill Profiles for this user from the PersonalDataManager,
+  // and stores copies of them, owned by this Request, in profile_cache_.
+  void PopulateProfileCache();
+
+  // Sets the default values for the selected Shipping and Contact profiles.
+  void SetDefaultProfileSelections();
+
   content::WebContents* web_contents_;
   std::unique_ptr<PaymentRequestDelegate> delegate_;
   // |manager_| owns this PaymentRequest.
@@ -91,7 +114,15 @@
   payments::mojom::PaymentRequestClientPtr client_;
   payments::mojom::PaymentDetailsPtr details_;
   std::unique_ptr<CurrencyFormatter> currency_formatter_;
-  std::unique_ptr<autofill::AutofillProfile> profile_;
+
+  // Profiles may change due to (e.g.) sync events, so profiles are cached after
+  // loading and owned here. They are populated once only, and ordered by
+  // frecency.
+  std::vector<std::unique_ptr<autofill::AutofillProfile>> profile_cache_;
+  std::vector<autofill::AutofillProfile*> shipping_profiles_;
+  std::vector<autofill::AutofillProfile*> contact_profiles_;
+  autofill::AutofillProfile* selected_shipping_profile_;
+  autofill::AutofillProfile* selected_contact_profile_;
 
   DISALLOW_COPY_AND_ASSIGN(PaymentRequest);
 };
diff --git a/components/sync/device_info/device_info_sync_bridge.cc b/components/sync/device_info/device_info_sync_bridge.cc
index 0ba09e3..9490815 100644
--- a/components/sync/device_info/device_info_sync_bridge.cc
+++ b/components/sync/device_info/device_info_sync_bridge.cc
@@ -86,7 +86,7 @@
 
 DeviceInfoSyncBridge::DeviceInfoSyncBridge(
     LocalDeviceInfoProvider* local_device_info_provider,
-    const StoreFactoryFunction& callback,
+    const ModelTypeStoreFactory& store_factory,
     const ChangeProcessorFactory& change_processor_factory)
     : ModelTypeSyncBridge(change_processor_factory, DEVICE_INFO),
       local_device_info_provider_(local_device_info_provider) {
@@ -102,7 +102,7 @@
                    base::Unretained(this)));
   }
 
-  callback.Run(
+  store_factory.Run(
       base::Bind(&DeviceInfoSyncBridge::OnStoreCreated, base::AsWeakPtr(this)));
 }
 
diff --git a/components/sync/device_info/device_info_sync_bridge.h b/components/sync/device_info/device_info_sync_bridge.h
index 2634df0..1ddbb2b 100644
--- a/components/sync/device_info/device_info_sync_bridge.h
+++ b/components/sync/device_info/device_info_sync_bridge.h
@@ -34,11 +34,8 @@
 class DeviceInfoSyncBridge : public ModelTypeSyncBridge,
                              public DeviceInfoTracker {
  public:
-  typedef base::Callback<void(const ModelTypeStore::InitCallback& callback)>
-      StoreFactoryFunction;
-
   DeviceInfoSyncBridge(LocalDeviceInfoProvider* local_device_info_provider,
-                       const StoreFactoryFunction& callback,
+                       const ModelTypeStoreFactory& store_factory,
                        const ChangeProcessorFactory& change_processor_factory);
   ~DeviceInfoSyncBridge() override;
 
diff --git a/components/sync/model/model_type_store.h b/components/sync/model/model_type_store.h
index d640c9e..dfe9e3fa 100644
--- a/components/sync/model/model_type_store.h
+++ b/components/sync/model/model_type_store.h
@@ -195,6 +195,10 @@
   // It will delete all metadata records and global metadata record.
 };
 
+// Typedef for a store factory that has all params bound except InitCallback.
+using ModelTypeStoreFactory =
+    base::Callback<void(const ModelTypeStore::InitCallback&)>;
+
 }  // namespace syncer
 
 #endif  // COMPONENTS_SYNC_MODEL_MODEL_TYPE_STORE_H_
diff --git a/components/translate/core/browser/language_model.cc b/components/translate/core/browser/language_model.cc
index 6c575499..6899b38 100644
--- a/components/translate/core/browser/language_model.cc
+++ b/components/translate/core/browser/language_model.cc
@@ -132,4 +132,14 @@
     DiscountAndCleanCounters(dict);
 }
 
+void LanguageModel::ClearHistory(base::Time begin, base::Time end) {
+  // Ignore all partial removals and react only to "entire" history removal.
+  bool is_entire_history = (begin == base::Time() && end == base::Time::Max());
+  if (!is_entire_history) {
+    return;
+  }
+
+  pref_service_->ClearPref(kLanguageModelCounters);
+}
+
 }  // namespace translate
diff --git a/components/translate/core/browser/language_model.h b/components/translate/core/browser/language_model.h
index 1dc7436..b6547f0 100644
--- a/components/translate/core/browser/language_model.h
+++ b/components/translate/core/browser/language_model.h
@@ -9,6 +9,7 @@
 #include <vector>
 
 #include "base/macros.h"
+#include "base/time/time.h"
 #include "components/keyed_service/core/keyed_service.h"
 
 class PrefRegistrySimple;
@@ -56,6 +57,9 @@
   // Informs the model that a page with the given language has been visited.
   void OnPageVisited(const std::string& language_code);
 
+  // Reflect in the model that history from |begin| to |end| gets cleared.
+  void ClearHistory(base::Time begin, base::Time end);
+
  private:
   PrefService* pref_service_;
 
diff --git a/components/translate/core/browser/language_model_unittest.cc b/components/translate/core/browser/language_model_unittest.cc
index df8b6ba..f59a31b 100644
--- a/components/translate/core/browser/language_model_unittest.cc
+++ b/components/translate/core/browser/language_model_unittest.cc
@@ -11,6 +11,7 @@
 using testing::ElementsAre;
 using testing::FloatEq;
 using testing::Gt;
+using testing::SizeIs;
 
 namespace {
 
@@ -105,4 +106,42 @@
               ElementsAre(LanguageModel::LanguageInfo{kLang1, 1}));
 }
 
+TEST(LanguageModelTest, ShouldClearHistoryIfAllTimes) {
+  TestingPrefServiceSimple prefs;
+  LanguageModel::RegisterProfilePrefs(prefs.registry());
+  LanguageModel model(&prefs);
+
+  for (int i = 0; i < 100; i++) {
+    model.OnPageVisited(kLang1);
+  }
+
+  EXPECT_THAT(model.GetTopLanguages(), SizeIs(1));
+  EXPECT_THAT(model.GetLanguageFrequency(kLang1), FloatEq(1.0));
+
+  model.ClearHistory(base::Time(), base::Time::Max());
+
+  EXPECT_THAT(model.GetTopLanguages(), SizeIs(0));
+  EXPECT_THAT(model.GetLanguageFrequency(kLang1), FloatEq(0.0));
+}
+
+TEST(LanguageModelTest, ShouldNotClearHistoryIfNotAllTimes) {
+  TestingPrefServiceSimple prefs;
+  LanguageModel::RegisterProfilePrefs(prefs.registry());
+  LanguageModel model(&prefs);
+
+  for (int i = 0; i < 100; i++) {
+    model.OnPageVisited(kLang1);
+  }
+
+  EXPECT_THAT(model.GetTopLanguages(), SizeIs(1));
+  EXPECT_THAT(model.GetLanguageFrequency(kLang1), FloatEq(1.0));
+
+  // Clearing only the last hour of the history has no effect.
+  model.ClearHistory(base::Time::Now() - base::TimeDelta::FromHours(2),
+                     base::Time::Max());
+
+  EXPECT_THAT(model.GetTopLanguages(), SizeIs(1));
+  EXPECT_THAT(model.GetLanguageFrequency(kLang1), FloatEq(1.0));
+}
+
 }  // namespace translate
diff --git a/content/browser/frame_host/frame_navigation_entry.cc b/content/browser/frame_host/frame_navigation_entry.cc
index 5ebb6c2..3a46ef6f 100644
--- a/content/browser/frame_host/frame_navigation_entry.cc
+++ b/content/browser/frame_host/frame_navigation_entry.cc
@@ -99,7 +99,6 @@
 
 scoped_refptr<ResourceRequestBodyImpl> FrameNavigationEntry::GetPostData()
     const {
-  DCHECK(SiteIsolationPolicy::UseSubframeNavigationEntries());
   if (method_ != "POST")
     return nullptr;
 
diff --git a/content/browser/frame_host/navigation_controller_impl.cc b/content/browser/frame_host/navigation_controller_impl.cc
index 8b528d0..23de865 100644
--- a/content/browser/frame_host/navigation_controller_impl.cc
+++ b/content/browser/frame_host/navigation_controller_impl.cc
@@ -721,16 +721,14 @@
       // Update the FTN ID to use below in case we found a named frame.
       frame_tree_node_id = node->frame_tree_node_id();
 
-      // In --site-per-process, create an identical NavigationEntry with a
-      // new FrameNavigationEntry for the target subframe.
-      if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
-        entry = GetLastCommittedEntry()->Clone();
-        entry->AddOrUpdateFrameEntry(
-            node, -1, -1, nullptr,
-            static_cast<SiteInstanceImpl*>(params.source_site_instance.get()),
-            params.url, params.referrer, params.redirect_chain, PageState(),
-            "GET", -1);
-      }
+      // Create an identical NavigationEntry with a new FrameNavigationEntry for
+      // the target subframe.
+      entry = GetLastCommittedEntry()->Clone();
+      entry->AddOrUpdateFrameEntry(
+          node, -1, -1, nullptr,
+          static_cast<SiteInstanceImpl*>(params.source_site_instance.get()),
+          params.url, params.referrer, params.redirect_chain, PageState(),
+          "GET", -1);
     }
   }
 
@@ -867,11 +865,10 @@
       break;
     case NAVIGATION_TYPE_AUTO_SUBFRAME:
       if (!RendererDidNavigateAutoSubframe(rfh, params)) {
-        // In UseSubframeNavigationEntries mode, we won't send a notification
-        // about auto-subframe PageState during UpdateStateForFrame, since it
-        // looks like nothing has changed.  Send it here at commit time instead.
-        if (SiteIsolationPolicy::UseSubframeNavigationEntries())
-          NotifyEntryChanged(GetLastCommittedEntry());
+        // We don't send a notification about auto-subframe PageState during
+        // UpdateStateForFrame, since it looks like nothing has changed.  Send
+        // it here at commit time instead.
+        NotifyEntryChanged(GetLastCommittedEntry());
         return false;
       }
       break;
@@ -916,17 +913,12 @@
 
   FrameNavigationEntry* frame_entry =
       active_entry->GetFrameEntry(rfh->frame_tree_node());
-  if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
-    // Update the frame-specific PageState and RedirectChain
-    // We may not find a frame_entry in some cases; ignore the PageState if so.
-    // TODO(creis): Remove the "if" once https://crbug.com/522193 is fixed.
-    if (frame_entry) {
-      frame_entry->SetPageState(params.page_state);
-      frame_entry->set_redirect_chain(params.redirects);
-    }
-  } else {
-    active_entry->SetPageState(params.page_state);
-    active_entry->SetRedirectChain(params.redirects);
+  // Update the frame-specific PageState and RedirectChain
+  // We may not find a frame_entry in some cases; ignore the PageState if so.
+  // TODO(creis): Remove the "if" once https://crbug.com/522193 is fixed.
+  if (frame_entry) {
+    frame_entry->SetPageState(params.page_state);
+    frame_entry->set_redirect_chain(params.redirects);
   }
 
   // Use histogram to track memory impact of redirect chain because it's now
@@ -1343,24 +1335,20 @@
   DCHECK(GetLastCommittedEntry()) << "ClassifyNavigation should guarantee "
                                   << "that a last committed entry exists.";
 
-  std::unique_ptr<NavigationEntryImpl> new_entry;
-  if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
-    // Make sure we don't leak frame_entry if new_entry doesn't take ownership.
-    scoped_refptr<FrameNavigationEntry> frame_entry(new FrameNavigationEntry(
-        params.frame_unique_name, params.item_sequence_number,
-        params.document_sequence_number, rfh->GetSiteInstance(), nullptr,
-        params.url, params.referrer, params.method, params.post_id));
-    new_entry = GetLastCommittedEntry()->CloneAndReplace(
-        frame_entry.get(), is_in_page, rfh->frame_tree_node(),
-        delegate_->GetFrameTree()->root());
+  // Make sure we don't leak frame_entry if new_entry doesn't take ownership.
+  scoped_refptr<FrameNavigationEntry> frame_entry(new FrameNavigationEntry(
+      params.frame_unique_name, params.item_sequence_number,
+      params.document_sequence_number, rfh->GetSiteInstance(), nullptr,
+      params.url, params.referrer, params.method, params.post_id));
+  std::unique_ptr<NavigationEntryImpl> new_entry =
+      GetLastCommittedEntry()->CloneAndReplace(
+          frame_entry.get(), is_in_page, rfh->frame_tree_node(),
+          delegate_->GetFrameTree()->root());
 
-    // TODO(creis): Update this to add the frame_entry if we can't find the one
-    // to replace, which can happen due to a unique name change.  See
-    // https://crbug.com/607205.  For now, frame_entry will be deleted when it
-    // goes out of scope if it doesn't get used.
-  } else {
-    new_entry = GetLastCommittedEntry()->Clone();
-  }
+  // TODO(creis): Update this to add the frame_entry if we can't find the one
+  // to replace, which can happen due to a unique name change.  See
+  // https://crbug.com/607205.  For now, frame_entry will be deleted when it
+  // goes out of scope if it doesn't get used.
 
   InsertOrReplaceEntry(std::move(new_entry), replace_entry);
 }
@@ -1413,16 +1401,14 @@
     }
   }
 
-  if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
-    // This may be a "new auto" case where we add a new FrameNavigationEntry, or
-    // it may be a "history auto" case where we update an existing one.
-    NavigationEntryImpl* last_committed = GetLastCommittedEntry();
-    last_committed->AddOrUpdateFrameEntry(
-        rfh->frame_tree_node(), params.item_sequence_number,
-        params.document_sequence_number, rfh->GetSiteInstance(), nullptr,
-        params.url, params.referrer, params.redirects, params.page_state,
-        params.method, params.post_id);
-  }
+  // This may be a "new auto" case where we add a new FrameNavigationEntry, or
+  // it may be a "history auto" case where we update an existing one.
+  NavigationEntryImpl* last_committed = GetLastCommittedEntry();
+  last_committed->AddOrUpdateFrameEntry(
+      rfh->frame_tree_node(), params.item_sequence_number,
+      params.document_sequence_number, rfh->GetSiteInstance(), nullptr,
+      params.url, params.referrer, params.redirects, params.page_state,
+      params.method, params.post_id);
 
   return send_commit_notification;
 }
@@ -1896,23 +1882,8 @@
   DCHECK(pending_entry_);
   FrameTreeNode* root = delegate_->GetFrameTree()->root();
 
-  // In default Chrome, there are no subframe FrameNavigationEntries.  Either
-  // navigate the main frame or use the main frame's FrameNavigationEntry to
-  // tell the indicated frame where to go.
-  if (!SiteIsolationPolicy::UseSubframeNavigationEntries()) {
-    FrameNavigationEntry* frame_entry = GetPendingEntry()->GetFrameEntry(root);
-    FrameTreeNode* frame = root;
-    int ftn_id = GetPendingEntry()->frame_tree_node_id();
-    if (ftn_id != -1) {
-      frame = delegate_->GetFrameTree()->FindByID(ftn_id);
-      DCHECK(frame);
-    }
-    return frame->navigator()->NavigateToPendingEntry(frame, *frame_entry,
-                                                      reload_type, false);
-  }
-
-  // In --site-per-process, we compare FrameNavigationEntries to see which
-  // frames in the tree need to be navigated.
+  // Compare FrameNavigationEntries to see which frames in the tree need to be
+  // navigated.
   FrameLoadVector same_document_loads;
   FrameLoadVector different_document_loads;
   if (GetLastCommittedEntry()) {
diff --git a/content/browser/frame_host/navigation_entry_impl.cc b/content/browser/frame_host/navigation_entry_impl.cc
index 86a2aec..b528804 100644
--- a/content/browser/frame_host/navigation_entry_impl.cc
+++ b/content/browser/frame_host/navigation_entry_impl.cc
@@ -355,11 +355,6 @@
 }
 
 void NavigationEntryImpl::SetPageState(const PageState& state) {
-  if (!SiteIsolationPolicy::UseSubframeNavigationEntries()) {
-    frame_tree_->frame_entry->SetPageState(state);
-    return;
-  }
-
   // SetPageState should only be called before the NavigationEntry has been
   // loaded, such as for restore (when there are no subframe
   // FrameNavigationEntries yet).  However, some callers expect to call this
@@ -387,10 +382,9 @@
 }
 
 PageState NavigationEntryImpl::GetPageState() const {
-  // Just return the main frame's PageState in default Chrome, or if there are
-  // no subframe FrameNavigationEntries.
-  if (!SiteIsolationPolicy::UseSubframeNavigationEntries() ||
-      frame_tree_->children.size() == 0U)
+  // Just return the main frame's state if there are no subframe
+  // FrameNavigationEntries.
+  if (frame_tree_->children.size() == 0U)
     return frame_tree_->frame_entry->page_state();
 
   // When we're using subframe entries, each FrameNavigationEntry has a
diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc
index 4483572..1927b1c 100644
--- a/content/browser/frame_host/navigator_impl.cc
+++ b/content/browser/frame_host/navigator_impl.cc
@@ -751,8 +751,7 @@
   // Send the navigation to the current FrameTreeNode if it's destined for a
   // subframe in the current tab.  We'll assume it's for the main frame
   // (possibly of a new or different WebContents) otherwise.
-  if (SiteIsolationPolicy::UseSubframeNavigationEntries() &&
-      disposition == WindowOpenDisposition::CURRENT_TAB &&
+  if (disposition == WindowOpenDisposition::CURRENT_TAB &&
       render_frame_host->GetParent()) {
     frame_tree_node_id =
         render_frame_host->frame_tree_node()->frame_tree_node_id();
@@ -867,7 +866,6 @@
   std::unique_ptr<NavigationEntryImpl> entry;
   if (!node->IsMainFrame()) {
     // Subframe case: create FrameNavigationEntry.
-    CHECK(SiteIsolationPolicy::UseSubframeNavigationEntries());
     if (controller_->GetLastCommittedEntry()) {
       entry = controller_->GetLastCommittedEntry()->Clone();
       entry->set_extra_headers(extra_headers);
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
index a564e6b..7424a5b 100644
--- a/content/browser/frame_host/render_frame_host_impl.cc
+++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -1067,8 +1067,6 @@
   GetProcess()->FilterURL(false, &validated_url);
 
   if (params.is_history_navigation_in_new_child) {
-    DCHECK(SiteIsolationPolicy::UseSubframeNavigationEntries());
-
     // Try to find a FrameNavigationEntry that matches this frame instead, based
     // on the frame's unique name.  If this can't be found, fall back to the
     // default params using RequestOpenURL below.
diff --git a/content/browser/renderer_host/render_view_host_delegate.h b/content/browser/renderer_host/render_view_host_delegate.h
index 2e1dda41..7dc40c3 100644
--- a/content/browser/renderer_host/render_view_host_delegate.h
+++ b/content/browser/renderer_host/render_view_host_delegate.h
@@ -32,7 +32,6 @@
 
 class BrowserContext;
 class FrameTree;
-class PageState;
 class RenderViewHost;
 class RenderViewHostImpl;
 class RenderViewHostDelegateView;
@@ -85,10 +84,6 @@
   // RenderView is going to be destroyed
   virtual void RenderViewDeleted(RenderViewHost* render_view_host) {}
 
-  // The state for the page changed and should be updated.
-  virtual void UpdateState(RenderViewHost* render_view_host,
-                           const PageState& state) {}
-
   // The destination URL has changed should be updated.
   virtual void UpdateTargetURL(RenderViewHost* render_view_host,
                                const GURL& url) {}
diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc
index 6cca925..0ada79d 100644
--- a/content/browser/renderer_host/render_view_host_impl.cc
+++ b/content/browser/renderer_host/render_view_host_impl.cc
@@ -769,7 +769,6 @@
     IPC_MESSAGE_HANDLER(ViewHostMsg_ShowWidget, OnShowWidget)
     IPC_MESSAGE_HANDLER(ViewHostMsg_ShowFullscreenWidget,
                         OnShowFullscreenWidget)
-    IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateState, OnUpdateState)
     IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateTargetURL, OnUpdateTargetURL)
     IPC_MESSAGE_HANDLER(ViewHostMsg_Close, OnClose)
     IPC_MESSAGE_HANDLER(ViewHostMsg_RequestMove, OnRequestMove)
@@ -833,20 +832,6 @@
   // decoupled.
 }
 
-void RenderViewHostImpl::OnUpdateState(const PageState& state) {
-  // Without this check, the renderer can trick the browser into using
-  // filenames it can't access in a future session restore.
-  auto* policy = ChildProcessSecurityPolicyImpl::GetInstance();
-  int child_id = GetProcess()->GetID();
-  if (!policy->CanReadAllFiles(child_id, state.GetReferencedFiles())) {
-    bad_message::ReceivedBadMessage(
-        GetProcess(), bad_message::RVH_CAN_ACCESS_FILES_OF_PAGE_STATE);
-    return;
-  }
-
-  delegate_->UpdateState(this, state);
-}
-
 void RenderViewHostImpl::OnUpdateTargetURL(const GURL& url) {
   if (is_active_)
     delegate_->UpdateTargetURL(this, url);
diff --git a/content/browser/renderer_host/render_view_host_impl.h b/content/browser/renderer_host/render_view_host_impl.h
index 88b7ea9a..cb30e86 100644
--- a/content/browser/renderer_host/render_view_host_impl.h
+++ b/content/browser/renderer_host/render_view_host_impl.h
@@ -35,7 +35,6 @@
 
 namespace content {
 
-class PageState;
 struct FrameReplicationState;
 
 // This implements the RenderViewHost interface that is exposed to
@@ -233,7 +232,6 @@
   void OnShowWidget(int route_id, const gfx::Rect& initial_rect);
   void OnShowFullscreenWidget(int route_id);
   void OnRenderProcessGone(int status, int error_code);
-  void OnUpdateState(const PageState& state);
   void OnUpdateTargetURL(const GURL& url);
   void OnClose();
   void OnRequestMove(const gfx::Rect& pos);
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc
index 2f2051fc..592bad2 100644
--- a/content/browser/site_per_process_browsertest.cc
+++ b/content/browser/site_per_process_browsertest.cc
@@ -2275,13 +2275,12 @@
   GURL url_a = child->current_url();
 
   // Disable host resolution in the test server and try to navigate the subframe
-  // cross-site, which will lead to a committed net error (which looks like
-  // success to the TestNavigationObserver).
+  // cross-site, which will lead to a committed net error.
   GURL url_b = embedded_test_server()->GetURL("b.com", "/title3.html");
   host_resolver()->ClearRules();
   TestNavigationObserver observer(shell()->web_contents());
   NavigateIframeToURL(shell()->web_contents(), "child-0", url_b);
-  EXPECT_TRUE(observer.last_navigation_succeeded());
+  EXPECT_FALSE(observer.last_navigation_succeeded());
   EXPECT_EQ(url_b, observer.last_navigation_url());
   EXPECT_EQ(2, shell()->web_contents()->GetController().GetEntryCount());
 
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 95a4592..5de41501 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -4392,33 +4392,6 @@
     observer.RenderViewDeleted(rvh);
 }
 
-void WebContentsImpl::UpdateState(RenderViewHost* rvh,
-                                  const PageState& page_state) {
-  DCHECK(!SiteIsolationPolicy::UseSubframeNavigationEntries());
-
-  // Ensure that this state update comes from a RenderViewHost that belongs to
-  // this WebContents.
-  // TODO(nasko): This should go through RenderFrameHost.
-  if (rvh->GetDelegate()->GetAsWebContents() != this)
-    return;
-
-  if (!rvh->GetMainFrame()) {
-    // When UseSubframeNavigationEntries is turned off, state updates only come
-    // in on main frames. When UseSubframeNavigationEntries is turned on,
-    // UpdateStateForFrame() should have been called rather than this function.
-    NOTREACHED();
-    return;
-  }
-
-  NavigationEntryImpl* entry = controller_.GetEntryWithUniqueID(
-      static_cast<RenderFrameHostImpl*>(rvh->GetMainFrame())->nav_entry_id());
-
-  if (page_state == entry->GetPageState())
-    return;  // Nothing to update.
-  entry->SetPageState(page_state);
-  controller_.NotifyEntryChanged(entry);
-}
-
 void WebContentsImpl::UpdateTargetURL(RenderViewHost* render_view_host,
                                       const GURL& url) {
   if (fullscreen_widget_routing_id_ != MSG_ROUTING_NONE) {
@@ -4584,8 +4557,6 @@
 
 void WebContentsImpl::UpdateStateForFrame(RenderFrameHost* render_frame_host,
                                           const PageState& page_state) {
-  DCHECK(SiteIsolationPolicy::UseSubframeNavigationEntries());
-
   // The state update affects the last NavigationEntry associated with the given
   // |render_frame_host|. This may not be the last committed NavigationEntry (as
   // in the case of an UpdateState from a frame being swapped out). We track
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h
index fcd0937..ab1c9e7 100644
--- a/content/browser/web_contents/web_contents_impl.h
+++ b/content/browser/web_contents/web_contents_impl.h
@@ -515,8 +515,6 @@
                             base::TerminationStatus status,
                             int error_code) override;
   void RenderViewDeleted(RenderViewHost* render_view_host) override;
-  void UpdateState(RenderViewHost* render_view_host,
-                   const PageState& page_state) override;
   void UpdateTargetURL(RenderViewHost* render_view_host,
                        const GURL& url) override;
   void Close(RenderViewHost* render_view_host) override;
diff --git a/content/common/site_isolation_policy.cc b/content/common/site_isolation_policy.cc
index 015940a..5a47487 100644
--- a/content/common/site_isolation_policy.cc
+++ b/content/common/site_isolation_policy.cc
@@ -38,9 +38,4 @@
       switches::kTopDocumentIsolation);
 }
 
-// static
-bool SiteIsolationPolicy::UseSubframeNavigationEntries() {
-  return true;
-}
-
 }  // namespace content
diff --git a/content/common/site_isolation_policy.h b/content/common/site_isolation_policy.h
index c6d6e61..3e70f64 100644
--- a/content/common/site_isolation_policy.h
+++ b/content/common/site_isolation_policy.h
@@ -41,12 +41,6 @@
   // different process from the main frame.
   static bool IsTopDocumentIsolationEnabled();
 
-  // Returns true if navigation and history code should maintain per-frame
-  // navigation entries. This is an in-progress feature related to site
-  // isolation, so the return value is currently tied to --site-per-process.
-  // TODO(creis, avi): Make this the default, and eliminate this.
-  static bool UseSubframeNavigationEntries();
-
  private:
   SiteIsolationPolicy();  // Not instantiable.
 
diff --git a/content/common/swapped_out_messages.cc b/content/common/swapped_out_messages.cc
index 0b19611..233d07d 100644
--- a/content/common/swapped_out_messages.cc
+++ b/content/common/swapped_out_messages.cc
@@ -58,8 +58,6 @@
   // Note that synchronous messages that are not handled will receive an
   // error reply instead, to avoid leaving the renderer in a stuck state.
   switch (msg.type()) {
-    // Updates the previous navigation entry.
-    case ViewHostMsg_UpdateState::ID:
     // Sends an ACK.
     case ViewHostMsg_UpdateTargetURL::ID:
     // We allow closing even if we are in the process of swapping out.
diff --git a/content/common/view_messages.h b/content/common/view_messages.h
index 8df18e9..e10872a 100644
--- a/content/common/view_messages.h
+++ b/content/common/view_messages.h
@@ -657,10 +657,6 @@
 // message.
 IPC_MESSAGE_ROUTED0(ViewHostMsg_ClosePage_ACK)
 
-// Notifies the browser that we have session history information.
-IPC_MESSAGE_ROUTED1(ViewHostMsg_UpdateState,
-                    content::PageState /* state */)
-
 // Notifies the browser that we want to show a destination url for a potential
 // action (e.g. when the user is hovering over a link).
 IPC_MESSAGE_ROUTED1(ViewHostMsg_UpdateTargetURL,
diff --git a/content/public/common/BUILD.gn b/content/public/common/BUILD.gn
index 22f354d..f04b7f90f 100644
--- a/content/public/common/BUILD.gn
+++ b/content/public/common/BUILD.gn
@@ -9,7 +9,7 @@
 import("//media/media_options.gni")
 import("//mojo/public/tools/bindings/mojom.gni")
 import("//ppapi/features/features.gni")
-import("//third_party/webrtc/build/webrtc.gni")
+import("//third_party/webrtc/webrtc.gni")
 
 # See //content/BUILD.gn for how this works.
 group("common") {
diff --git a/content/public/test/render_view_test.cc b/content/public/test/render_view_test.cc
index d36497a8..bc99abf7 100644
--- a/content/public/test/render_view_test.cc
+++ b/content/public/test/render_view_test.cc
@@ -20,7 +20,6 @@
 #include "content/common/input_messages.h"
 #include "content/common/renderer.mojom.h"
 #include "content/common/resize_params.h"
-#include "content/common/site_isolation_policy.h"
 #include "content/common/view_messages.h"
 #include "content/public/browser/content_browser_client.h"
 #include "content/public/browser/native_web_keyboard_event.h"
@@ -30,7 +29,6 @@
 #include "content/public/common/renderer_preferences.h"
 #include "content/public/renderer/content_renderer_client.h"
 #include "content/public/test/frame_load_waiter.h"
-#include "content/renderer/history_controller.h"
 #include "content/renderer/history_serialization.h"
 #include "content/renderer/render_thread_impl.h"
 #include "content/renderer/render_view_impl.h"
@@ -212,17 +210,12 @@
 PageState RenderViewTest::GetCurrentPageState() {
   RenderViewImpl* view_impl = static_cast<RenderViewImpl*>(view_);
 
-  if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
-    // This returns a PageState object for the main frame, excluding subframes.
-    // This could be extended to all local frames if needed by tests, but it
-    // cannot include out-of-process frames.
-    TestRenderFrame* frame =
-        static_cast<TestRenderFrame*>(view_impl->GetMainRenderFrame());
-    return SingleHistoryItemToPageState(frame->current_history_item());
-  } else {
-    return HistoryEntryToPageState(
-        view_impl->history_controller()->GetCurrentEntry());
-  }
+  // This returns a PageState object for the main frame, excluding subframes.
+  // This could be extended to all local frames if needed by tests, but it
+  // cannot include out-of-process frames.
+  TestRenderFrame* frame =
+      static_cast<TestRenderFrame*>(view_impl->GetMainRenderFrame());
+  return SingleHistoryItemToPageState(frame->current_history_item());
 }
 
 void RenderViewTest::GoBack(const GURL& url, const PageState& state) {
diff --git a/content/public/test/test_navigation_observer.cc b/content/public/test/test_navigation_observer.cc
index dcaf956..2abb8e2 100644
--- a/content/public/test/test_navigation_observer.cc
+++ b/content/public/test/test_navigation_observer.cc
@@ -5,13 +5,10 @@
 #include "content/public/test/test_navigation_observer.h"
 
 #include "base/bind.h"
-#include "base/macros.h"
-#include "base/memory/ptr_util.h"
 #include "base/message_loop/message_loop.h"
-#include "base/run_loop.h"
 #include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/web_contents_observer.h"
-#include "testing/gtest/include/gtest/gtest.h"
 
 namespace content {
 
@@ -47,29 +44,19 @@
     parent_->OnDidStopLoading(web_contents());
   }
 
-  void DidStartProvisionalLoadForFrame(RenderFrameHost* render_frame_host,
-                                       const GURL& validated_url,
-                                       bool is_error_page) override {
-    parent_->OnDidStartProvisionalLoad(render_frame_host, validated_url,
-                                       is_error_page);
+  void DidStartNavigation(NavigationHandle* navigation_handle) override {
+    if (navigation_handle->IsSamePage())
+      return;
+
+    parent_->OnDidStartNavigation();
   }
 
-  void DidFailProvisionalLoad(
-      RenderFrameHost* render_frame_host,
-      const GURL& validated_url,
-      int error_code,
-      const base::string16& error_description,
-      bool was_ignored_by_handler) override {
-    parent_->OnDidFailProvisionalLoad(render_frame_host, validated_url,
-                                      error_code, error_description);
-  }
+  void DidFinishNavigation(NavigationHandle* navigation_handle) override {
+    if (!navigation_handle->HasCommitted())
+      return;
 
-  void DidCommitProvisionalLoadForFrame(
-      RenderFrameHost* render_frame_host,
-      const GURL& url,
-      ui::PageTransition transition_type) override {
-    parent_->OnDidCommitProvisionalLoadForFrame(
-        render_frame_host, url, transition_type);
+    parent_->OnDidFinishNavigation(navigation_handle->IsErrorPage(),
+                                   navigation_handle->GetURL());
   }
 
   TestNavigationObserver* parent_;
@@ -163,28 +150,14 @@
   }
 }
 
-void TestNavigationObserver::OnDidStartProvisionalLoad(
-    RenderFrameHost* render_frame_host,
-    const GURL& validated_url,
-    bool is_error_page) {
+void TestNavigationObserver::OnDidStartNavigation() {
   last_navigation_succeeded_ = false;
 }
 
-void TestNavigationObserver::OnDidFailProvisionalLoad(
-    RenderFrameHost* render_frame_host,
-    const GURL& validated_url,
-    int error_code,
-    const base::string16& error_description) {
-  last_navigation_url_ = validated_url;
-  last_navigation_succeeded_ = false;
-}
-
-void TestNavigationObserver::OnDidCommitProvisionalLoadForFrame(
-    RenderFrameHost* render_frame_host,
-    const GURL& url,
-    ui::PageTransition transition_type) {
+void TestNavigationObserver::OnDidFinishNavigation(bool is_error_page,
+                                                   const GURL& url) {
   last_navigation_url_ = url;
-  last_navigation_succeeded_ = true;
+  last_navigation_succeeded_ = !is_error_page;
 }
 
 }  // namespace content
diff --git a/content/public/test/test_navigation_observer.h b/content/public/test/test_navigation_observer.h
index 6409486..a2333f3 100644
--- a/content/public/test/test_navigation_observer.h
+++ b/content/public/test/test_navigation_observer.h
@@ -9,16 +9,12 @@
 #include <set>
 
 #include "base/callback.h"
-#include "base/compiler_specific.h"
 #include "base/macros.h"
 #include "content/public/test/test_utils.h"
-#include "ui/base/page_transition_types.h"
 #include "url/gurl.h"
 
 namespace content {
-class RenderFrameHost;
 class WebContents;
-struct LoadCommittedDetails;
 
 // For browser_tests, which run on the UI thread, run a second
 // MessageLoop and quit when the navigation completes loading.
@@ -67,16 +63,8 @@
   void OnDidAttachInterstitialPage(WebContents* web_contents);
   void OnDidStartLoading(WebContents* web_contents);
   void OnDidStopLoading(WebContents* web_contents);
-  void OnDidStartProvisionalLoad(RenderFrameHost* render_frame_host,
-                                 const GURL& validated_url,
-                                 bool is_error_page);
-  void OnDidFailProvisionalLoad(RenderFrameHost* render_frame_host,
-                                const GURL& validated_url,
-                                int error_code,
-                                const base::string16& error_description);
-  void OnDidCommitProvisionalLoadForFrame(RenderFrameHost* render_frame_host,
-                                          const GURL& url,
-                                          ui::PageTransition transition_type);
+  void OnDidStartNavigation();
+  void OnDidFinishNavigation(bool is_error_page, const GURL& url);
 
   // If true the navigation has started.
   bool navigation_started_;
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn
index ddf805f..06535765 100644
--- a/content/renderer/BUILD.gn
+++ b/content/renderer/BUILD.gn
@@ -9,7 +9,7 @@
 import("//media/media_options.gni")
 import("//ppapi/features/features.gni")
 import("//printing/features/features.gni")
-import("//third_party/webrtc/build/webrtc.gni")
+import("//third_party/webrtc/webrtc.gni")
 import("//tools/ipc_fuzzer/ipc_fuzzer.gni")
 
 if (is_component_build) {
@@ -147,8 +147,6 @@
     "gpu/renderer_compositor_frame_sink.h",
     "gpu/stream_texture_host_android.cc",
     "gpu/stream_texture_host_android.h",
-    "history_controller.cc",
-    "history_controller.h",
     "history_entry.cc",
     "history_entry.h",
     "history_serialization.cc",
diff --git a/content/renderer/history_controller.cc b/content/renderer/history_controller.cc
deleted file mode 100644
index 6369f09..0000000
--- a/content/renderer/history_controller.cc
+++ /dev/null
@@ -1,335 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/*
- * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
- * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
- * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved.
- *     (http://www.torchmobile.com/)
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "content/renderer/history_controller.h"
-
-#include <utility>
-
-#include "base/memory/ptr_util.h"
-#include "content/common/navigation_params.h"
-#include "content/common/site_isolation_policy.h"
-#include "content/renderer/render_frame_impl.h"
-#include "content/renderer/render_view_impl.h"
-#include "third_party/WebKit/public/web/WebFrameLoadType.h"
-#include "third_party/WebKit/public/web/WebLocalFrame.h"
-
-using blink::WebCachePolicy;
-using blink::WebFrame;
-using blink::WebHistoryCommitType;
-using blink::WebHistoryItem;
-using blink::WebURLRequest;
-
-namespace content {
-
-HistoryController::HistoryController(RenderViewImpl* render_view)
-    : render_view_(render_view) {
-  // We don't use HistoryController in OOPIF enabled modes.
-  DCHECK(!SiteIsolationPolicy::UseSubframeNavigationEntries());
-}
-
-HistoryController::~HistoryController() {
-}
-
-bool HistoryController::GoToEntry(
-    blink::WebLocalFrame* main_frame,
-    std::unique_ptr<HistoryEntry> target_entry,
-    std::unique_ptr<NavigationParams> navigation_params,
-    WebCachePolicy cache_policy) {
-  DCHECK(!main_frame->parent());
-  HistoryFrameLoadVector same_document_loads;
-  HistoryFrameLoadVector different_document_loads;
-
-  set_provisional_entry(std::move(target_entry));
-  navigation_params_ = std::move(navigation_params);
-
-  if (current_entry_) {
-    RecursiveGoToEntry(
-        main_frame, same_document_loads, different_document_loads);
-  }
-
-  if (same_document_loads.empty() && different_document_loads.empty()) {
-    // If we don't have any frames to navigate at this point, either
-    // (1) there is no previous history entry to compare against, or
-    // (2) we were unable to match any frames by name. In the first case,
-    // doing a different document navigation to the root item is the only valid
-    // thing to do. In the second case, we should have been able to find a
-    // frame to navigate based on names if this were a same document
-    // navigation, so we can safely assume this is the different document case.
-    different_document_loads.push_back(
-        std::make_pair(main_frame, provisional_entry_->root()));
-  }
-
-  bool has_main_frame_request = false;
-  for (const auto& item : same_document_loads) {
-    WebFrame* frame = item.first;
-    RenderFrameImpl* render_frame = RenderFrameImpl::FromWebFrame(frame);
-    if (!render_frame)
-      continue;
-    render_frame->SetPendingNavigationParams(
-        base::MakeUnique<NavigationParams>(*navigation_params_.get()));
-    WebURLRequest request = frame->toWebLocalFrame()->requestFromHistoryItem(
-        item.second, cache_policy);
-    frame->toWebLocalFrame()->load(
-        request, blink::WebFrameLoadType::BackForward, item.second,
-        blink::WebHistorySameDocumentLoad);
-    if (frame == main_frame)
-      has_main_frame_request = true;
-  }
-  for (const auto& item : different_document_loads) {
-    WebFrame* frame = item.first;
-    RenderFrameImpl* render_frame = RenderFrameImpl::FromWebFrame(frame);
-    if (!render_frame)
-      continue;
-    render_frame->SetPendingNavigationParams(
-        base::MakeUnique<NavigationParams>(*navigation_params_.get()));
-    WebURLRequest request = frame->toWebLocalFrame()->requestFromHistoryItem(
-        item.second, cache_policy);
-    frame->toWebLocalFrame()->load(
-        request, blink::WebFrameLoadType::BackForward, item.second,
-        blink::WebHistoryDifferentDocumentLoad);
-    if (frame == main_frame)
-      has_main_frame_request = true;
-  }
-
-  return has_main_frame_request;
-}
-
-void HistoryController::RecursiveGoToEntry(
-    WebFrame* frame,
-    HistoryFrameLoadVector& same_document_loads,
-    HistoryFrameLoadVector& different_document_loads) {
-  DCHECK(provisional_entry_);
-  DCHECK(current_entry_);
-  RenderFrameImpl* render_frame = RenderFrameImpl::FromWebFrame(frame);
-  const WebHistoryItem& new_item =
-      provisional_entry_->GetItemForFrame(render_frame);
-
-  // Use the last committed history item for the frame rather than
-  // current_entry_, since the latter may not accurately reflect which URL is
-  // currently committed in the frame.  See https://crbug.com/612713#c12.
-  const WebHistoryItem& old_item = render_frame->current_history_item();
-
-  if (new_item.isNull())
-    return;
-
-  if (old_item.isNull() ||
-      new_item.itemSequenceNumber() != old_item.itemSequenceNumber()) {
-    if (!old_item.isNull() &&
-        new_item.documentSequenceNumber() ==
-            old_item.documentSequenceNumber()) {
-      same_document_loads.push_back(std::make_pair(frame, new_item));
-
-      // Returning here (and omitting child frames which have also changed) is
-      // wrong, but not returning here is worse. See the discussion in
-      // NavigationControllerImpl::FindFramesToNavigate for more information.
-      return;
-    } else {
-      different_document_loads.push_back(std::make_pair(frame, new_item));
-      // For a different document, the subframes will be destroyed, so there's
-      // no need to consider them.
-      return;
-    }
-  }
-
-  for (WebFrame* child = frame->firstChild(); child;
-       child = child->nextSibling()) {
-    RecursiveGoToEntry(child, same_document_loads, different_document_loads);
-  }
-}
-
-void HistoryController::UpdateForInitialLoadInChildFrame(
-    RenderFrameImpl* frame,
-    const WebHistoryItem& item) {
-  DCHECK_NE(frame->GetWebFrame()->top(), frame->GetWebFrame());
-  if (!current_entry_)
-    return;
-  if (HistoryEntry::HistoryNode* existing_node =
-          current_entry_->GetHistoryNodeForFrame(frame)) {
-    // Clear the children and any NavigationParams if this commit isn't for
-    // the same item.  Otherwise we might have stale data after a redirect.
-    if (existing_node->item().itemSequenceNumber() !=
-        item.itemSequenceNumber()) {
-      existing_node->RemoveChildren();
-      navigation_params_.reset();
-    }
-    existing_node->set_item(item);
-    return;
-  }
-  RenderFrameImpl* parent =
-      RenderFrameImpl::FromWebFrame(frame->GetWebFrame()->parent());
-  if (!parent)
-    return;
-  if (HistoryEntry::HistoryNode* parent_history_node =
-          current_entry_->GetHistoryNodeForFrame(parent)) {
-    parent_history_node->AddChild(item);
-  }
-}
-
-void HistoryController::UpdateForCommit(RenderFrameImpl* frame,
-                                        const WebHistoryItem& item,
-                                        WebHistoryCommitType commit_type,
-                                        bool navigation_within_page) {
-  switch (commit_type) {
-    case blink::WebBackForwardCommit:
-      if (!provisional_entry_) {
-        // The provisional entry may have been discarded due to a navigation in
-        // a different frame.  For main frames, it is not safe to leave the
-        // current_entry_ in place, which may have a cross-site page and will be
-        // included in the PageState for this commit.  Replace it with a new
-        // HistoryEntry corresponding to the commit, and clear any stale
-        // NavigationParams which might point to the wrong entry.
-        //
-        // This will lack any subframe history items that were in the original
-        // provisional entry, but we don't know what those were after discarding
-        // it.  We'll load the default URL in those subframes instead.
-        //
-        // TODO(creis): It's also possible to get here for subframe commits.
-        // We'll leave a stale current_entry_ in that case, but that only causes
-        // an earlier URL to load in the subframe when leaving and coming back,
-        // and only in rare cases.  It does not risk a URL spoof, unlike the
-        // main frame case.  Since this bug is not present in the new
-        // FrameNavigationEntry-based navigation path (https://crbug.com/236848)
-        // we'll wait for that to fix the subframe case.
-        if (frame->IsMainFrame()) {
-          current_entry_.reset(new HistoryEntry(item));
-          navigation_params_.reset();
-        }
-
-        return;
-      }
-
-      // If the current entry is null, this must be a main frame commit.
-      DCHECK(current_entry_ || frame->IsMainFrame());
-
-      // Commit the provisional entry, but only if it is a plausible transition.
-      // Do not commit it if the navigation is in a subframe and the provisional
-      // entry's main frame item does not match the current entry's main frame,
-      // which can happen if multiple forward navigations occur.  In that case,
-      // committing the provisional entry would corrupt it, leading to a URL
-      // spoof.  See https://crbug.com/597322.  (Note that the race in this bug
-      // does not affect main frame navigations, only navigations in subframes.)
-      //
-      // Note that we cannot compare the provisional entry against |item|, since
-      // |item| may have redirected to a different URL and ISN.  We also cannot
-      // compare against the main frame's URL, since that may have changed due
-      // to a replaceState.  (Even origin can change on replaceState in certain
-      // modes.)
-      //
-      // It would be safe to additionally check the ISNs of all parent frames
-      // (and not just the root), but that is less critical because it won't
-      // lead to a URL spoof.
-      if (frame->IsMainFrame() ||
-          current_entry_->root().itemSequenceNumber() ==
-              provisional_entry_->root().itemSequenceNumber()) {
-        current_entry_ = std::move(provisional_entry_);
-      }
-
-      // We're guaranteed to have a current entry now.
-      DCHECK(current_entry_);
-
-      if (HistoryEntry::HistoryNode* node =
-              current_entry_->GetHistoryNodeForFrame(frame)) {
-        // Clear the children and any NavigationParams if this commit isn't for
-        // the same item.  Otherwise we might have stale data from a race.
-        if (node->item().itemSequenceNumber() != item.itemSequenceNumber()) {
-          node->RemoveChildren();
-          navigation_params_.reset();
-        }
-
-        node->set_item(item);
-      }
-      break;
-    case blink::WebStandardCommit:
-      CreateNewBackForwardItem(frame, item, navigation_within_page);
-      break;
-    case blink::WebInitialCommitInChildFrame:
-      UpdateForInitialLoadInChildFrame(frame, item);
-      break;
-    case blink::WebHistoryInertCommit:
-      // Even for inert commits (e.g., location.replace, client redirects), make
-      // sure the current entry gets updated, if there is one.
-      if (current_entry_) {
-        if (HistoryEntry::HistoryNode* node =
-                current_entry_->GetHistoryNodeForFrame(frame)) {
-          // Inert commits that reset the page without changing the item (e.g.,
-          // reloads, location.replace) shouldn't keep the old subtree.
-          if (!navigation_within_page)
-            node->RemoveChildren();
-          node->set_item(item);
-        }
-      }
-      break;
-    default:
-      NOTREACHED() << "Invalid commit type: " << commit_type;
-  }
-}
-
-HistoryEntry* HistoryController::GetCurrentEntry() {
-  return current_entry_.get();
-}
-
-WebHistoryItem HistoryController::GetItemForNewChildFrame(
-    RenderFrameImpl* frame) const {
-  if (navigation_params_.get()) {
-    frame->SetPendingNavigationParams(
-        base::MakeUnique<NavigationParams>(*navigation_params_.get()));
-  }
-
-  if (!current_entry_)
-    return WebHistoryItem();
-  return current_entry_->GetItemForFrame(frame);
-}
-
-void HistoryController::RemoveChildrenForRedirect(RenderFrameImpl* frame) {
-  if (!provisional_entry_)
-    return;
-  if (HistoryEntry::HistoryNode* node =
-          provisional_entry_->GetHistoryNodeForFrame(frame))
-    node->RemoveChildren();
-}
-
-void HistoryController::CreateNewBackForwardItem(
-    RenderFrameImpl* target_frame,
-    const WebHistoryItem& new_item,
-    bool clone_children_of_target) {
-  if (!current_entry_) {
-    current_entry_.reset(new HistoryEntry(new_item));
-  } else {
-    current_entry_.reset(current_entry_->CloneAndReplace(
-        new_item, clone_children_of_target, target_frame, render_view_));
-  }
-}
-
-}  // namespace content
diff --git a/content/renderer/history_controller.h b/content/renderer/history_controller.h
deleted file mode 100644
index ac52241..0000000
--- a/content/renderer/history_controller.h
+++ /dev/null
@@ -1,172 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/*
- * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
- * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved.
- *     (http://www.torchmobile.com/)
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef CONTENT_RENDERER_HISTORY_CONTROLLER_H_
-#define CONTENT_RENDERER_HISTORY_CONTROLLER_H_
-
-#include <memory>
-#include <utility>
-
-#include "base/containers/hash_tables.h"
-#include "base/macros.h"
-#include "content/common/content_export.h"
-#include "content/renderer/history_entry.h"
-#include "third_party/WebKit/public/web/WebHistoryCommitType.h"
-#include "third_party/WebKit/public/web/WebHistoryItem.h"
-
-namespace blink {
-class WebFrame;
-class WebLocalFrame;
-enum class WebCachePolicy;
-}
-
-namespace content {
-class RenderFrameImpl;
-class RenderViewImpl;
-struct NavigationParams;
-
-// A guide to history state in the renderer:
-//
-// HistoryController: Owned by RenderView, is the entry point for interacting
-//     with history. Handles most of the operations to modify history state,
-//     navigate to an existing back/forward entry, etc.
-//
-// HistoryEntry: Represents a single entry in the back/forward list,
-//     encapsulating all frames in the page it represents. It provides access
-//     to each frame's state via lookups by frame id or frame name.
-// HistoryNode: Represents a single frame in a HistoryEntry. Owned by a
-//     HistoryEntry. HistoryNodes form a tree that mirrors the frame tree in
-//     the corresponding page.
-// HistoryNodes represent the structure of the page, but don't hold any
-// per-frame state except a list of child frames.
-// WebHistoryItem (lives in blink): The state for a given frame. Can persist
-//     across navigations. WebHistoryItem is reference counted, and each
-//     HistoryNode holds a reference to its single corresponding
-//     WebHistoryItem. Can be referenced by multiple HistoryNodes and can
-//     therefore exist in multiple HistoryEntry instances.
-//
-// Suppose we have the following page, foo.com, which embeds foo.com/a in an
-// iframe:
-//
-// HistoryEntry 0:
-//     HistoryNode 0_0 (WebHistoryItem A (url: foo.com))
-//         HistoryNode 0_1: (WebHistoryItem B (url: foo.com/a))
-//
-// Now we navigate the top frame to bar.com, which embeds bar.com/b and
-// bar.com/c in iframes, and bar.com/b in turn embeds bar.com/d. We will
-// create a new HistoryEntry with a tree containing 4 new HistoryNodes. The
-// state will be:
-//
-// HistoryEntry 1:
-//     HistoryNode 1_0 (WebHistoryItem C (url: bar.com))
-//         HistoryNode 1_1: (WebHistoryItem D (url: bar.com/b))
-//             HistoryNode 1_3: (WebHistoryItem F (url: bar.com/d))
-//         HistoryNode 1_2: (WebHistoryItem E (url: bar.com/c))
-//
-//
-// Finally, we navigate the first subframe from bar.com/b to bar.com/e, which
-// embeds bar.com/f. We will create a new HistoryEntry and new HistoryNode for
-// each frame. Any frame that navigates (bar.com/e and its child, bar.com/f)
-// will receive a new WebHistoryItem. However, 2 frames were not navigated
-// (bar.com and bar.com/c), so those two frames will reuse the existing
-// WebHistoryItem:
-//
-// HistoryEntry 2:
-//     HistoryNode 2_0 (WebHistoryItem C (url: bar.com))  *REUSED*
-//         HistoryNode 2_1: (WebHistoryItem G (url: bar.com/e))
-//            HistoryNode 2_3: (WebHistoryItem H (url: bar.com/f))
-//         HistoryNode 2_2: (WebHistoryItem E (url: bar.com/c)) *REUSED*
-//
-class CONTENT_EXPORT HistoryController {
- public:
-  explicit HistoryController(RenderViewImpl* render_view);
-  ~HistoryController();
-
-  void set_provisional_entry(std::unique_ptr<HistoryEntry> entry) {
-    provisional_entry_ = std::move(entry);
-  }
-
-  // Return true if the main frame ended up loading a request as part of the
-  // history navigation.
-  bool GoToEntry(blink::WebLocalFrame* main_frame,
-                 std::unique_ptr<HistoryEntry> entry,
-                 std::unique_ptr<NavigationParams> navigation_params,
-                 blink::WebCachePolicy cache_policy);
-
-  void UpdateForCommit(RenderFrameImpl* frame,
-                       const blink::WebHistoryItem& item,
-                       blink::WebHistoryCommitType commit_type,
-                       bool navigation_within_page);
-
-  HistoryEntry* GetCurrentEntry();
-  blink::WebHistoryItem GetItemForNewChildFrame(RenderFrameImpl* frame) const;
-  void RemoveChildrenForRedirect(RenderFrameImpl* frame);
-
- private:
-  typedef std::vector<std::pair<blink::WebFrame*, blink::WebHistoryItem> >
-      HistoryFrameLoadVector;
-  void RecursiveGoToEntry(blink::WebFrame* frame,
-                          HistoryFrameLoadVector& sameDocumentLoads,
-                          HistoryFrameLoadVector& differentDocumentLoads);
-
-  void UpdateForInitialLoadInChildFrame(RenderFrameImpl* frame,
-                                        const blink::WebHistoryItem& item);
-  void CreateNewBackForwardItem(RenderFrameImpl* frame,
-                                const blink::WebHistoryItem& item,
-                                bool clone_children_of_target);
-
-  RenderViewImpl* render_view_;
-
-  // A HistoryEntry representing the currently-loaded page.
-  std::unique_ptr<HistoryEntry> current_entry_;
-  // A HistoryEntry representing the page that is being loaded, or an empty
-  // scoped_ptr if no page is being loaded.
-  std::unique_ptr<HistoryEntry> provisional_entry_;
-
-  // The NavigationParams corresponding to the last back/forward load that was
-  // initiated by |GoToEntry|. This is kept around so that it can be passed into
-  // existing frames affected by a history navigation in GoToEntry(), and can be
-  // passed into frames created after the commit that resulted from the
-  // navigation in GetItemForNewChildFrame().
-  //
-  // This is reset in UpdateForCommit if we see a commit from a different
-  // navigation, to avoid using stale parameters.
-  std::unique_ptr<NavigationParams> navigation_params_;
-
-  DISALLOW_COPY_AND_ASSIGN(HistoryController);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_RENDERER_HISTORY_CONTROLLER_H_
diff --git a/content/renderer/history_controller_browsertest.cc b/content/renderer/history_controller_browsertest.cc
deleted file mode 100644
index 148c0c3..0000000
--- a/content/renderer/history_controller_browsertest.cc
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "build/build_config.h"
-#include "content/common/site_isolation_policy.h"
-#include "content/public/test/render_view_test.h"
-#include "content/renderer/history_controller.h"
-#include "content/renderer/render_frame_impl.h"
-#include "content/renderer/render_view_impl.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/WebKit/public/web/WebHistoryItem.h"
-
-namespace content {
-
-class HistoryControllerTest : public RenderViewTest {
- public:
-  ~HistoryControllerTest() override {}
-
-  // Create a main frame with a single child frame.
-  void SetUp() override {
-    RenderViewTest::SetUp();
-    LoadHTML("Parent frame <iframe name='frame'></iframe>");
-  }
-
-  void TearDown() override { RenderViewTest::TearDown(); }
-
-  HistoryController* history_controller() {
-    return static_cast<RenderViewImpl*>(view_)->history_controller();
-  }
-};
-
-#if defined(OS_ANDROID)
-// See https://crbug.com/472717
-#define MAYBE_InertCommitRemovesChildren DISABLED_InertCommitRemovesChildren
-#else
-#define MAYBE_InertCommitRemovesChildren InertCommitRemovesChildren
-#endif
-
-TEST_F(HistoryControllerTest, MAYBE_InertCommitRemovesChildren) {
-  // This test is moot when subframe FrameNavigationEntries are enabled, since
-  // we don't use HistoryController in that case.
-  if (SiteIsolationPolicy::UseSubframeNavigationEntries())
-    return;
-
-  HistoryEntry* entry = history_controller()->GetCurrentEntry();
-  ASSERT_TRUE(entry);
-  ASSERT_EQ(1ul, entry->root_history_node()->children().size());
-
-  blink::WebHistoryItem item;
-  item.initialize();
-  RenderFrameImpl* main_frame =
-      static_cast<RenderFrameImpl*>(view_->GetMainRenderFrame());
-
-  // Don't clear children for in-page navigations.
-  history_controller()->UpdateForCommit(main_frame, item,
-                                        blink::WebHistoryInertCommit, true);
-  EXPECT_EQ(1ul, entry->root_history_node()->children().size());
-
-  // Clear children for cross-page navigations.
-  history_controller()->UpdateForCommit(main_frame, item,
-                                        blink::WebHistoryInertCommit, false);
-  EXPECT_EQ(0ul, entry->root_history_node()->children().size());
-}
-
-}  // namespace
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 4f6c272b..eb5dfd4 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -100,7 +100,7 @@
 #include "content/renderer/effective_connection_type_helper.h"
 #include "content/renderer/external_popup_menu.h"
 #include "content/renderer/gpu/gpu_benchmarking_extension.h"
-#include "content/renderer/history_controller.h"
+#include "content/renderer/history_entry.h"
 #include "content/renderer/history_serialization.h"
 #include "content/renderer/image_downloader/image_downloader_impl.h"
 #include "content/renderer/ime_event_guard.h"
@@ -1693,10 +1693,7 @@
   // other active RenderFrames in it.
 
   // Send an UpdateState message before we get deleted.
-  if (SiteIsolationPolicy::UseSubframeNavigationEntries())
-    SendUpdateState();
-  else
-    render_view_->SendUpdateState();
+  SendUpdateState();
 
   // There should always be a proxy to replace this RenderFrame.  Create it now
   // so its routing id is registered for receiving IPC messages.
@@ -3094,8 +3091,7 @@
     observer.FrameDetached(frame);
 
   // Send a state update before the frame is detached.
-  if (SiteIsolationPolicy::UseSubframeNavigationEntries())
-    SendUpdateState();
+  SendUpdateState();
 
   // We only notify the browser process when the frame is being detached for
   // removal and it was initiated from the renderer process.
@@ -3297,12 +3293,9 @@
 }
 
 blink::WebHistoryItem RenderFrameImpl::historyItemForNewChildFrame() {
-  // OOPIF enabled modes will punt this navigation to the browser in
-  // decidePolicyForNavigation.
-  if (SiteIsolationPolicy::UseSubframeNavigationEntries())
-    return WebHistoryItem();
-
-  return render_view_->history_controller()->GetItemForNewChildFrame(this);
+  // We will punt this navigation to the browser in decidePolicyForNavigation.
+  // TODO(creis): Look into cleaning this up.
+  return WebHistoryItem();
 }
 
 void RenderFrameImpl::willSendSubmitEvent(const blink::WebFormElement& form) {
@@ -3472,11 +3465,8 @@
     blink::WebLocalFrame* frame) {
   DCHECK_EQ(frame_, frame);
 
-  // We don't use HistoryController in OOPIF enabled modes.
-  if (SiteIsolationPolicy::UseSubframeNavigationEntries())
-    return;
-
-  render_view_->history_controller()->RemoveChildrenForRedirect(this);
+  // TODO(creis): Determine if this can be removed or if we need to clear any
+  // local state here to fix https://crbug.com/671276.
 }
 
 void RenderFrameImpl::didFailProvisionalLoad(
@@ -3615,13 +3605,8 @@
   // When we perform a new navigation, we need to update the last committed
   // session history entry with state for the page we are leaving. Do this
   // before updating the current history item.
-  if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
-    SendUpdateState();
-  } else {
-    render_view_->SendUpdateState();
-    render_view_->history_controller()->UpdateForCommit(
-        this, item, commit_type, navigation_state->WasWithinSamePage());
-  }
+  SendUpdateState();
+
   // Update the current history item for this frame (both in default Chrome and
   // subframe FrameNavigationEntry modes).
   current_history_item_ = item;
@@ -4880,31 +4865,14 @@
   render_view_->navigation_gesture_ = NavigationGestureUnknown;
 
   // Make navigation state a part of the DidCommitProvisionalLoad message so
-  // that committed entry has it at all times.
-  int64_t post_id = -1;
-  if (!SiteIsolationPolicy::UseSubframeNavigationEntries()) {
-    HistoryEntry* entry = render_view_->history_controller()->GetCurrentEntry();
-    if (entry) {
-      params.page_state = HistoryEntryToPageState(entry);
-      post_id = ExtractPostId(entry->root());
-    } else {
-      params.page_state = PageState::CreateFromURL(request.url());
-    }
-  } else {
-    // In --site-per-process, just send a single HistoryItem for this frame,
-    // rather than the whole tree.  It will be stored in the corresponding
-    // FrameNavigationEntry.
-    params.page_state = SingleHistoryItemToPageState(item);
-    post_id = ExtractPostId(item);
-  }
+  // that committed entry has it at all times.  Send a single HistoryItem for
+  // this frame, rather than the whole tree.  It will be stored in the
+  // corresponding FrameNavigationEntry.
+  params.page_state = SingleHistoryItemToPageState(item);
 
-  // When using subframe navigation entries, method and post id are set for all
-  // frames. Otherwise, they are only set for the main frame navigation.
-  if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
-    params.method = request.httpMethod().latin1();
-    if (params.method == "POST")
-      params.post_id = post_id;
-  }
+  params.method = request.httpMethod().latin1();
+  if (params.method == "POST")
+    params.post_id = ExtractPostId(item);
 
   params.frame_unique_name = item.target().utf8();
   params.item_sequence_number = item.itemSequenceNumber();
@@ -4978,14 +4946,6 @@
           params.transition | ui::PAGE_TRANSITION_CLIENT_REDIRECT);
     }
 
-    // When using subframe navigation entries, method and post id have already
-    // been set.
-    if (!SiteIsolationPolicy::UseSubframeNavigationEntries()) {
-      params.method = request.httpMethod().latin1();
-      if (params.method == "POST")
-        params.post_id = post_id;
-    }
-
     // Send the user agent override back.
     params.is_overriding_user_agent = internal_data->is_overriding_user_agent();
 
@@ -5297,15 +5257,13 @@
     return blink::WebNavigationPolicyIgnore;  // Suppress the load here.
   }
 
-  // In OOPIF-enabled modes, back/forward navigations in newly created subframes
-  // should be sent to the browser if there is a matching FrameNavigationEntry,
-  // and if it isn't just staying at about:blank.  If this frame isn't in the
-  // map of unique names that have history items, or if it's staying at the
-  // initial about:blank URL, fall back to loading the default url.  (We remove
-  // each name as we encounter it, because it will only be used once as the
-  // frame is created.)
-  if (SiteIsolationPolicy::UseSubframeNavigationEntries() &&
-      info.isHistoryNavigationInNewChildFrame && is_content_initiated &&
+  // Back/forward navigations in newly created subframes should be sent to the
+  // browser if there is a matching FrameNavigationEntry, and if it isn't just
+  // staying at about:blank.  If this frame isn't in the map of unique names
+  // that have history items, or if it's staying at the initial about:blank URL,
+  // fall back to loading the default url.  (We remove each name as we encounter
+  // it, because it will only be used once as the frame is created.)
+  if (info.isHistoryNavigationInNewChildFrame && is_content_initiated &&
       frame_->parent()) {
     // Check whether the browser has a history item for this frame that isn't
     // just staying at the initial about:blank document.
@@ -5825,10 +5783,8 @@
     WebUserGestureIndicator::consumeUserGesture();
   }
 
-  if (is_history_navigation_in_new_child) {
-    DCHECK(SiteIsolationPolicy::UseSubframeNavigationEntries());
+  if (is_history_navigation_in_new_child)
     params.is_history_navigation_in_new_child = true;
-  }
 
   Send(new FrameHostMsg_OpenURL(routing_id_, params));
 }
@@ -5857,11 +5813,7 @@
   if (request_params.has_committed_real_load && frame_->parent())
     frame_->setCommittedFirstRealLoad();
 
-  bool no_current_entry =
-      SiteIsolationPolicy::UseSubframeNavigationEntries()
-          ? current_history_item_.isNull()
-          : !render_view_->history_controller()->GetCurrentEntry();
-  if (is_reload && no_current_entry) {
+  if (is_reload && current_history_item_.isNull()) {
     // We cannot reload if we do not have any history state.  This happens, for
     // example, when recovering from a crash.
     is_reload = false;
@@ -5943,78 +5895,62 @@
     std::unique_ptr<HistoryEntry> entry =
         PageStateToHistoryEntry(request_params.page_state);
     if (entry) {
-      if (!SiteIsolationPolicy::UseSubframeNavigationEntries()) {
-        // By default, tell the HistoryController to go the deserialized
-        // HistoryEntry.  This only works if all frames are in the same
-        // process.
-        DCHECK(!frame_->parent());
-        DCHECK(!browser_side_navigation);
-        std::unique_ptr<NavigationParams> navigation_params(
-            new NavigationParams(*pending_navigation_params_.get()));
-        has_history_navigation_in_frame =
-            render_view_->history_controller()->GoToEntry(
-                frame_, std::move(entry), std::move(navigation_params),
-                cache_policy);
-      } else {
-        // In --site-per-process, the browser process sends a single
-        // WebHistoryItem destined for this frame.
-        // TODO(creis): Change PageState to FrameState.  In the meantime, we
-        // store the relevant frame's WebHistoryItem in the root of the
-        // PageState.
-        item_for_history_navigation = entry->root();
-        history_load_type = request_params.is_same_document_history_load
-                                ? blink::WebHistorySameDocumentLoad
-                                : blink::WebHistoryDifferentDocumentLoad;
-        load_type = request_params.is_history_navigation_in_new_child
-                        ? blink::WebFrameLoadType::InitialHistoryLoad
-                        : blink::WebFrameLoadType::BackForward;
-        should_load_request = true;
+      // The browser process sends a single WebHistoryItem for this frame.
+      // TODO(creis): Change PageState to FrameState.  In the meantime, we
+      // store the relevant frame's WebHistoryItem in the root of the
+      // PageState.
+      item_for_history_navigation = entry->root();
+      history_load_type = request_params.is_same_document_history_load
+                              ? blink::WebHistorySameDocumentLoad
+                              : blink::WebHistoryDifferentDocumentLoad;
+      load_type = request_params.is_history_navigation_in_new_child
+                      ? blink::WebFrameLoadType::InitialHistoryLoad
+                      : blink::WebFrameLoadType::BackForward;
+      should_load_request = true;
 
-        // Keep track of which subframes the browser process has history items
-        // for during a history navigation.
-        history_subframe_unique_names_ = request_params.subframe_unique_names;
+      // Keep track of which subframes the browser process has history items
+      // for during a history navigation.
+      history_subframe_unique_names_ = request_params.subframe_unique_names;
 
-        if (history_load_type == blink::WebHistorySameDocumentLoad) {
-          // If this is marked as a same document load but we haven't committed
-          // anything, treat it as a new load.  The browser shouldn't let this
-          // happen.
-          if (current_history_item_.isNull()) {
+      if (history_load_type == blink::WebHistorySameDocumentLoad) {
+        // If this is marked as a same document load but we haven't committed
+        // anything, treat it as a new load.  The browser shouldn't let this
+        // happen.
+        if (current_history_item_.isNull()) {
+          history_load_type = blink::WebHistoryDifferentDocumentLoad;
+          NOTREACHED();
+        } else {
+          // Additionally, if the |current_history_item_|'s document
+          // sequence number doesn't match the one sent from the browser, it
+          // is possible that this renderer has committed a different
+          // document. In such case, don't use WebHistorySameDocumentLoad.
+          if (current_history_item_.documentSequenceNumber() !=
+              item_for_history_navigation.documentSequenceNumber()) {
             history_load_type = blink::WebHistoryDifferentDocumentLoad;
-            NOTREACHED();
-          } else {
-            // Additionally, if the |current_history_item_|'s document
-            // sequence number doesn't match the one sent from the browser, it
-            // is possible that this renderer has committed a different
-            // document. In such case, don't use WebHistorySameDocumentLoad.
-            if (current_history_item_.documentSequenceNumber() !=
-                item_for_history_navigation.documentSequenceNumber()) {
-              history_load_type = blink::WebHistoryDifferentDocumentLoad;
-            }
           }
         }
+      }
 
-        // If this navigation is to a history item for a new child frame, we may
-        // want to ignore it in some cases.  If a Javascript navigation (i.e.,
-        // client redirect) interrupted it and has either been scheduled,
-        // started loading, or has committed, we should ignore the history item.
-        bool interrupted_by_client_redirect =
-            frame_->isNavigationScheduledWithin(0) ||
-            frame_->provisionalDataSource() ||
-            !current_history_item_.isNull();
-        if (request_params.is_history_navigation_in_new_child &&
-            interrupted_by_client_redirect) {
-          should_load_request = false;
-          has_history_navigation_in_frame = false;
-        }
+      // If this navigation is to a history item for a new child frame, we may
+      // want to ignore it in some cases.  If a Javascript navigation (i.e.,
+      // client redirect) interrupted it and has either been scheduled,
+      // started loading, or has committed, we should ignore the history item.
+      bool interrupted_by_client_redirect =
+          frame_->isNavigationScheduledWithin(0) ||
+          frame_->provisionalDataSource() || !current_history_item_.isNull();
+      if (request_params.is_history_navigation_in_new_child &&
+          interrupted_by_client_redirect) {
+        should_load_request = false;
+        has_history_navigation_in_frame = false;
+      }
 
-        // Generate the request for the load from the HistoryItem.
-        // PlzNavigate: use the data sent by the browser for the url and the
-        // HTTP state. The restoration of user state such as scroll position
-        // will be done based on the history item during the load.
-        if (!browser_side_navigation && should_load_request) {
-          request = frame_->requestFromHistoryItem(item_for_history_navigation,
-                                                   cache_policy);
-        }
+      // Generate the request for the load from the HistoryItem.
+      // PlzNavigate: use the data sent by the browser for the url and the
+      // HTTP state. The restoration of user state such as scroll position
+      // will be done based on the history item during the load.
+      if (!browser_side_navigation && should_load_request) {
+        request = frame_->requestFromHistoryItem(item_for_history_navigation,
+                                                 cache_policy);
       }
     }
   } else {
@@ -6075,7 +6011,7 @@
     // that the load stopped if needed.
     // Note: in the case of history navigations, |should_load_request| will be
     // false, and the frame may not have been set in a loading state. Do not
-    // send a stop message if the HistoryController is loading in this frame
+    // send a stop message if a history navigation is loading in this frame
     // nonetheless. This behavior will go away with subframe navigation
     // entries.
     if (frame_ && !frame_->isLoading() && !has_history_navigation_in_frame)
@@ -6353,7 +6289,6 @@
 }
 
 void RenderFrameImpl::SendUpdateState() {
-  DCHECK(SiteIsolationPolicy::UseSubframeNavigationEntries());
   if (current_history_item_.isNull())
     return;
 
diff --git a/content/renderer/render_view_browsertest.cc b/content/renderer/render_view_browsertest.cc
index 25bd75d..0d23fcdd 100644
--- a/content/renderer/render_view_browsertest.cc
+++ b/content/renderer/render_view_browsertest.cc
@@ -50,7 +50,7 @@
 #include "content/renderer/accessibility/render_accessibility_impl.h"
 #include "content/renderer/devtools/devtools_agent.h"
 #include "content/renderer/gpu/render_widget_compositor.h"
-#include "content/renderer/history_controller.h"
+#include "content/renderer/history_entry.h"
 #include "content/renderer/history_serialization.h"
 #include "content/renderer/navigation_state_impl.h"
 #include "content/renderer/render_frame_proxy.h"
@@ -585,8 +585,6 @@
   // We should NOT have gotten a form state change notification yet.
   EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching(
       FrameHostMsg_UpdateState::ID));
-  EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching(
-      ViewHostMsg_UpdateState::ID));
   render_thread_->sink().ClearMessages();
 
   // Change the value of the input. We should have gotten an update state
@@ -937,10 +935,10 @@
   // Check for a valid UpdateState message for page A.
   ProcessPendingMessages();
   const IPC::Message* msg_A = render_thread_->sink().GetUniqueMessageMatching(
-      ViewHostMsg_UpdateState::ID);
+      FrameHostMsg_UpdateState::ID);
   ASSERT_TRUE(msg_A);
-  ViewHostMsg_UpdateState::Param param;
-  ViewHostMsg_UpdateState::Read(msg_A, &param);
+  FrameHostMsg_UpdateState::Param param;
+  FrameHostMsg_UpdateState::Read(msg_A, &param);
   PageState state_A = std::get<0>(param);
   render_thread_->sink().ClearMessages();
 
@@ -950,9 +948,9 @@
   // Check for a valid UpdateState for page B.
   ProcessPendingMessages();
   const IPC::Message* msg_B = render_thread_->sink().GetUniqueMessageMatching(
-      ViewHostMsg_UpdateState::ID);
+      FrameHostMsg_UpdateState::ID);
   ASSERT_TRUE(msg_B);
-  ViewHostMsg_UpdateState::Read(msg_B, &param);
+  FrameHostMsg_UpdateState::Read(msg_B, &param);
   PageState state_B = std::get<0>(param);
   EXPECT_NE(state_A, state_B);
   render_thread_->sink().ClearMessages();
@@ -963,9 +961,9 @@
   // Check for a valid UpdateState for page C.
   ProcessPendingMessages();
   const IPC::Message* msg_C = render_thread_->sink().GetUniqueMessageMatching(
-      ViewHostMsg_UpdateState::ID);
+      FrameHostMsg_UpdateState::ID);
   ASSERT_TRUE(msg_C);
-  ViewHostMsg_UpdateState::Read(msg_C, &param);
+  FrameHostMsg_UpdateState::Read(msg_C, &param);
   PageState state_C = std::get<0>(param);
   EXPECT_NE(state_B, state_C);
   render_thread_->sink().ClearMessages();
@@ -978,6 +976,7 @@
   request_params_C.current_history_list_length = 4;
   request_params_C.current_history_list_offset = 3;
   request_params_C.pending_history_list_offset = 2;
+  request_params_C.nav_entry_id = 3;
   request_params_C.page_state = state_C;
   frame()->Navigate(common_params_C, StartNavigationParams(), request_params_C);
   ProcessPendingMessages();
@@ -995,6 +994,7 @@
   request_params_B.current_history_list_length = 4;
   request_params_B.current_history_list_offset = 2;
   request_params_B.pending_history_list_offset = 1;
+  request_params_B.nav_entry_id = 2;
   request_params_B.page_state = state_B;
   frame()->Navigate(common_params_B, StartNavigationParams(), request_params_B);
 
@@ -1006,6 +1006,7 @@
   request_params.current_history_list_length = 4;
   request_params.current_history_list_offset = 2;
   request_params.pending_history_list_offset = 0;
+  request_params.nav_entry_id = 1;
   request_params.page_state = state_A;
   frame()->Navigate(common_params, StartNavigationParams(), request_params);
   ProcessPendingMessages();
@@ -1013,9 +1014,9 @@
   // Now ensure that the UpdateState message we receive is consistent
   // and represents page C in state.
   const IPC::Message* msg = render_thread_->sink().GetUniqueMessageMatching(
-      ViewHostMsg_UpdateState::ID);
+      FrameHostMsg_UpdateState::ID);
   ASSERT_TRUE(msg);
-  ViewHostMsg_UpdateState::Read(msg, &param);
+  FrameHostMsg_UpdateState::Read(msg, &param);
   PageState state = std::get<0>(param);
   EXPECT_NE(state_A, state);
   EXPECT_NE(state_B, state);
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
index e157b37..a4ddccb4 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -53,7 +53,6 @@
 #include "content/common/input_messages.h"
 #include "content/common/page_messages.h"
 #include "content/common/render_message_filter.mojom.h"
-#include "content/common/site_isolation_policy.h"
 #include "content/common/view_messages.h"
 #include "content/public/common/bindings_policy.h"
 #include "content/public/common/browser_side_navigation_policy.h"
@@ -77,7 +76,6 @@
 #include "content/renderer/dom_storage/webstoragenamespace_impl.h"
 #include "content/renderer/drop_data_builder.h"
 #include "content/renderer/gpu/render_widget_compositor.h"
-#include "content/renderer/history_controller.h"
 #include "content/renderer/history_serialization.h"
 #include "content/renderer/idle_user_detector.h"
 #include "content/renderer/ime_event_guard.h"
@@ -712,10 +710,6 @@
     OnEnableAutoResize(params.min_size, params.max_size);
   }
 
-  // We don't use HistoryController in OOPIF-enabled modes.
-  if (!SiteIsolationPolicy::UseSubframeNavigationEntries())
-    history_controller_.reset(new HistoryController(this));
-
   new IdleUserDetector(this);
 
   if (command_line.HasSwitch(switches::kDomAutomationController))
@@ -1343,18 +1337,6 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-void RenderViewImpl::SendUpdateState() {
-  // We don't use this path in OOPIF-enabled modes.
-  DCHECK(!SiteIsolationPolicy::UseSubframeNavigationEntries());
-
-  HistoryEntry* entry = history_controller_->GetCurrentEntry();
-  if (!entry)
-    return;
-
-  Send(new ViewHostMsg_UpdateState(GetRoutingID(),
-                                   HistoryEntryToPageState(entry)));
-}
-
 void RenderViewImpl::ShowCreatedPopupWidget(RenderWidget* popup_widget,
                                             WebNavigationPolicy policy,
                                             const gfx::Rect& initial_rect) {
@@ -1371,9 +1353,6 @@
 }
 
 void RenderViewImpl::SendFrameStateUpdates() {
-  // We only use this path in OOPIF-enabled modes.
-  DCHECK(SiteIsolationPolicy::UseSubframeNavigationEntries());
-
   // Tell each frame with pending state to send its UpdateState message.
   for (int render_frame_routing_id : frames_with_pending_state_) {
     RenderFrameImpl* frame =
@@ -1681,9 +1660,8 @@
 }
 
 void RenderViewImpl::StartNavStateSyncTimerIfNecessary(RenderFrameImpl* frame) {
-  // In OOPIF modes, keep track of which frames have pending updates.
-  if (SiteIsolationPolicy::UseSubframeNavigationEntries())
-    frames_with_pending_state_.insert(frame->GetRoutingID());
+  // Keep track of which frames have pending updates.
+  frames_with_pending_state_.insert(frame->GetRoutingID());
 
   int delay;
   if (send_content_state_immediately_)
@@ -1702,15 +1680,9 @@
     nav_state_sync_timer_.Stop();
   }
 
-  if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
-    // In OOPIF modes, tell each frame with pending state to inform the browser.
-    nav_state_sync_timer_.Start(FROM_HERE, TimeDelta::FromSeconds(delay), this,
-                                &RenderViewImpl::SendFrameStateUpdates);
-  } else {
-    // By default, send an UpdateState for the current history item.
-    nav_state_sync_timer_.Start(FROM_HERE, TimeDelta::FromSeconds(delay), this,
-                                &RenderViewImpl::SendUpdateState);
-  }
+  // Tell each frame with pending state to inform the browser.
+  nav_state_sync_timer_.Start(FROM_HERE, TimeDelta::FromSeconds(delay), this,
+                              &RenderViewImpl::SendFrameStateUpdates);
 }
 
 void RenderViewImpl::setMouseOverURL(const WebURL& url) {
diff --git a/content/renderer/render_view_impl.h b/content/renderer/render_view_impl.h
index 96b6012..57d38b4 100644
--- a/content/renderer/render_view_impl.h
+++ b/content/renderer/render_view_impl.h
@@ -94,7 +94,6 @@
 
 namespace content {
 
-class HistoryController;
 class RendererDateTimePicker;
 class RenderViewImplTest;
 class RenderViewObserver;
@@ -165,10 +164,6 @@
     send_content_state_immediately_ = value;
   }
 
-  HistoryController* history_controller() {
-    return history_controller_.get();
-  }
-
   // Functions to add and remove observers for this object.
   void AddObserver(RenderViewObserver* observer);
   void RemoveObserver(RenderViewObserver* observer);
@@ -218,9 +213,6 @@
   // be coalesced into one update.
   void StartNavStateSyncTimerIfNecessary(RenderFrameImpl* frame);
 
-  // Synchronously sends the current navigation state to the browser.
-  void SendUpdateState();
-
   // A popup widget opened by this view needs to be shown.
   void ShowCreatedPopupWidget(RenderWidget* popup_widget,
                               blink::WebNavigationPolicy policy,
@@ -796,8 +788,6 @@
   // initialized.
   SpeechRecognitionDispatcher* speech_recognition_dispatcher_;
 
-  std::unique_ptr<HistoryController> history_controller_;
-
 #if defined(OS_ANDROID)
   // Android Specific ---------------------------------------------------------
 
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index 86c8bb1c..a563ecc 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -654,7 +654,6 @@
     "../renderer/accessibility/render_accessibility_impl_browsertest.cc",
     "../renderer/blink_platform_audio_hardware_browsertest.cc",
     "../renderer/gin_browsertest.cc",
-    "../renderer/history_controller_browsertest.cc",
     "../renderer/media/renderer_webmediaplayer_delegate_browsertest.cc",
     "../renderer/mouse_lock_dispatcher_browsertest.cc",
     "../renderer/render_frame_impl_browsertest.cc",
diff --git a/content/test/layouttest_support.cc b/content/test/layouttest_support.cc
index 117f9bd..784fb2c 100644
--- a/content/test/layouttest_support.cc
+++ b/content/test/layouttest_support.cc
@@ -24,7 +24,6 @@
 #include "content/browser/renderer_host/render_process_host_impl.h"
 #include "content/browser/renderer_host/render_widget_host_impl.h"
 #include "content/common/renderer.mojom.h"
-#include "content/common/site_isolation_policy.h"
 #include "content/public/common/page_state.h"
 #include "content/public/common/screen_info.h"
 #include "content/public/renderer/renderer_gamepad_provider.h"
@@ -459,9 +458,6 @@
 void SyncNavigationState(RenderView* render_view) {
   // TODO(creis): Add support for testing in OOPIF-enabled modes.
   // See https://crbug.com/477150.
-  if (SiteIsolationPolicy::UseSubframeNavigationEntries())
-    return;
-  static_cast<RenderViewImpl*>(render_view)->SendUpdateState();
 }
 
 void SetFocusAndActivate(RenderView* render_view, bool enable) {
diff --git a/content/test/test_render_view_host.cc b/content/test/test_render_view_host.cc
index b03f7b8..380ae45 100644
--- a/content/test/test_render_view_host.cc
+++ b/content/test/test_render_view_host.cc
@@ -17,7 +17,6 @@
 #include "content/browser/site_instance_impl.h"
 #include "content/common/dom_storage/dom_storage_types.h"
 #include "content/common/frame_messages.h"
-#include "content/common/site_isolation_policy.h"
 #include "content/common/view_messages.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_thread.h"
@@ -313,11 +312,7 @@
     const base::FilePath& file_path) {
   PageState state = PageState::CreateForTesting(GURL("http://www.google.com"),
                                                 false, "data", &file_path);
-  if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
-    static_cast<RenderFrameHostImpl*>(GetMainFrame())->OnUpdateState(state);
-  } else {
-    OnUpdateState(state);
-  }
+  static_cast<RenderFrameHostImpl*>(GetMainFrame())->OnUpdateState(state);
 }
 
 RenderViewHostImplTestHarness::RenderViewHostImplTestHarness() {
diff --git a/ios/BUILD.gn b/ios/BUILD.gn
index 98cb99a..e4dc67f 100644
--- a/ios/BUILD.gn
+++ b/ios/BUILD.gn
@@ -28,6 +28,9 @@
     deps = [
       # List all the targets that need to be build on iOS by default.
       "//ios/chrome/app:chrome",
+      "//ios/chrome/share_extension",
+      "//ios/chrome/today_extension",
+      "//ios/chrome/widget_extension",
       "//ios/clean/chrome/app:chrome_clean_skeleton",
       "//ios/showcase",
       "//ios/web/shell:ios_web_shell",
diff --git a/ios/chrome/browser/sync/ios_chrome_profile_sync_service_factory.cc b/ios/chrome/browser/sync/ios_chrome_profile_sync_service_factory.cc
index 45b759c..ea0f45cd 100644
--- a/ios/chrome/browser/sync/ios_chrome_profile_sync_service_factory.cc
+++ b/ios/chrome/browser/sync/ios_chrome_profile_sync_service_factory.cc
@@ -141,7 +141,11 @@
   init_params.url_request_context = browser_state->GetRequestContext();
   init_params.debug_identifier = browser_state->GetDebugName();
   init_params.channel = ::GetChannel();
-  init_params.blocking_pool = web::WebThread::GetBlockingPool();
+  base::SequencedWorkerPool* blocking_pool = web::WebThread::GetBlockingPool();
+  init_params.blocking_task_runner =
+      blocking_pool->GetSequencedTaskRunnerWithShutdownBehavior(
+          blocking_pool->GetSequenceToken(),
+          base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
 
   auto pss = base::MakeUnique<ProfileSyncService>(std::move(init_params));
 
diff --git a/ios/chrome/browser/sync/ios_chrome_profile_sync_test_util.cc b/ios/chrome/browser/sync/ios_chrome_profile_sync_test_util.cc
index 9bc40fc..f83e9782 100644
--- a/ios/chrome/browser/sync/ios_chrome_profile_sync_test_util.cc
+++ b/ios/chrome/browser/sync/ios_chrome_profile_sync_test_util.cc
@@ -38,7 +38,11 @@
   init_params.url_request_context = browser_state->GetRequestContext();
   init_params.debug_identifier = browser_state->GetDebugName();
   init_params.channel = ::GetChannel();
-  init_params.blocking_pool = web::WebThread::GetBlockingPool();
+  base::SequencedWorkerPool* blocking_pool = web::WebThread::GetBlockingPool();
+  init_params.blocking_task_runner =
+      blocking_pool->GetSequencedTaskRunnerWithShutdownBehavior(
+          blocking_pool->GetSequenceToken(),
+          base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
 
   return init_params;
 }
diff --git a/ios/web/BUILD.gn b/ios/web/BUILD.gn
index 684d845..ad7c532 100644
--- a/ios/web/BUILD.gn
+++ b/ios/web/BUILD.gn
@@ -525,6 +525,8 @@
     "payments/payment_request_unittest.cc",
     "public/origin_util_unittest.mm",
     "public/referrer_util_unittest.cc",
+    "public/test/crw_mock_web_state_delegate.h",
+    "public/test/crw_mock_web_state_delegate.mm",
     "public/web_state/page_viewport_state_unittest.mm",
     "url_scheme_util_unittest.mm",
     "url_util_unittest.cc",
@@ -548,8 +550,6 @@
     "web_state/ui/wk_back_forward_list_item_holder_unittest.mm",
     "web_state/ui/wk_web_view_configuration_provider_unittest.mm",
     "web_state/web_state_delegate_bridge_unittest.mm",
-    "web_state/web_state_delegate_stub.h",
-    "web_state/web_state_delegate_stub.mm",
     "web_state/web_state_impl_unittest.mm",
     "web_state/web_view_internal_creation_util_unittest.mm",
     "web_state/wk_web_view_security_util_unittest.mm",
diff --git a/ios/web/web_state/web_state_delegate_stub.h b/ios/web/public/test/crw_mock_web_state_delegate.h
similarity index 86%
rename from ios/web/web_state/web_state_delegate_stub.h
rename to ios/web/public/test/crw_mock_web_state_delegate.h
index dac17d55..bbf7bcd 100644
--- a/ios/web/web_state/web_state_delegate_stub.h
+++ b/ios/web/public/test/crw_mock_web_state_delegate.h
@@ -2,14 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef IOS_WEB_WEB_STATE_WEB_STATE_DELEGATE_STUB_H_
-#define IOS_WEB_WEB_STATE_WEB_STATE_DELEGATE_STUB_H_
+#ifndef IOS_WEB_PUBLIC_TEST_CRW_MOCK_WEB_STATE_DELEGATE_H_
+#define IOS_WEB_PUBLIC_TEST_CRW_MOCK_WEB_STATE_DELEGATE_H_
 
 #import "ios/testing/ocmock_complex_type_helper.h"
 #import "ios/web/public/web_state/web_state_delegate_bridge.h"
 
 // Stub implementation for CRWWebStateDelegate protocol.
-@interface CRWWebStateDelegateStub
+@interface CRWMockWebStateDelegate
     : OCMockComplexTypeHelper<CRWWebStateDelegate>
 // web::WebState::OpenURLParams in |webState:openURLWithParams:| call.
 @property(nonatomic, readonly)
@@ -32,4 +32,4 @@
 
 @end
 
-#endif  // IOS_WEB_WEB_STATE_WEB_STATE_DELEGATE_STUB_H_
+#endif  // IOS_WEB_PUBLIC_TEST_CRW_MOCK_WEB_STATE_DELEGATE_H_
diff --git a/ios/web/web_state/web_state_delegate_stub.mm b/ios/web/public/test/crw_mock_web_state_delegate.mm
similarity index 95%
rename from ios/web/web_state/web_state_delegate_stub.mm
rename to ios/web/public/test/crw_mock_web_state_delegate.mm
index 05e53fb..6b8b15a 100644
--- a/ios/web/web_state/web_state_delegate_stub.mm
+++ b/ios/web/public/test/crw_mock_web_state_delegate.mm
@@ -2,12 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/web/web_state/web_state_delegate_stub.h"
+#import "ios/web/public/test/crw_mock_web_state_delegate.h"
 
-#import "ios/web/public/web_state/web_state.h"
 #import "ios/web/public/web_state/context_menu_params.h"
+#import "ios/web/public/web_state/web_state.h"
 
-@implementation CRWWebStateDelegateStub {
+@implementation CRWMockWebStateDelegate {
   // Backs up the property with the same name.
   std::unique_ptr<web::WebState::OpenURLParams> _openURLParams;
   // Backs up the property with the same name.
diff --git a/ios/web/web_state/web_state_delegate_bridge_unittest.mm b/ios/web/web_state/web_state_delegate_bridge_unittest.mm
index 1429a63b..fb7d4292 100644
--- a/ios/web/web_state/web_state_delegate_bridge_unittest.mm
+++ b/ios/web/web_state/web_state_delegate_bridge_unittest.mm
@@ -11,9 +11,9 @@
 #include "base/mac/bind_objc_block.h"
 #import "base/mac/scoped_nsobject.h"
 #include "base/strings/utf_string_conversions.h"
+#import "ios/web/public/test/crw_mock_web_state_delegate.h"
 #import "ios/web/public/test/fakes/test_web_state.h"
 #import "ios/web/public/web_state/context_menu_params.h"
-#import "ios/web/web_state/web_state_delegate_stub.h"
 #include "testing/platform_test.h"
 #import "third_party/ocmock/gtest_support.h"
 #include "ui/base/page_transition_types.h"
@@ -35,7 +35,7 @@
 
     id originalMockDelegate =
         [OCMockObject niceMockForProtocol:@protocol(CRWWebStateDelegate)];
-    delegate_.reset([[CRWWebStateDelegateStub alloc]
+    delegate_.reset([[CRWMockWebStateDelegate alloc]
         initWithRepresentedObject:originalMockDelegate]);
     empty_delegate_.reset([[TestEmptyWebStateDelegate alloc] init]);
 
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index d8feb667..489d3246 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -1881,18 +1881,18 @@
 crbug.com/626703 external/csswg-test/vendor-imports/mozilla/mozilla-central-reftests/writing-modes-3/logical-physical-mapping-001.html [ Failure ]
 crbug.com/626703 external/wpt/html/semantics/grouping-content/the-li-element/grouping-li-reftest-list-owner-menu.html [ Failure ]
 crbug.com/626703 external/wpt/html/semantics/grouping-content/the-li-element/grouping-li-reftest-list-owner-skip-no-boxes.html [ Failure ]
-crbug.com/626703 external/wpt/streams/count-queuing-strategy.https.html [ Timeout Failure ]
-crbug.com/626703 external/wpt/streams/readable-streams/bad-strategies.https.html [ Timeout Failure ]
-crbug.com/626703 external/wpt/streams/readable-streams/bad-underlying-sources.https.html [ Timeout Failure ]
-crbug.com/626703 external/wpt/streams/readable-streams/brand-checks.https.html [ Timeout Failure ]
-crbug.com/626703 external/wpt/streams/readable-streams/cancel.https.html [ Timeout Failure ]
-crbug.com/626703 external/wpt/streams/readable-streams/count-queuing-strategy-integration.https.html [ Timeout Failure ]
-crbug.com/626703 external/wpt/streams/readable-streams/garbage-collection.https.html [ Timeout Failure ]
+crbug.com/626703 external/wpt/streams/count-queuing-strategy.https.html [ Pass Timeout ]
+crbug.com/626703 external/wpt/streams/readable-streams/bad-strategies.https.html [ Pass Timeout ]
+crbug.com/626703 external/wpt/streams/readable-streams/bad-underlying-sources.https.html [ Pass Timeout ]
+crbug.com/626703 external/wpt/streams/readable-streams/brand-checks.https.html [ Pass Timeout ]
+crbug.com/626703 external/wpt/streams/readable-streams/cancel.https.html [ Pass Timeout ]
+crbug.com/626703 external/wpt/streams/readable-streams/count-queuing-strategy-integration.https.html [ Pass Timeout ]
+crbug.com/626703 external/wpt/streams/readable-streams/garbage-collection.https.html [ Pass Timeout ]
 crbug.com/626703 external/wpt/streams/readable-streams/general.https.html [ Timeout Failure ]
-crbug.com/626703 external/wpt/streams/readable-streams/pipe-through.https.html [ Timeout Failure ]
-crbug.com/626703 external/wpt/streams/readable-streams/readable-stream-reader.https.html [ Timeout Failure ]
-crbug.com/626703 external/wpt/streams/readable-streams/tee.https.html [ Timeout Failure ]
-crbug.com/626703 external/wpt/streams/readable-streams/templated.https.html [ Timeout Failure ]
+crbug.com/626703 external/wpt/streams/readable-streams/pipe-through.https.html [ Pass Timeout ]
+crbug.com/626703 external/wpt/streams/readable-streams/readable-stream-reader.https.html [ Pass Timeout ]
+crbug.com/626703 external/wpt/streams/readable-streams/tee.https.html [ Pass Timeout ]
+crbug.com/626703 external/wpt/streams/readable-streams/templated.https.html [ Pass Timeout ]
 crbug.com/626703 external/wpt/html/webappapis/idle-callbacks/callback-timeout.html [ Timeout ]
 crbug.com/626703 external/wpt/html/webappapis/idle-callbacks/callback-multiple-calls.html [ Timeout ]
 crbug.com/626703 external/wpt/html/webappapis/idle-callbacks/callback-exception.html [ Timeout ]
@@ -2297,8 +2297,6 @@
 
 # ====== End of display: contents tests ======
 
-crbug.com/682521 inspector/console/console-tests.html [ NeedsManualRebaseline ]
-
 crbug.com/676229 [ Linux ] plugins/mouse-click-plugin-clears-selection.html [ Failure Pass ]
 
 crbug.com/678346 [ Win7 Debug ] fast/dom/shadow/selections-in-shadow.html [ Pass Timeout ]
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/close-propagation-backward.dedicatedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/close-propagation-backward.dedicatedworker-expected.txt
deleted file mode 100644
index be287d9..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/close-propagation-backward.dedicatedworker-expected.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-This is a testharness.js-based test.
-FAIL Closing must be propagated backward: starts closed; preventCancel omitted; fulfilled cancel promise rs.pipeTo is not a function
-FAIL Closing must be propagated backward: starts closed; preventCancel omitted; rejected cancel promise rs.pipeTo is not a function
-FAIL Closing must be propagated backward: starts closed; preventCancel = undefined (falsy); fulfilled cancel promise rs.pipeTo is not a function
-FAIL Closing must be propagated backward: starts closed; preventCancel = null (falsy); fulfilled cancel promise rs.pipeTo is not a function
-FAIL Closing must be propagated backward: starts closed; preventCancel = false (falsy); fulfilled cancel promise rs.pipeTo is not a function
-FAIL Closing must be propagated backward: starts closed; preventCancel = 0 (falsy); fulfilled cancel promise rs.pipeTo is not a function
-FAIL Closing must be propagated backward: starts closed; preventCancel = -0 (falsy); fulfilled cancel promise rs.pipeTo is not a function
-FAIL Closing must be propagated backward: starts closed; preventCancel = NaN (falsy); fulfilled cancel promise rs.pipeTo is not a function
-FAIL Closing must be propagated backward: starts closed; preventCancel =  (falsy); fulfilled cancel promise rs.pipeTo is not a function
-FAIL Closing must be propagated backward: starts closed; preventCancel = true (truthy) rs.pipeTo is not a function
-FAIL Closing must be propagated backward: starts closed; preventCancel = a (truthy) rs.pipeTo is not a function
-FAIL Closing must be propagated backward: starts closed; preventCancel = 1 (truthy) rs.pipeTo is not a function
-FAIL Closing must be propagated backward: starts closed; preventCancel = Symbol() (truthy) rs.pipeTo is not a function
-FAIL Closing must be propagated backward: starts closed; preventCancel = [object Object] (truthy) rs.pipeTo is not a function
-FAIL Closing must be propagated backward: starts closed; preventCancel = true, preventAbort = true rs.pipeTo is not a function
-FAIL Closing must be propagated backward: starts closed; preventCancel = true, preventAbort = true, preventClose = true rs.pipeTo is not a function
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/close-propagation-backward.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/close-propagation-backward.https-expected.txt
deleted file mode 100644
index be287d9..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/close-propagation-backward.https-expected.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-This is a testharness.js-based test.
-FAIL Closing must be propagated backward: starts closed; preventCancel omitted; fulfilled cancel promise rs.pipeTo is not a function
-FAIL Closing must be propagated backward: starts closed; preventCancel omitted; rejected cancel promise rs.pipeTo is not a function
-FAIL Closing must be propagated backward: starts closed; preventCancel = undefined (falsy); fulfilled cancel promise rs.pipeTo is not a function
-FAIL Closing must be propagated backward: starts closed; preventCancel = null (falsy); fulfilled cancel promise rs.pipeTo is not a function
-FAIL Closing must be propagated backward: starts closed; preventCancel = false (falsy); fulfilled cancel promise rs.pipeTo is not a function
-FAIL Closing must be propagated backward: starts closed; preventCancel = 0 (falsy); fulfilled cancel promise rs.pipeTo is not a function
-FAIL Closing must be propagated backward: starts closed; preventCancel = -0 (falsy); fulfilled cancel promise rs.pipeTo is not a function
-FAIL Closing must be propagated backward: starts closed; preventCancel = NaN (falsy); fulfilled cancel promise rs.pipeTo is not a function
-FAIL Closing must be propagated backward: starts closed; preventCancel =  (falsy); fulfilled cancel promise rs.pipeTo is not a function
-FAIL Closing must be propagated backward: starts closed; preventCancel = true (truthy) rs.pipeTo is not a function
-FAIL Closing must be propagated backward: starts closed; preventCancel = a (truthy) rs.pipeTo is not a function
-FAIL Closing must be propagated backward: starts closed; preventCancel = 1 (truthy) rs.pipeTo is not a function
-FAIL Closing must be propagated backward: starts closed; preventCancel = Symbol() (truthy) rs.pipeTo is not a function
-FAIL Closing must be propagated backward: starts closed; preventCancel = [object Object] (truthy) rs.pipeTo is not a function
-FAIL Closing must be propagated backward: starts closed; preventCancel = true, preventAbort = true rs.pipeTo is not a function
-FAIL Closing must be propagated backward: starts closed; preventCancel = true, preventAbort = true, preventClose = true rs.pipeTo is not a function
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/close-propagation-backward.sharedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/close-propagation-backward.sharedworker-expected.txt
deleted file mode 100644
index be287d9..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/close-propagation-backward.sharedworker-expected.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-This is a testharness.js-based test.
-FAIL Closing must be propagated backward: starts closed; preventCancel omitted; fulfilled cancel promise rs.pipeTo is not a function
-FAIL Closing must be propagated backward: starts closed; preventCancel omitted; rejected cancel promise rs.pipeTo is not a function
-FAIL Closing must be propagated backward: starts closed; preventCancel = undefined (falsy); fulfilled cancel promise rs.pipeTo is not a function
-FAIL Closing must be propagated backward: starts closed; preventCancel = null (falsy); fulfilled cancel promise rs.pipeTo is not a function
-FAIL Closing must be propagated backward: starts closed; preventCancel = false (falsy); fulfilled cancel promise rs.pipeTo is not a function
-FAIL Closing must be propagated backward: starts closed; preventCancel = 0 (falsy); fulfilled cancel promise rs.pipeTo is not a function
-FAIL Closing must be propagated backward: starts closed; preventCancel = -0 (falsy); fulfilled cancel promise rs.pipeTo is not a function
-FAIL Closing must be propagated backward: starts closed; preventCancel = NaN (falsy); fulfilled cancel promise rs.pipeTo is not a function
-FAIL Closing must be propagated backward: starts closed; preventCancel =  (falsy); fulfilled cancel promise rs.pipeTo is not a function
-FAIL Closing must be propagated backward: starts closed; preventCancel = true (truthy) rs.pipeTo is not a function
-FAIL Closing must be propagated backward: starts closed; preventCancel = a (truthy) rs.pipeTo is not a function
-FAIL Closing must be propagated backward: starts closed; preventCancel = 1 (truthy) rs.pipeTo is not a function
-FAIL Closing must be propagated backward: starts closed; preventCancel = Symbol() (truthy) rs.pipeTo is not a function
-FAIL Closing must be propagated backward: starts closed; preventCancel = [object Object] (truthy) rs.pipeTo is not a function
-FAIL Closing must be propagated backward: starts closed; preventCancel = true, preventAbort = true rs.pipeTo is not a function
-FAIL Closing must be propagated backward: starts closed; preventCancel = true, preventAbort = true, preventClose = true rs.pipeTo is not a function
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/close-propagation-forward.dedicatedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/close-propagation-forward.dedicatedworker-expected.txt
deleted file mode 100644
index 1862e6d..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/close-propagation-forward.dedicatedworker-expected.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-This is a testharness.js-based test.
-FAIL Closing must be propagated forward: starts closed; preventClose omitted; fulfilled close promise rs.pipeTo is not a function
-FAIL Closing must be propagated forward: starts closed; preventClose omitted; rejected close promise rs.pipeTo is not a function
-FAIL Closing must be propagated forward: starts closed; preventClose = undefined (falsy); fulfilled close promise rs.pipeTo is not a function
-FAIL Closing must be propagated forward: starts closed; preventClose = null (falsy); fulfilled close promise rs.pipeTo is not a function
-FAIL Closing must be propagated forward: starts closed; preventClose = false (falsy); fulfilled close promise rs.pipeTo is not a function
-FAIL Closing must be propagated forward: starts closed; preventClose = 0 (falsy); fulfilled close promise rs.pipeTo is not a function
-FAIL Closing must be propagated forward: starts closed; preventClose = -0 (falsy); fulfilled close promise rs.pipeTo is not a function
-FAIL Closing must be propagated forward: starts closed; preventClose = NaN (falsy); fulfilled close promise rs.pipeTo is not a function
-FAIL Closing must be propagated forward: starts closed; preventClose =  (falsy); fulfilled close promise rs.pipeTo is not a function
-FAIL Closing must be propagated forward: starts closed; preventClose = true (truthy) rs.pipeTo is not a function
-FAIL Closing must be propagated forward: starts closed; preventClose = a (truthy) rs.pipeTo is not a function
-FAIL Closing must be propagated forward: starts closed; preventClose = 1 (truthy) rs.pipeTo is not a function
-FAIL Closing must be propagated forward: starts closed; preventClose = Symbol() (truthy) rs.pipeTo is not a function
-FAIL Closing must be propagated forward: starts closed; preventClose = [object Object] (truthy) rs.pipeTo is not a function
-FAIL Closing must be propagated forward: starts closed; preventClose = true, preventAbort = true rs.pipeTo is not a function
-FAIL Closing must be propagated forward: starts closed; preventClose = true, preventAbort = true, preventCancel = true rs.pipeTo is not a function
-FAIL Closing must be propagated forward: becomes closed asynchronously; preventClose omitted; fulfilled close promise rs.pipeTo is not a function
-FAIL Closing must be propagated forward: becomes closed asynchronously; preventClose omitted; rejected close promise rs.pipeTo is not a function
-FAIL Closing must be propagated forward: becomes closed asynchronously; preventClose = true rs.pipeTo is not a function
-FAIL Closing must be propagated forward: becomes closed asynchronously; dest never desires chunks; preventClose omitted; fulfilled close promise rs.pipeTo is not a function
-FAIL Closing must be propagated forward: becomes closed asynchronously; dest never desires chunks; preventClose omitted; rejected close promise rs.pipeTo is not a function
-FAIL Closing must be propagated forward: becomes closed asynchronously; dest never desires chunks; preventClose = true rs.pipeTo is not a function
-FAIL Closing must be propagated forward: becomes closed after one chunk; preventClose omitted; fulfilled close promise rs.pipeTo is not a function
-FAIL Closing must be propagated forward: becomes closed after one chunk; preventClose omitted; rejected close promise rs.pipeTo is not a function
-FAIL Closing must be propagated forward: becomes closed after one chunk; preventClose = true rs.pipeTo is not a function
-FAIL Closing must be propagated forward: shutdown must not occur until the final write completes rs.pipeTo is not a function
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/close-propagation-forward.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/close-propagation-forward.https-expected.txt
deleted file mode 100644
index 1862e6d..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/close-propagation-forward.https-expected.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-This is a testharness.js-based test.
-FAIL Closing must be propagated forward: starts closed; preventClose omitted; fulfilled close promise rs.pipeTo is not a function
-FAIL Closing must be propagated forward: starts closed; preventClose omitted; rejected close promise rs.pipeTo is not a function
-FAIL Closing must be propagated forward: starts closed; preventClose = undefined (falsy); fulfilled close promise rs.pipeTo is not a function
-FAIL Closing must be propagated forward: starts closed; preventClose = null (falsy); fulfilled close promise rs.pipeTo is not a function
-FAIL Closing must be propagated forward: starts closed; preventClose = false (falsy); fulfilled close promise rs.pipeTo is not a function
-FAIL Closing must be propagated forward: starts closed; preventClose = 0 (falsy); fulfilled close promise rs.pipeTo is not a function
-FAIL Closing must be propagated forward: starts closed; preventClose = -0 (falsy); fulfilled close promise rs.pipeTo is not a function
-FAIL Closing must be propagated forward: starts closed; preventClose = NaN (falsy); fulfilled close promise rs.pipeTo is not a function
-FAIL Closing must be propagated forward: starts closed; preventClose =  (falsy); fulfilled close promise rs.pipeTo is not a function
-FAIL Closing must be propagated forward: starts closed; preventClose = true (truthy) rs.pipeTo is not a function
-FAIL Closing must be propagated forward: starts closed; preventClose = a (truthy) rs.pipeTo is not a function
-FAIL Closing must be propagated forward: starts closed; preventClose = 1 (truthy) rs.pipeTo is not a function
-FAIL Closing must be propagated forward: starts closed; preventClose = Symbol() (truthy) rs.pipeTo is not a function
-FAIL Closing must be propagated forward: starts closed; preventClose = [object Object] (truthy) rs.pipeTo is not a function
-FAIL Closing must be propagated forward: starts closed; preventClose = true, preventAbort = true rs.pipeTo is not a function
-FAIL Closing must be propagated forward: starts closed; preventClose = true, preventAbort = true, preventCancel = true rs.pipeTo is not a function
-FAIL Closing must be propagated forward: becomes closed asynchronously; preventClose omitted; fulfilled close promise rs.pipeTo is not a function
-FAIL Closing must be propagated forward: becomes closed asynchronously; preventClose omitted; rejected close promise rs.pipeTo is not a function
-FAIL Closing must be propagated forward: becomes closed asynchronously; preventClose = true rs.pipeTo is not a function
-FAIL Closing must be propagated forward: becomes closed asynchronously; dest never desires chunks; preventClose omitted; fulfilled close promise rs.pipeTo is not a function
-FAIL Closing must be propagated forward: becomes closed asynchronously; dest never desires chunks; preventClose omitted; rejected close promise rs.pipeTo is not a function
-FAIL Closing must be propagated forward: becomes closed asynchronously; dest never desires chunks; preventClose = true rs.pipeTo is not a function
-FAIL Closing must be propagated forward: becomes closed after one chunk; preventClose omitted; fulfilled close promise rs.pipeTo is not a function
-FAIL Closing must be propagated forward: becomes closed after one chunk; preventClose omitted; rejected close promise rs.pipeTo is not a function
-FAIL Closing must be propagated forward: becomes closed after one chunk; preventClose = true rs.pipeTo is not a function
-FAIL Closing must be propagated forward: shutdown must not occur until the final write completes rs.pipeTo is not a function
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/close-propagation-forward.sharedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/close-propagation-forward.sharedworker-expected.txt
deleted file mode 100644
index 1862e6d..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/close-propagation-forward.sharedworker-expected.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-This is a testharness.js-based test.
-FAIL Closing must be propagated forward: starts closed; preventClose omitted; fulfilled close promise rs.pipeTo is not a function
-FAIL Closing must be propagated forward: starts closed; preventClose omitted; rejected close promise rs.pipeTo is not a function
-FAIL Closing must be propagated forward: starts closed; preventClose = undefined (falsy); fulfilled close promise rs.pipeTo is not a function
-FAIL Closing must be propagated forward: starts closed; preventClose = null (falsy); fulfilled close promise rs.pipeTo is not a function
-FAIL Closing must be propagated forward: starts closed; preventClose = false (falsy); fulfilled close promise rs.pipeTo is not a function
-FAIL Closing must be propagated forward: starts closed; preventClose = 0 (falsy); fulfilled close promise rs.pipeTo is not a function
-FAIL Closing must be propagated forward: starts closed; preventClose = -0 (falsy); fulfilled close promise rs.pipeTo is not a function
-FAIL Closing must be propagated forward: starts closed; preventClose = NaN (falsy); fulfilled close promise rs.pipeTo is not a function
-FAIL Closing must be propagated forward: starts closed; preventClose =  (falsy); fulfilled close promise rs.pipeTo is not a function
-FAIL Closing must be propagated forward: starts closed; preventClose = true (truthy) rs.pipeTo is not a function
-FAIL Closing must be propagated forward: starts closed; preventClose = a (truthy) rs.pipeTo is not a function
-FAIL Closing must be propagated forward: starts closed; preventClose = 1 (truthy) rs.pipeTo is not a function
-FAIL Closing must be propagated forward: starts closed; preventClose = Symbol() (truthy) rs.pipeTo is not a function
-FAIL Closing must be propagated forward: starts closed; preventClose = [object Object] (truthy) rs.pipeTo is not a function
-FAIL Closing must be propagated forward: starts closed; preventClose = true, preventAbort = true rs.pipeTo is not a function
-FAIL Closing must be propagated forward: starts closed; preventClose = true, preventAbort = true, preventCancel = true rs.pipeTo is not a function
-FAIL Closing must be propagated forward: becomes closed asynchronously; preventClose omitted; fulfilled close promise rs.pipeTo is not a function
-FAIL Closing must be propagated forward: becomes closed asynchronously; preventClose omitted; rejected close promise rs.pipeTo is not a function
-FAIL Closing must be propagated forward: becomes closed asynchronously; preventClose = true rs.pipeTo is not a function
-FAIL Closing must be propagated forward: becomes closed asynchronously; dest never desires chunks; preventClose omitted; fulfilled close promise rs.pipeTo is not a function
-FAIL Closing must be propagated forward: becomes closed asynchronously; dest never desires chunks; preventClose omitted; rejected close promise rs.pipeTo is not a function
-FAIL Closing must be propagated forward: becomes closed asynchronously; dest never desires chunks; preventClose = true rs.pipeTo is not a function
-FAIL Closing must be propagated forward: becomes closed after one chunk; preventClose omitted; fulfilled close promise rs.pipeTo is not a function
-FAIL Closing must be propagated forward: becomes closed after one chunk; preventClose omitted; rejected close promise rs.pipeTo is not a function
-FAIL Closing must be propagated forward: becomes closed after one chunk; preventClose = true rs.pipeTo is not a function
-FAIL Closing must be propagated forward: shutdown must not occur until the final write completes rs.pipeTo is not a function
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/error-propagation-backward.dedicatedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/error-propagation-backward.dedicatedworker-expected.txt
deleted file mode 100644
index cb0fa19..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/error-propagation-backward.dedicatedworker-expected.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-This is a testharness.js-based test.
-FAIL Errors must be propagated backward: starts errored; preventCancel omitted; fulfilled cancel promise rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel omitted; fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel omitted; rejected cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = undefined (falsy); fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = null (falsy); fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = false (falsy); fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = 0 (falsy); fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = -0 (falsy); fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = NaN (falsy); fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel =  (falsy); fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = true (truthy) promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = a (truthy) promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = 1 (truthy) promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = Symbol() (truthy) promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = [object Object] (truthy) promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored before piping due to write, preventCancel = true; preventAbort = true promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = true, preventAbort = true, preventClose = true promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored during piping due to write; preventCancel omitted; fulfilled cancel promise rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored during piping due to write; preventCancel omitted; rejected cancel promise rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored during piping due to write; preventCancel = true rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored during piping due to write, but async; preventCancel = false; fulfilled cancel promise rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored during piping due to write, but async; preventCancel = false; rejected cancel promise rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored during piping due to write, but async; preventCancel = true rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored after piping; preventCancel omitted; fulfilled cancel promise rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored after piping; preventCancel omitted; rejected cancel promise rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored after piping; preventCancel = true rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored after piping due to last write; source is closed; preventCancel omitted (but cancel is never called) rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored after piping due to last write; source is closed; preventCancel = true rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored after piping; dest never desires chunks; preventCancel = false; fulfilled cancel promise rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored after piping; dest never desires chunks; preventCancel = false; rejected cancel promise rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored after piping; dest never desires chunks; preventCancel = true rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored before piping via abort; preventCancel omitted; fulfilled cancel promise rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored before piping via abort; preventCancel omitted; rejected cancel promise rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored before piping via abort; preventCancel = true rs.pipeTo is not a function
-FAIL Errors must be propagated backward: erroring via the controller errors once pending write completes rs.pipeTo is not a function
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/error-propagation-backward.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/error-propagation-backward.https-expected.txt
deleted file mode 100644
index cb0fa19..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/error-propagation-backward.https-expected.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-This is a testharness.js-based test.
-FAIL Errors must be propagated backward: starts errored; preventCancel omitted; fulfilled cancel promise rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel omitted; fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel omitted; rejected cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = undefined (falsy); fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = null (falsy); fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = false (falsy); fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = 0 (falsy); fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = -0 (falsy); fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = NaN (falsy); fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel =  (falsy); fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = true (truthy) promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = a (truthy) promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = 1 (truthy) promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = Symbol() (truthy) promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = [object Object] (truthy) promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored before piping due to write, preventCancel = true; preventAbort = true promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = true, preventAbort = true, preventClose = true promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored during piping due to write; preventCancel omitted; fulfilled cancel promise rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored during piping due to write; preventCancel omitted; rejected cancel promise rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored during piping due to write; preventCancel = true rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored during piping due to write, but async; preventCancel = false; fulfilled cancel promise rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored during piping due to write, but async; preventCancel = false; rejected cancel promise rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored during piping due to write, but async; preventCancel = true rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored after piping; preventCancel omitted; fulfilled cancel promise rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored after piping; preventCancel omitted; rejected cancel promise rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored after piping; preventCancel = true rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored after piping due to last write; source is closed; preventCancel omitted (but cancel is never called) rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored after piping due to last write; source is closed; preventCancel = true rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored after piping; dest never desires chunks; preventCancel = false; fulfilled cancel promise rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored after piping; dest never desires chunks; preventCancel = false; rejected cancel promise rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored after piping; dest never desires chunks; preventCancel = true rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored before piping via abort; preventCancel omitted; fulfilled cancel promise rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored before piping via abort; preventCancel omitted; rejected cancel promise rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored before piping via abort; preventCancel = true rs.pipeTo is not a function
-FAIL Errors must be propagated backward: erroring via the controller errors once pending write completes rs.pipeTo is not a function
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/error-propagation-backward.sharedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/error-propagation-backward.sharedworker-expected.txt
deleted file mode 100644
index cb0fa19..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/error-propagation-backward.sharedworker-expected.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-This is a testharness.js-based test.
-FAIL Errors must be propagated backward: starts errored; preventCancel omitted; fulfilled cancel promise rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel omitted; fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel omitted; rejected cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = undefined (falsy); fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = null (falsy); fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = false (falsy); fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = 0 (falsy); fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = -0 (falsy); fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = NaN (falsy); fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel =  (falsy); fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = true (truthy) promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = a (truthy) promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = 1 (truthy) promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = Symbol() (truthy) promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = [object Object] (truthy) promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored before piping due to write, preventCancel = true; preventAbort = true promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = true, preventAbort = true, preventClose = true promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Errors must be propagated backward: becomes errored during piping due to write; preventCancel omitted; fulfilled cancel promise rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored during piping due to write; preventCancel omitted; rejected cancel promise rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored during piping due to write; preventCancel = true rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored during piping due to write, but async; preventCancel = false; fulfilled cancel promise rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored during piping due to write, but async; preventCancel = false; rejected cancel promise rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored during piping due to write, but async; preventCancel = true rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored after piping; preventCancel omitted; fulfilled cancel promise rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored after piping; preventCancel omitted; rejected cancel promise rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored after piping; preventCancel = true rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored after piping due to last write; source is closed; preventCancel omitted (but cancel is never called) rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored after piping due to last write; source is closed; preventCancel = true rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored after piping; dest never desires chunks; preventCancel = false; fulfilled cancel promise rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored after piping; dest never desires chunks; preventCancel = false; rejected cancel promise rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored after piping; dest never desires chunks; preventCancel = true rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored before piping via abort; preventCancel omitted; fulfilled cancel promise rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored before piping via abort; preventCancel omitted; rejected cancel promise rs.pipeTo is not a function
-FAIL Errors must be propagated backward: becomes errored before piping via abort; preventCancel = true rs.pipeTo is not a function
-FAIL Errors must be propagated backward: erroring via the controller errors once pending write completes rs.pipeTo is not a function
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/error-propagation-forward.dedicatedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/error-propagation-forward.dedicatedworker-expected.txt
deleted file mode 100644
index cc9c3ef2..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/error-propagation-forward.dedicatedworker-expected.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-This is a testharness.js-based test.
-FAIL Errors must be propagated forward: starts errored; preventAbort = false; fulfilled abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: starts errored; preventAbort = false; rejected abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: starts errored; preventAbort = undefined (falsy); fulfilled abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: starts errored; preventAbort = null (falsy); fulfilled abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: starts errored; preventAbort = false (falsy); fulfilled abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: starts errored; preventAbort = 0 (falsy); fulfilled abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: starts errored; preventAbort = -0 (falsy); fulfilled abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: starts errored; preventAbort = NaN (falsy); fulfilled abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: starts errored; preventAbort =  (falsy); fulfilled abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: starts errored; preventAbort = true (truthy) rs.pipeTo is not a function
-FAIL Errors must be propagated forward: starts errored; preventAbort = a (truthy) rs.pipeTo is not a function
-FAIL Errors must be propagated forward: starts errored; preventAbort = 1 (truthy) rs.pipeTo is not a function
-FAIL Errors must be propagated forward: starts errored; preventAbort = Symbol() (truthy) rs.pipeTo is not a function
-FAIL Errors must be propagated forward: starts errored; preventAbort = [object Object] (truthy) rs.pipeTo is not a function
-FAIL Errors must be propagated forward: starts errored; preventAbort = true, preventCancel = true rs.pipeTo is not a function
-FAIL Errors must be propagated forward: starts errored; preventAbort = true, preventCancel = true, preventClose = true rs.pipeTo is not a function
-FAIL Errors must be propagated forward: becomes errored while empty; preventAbort = false; fulfilled abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: becomes errored while empty; preventAbort = false; rejected abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: becomes errored while empty; preventAbort = true rs.pipeTo is not a function
-FAIL Errors must be propagated forward: becomes errored while empty; dest never desires chunks; preventAbort = false; fulfilled abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: becomes errored while empty; dest never desires chunks; preventAbort = false; rejected abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: becomes errored while empty; dest never desires chunks; preventAbort = true rs.pipeTo is not a function
-FAIL Errors must be propagated forward: becomes errored after one chunk; preventAbort = false; fulfilled abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: becomes errored after one chunk; preventAbort = false; rejected abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: becomes errored after one chunk; preventAbort = true rs.pipeTo is not a function
-FAIL Errors must be propagated forward: becomes errored after one chunk; dest never desires chunks; preventAbort = false; fulfilled abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: becomes errored after one chunk; dest never desires chunks; preventAbort = false; rejected abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: becomes errored after one chunk; dest never desires chunks; preventAbort = true rs.pipeTo is not a function
-FAIL Errors must be propagated forward: shutdown must not occur until the final write completes rs.pipeTo is not a function
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/error-propagation-forward.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/error-propagation-forward.https-expected.txt
deleted file mode 100644
index cc9c3ef2..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/error-propagation-forward.https-expected.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-This is a testharness.js-based test.
-FAIL Errors must be propagated forward: starts errored; preventAbort = false; fulfilled abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: starts errored; preventAbort = false; rejected abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: starts errored; preventAbort = undefined (falsy); fulfilled abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: starts errored; preventAbort = null (falsy); fulfilled abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: starts errored; preventAbort = false (falsy); fulfilled abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: starts errored; preventAbort = 0 (falsy); fulfilled abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: starts errored; preventAbort = -0 (falsy); fulfilled abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: starts errored; preventAbort = NaN (falsy); fulfilled abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: starts errored; preventAbort =  (falsy); fulfilled abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: starts errored; preventAbort = true (truthy) rs.pipeTo is not a function
-FAIL Errors must be propagated forward: starts errored; preventAbort = a (truthy) rs.pipeTo is not a function
-FAIL Errors must be propagated forward: starts errored; preventAbort = 1 (truthy) rs.pipeTo is not a function
-FAIL Errors must be propagated forward: starts errored; preventAbort = Symbol() (truthy) rs.pipeTo is not a function
-FAIL Errors must be propagated forward: starts errored; preventAbort = [object Object] (truthy) rs.pipeTo is not a function
-FAIL Errors must be propagated forward: starts errored; preventAbort = true, preventCancel = true rs.pipeTo is not a function
-FAIL Errors must be propagated forward: starts errored; preventAbort = true, preventCancel = true, preventClose = true rs.pipeTo is not a function
-FAIL Errors must be propagated forward: becomes errored while empty; preventAbort = false; fulfilled abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: becomes errored while empty; preventAbort = false; rejected abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: becomes errored while empty; preventAbort = true rs.pipeTo is not a function
-FAIL Errors must be propagated forward: becomes errored while empty; dest never desires chunks; preventAbort = false; fulfilled abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: becomes errored while empty; dest never desires chunks; preventAbort = false; rejected abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: becomes errored while empty; dest never desires chunks; preventAbort = true rs.pipeTo is not a function
-FAIL Errors must be propagated forward: becomes errored after one chunk; preventAbort = false; fulfilled abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: becomes errored after one chunk; preventAbort = false; rejected abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: becomes errored after one chunk; preventAbort = true rs.pipeTo is not a function
-FAIL Errors must be propagated forward: becomes errored after one chunk; dest never desires chunks; preventAbort = false; fulfilled abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: becomes errored after one chunk; dest never desires chunks; preventAbort = false; rejected abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: becomes errored after one chunk; dest never desires chunks; preventAbort = true rs.pipeTo is not a function
-FAIL Errors must be propagated forward: shutdown must not occur until the final write completes rs.pipeTo is not a function
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/error-propagation-forward.sharedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/error-propagation-forward.sharedworker-expected.txt
deleted file mode 100644
index cc9c3ef2..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/error-propagation-forward.sharedworker-expected.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-This is a testharness.js-based test.
-FAIL Errors must be propagated forward: starts errored; preventAbort = false; fulfilled abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: starts errored; preventAbort = false; rejected abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: starts errored; preventAbort = undefined (falsy); fulfilled abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: starts errored; preventAbort = null (falsy); fulfilled abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: starts errored; preventAbort = false (falsy); fulfilled abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: starts errored; preventAbort = 0 (falsy); fulfilled abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: starts errored; preventAbort = -0 (falsy); fulfilled abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: starts errored; preventAbort = NaN (falsy); fulfilled abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: starts errored; preventAbort =  (falsy); fulfilled abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: starts errored; preventAbort = true (truthy) rs.pipeTo is not a function
-FAIL Errors must be propagated forward: starts errored; preventAbort = a (truthy) rs.pipeTo is not a function
-FAIL Errors must be propagated forward: starts errored; preventAbort = 1 (truthy) rs.pipeTo is not a function
-FAIL Errors must be propagated forward: starts errored; preventAbort = Symbol() (truthy) rs.pipeTo is not a function
-FAIL Errors must be propagated forward: starts errored; preventAbort = [object Object] (truthy) rs.pipeTo is not a function
-FAIL Errors must be propagated forward: starts errored; preventAbort = true, preventCancel = true rs.pipeTo is not a function
-FAIL Errors must be propagated forward: starts errored; preventAbort = true, preventCancel = true, preventClose = true rs.pipeTo is not a function
-FAIL Errors must be propagated forward: becomes errored while empty; preventAbort = false; fulfilled abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: becomes errored while empty; preventAbort = false; rejected abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: becomes errored while empty; preventAbort = true rs.pipeTo is not a function
-FAIL Errors must be propagated forward: becomes errored while empty; dest never desires chunks; preventAbort = false; fulfilled abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: becomes errored while empty; dest never desires chunks; preventAbort = false; rejected abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: becomes errored while empty; dest never desires chunks; preventAbort = true rs.pipeTo is not a function
-FAIL Errors must be propagated forward: becomes errored after one chunk; preventAbort = false; fulfilled abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: becomes errored after one chunk; preventAbort = false; rejected abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: becomes errored after one chunk; preventAbort = true rs.pipeTo is not a function
-FAIL Errors must be propagated forward: becomes errored after one chunk; dest never desires chunks; preventAbort = false; fulfilled abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: becomes errored after one chunk; dest never desires chunks; preventAbort = false; rejected abort promise rs.pipeTo is not a function
-FAIL Errors must be propagated forward: becomes errored after one chunk; dest never desires chunks; preventAbort = true rs.pipeTo is not a function
-FAIL Errors must be propagated forward: shutdown must not occur until the final write completes rs.pipeTo is not a function
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/flow-control.dedicatedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/flow-control.dedicatedworker-expected.txt
deleted file mode 100644
index 82ac6f2..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/flow-control.dedicatedworker-expected.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-This is a testharness.js-based test.
-FAIL Piping from a non-empty ReadableStream into a WritableStream that does not desire chunks rs.pipeTo is not a function
-FAIL Piping from a non-empty ReadableStream into a WritableStream that does not desire chunks, but then does rs.pipeTo is not a function
-FAIL Piping from an empty ReadableStream into a WritableStream that does not desire chunks, but then the readable stream becomes non-empty and the writable stream starts desiring chunks promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Piping to a WritableStream that does not consume the writes fast enough exerts backpressure on the ReadableStream promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/flow-control.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/flow-control.https-expected.txt
deleted file mode 100644
index 82ac6f2..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/flow-control.https-expected.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-This is a testharness.js-based test.
-FAIL Piping from a non-empty ReadableStream into a WritableStream that does not desire chunks rs.pipeTo is not a function
-FAIL Piping from a non-empty ReadableStream into a WritableStream that does not desire chunks, but then does rs.pipeTo is not a function
-FAIL Piping from an empty ReadableStream into a WritableStream that does not desire chunks, but then the readable stream becomes non-empty and the writable stream starts desiring chunks promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Piping to a WritableStream that does not consume the writes fast enough exerts backpressure on the ReadableStream promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/flow-control.sharedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/flow-control.sharedworker-expected.txt
deleted file mode 100644
index 82ac6f2..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/flow-control.sharedworker-expected.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-This is a testharness.js-based test.
-FAIL Piping from a non-empty ReadableStream into a WritableStream that does not desire chunks rs.pipeTo is not a function
-FAIL Piping from a non-empty ReadableStream into a WritableStream that does not desire chunks, but then does rs.pipeTo is not a function
-FAIL Piping from an empty ReadableStream into a WritableStream that does not desire chunks, but then the readable stream becomes non-empty and the writable stream starts desiring chunks promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-FAIL Piping to a WritableStream that does not consume the writes fast enough exerts backpressure on the ReadableStream promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function"
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/general.dedicatedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/general.dedicatedworker-expected.txt
deleted file mode 100644
index cb4eb742..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/general.dedicatedworker-expected.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-This is a testharness.js-based test.
-FAIL Piping must lock both the ReadableStream and WritableStream rs.pipeTo is not a function
-FAIL Piping finishing must unlock both the ReadableStream and WritableStream rs.pipeTo is not a function
-FAIL pipeTo must check the brand of its ReadableStream this value Cannot read property 'apply' of undefined
-FAIL pipeTo must check the brand of its WritableStream argument Cannot read property 'apply' of undefined
-FAIL pipeTo must fail if the ReadableStream is locked, and not lock the WritableStream rs.pipeTo is not a function
-FAIL pipeTo must fail if the WritableStream is locked, and not lock the ReadableStream rs.pipeTo is not a function
-FAIL Piping from a ReadableStream from which lots of chunks are synchronously readable rs.pipeTo is not a function
-FAIL Piping from a ReadableStream for which a chunk becomes asynchronously readable after the pipeTo rs.pipeTo is not a function
-FAIL an undefined rejection from pull should cause pipeTo() to reject when preventAbort is true rs.pipeTo is not a function
-FAIL an undefined rejection from pull should cause pipeTo() to reject when preventAbort is false rs.pipeTo is not a function
-FAIL an undefined rejection from write should cause pipeTo() to reject when preventCancel is true rs.pipeTo is not a function
-FAIL an undefined rejection from write should cause pipeTo() to reject when preventCancel is false rs.pipeTo is not a function
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/general.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/general.https-expected.txt
deleted file mode 100644
index cb4eb742..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/general.https-expected.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-This is a testharness.js-based test.
-FAIL Piping must lock both the ReadableStream and WritableStream rs.pipeTo is not a function
-FAIL Piping finishing must unlock both the ReadableStream and WritableStream rs.pipeTo is not a function
-FAIL pipeTo must check the brand of its ReadableStream this value Cannot read property 'apply' of undefined
-FAIL pipeTo must check the brand of its WritableStream argument Cannot read property 'apply' of undefined
-FAIL pipeTo must fail if the ReadableStream is locked, and not lock the WritableStream rs.pipeTo is not a function
-FAIL pipeTo must fail if the WritableStream is locked, and not lock the ReadableStream rs.pipeTo is not a function
-FAIL Piping from a ReadableStream from which lots of chunks are synchronously readable rs.pipeTo is not a function
-FAIL Piping from a ReadableStream for which a chunk becomes asynchronously readable after the pipeTo rs.pipeTo is not a function
-FAIL an undefined rejection from pull should cause pipeTo() to reject when preventAbort is true rs.pipeTo is not a function
-FAIL an undefined rejection from pull should cause pipeTo() to reject when preventAbort is false rs.pipeTo is not a function
-FAIL an undefined rejection from write should cause pipeTo() to reject when preventCancel is true rs.pipeTo is not a function
-FAIL an undefined rejection from write should cause pipeTo() to reject when preventCancel is false rs.pipeTo is not a function
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/general.sharedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/general.sharedworker-expected.txt
deleted file mode 100644
index cb4eb742..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/general.sharedworker-expected.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-This is a testharness.js-based test.
-FAIL Piping must lock both the ReadableStream and WritableStream rs.pipeTo is not a function
-FAIL Piping finishing must unlock both the ReadableStream and WritableStream rs.pipeTo is not a function
-FAIL pipeTo must check the brand of its ReadableStream this value Cannot read property 'apply' of undefined
-FAIL pipeTo must check the brand of its WritableStream argument Cannot read property 'apply' of undefined
-FAIL pipeTo must fail if the ReadableStream is locked, and not lock the WritableStream rs.pipeTo is not a function
-FAIL pipeTo must fail if the WritableStream is locked, and not lock the ReadableStream rs.pipeTo is not a function
-FAIL Piping from a ReadableStream from which lots of chunks are synchronously readable rs.pipeTo is not a function
-FAIL Piping from a ReadableStream for which a chunk becomes asynchronously readable after the pipeTo rs.pipeTo is not a function
-FAIL an undefined rejection from pull should cause pipeTo() to reject when preventAbort is true rs.pipeTo is not a function
-FAIL an undefined rejection from pull should cause pipeTo() to reject when preventAbort is false rs.pipeTo is not a function
-FAIL an undefined rejection from write should cause pipeTo() to reject when preventCancel is true rs.pipeTo is not a function
-FAIL an undefined rejection from write should cause pipeTo() to reject when preventCancel is false rs.pipeTo is not a function
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/multiple-propagation.dedicatedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/multiple-propagation.dedicatedworker-expected.txt
index 859fcbe9..cfd2234 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/multiple-propagation.dedicatedworker-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/multiple-propagation.dedicatedworker-expected.txt
@@ -1,8 +1,9 @@
+CONSOLE ERROR: line 77: Uncaught (in promise) TypeError: The stream has been aborted
 This is a testharness.js-based test.
-FAIL Piping from an errored readable stream to an errored writable stream rs.pipeTo is not a function
-FAIL Piping from an errored readable stream to an errored writable stream; preventAbort = true rs.pipeTo is not a function
-FAIL Piping from an errored readable stream to a closed writable stream rs.pipeTo is not a function
-FAIL Piping from a closed readable stream to an errored writable stream rs.pipeTo is not a function
-FAIL Piping from a closed readable stream to a closed writable stream rs.pipeTo is not a function
+PASS Piping from an errored readable stream to an errored writable stream 
+PASS Piping from an errored readable stream to an errored writable stream; preventAbort = true 
+FAIL Piping from an errored readable stream to a closed writable stream assert_array_equals: lengths differ, expected 1 got 2
+PASS Piping from a closed readable stream to an errored writable stream 
+PASS Piping from a closed readable stream to a closed writable stream 
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/multiple-propagation.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/multiple-propagation.https-expected.txt
index 859fcbe9..cfd2234 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/multiple-propagation.https-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/multiple-propagation.https-expected.txt
@@ -1,8 +1,9 @@
+CONSOLE ERROR: line 77: Uncaught (in promise) TypeError: The stream has been aborted
 This is a testharness.js-based test.
-FAIL Piping from an errored readable stream to an errored writable stream rs.pipeTo is not a function
-FAIL Piping from an errored readable stream to an errored writable stream; preventAbort = true rs.pipeTo is not a function
-FAIL Piping from an errored readable stream to a closed writable stream rs.pipeTo is not a function
-FAIL Piping from a closed readable stream to an errored writable stream rs.pipeTo is not a function
-FAIL Piping from a closed readable stream to a closed writable stream rs.pipeTo is not a function
+PASS Piping from an errored readable stream to an errored writable stream 
+PASS Piping from an errored readable stream to an errored writable stream; preventAbort = true 
+FAIL Piping from an errored readable stream to a closed writable stream assert_array_equals: lengths differ, expected 1 got 2
+PASS Piping from a closed readable stream to an errored writable stream 
+PASS Piping from a closed readable stream to a closed writable stream 
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/multiple-propagation.sharedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/multiple-propagation.sharedworker-expected.txt
index 859fcbe9..32b3cd1 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/multiple-propagation.sharedworker-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/multiple-propagation.sharedworker-expected.txt
@@ -1,8 +1,8 @@
 This is a testharness.js-based test.
-FAIL Piping from an errored readable stream to an errored writable stream rs.pipeTo is not a function
-FAIL Piping from an errored readable stream to an errored writable stream; preventAbort = true rs.pipeTo is not a function
-FAIL Piping from an errored readable stream to a closed writable stream rs.pipeTo is not a function
-FAIL Piping from a closed readable stream to an errored writable stream rs.pipeTo is not a function
-FAIL Piping from a closed readable stream to a closed writable stream rs.pipeTo is not a function
+PASS Piping from an errored readable stream to an errored writable stream 
+PASS Piping from an errored readable stream to an errored writable stream; preventAbort = true 
+FAIL Piping from an errored readable stream to a closed writable stream assert_array_equals: lengths differ, expected 1 got 2
+PASS Piping from a closed readable stream to an errored writable stream 
+PASS Piping from a closed readable stream to a closed writable stream 
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through.dedicatedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through.dedicatedworker-expected.txt
deleted file mode 100644
index 0afae02..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through.dedicatedworker-expected.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-This is a testharness.js-based test.
-FAIL Piping through a duck-typed pass-through transform stream should work sequentialReadableStream(...).pipeThrough is not a function
-FAIL Piping through a transform errored on the writable end does not cause an unhandled promise rejection sequentialReadableStream(...).pipeThrough is not a function
-FAIL pipeThrough generically calls pipeTo with the appropriate args Cannot read property 'call' of undefined
-FAIL pipeThrough can handle calling a pipeTo that returns a non-promise object Cannot read property 'call' of undefined
-FAIL pipeThrough can handle calling a pipeTo that returns a non-promise thenable object Cannot read property 'call' of undefined
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through.https-expected.txt
deleted file mode 100644
index 0afae02..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through.https-expected.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-This is a testharness.js-based test.
-FAIL Piping through a duck-typed pass-through transform stream should work sequentialReadableStream(...).pipeThrough is not a function
-FAIL Piping through a transform errored on the writable end does not cause an unhandled promise rejection sequentialReadableStream(...).pipeThrough is not a function
-FAIL pipeThrough generically calls pipeTo with the appropriate args Cannot read property 'call' of undefined
-FAIL pipeThrough can handle calling a pipeTo that returns a non-promise object Cannot read property 'call' of undefined
-FAIL pipeThrough can handle calling a pipeTo that returns a non-promise thenable object Cannot read property 'call' of undefined
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through.sharedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through.sharedworker-expected.txt
deleted file mode 100644
index 0afae02..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through.sharedworker-expected.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-This is a testharness.js-based test.
-FAIL Piping through a duck-typed pass-through transform stream should work sequentialReadableStream(...).pipeThrough is not a function
-FAIL Piping through a transform errored on the writable end does not cause an unhandled promise rejection sequentialReadableStream(...).pipeThrough is not a function
-FAIL pipeThrough generically calls pipeTo with the appropriate args Cannot read property 'call' of undefined
-FAIL pipeThrough can handle calling a pipeTo that returns a non-promise object Cannot read property 'call' of undefined
-FAIL pipeThrough can handle calling a pipeTo that returns a non-promise thenable object Cannot read property 'call' of undefined
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general.dedicatedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general.dedicatedworker-expected.txt
index d2b57a8..aa3e4e49 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general.dedicatedworker-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general.dedicatedworker-expected.txt
@@ -2,7 +2,7 @@
 PASS ReadableStream can be constructed with no errors 
 PASS ReadableStream can't be constructed with garbage 
 PASS ReadableStream can't be constructed with an invalid type 
-FAIL ReadableStream instances should have the correct list of properties assert_array_equals: should have all the correct methods lengths differ, expected 7 got 5
+PASS ReadableStream instances should have the correct list of properties 
 PASS ReadableStream constructor should throw for non-function start arguments 
 PASS ReadableStream constructor can get initial garbage as cancel argument 
 PASS ReadableStream constructor can get initial garbage as pull argument 
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general.sharedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general.sharedworker-expected.txt
index d2b57a8..aa3e4e49 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general.sharedworker-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general.sharedworker-expected.txt
@@ -2,7 +2,7 @@
 PASS ReadableStream can be constructed with no errors 
 PASS ReadableStream can't be constructed with garbage 
 PASS ReadableStream can't be constructed with an invalid type 
-FAIL ReadableStream instances should have the correct list of properties assert_array_equals: should have all the correct methods lengths differ, expected 7 got 5
+PASS ReadableStream instances should have the correct list of properties 
 PASS ReadableStream constructor should throw for non-function start arguments 
 PASS ReadableStream constructor can get initial garbage as cancel argument 
 PASS ReadableStream constructor can get initial garbage as pull argument 
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/pipe-through.dedicatedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/pipe-through.dedicatedworker-expected.txt
deleted file mode 100644
index d1308fd..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/pipe-through.dedicatedworker-expected.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-This is a testharness.js-based test.
-FAIL ReadableStream.prototype.pipeThrough should work generically on its this and its arguments Cannot read property 'call' of undefined
-PASS ReadableStream.prototype.pipeThrough should throw when its first argument is not convertible to an object 
-PASS ReadableStream.prototype.pipeThrough should throw when "this" has no pipeTo method 
-FAIL ReadableStream.prototype.pipeThrough should rethrow errors from accessing pipeTo, readable, or writable assert_throws: pipeThrough should rethrow the error thrown by pipeTo function "() => ReadableStream.prototype.pipeThrough.call(throwingPipeTo, { readable: { }, writable: { } }, {})" threw object "TypeError: Cannot read property 'call' of undefined" ("TypeError") expected object "Error: potato" ("Error")
-FAIL ReadableStream.prototype.pipeThrough should work with missing readable, writable, or options Cannot read property 'call' of undefined
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/pipe-through.sharedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/pipe-through.sharedworker-expected.txt
deleted file mode 100644
index d1308fd..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/pipe-through.sharedworker-expected.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-This is a testharness.js-based test.
-FAIL ReadableStream.prototype.pipeThrough should work generically on its this and its arguments Cannot read property 'call' of undefined
-PASS ReadableStream.prototype.pipeThrough should throw when its first argument is not convertible to an object 
-PASS ReadableStream.prototype.pipeThrough should throw when "this" has no pipeTo method 
-FAIL ReadableStream.prototype.pipeThrough should rethrow errors from accessing pipeTo, readable, or writable assert_throws: pipeThrough should rethrow the error thrown by pipeTo function "() => ReadableStream.prototype.pipeThrough.call(throwingPipeTo, { readable: { }, writable: { } }, {})" threw object "TypeError: Cannot read property 'call' of undefined" ("TypeError") expected object "Error: potato" ("Error")
-FAIL ReadableStream.prototype.pipeThrough should work with missing readable, writable, or options Cannot read property 'call' of undefined
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/templated.dedicatedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/templated.dedicatedworker-expected.txt
deleted file mode 100644
index 927ae8ef..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/templated.dedicatedworker-expected.txt
+++ /dev/null
@@ -1,89 +0,0 @@
-This is a testharness.js-based test.
-PASS Running templatedRSEmpty with ReadableStream (empty) 
-FAIL ReadableStream (empty): instances have the correct methods and properties assert_equals: has a pipeThrough method expected "function" but got "undefined"
-PASS ReadableStream (empty): calling getReader with invalid arguments should throw appropriate errors 
-PASS Running templatedRSEmptyReader with ReadableStream (empty) reader 
-PASS ReadableStream (empty) reader: instances have the correct methods and properties 
-PASS ReadableStream (empty) reader: locked should be true 
-PASS ReadableStream (empty) reader: read() should never settle 
-PASS ReadableStream (empty) reader: two read()s should both never settle 
-PASS ReadableStream (empty) reader: read() should return distinct promises each time 
-PASS ReadableStream (empty) reader: getReader() again on the stream should fail 
-PASS ReadableStream (empty) reader: releasing the lock with pending read requests should throw but the read requests should stay pending 
-PASS ReadableStream (empty) reader: releasing the lock should cause further read() calls to reject with a TypeError 
-PASS ReadableStream (empty) reader: releasing the lock should cause closed calls to reject with a TypeError 
-PASS ReadableStream (empty) reader: releasing the lock should cause locked to become false 
-PASS ReadableStream (empty) reader: canceling via the reader should cause the reader to act closed 
-PASS ReadableStream (empty) reader: canceling via the stream should fail 
-PASS Running templatedRSClosed with ReadableStream (closed via call in start) 
-PASS ReadableStream (closed via call in start): cancel() should return a distinct fulfilled promise each time 
-PASS ReadableStream (closed via call in start): locked should be false 
-PASS ReadableStream (closed via call in start): getReader() should be OK 
-PASS ReadableStream (closed via call in start): should be able to acquire multiple readers if they are released in succession 
-PASS ReadableStream (closed via call in start): should not be able to acquire a second reader if we don't release the first one 
-PASS Running templatedRSClosedReader with ReadableStream reader (closed before getting reader) 
-PASS ReadableStream reader (closed before getting reader): read() should fulfill with { value: undefined, done: true } 
-PASS ReadableStream reader (closed before getting reader): read() multiple times should fulfill with { value: undefined, done: true } 
-PASS ReadableStream reader (closed before getting reader): read() should work when used within another read() fulfill callback 
-PASS ReadableStream reader (closed before getting reader): closed should fulfill with undefined 
-PASS ReadableStream reader (closed before getting reader): releasing the lock should cause closed to reject and change identity 
-PASS ReadableStream reader (closed before getting reader): cancel() should return a distinct fulfilled promise each time 
-PASS Running templatedRSClosedReader with ReadableStream reader (closed after getting reader) 
-PASS ReadableStream reader (closed after getting reader): read() should fulfill with { value: undefined, done: true } 
-PASS ReadableStream reader (closed after getting reader): read() multiple times should fulfill with { value: undefined, done: true } 
-PASS ReadableStream reader (closed after getting reader): read() should work when used within another read() fulfill callback 
-PASS ReadableStream reader (closed after getting reader): closed should fulfill with undefined 
-PASS ReadableStream reader (closed after getting reader): releasing the lock should cause closed to reject and change identity 
-PASS ReadableStream reader (closed after getting reader): cancel() should return a distinct fulfilled promise each time 
-PASS Running templatedRSClosed with ReadableStream (closed via cancel) 
-PASS ReadableStream (closed via cancel): cancel() should return a distinct fulfilled promise each time 
-PASS ReadableStream (closed via cancel): locked should be false 
-PASS ReadableStream (closed via cancel): getReader() should be OK 
-PASS ReadableStream (closed via cancel): should be able to acquire multiple readers if they are released in succession 
-PASS ReadableStream (closed via cancel): should not be able to acquire a second reader if we don't release the first one 
-PASS Running templatedRSClosedReader with ReadableStream reader (closed via cancel after getting reader) 
-PASS ReadableStream reader (closed via cancel after getting reader): read() should fulfill with { value: undefined, done: true } 
-PASS ReadableStream reader (closed via cancel after getting reader): read() multiple times should fulfill with { value: undefined, done: true } 
-PASS ReadableStream reader (closed via cancel after getting reader): read() should work when used within another read() fulfill callback 
-PASS ReadableStream reader (closed via cancel after getting reader): closed should fulfill with undefined 
-PASS ReadableStream reader (closed via cancel after getting reader): releasing the lock should cause closed to reject and change identity 
-PASS ReadableStream reader (closed via cancel after getting reader): cancel() should return a distinct fulfilled promise each time 
-PASS Running templatedRSErrored with ReadableStream (errored via call in start) 
-PASS ReadableStream (errored via call in start): getReader() should return a reader that acts errored 
-PASS ReadableStream (errored via call in start): read() twice should give the error each time 
-PASS ReadableStream (errored via call in start): locked should be false 
-PASS Running templatedRSErroredSyncOnly with ReadableStream (errored via call in start) 
-PASS ReadableStream (errored via call in start): should be able to obtain a second reader, with the correct closed promise 
-PASS ReadableStream (errored via call in start): should not be able to obtain additional readers if we don't release the first lock 
-PASS ReadableStream (errored via call in start): cancel() should return a distinct rejected promise each time 
-PASS ReadableStream (errored via call in start): reader cancel() should return a distinct rejected promise each time 
-PASS Running templatedRSErrored with ReadableStream (errored via returning a rejected promise in start) 
-PASS ReadableStream (errored via returning a rejected promise in start): getReader() should return a reader that acts errored 
-PASS ReadableStream (errored via returning a rejected promise in start): read() twice should give the error each time 
-PASS ReadableStream (errored via returning a rejected promise in start): locked should be false 
-PASS Running templatedRSErroredReader with ReadableStream (errored via returning a rejected promise in start) reader 
-PASS ReadableStream (errored via returning a rejected promise in start) reader: closed should reject with the error 
-PASS ReadableStream (errored via returning a rejected promise in start) reader: releasing the lock should cause closed to reject and change identity 
-PASS ReadableStream (errored via returning a rejected promise in start) reader: read() should reject with the error 
-PASS Running templatedRSErroredReader with ReadableStream reader (errored before getting reader) 
-PASS ReadableStream reader (errored before getting reader): closed should reject with the error 
-PASS ReadableStream reader (errored before getting reader): releasing the lock should cause closed to reject and change identity 
-PASS ReadableStream reader (errored before getting reader): read() should reject with the error 
-PASS Running templatedRSErroredReader with ReadableStream reader (errored after getting reader) 
-PASS ReadableStream reader (errored after getting reader): closed should reject with the error 
-PASS ReadableStream reader (errored after getting reader): releasing the lock should cause closed to reject and change identity 
-PASS ReadableStream reader (errored after getting reader): read() should reject with the error 
-PASS Running templatedRSTwoChunksOpenReader with ReadableStream (two chunks enqueued, still open) reader 
-PASS ReadableStream (two chunks enqueued, still open) reader: calling read() twice without waiting will eventually give both chunks (sequential) 
-PASS ReadableStream (two chunks enqueued, still open) reader: calling read() twice without waiting will eventually give both chunks (nested) 
-PASS ReadableStream (two chunks enqueued, still open) reader: read() should return distinct promises each time 
-PASS ReadableStream (two chunks enqueued, still open) reader: cancel() after a read() should still give that single read result 
-PASS Running templatedRSTwoChunksClosedReader with ReadableStream (two chunks enqueued, then closed) reader 
-PASS ReadableStream (two chunks enqueued, then closed) reader: third read(), without waiting, should give { value: undefined, done: true } (sequential) 
-PASS ReadableStream (two chunks enqueued, then closed) reader: third read(), without waiting, should give { value: undefined, done: true } (nested) 
-PASS ReadableStream (two chunks enqueued, then closed) reader: draining the stream via read() should cause the reader closed promise to fulfill, but locked stays true 
-PASS ReadableStream (two chunks enqueued, then closed) reader: releasing the lock after the stream is closed should cause locked to become false 
-PASS ReadableStream (two chunks enqueued, then closed) reader: releasing the lock should cause further read() calls to reject with a TypeError 
-PASS ReadableStream (two chunks enqueued, then closed) reader: reader's closed property always returns the same promise 
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/templated.sharedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/templated.sharedworker-expected.txt
deleted file mode 100644
index 927ae8ef..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/templated.sharedworker-expected.txt
+++ /dev/null
@@ -1,89 +0,0 @@
-This is a testharness.js-based test.
-PASS Running templatedRSEmpty with ReadableStream (empty) 
-FAIL ReadableStream (empty): instances have the correct methods and properties assert_equals: has a pipeThrough method expected "function" but got "undefined"
-PASS ReadableStream (empty): calling getReader with invalid arguments should throw appropriate errors 
-PASS Running templatedRSEmptyReader with ReadableStream (empty) reader 
-PASS ReadableStream (empty) reader: instances have the correct methods and properties 
-PASS ReadableStream (empty) reader: locked should be true 
-PASS ReadableStream (empty) reader: read() should never settle 
-PASS ReadableStream (empty) reader: two read()s should both never settle 
-PASS ReadableStream (empty) reader: read() should return distinct promises each time 
-PASS ReadableStream (empty) reader: getReader() again on the stream should fail 
-PASS ReadableStream (empty) reader: releasing the lock with pending read requests should throw but the read requests should stay pending 
-PASS ReadableStream (empty) reader: releasing the lock should cause further read() calls to reject with a TypeError 
-PASS ReadableStream (empty) reader: releasing the lock should cause closed calls to reject with a TypeError 
-PASS ReadableStream (empty) reader: releasing the lock should cause locked to become false 
-PASS ReadableStream (empty) reader: canceling via the reader should cause the reader to act closed 
-PASS ReadableStream (empty) reader: canceling via the stream should fail 
-PASS Running templatedRSClosed with ReadableStream (closed via call in start) 
-PASS ReadableStream (closed via call in start): cancel() should return a distinct fulfilled promise each time 
-PASS ReadableStream (closed via call in start): locked should be false 
-PASS ReadableStream (closed via call in start): getReader() should be OK 
-PASS ReadableStream (closed via call in start): should be able to acquire multiple readers if they are released in succession 
-PASS ReadableStream (closed via call in start): should not be able to acquire a second reader if we don't release the first one 
-PASS Running templatedRSClosedReader with ReadableStream reader (closed before getting reader) 
-PASS ReadableStream reader (closed before getting reader): read() should fulfill with { value: undefined, done: true } 
-PASS ReadableStream reader (closed before getting reader): read() multiple times should fulfill with { value: undefined, done: true } 
-PASS ReadableStream reader (closed before getting reader): read() should work when used within another read() fulfill callback 
-PASS ReadableStream reader (closed before getting reader): closed should fulfill with undefined 
-PASS ReadableStream reader (closed before getting reader): releasing the lock should cause closed to reject and change identity 
-PASS ReadableStream reader (closed before getting reader): cancel() should return a distinct fulfilled promise each time 
-PASS Running templatedRSClosedReader with ReadableStream reader (closed after getting reader) 
-PASS ReadableStream reader (closed after getting reader): read() should fulfill with { value: undefined, done: true } 
-PASS ReadableStream reader (closed after getting reader): read() multiple times should fulfill with { value: undefined, done: true } 
-PASS ReadableStream reader (closed after getting reader): read() should work when used within another read() fulfill callback 
-PASS ReadableStream reader (closed after getting reader): closed should fulfill with undefined 
-PASS ReadableStream reader (closed after getting reader): releasing the lock should cause closed to reject and change identity 
-PASS ReadableStream reader (closed after getting reader): cancel() should return a distinct fulfilled promise each time 
-PASS Running templatedRSClosed with ReadableStream (closed via cancel) 
-PASS ReadableStream (closed via cancel): cancel() should return a distinct fulfilled promise each time 
-PASS ReadableStream (closed via cancel): locked should be false 
-PASS ReadableStream (closed via cancel): getReader() should be OK 
-PASS ReadableStream (closed via cancel): should be able to acquire multiple readers if they are released in succession 
-PASS ReadableStream (closed via cancel): should not be able to acquire a second reader if we don't release the first one 
-PASS Running templatedRSClosedReader with ReadableStream reader (closed via cancel after getting reader) 
-PASS ReadableStream reader (closed via cancel after getting reader): read() should fulfill with { value: undefined, done: true } 
-PASS ReadableStream reader (closed via cancel after getting reader): read() multiple times should fulfill with { value: undefined, done: true } 
-PASS ReadableStream reader (closed via cancel after getting reader): read() should work when used within another read() fulfill callback 
-PASS ReadableStream reader (closed via cancel after getting reader): closed should fulfill with undefined 
-PASS ReadableStream reader (closed via cancel after getting reader): releasing the lock should cause closed to reject and change identity 
-PASS ReadableStream reader (closed via cancel after getting reader): cancel() should return a distinct fulfilled promise each time 
-PASS Running templatedRSErrored with ReadableStream (errored via call in start) 
-PASS ReadableStream (errored via call in start): getReader() should return a reader that acts errored 
-PASS ReadableStream (errored via call in start): read() twice should give the error each time 
-PASS ReadableStream (errored via call in start): locked should be false 
-PASS Running templatedRSErroredSyncOnly with ReadableStream (errored via call in start) 
-PASS ReadableStream (errored via call in start): should be able to obtain a second reader, with the correct closed promise 
-PASS ReadableStream (errored via call in start): should not be able to obtain additional readers if we don't release the first lock 
-PASS ReadableStream (errored via call in start): cancel() should return a distinct rejected promise each time 
-PASS ReadableStream (errored via call in start): reader cancel() should return a distinct rejected promise each time 
-PASS Running templatedRSErrored with ReadableStream (errored via returning a rejected promise in start) 
-PASS ReadableStream (errored via returning a rejected promise in start): getReader() should return a reader that acts errored 
-PASS ReadableStream (errored via returning a rejected promise in start): read() twice should give the error each time 
-PASS ReadableStream (errored via returning a rejected promise in start): locked should be false 
-PASS Running templatedRSErroredReader with ReadableStream (errored via returning a rejected promise in start) reader 
-PASS ReadableStream (errored via returning a rejected promise in start) reader: closed should reject with the error 
-PASS ReadableStream (errored via returning a rejected promise in start) reader: releasing the lock should cause closed to reject and change identity 
-PASS ReadableStream (errored via returning a rejected promise in start) reader: read() should reject with the error 
-PASS Running templatedRSErroredReader with ReadableStream reader (errored before getting reader) 
-PASS ReadableStream reader (errored before getting reader): closed should reject with the error 
-PASS ReadableStream reader (errored before getting reader): releasing the lock should cause closed to reject and change identity 
-PASS ReadableStream reader (errored before getting reader): read() should reject with the error 
-PASS Running templatedRSErroredReader with ReadableStream reader (errored after getting reader) 
-PASS ReadableStream reader (errored after getting reader): closed should reject with the error 
-PASS ReadableStream reader (errored after getting reader): releasing the lock should cause closed to reject and change identity 
-PASS ReadableStream reader (errored after getting reader): read() should reject with the error 
-PASS Running templatedRSTwoChunksOpenReader with ReadableStream (two chunks enqueued, still open) reader 
-PASS ReadableStream (two chunks enqueued, still open) reader: calling read() twice without waiting will eventually give both chunks (sequential) 
-PASS ReadableStream (two chunks enqueued, still open) reader: calling read() twice without waiting will eventually give both chunks (nested) 
-PASS ReadableStream (two chunks enqueued, still open) reader: read() should return distinct promises each time 
-PASS ReadableStream (two chunks enqueued, still open) reader: cancel() after a read() should still give that single read result 
-PASS Running templatedRSTwoChunksClosedReader with ReadableStream (two chunks enqueued, then closed) reader 
-PASS ReadableStream (two chunks enqueued, then closed) reader: third read(), without waiting, should give { value: undefined, done: true } (sequential) 
-PASS ReadableStream (two chunks enqueued, then closed) reader: third read(), without waiting, should give { value: undefined, done: true } (nested) 
-PASS ReadableStream (two chunks enqueued, then closed) reader: draining the stream via read() should cause the reader closed promise to fulfill, but locked stays true 
-PASS ReadableStream (two chunks enqueued, then closed) reader: releasing the lock after the stream is closed should cause locked to become false 
-PASS ReadableStream (two chunks enqueued, then closed) reader: releasing the lock should cause further read() calls to reject with a TypeError 
-PASS ReadableStream (two chunks enqueued, then closed) reader: reader's closed property always returns the same promise 
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/async-callstack-network-initiator-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/async-callstack-network-initiator-expected.txt
index 4cb1eda8..34ce22c6 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/async-callstack-network-initiator-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/async-callstack-network-initiator-expected.txt
@@ -1,4 +1,3 @@
-CONSOLE MESSAGE: line 11: console.clear
 Tests asynchronous call stacks printed in console for a Network.Initiator.
 
 Set timer for test function.
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
index f0fc9305..9f14b26 100644
--- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -217,6 +217,25 @@
     method toString
     method transformPoint
     method translate
+interface DOMPoint : DOMPointReadOnly
+    getter w
+    getter x
+    getter y
+    getter z
+    method constructor
+    setter w
+    setter x
+    setter y
+    setter z
+interface DOMPointReadOnly
+    static method fromPoint
+    getter w
+    getter x
+    getter y
+    getter z
+    method constructor
+    method matrixTransform
+    method toJSON
 interface DOMStringList
     getter length
     method constructor
@@ -735,6 +754,8 @@
     method cancel
     method constructor
     method getReader
+    method pipeThrough
+    method pipeTo
     method tee
 interface Request
     getter bodyUsed
diff --git a/third_party/WebKit/LayoutTests/http/tests/streams/piping/multiple-propagation.https.html b/third_party/WebKit/LayoutTests/http/tests/streams/piping/multiple-propagation.https.html
new file mode 100644
index 0000000..c7951db8
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/streams/piping/multiple-propagation.https.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/serviceworker/resources/test-helpers.js"></script>
+<script src="../resources/test-initializer.js"></script>
+<script src="../resources/test-utils.js"></script>
+<script src="../resources/recording-streams.js"></script>
+
+<script src="multiple-propagation.js"></script>
+<script>
+'use strict';
+worker_test('multiple-propagation.js');
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/streams/piping/multiple-propagation.js b/third_party/WebKit/LayoutTests/http/tests/streams/piping/multiple-propagation.js
new file mode 100644
index 0000000..2c7fd141
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/streams/piping/multiple-propagation.js
@@ -0,0 +1,139 @@
+'use strict';
+
+if (self.importScripts) {
+  self.importScripts('/resources/testharness.js');
+  self.importScripts('../resources/test-utils.js');
+  self.importScripts('../resources/recording-streams.js');
+}
+
+const error1 = new Error('error1!');
+error1.name = 'error1';
+
+const error2 = new Error('error2!');
+error2.name = 'error2';
+
+promise_test(t => {
+  const rs = recordingReadableStream({
+    start(c) {
+      c.error(error1);
+    }
+  });
+  const ws = recordingWritableStream({
+    start(c) {
+      c.error(error2);
+    }
+  });
+
+  // Trying to abort a stream that was errored will give that error back
+  return promise_rejects(t, error2, rs.pipeTo(ws), 'pipeTo must reject with the writable stream\'s error').then(() => {
+    assert_array_equals(rs.events, []);
+    assert_array_equals(ws.events, []);
+
+    return Promise.all([
+      promise_rejects(t, error1, rs.getReader().closed, 'the readable stream must be errored with error1'),
+      promise_rejects(t, error2, ws.getWriter().closed, 'the writable stream must be errored with error2')
+    ]);
+  });
+
+}, 'Piping from an errored readable stream to an errored writable stream');
+
+promise_test(t => {
+  const rs = recordingReadableStream({
+    start(c) {
+      c.error(error1);
+    }
+  });
+  const ws = recordingWritableStream({
+    start(c) {
+      c.error(error2);
+    }
+  });
+
+  return promise_rejects(t, error1, rs.pipeTo(ws, { preventAbort: true }),
+    'pipeTo must reject with the readable stream\'s error')
+  .then(() => {
+    assert_array_equals(rs.events, []);
+    assert_array_equals(ws.events, []);
+
+    return Promise.all([
+      promise_rejects(t, error1, rs.getReader().closed, 'the readable stream must be errored with error1'),
+      promise_rejects(t, error2, ws.getWriter().closed, 'the writable stream must be errored with error2')
+    ]);
+  });
+
+}, 'Piping from an errored readable stream to an errored writable stream; preventAbort = true');
+
+// TODO(ricea): Revert to the upstream version of this test once https://github.com/whatwg/streams/pull/634 is
+// resolved and WritableStream.js has been updated to match.
+promise_test(t => {
+  const rs = recordingReadableStream({
+    start(c) {
+      c.error(error1);
+    }
+  });
+  const ws = recordingWritableStream();
+  const writer = ws.getWriter();
+  const closePromise = writer.close();
+  writer.releaseLock();
+
+  return promise_rejects(t, error1, rs.pipeTo(ws), 'pipeTo must reject with the readable stream\'s error').then(() => {
+    assert_array_equals(rs.events, []);
+    assert_array_equals(ws.events, ['abort', error1], 'ws.events should contain abort for the time being');
+
+    return Promise.all([
+      promise_rejects(t, error1, rs.getReader().closed, 'the readable stream must be errored with error1'),
+      promise_rejects(t, new TypeError(), ws.getWriter().closed, 'the writable stream should be errored for the time being'),
+      promise_rejects(t, new TypeError(), closePromise, 'close() should reject for the time being')
+    ]);
+  });
+
+}, 'Piping from an errored readable stream to a closed writable stream');
+
+promise_test(t => {
+  const rs = recordingReadableStream({
+    start(c) {
+      c.close();
+    }
+  });
+  const ws = recordingWritableStream({
+    start(c) {
+      c.error(error1);
+    }
+  });
+
+  return promise_rejects(t, error1, rs.pipeTo(ws), 'pipeTo must reject with the writable stream\'s error').then(() => {
+    assert_array_equals(rs.events, []);
+    assert_array_equals(ws.events, []);
+
+    return Promise.all([
+      rs.getReader().closed,
+      promise_rejects(t, error1, ws.getWriter().closed, 'the writable stream must be errored with error1')
+    ]);
+  });
+
+}, 'Piping from a closed readable stream to an errored writable stream');
+
+promise_test(() => {
+  const rs = recordingReadableStream({
+    start(c) {
+      c.close();
+    }
+  });
+  const ws = recordingWritableStream();
+  const writer = ws.getWriter();
+  writer.close();
+  writer.releaseLock();
+
+  return rs.pipeTo(ws).then(() => {
+    assert_array_equals(rs.events, []);
+    assert_array_equals(ws.events, ['close']);
+
+    return Promise.all([
+      rs.getReader().closed,
+      ws.getWriter().closed
+    ]);
+  });
+
+}, 'Piping from a closed readable stream to a closed writable stream');
+
+done();
diff --git a/third_party/WebKit/LayoutTests/http/tests/streams/readable-streams/general.js b/third_party/WebKit/LayoutTests/http/tests/streams/readable-streams/general.js
index 28c0c10..288fcce 100644
--- a/third_party/WebKit/LayoutTests/http/tests/streams/readable-streams/general.js
+++ b/third_party/WebKit/LayoutTests/http/tests/streams/readable-streams/general.js
@@ -37,7 +37,7 @@
 
 test(() => {
 
-  const methods = ['cancel', 'constructor', 'getReader', 'tee'];
+  const methods = ['cancel', 'constructor', 'getReader', 'pipeThrough', 'pipeTo', 'tee'];
   const properties = methods.concat(['locked']).sort();
 
   const rs = new ReadableStream();
diff --git a/third_party/WebKit/LayoutTests/http/tests/worklet/webexposed/global-interface-listing-paint-worklet-expected.txt b/third_party/WebKit/LayoutTests/http/tests/worklet/webexposed/global-interface-listing-paint-worklet-expected.txt
index 53baf8a..ba11504 100644
--- a/third_party/WebKit/LayoutTests/http/tests/worklet/webexposed/global-interface-listing-paint-worklet-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/worklet/webexposed/global-interface-listing-paint-worklet-expected.txt
@@ -242,6 +242,8 @@
 CONSOLE MESSAGE: line 138:     method cancel
 CONSOLE MESSAGE: line 138:     method constructor
 CONSOLE MESSAGE: line 138:     method getReader
+CONSOLE MESSAGE: line 138:     method pipeThrough
+CONSOLE MESSAGE: line 138:     method pipeTo
 CONSOLE MESSAGE: line 138:     method tee
 CONSOLE MESSAGE: line 138: interface StylePropertyMap
 CONSOLE MESSAGE: line 138:     method append
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-clear-function-expected.txt b/third_party/WebKit/LayoutTests/inspector/console/console-clear-function-expected.txt
index d2bbb2c..816acea 100644
--- a/third_party/WebKit/LayoutTests/inspector/console/console-clear-function-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector/console/console-clear-function-expected.txt
@@ -1,7 +1,6 @@
 CONSOLE MESSAGE: line 10: one
 CONSOLE MESSAGE: line 11: two
 CONSOLE MESSAGE: line 12: three
-CONSOLE MESSAGE: line 19: console.clear
 Tests that console is cleared via console.clear() method
 
 Bug 101021
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-command-clear-expected.txt b/third_party/WebKit/LayoutTests/inspector/console/console-command-clear-expected.txt
index 75760b6..dc9c35e 100644
--- a/third_party/WebKit/LayoutTests/inspector/console/console-command-clear-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector/console/console-command-clear-expected.txt
@@ -1,7 +1,6 @@
 CONSOLE MESSAGE: line 9: one
 CONSOLE MESSAGE: line 10: two
 CONSOLE MESSAGE: line 11: three
-CONSOLE MESSAGE: line 1: console.clear
 Tests that console is cleared upon clear() eval in console.
 
 === Before clear ===
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-tests-expected.txt b/third_party/WebKit/LayoutTests/inspector/console/console-tests-expected.txt
index 436df7dc..0644e98 100644
--- a/third_party/WebKit/LayoutTests/inspector/console/console-tests-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector/console/console-tests-expected.txt
@@ -41,15 +41,15 @@
 console-tests.html:13 error
 onload @ console-tests.html:13 console-message-wrapper console-error-level > console-message
 5console-tests.html:15 repeated console-message-wrapper console-info-level > console-message repeated-message
-console-tests.html:17 count: 1 console-message-wrapper console-verbose-level > console-message
-console-tests.html:17 count: 2 console-message-wrapper console-verbose-level > console-message
+console-tests.html:17 count: 1 console-message-wrapper console-info-level > console-message
+console-tests.html:17 count: 2 console-message-wrapper console-info-level > console-message
 console-tests.html:18 group console-message-wrapper console-info-level > console-message console-group-title
 console-tests.html:20 1 2 3 console-message-wrapper console-info-level > console-message
 console-tests.html:21 groupCollapsed console-message-wrapper console-info-level > console-message console-group-title
-console-tests.html:33 : 1 console-message-wrapper console-verbose-level > console-message
-console-tests.html:34 : 1 console-message-wrapper console-verbose-level > console-message
-console-tests.html:35 : 1 console-message-wrapper console-verbose-level > console-message
-console-tests.html:36 title: 1 console-message-wrapper console-verbose-level > console-message
-console-tests.html:37 title: 2 console-message-wrapper console-verbose-level > console-message
-console-tests.html:38 title: 3 console-message-wrapper console-verbose-level > console-message
+console-tests.html:33 : 1 console-message-wrapper console-info-level > console-message
+console-tests.html:34 : 1 console-message-wrapper console-info-level > console-message
+console-tests.html:35 : 1 console-message-wrapper console-info-level > console-message
+console-tests.html:36 title: 1 console-message-wrapper console-info-level > console-message
+console-tests.html:37 title: 2 console-message-wrapper console-info-level > console-message
+console-tests.html:38 title: 3 console-message-wrapper console-info-level > console-message
 
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-async/async-callstack-in-console-expected.txt b/third_party/WebKit/LayoutTests/inspector/sources/debugger-async/async-callstack-in-console-expected.txt
index 372acb7..1b0ffa1 100644
--- a/third_party/WebKit/LayoutTests/inspector/sources/debugger-async/async-callstack-in-console-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-async/async-callstack-in-console-expected.txt
@@ -1,4 +1,3 @@
-CONSOLE MESSAGE: line 11: console.clear
 CONSOLE MESSAGE: line 17: console.trace
 CONSOLE ERROR: line 24: Uncaught Error: foo
 CONSOLE MESSAGE: line 29: console.trace
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger/rethrow-error-from-bindings-crash-expected.txt b/third_party/WebKit/LayoutTests/inspector/sources/debugger/rethrow-error-from-bindings-crash-expected.txt
index 9e8fd33..eaf8908 100644
--- a/third_party/WebKit/LayoutTests/inspector/sources/debugger/rethrow-error-from-bindings-crash-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger/rethrow-error-from-bindings-crash-expected.txt
@@ -1,4 +1,3 @@
-CONSOLE MESSAGE: line 11: console.clear
 CONSOLE ERROR: line 25: Uncaught TypeError: Failed to execute 'compareBoundaryPoints' on 'Range': parameter 2 is not of type 'Range'.
 CONSOLE ERROR: line 20: Uncaught TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'.
 CONSOLE ERROR: line 25: Uncaught TypeError: Failed to execute 'compareBoundaryPoints' on 'Range': parameter 2 is not of type 'Range'.
diff --git a/third_party/WebKit/LayoutTests/scrollbars/custom-scrollbar-reconstruction-document-write.html b/third_party/WebKit/LayoutTests/scrollbars/custom-scrollbar-reconstruction-document-write.html
new file mode 100644
index 0000000..f2390975
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/scrollbars/custom-scrollbar-reconstruction-document-write.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<script src="../resources/testharness.js"></script>
+<script src="../resources/testharnessreport.js"></script>
+<iframe></iframe>
+<script>
+
+function writeDoc() {
+  var doc = document.querySelector("iframe").contentDocument;
+  doc.open();
+  doc.write(`
+    <style>
+      ::-webkit-scrollbar-thumb { background-color: blue; }
+      ::-webkit-scrollbar { width: 50px; height: 50px; }
+      body { height: 400px; overflow: scroll; }
+    </style>`);
+  doc.close();
+  assert_equals(doc.documentElement.offsetWidth, 250);
+}
+
+test(() => {
+  writeDoc();
+  writeDoc();
+}, "Preserve iframe custom scrollbar after replacing contents with document.write.");
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
index 9c59386..20069ec2 100644
--- a/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -217,6 +217,25 @@
     method toString
     method transformPoint
     method translate
+interface DOMPoint : DOMPointReadOnly
+    getter w
+    getter x
+    getter y
+    getter z
+    method constructor
+    setter w
+    setter x
+    setter y
+    setter z
+interface DOMPointReadOnly
+    static method fromPoint
+    getter w
+    getter x
+    getter y
+    getter z
+    method constructor
+    method matrixTransform
+    method toJSON
 interface DOMStringList
     getter length
     method constructor
@@ -742,6 +761,8 @@
     method cancel
     method constructor
     method getReader
+    method pipeThrough
+    method pipeTo
     method tee
 interface Request
     getter bodyUsed
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-compositor-worker-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-compositor-worker-expected.txt
index 9cb32d2..919ec9e6 100644
--- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-compositor-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-compositor-worker-expected.txt
@@ -55,6 +55,8 @@
 [Worker]     method cancel
 [Worker]     method constructor
 [Worker]     method getReader
+[Worker]     method pipeThrough
+[Worker]     method pipeTo
 [Worker]     method tee
 [Worker] interface WritableStream
 [Worker]     getter locked
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt
index bf1e2d4..a0f69402 100644
--- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -228,6 +228,27 @@
 [Worker]     method toString
 [Worker]     method transformPoint
 [Worker]     method translate
+[Worker] interface DOMPoint : DOMPointReadOnly
+[Worker]     attribute @@toStringTag
+[Worker]     getter w
+[Worker]     getter x
+[Worker]     getter y
+[Worker]     getter z
+[Worker]     method constructor
+[Worker]     setter w
+[Worker]     setter x
+[Worker]     setter y
+[Worker]     setter z
+[Worker] interface DOMPointReadOnly
+[Worker]     static method fromPoint
+[Worker]     attribute @@toStringTag
+[Worker]     getter w
+[Worker]     getter x
+[Worker]     getter y
+[Worker]     getter z
+[Worker]     method constructor
+[Worker]     method matrixTransform
+[Worker]     method toJSON
 [Worker] interface DOMStringList
 [Worker]     attribute @@toStringTag
 [Worker]     getter length
@@ -743,6 +764,8 @@
 [Worker]     method cancel
 [Worker]     method constructor
 [Worker]     method getReader
+[Worker]     method pipeThrough
+[Worker]     method pipeTo
 [Worker]     method tee
 [Worker] interface Request
 [Worker]     attribute @@toStringTag
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
index 40866062..422fe01 100644
--- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -5015,6 +5015,8 @@
     method cancel
     method constructor
     method getReader
+    method pipeThrough
+    method pipeTo
     method tee
 interface RelatedApplication
     attribute @@toStringTag
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt
index 2be997b..8100512 100644
--- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -228,6 +228,27 @@
 [Worker]     method toString
 [Worker]     method transformPoint
 [Worker]     method translate
+[Worker] interface DOMPoint : DOMPointReadOnly
+[Worker]     attribute @@toStringTag
+[Worker]     getter w
+[Worker]     getter x
+[Worker]     getter y
+[Worker]     getter z
+[Worker]     method constructor
+[Worker]     setter w
+[Worker]     setter x
+[Worker]     setter y
+[Worker]     setter z
+[Worker] interface DOMPointReadOnly
+[Worker]     static method fromPoint
+[Worker]     attribute @@toStringTag
+[Worker]     getter w
+[Worker]     getter x
+[Worker]     getter y
+[Worker]     getter z
+[Worker]     method constructor
+[Worker]     method matrixTransform
+[Worker]     method toJSON
 [Worker] interface DOMStringList
 [Worker]     attribute @@toStringTag
 [Worker]     getter length
@@ -738,6 +759,8 @@
 [Worker]     method cancel
 [Worker]     method constructor
 [Worker]     method getReader
+[Worker]     method pipeThrough
+[Worker]     method pipeTo
 [Worker]     method tee
 [Worker] interface Request
 [Worker]     attribute @@toStringTag
diff --git a/third_party/WebKit/Source/core/css/CSSMarkup.cpp b/third_party/WebKit/Source/core/css/CSSMarkup.cpp
index 3a1b9e6..ce56f45 100644
--- a/third_party/WebKit/Source/core/css/CSSMarkup.cpp
+++ b/third_party/WebKit/Source/core/css/CSSMarkup.cpp
@@ -77,7 +77,7 @@
 
 static void serializeCharacterAsCodePoint(UChar32 c, StringBuilder& appendTo) {
   appendTo.append('\\');
-  appendUnsignedAsHex(c, appendTo, Lowercase);
+  HexNumber::appendUnsignedAsHex(c, appendTo, HexNumber::Lowercase);
   appendTo.append(' ');
 }
 
diff --git a/third_party/WebKit/Source/core/dom/DOMPoint.idl b/third_party/WebKit/Source/core/dom/DOMPoint.idl
index 737f446..78672b8 100644
--- a/third_party/WebKit/Source/core/dom/DOMPoint.idl
+++ b/third_party/WebKit/Source/core/dom/DOMPoint.idl
@@ -7,7 +7,7 @@
 [
     Constructor(optional unrestricted double x = 0, optional unrestricted double y = 0,
                 optional unrestricted double z = 0, optional unrestricted double w = 1),
-    // FIXME: Exposed=(Window,Worker)
+    Exposed=(Window,Worker),
     RuntimeEnabled=GeometryInterfaces,
 ] interface DOMPoint : DOMPointReadOnly {
     [NewObject] static DOMPoint fromPoint(optional DOMPointInit other);
diff --git a/third_party/WebKit/Source/core/dom/DOMPointReadOnly.idl b/third_party/WebKit/Source/core/dom/DOMPointReadOnly.idl
index 7c381bdd..f1b0d0b 100644
--- a/third_party/WebKit/Source/core/dom/DOMPointReadOnly.idl
+++ b/third_party/WebKit/Source/core/dom/DOMPointReadOnly.idl
@@ -7,7 +7,7 @@
 [
     Constructor(optional unrestricted double x = 0, optional unrestricted double y = 0,
                 optional unrestricted double z = 0, optional unrestricted double w = 1),
-    // FIXME: Exposed=(Window,Worker)
+    Exposed=(Window,Worker),
     RuntimeEnabled=GeometryInterfaces,
 ] interface DOMPointReadOnly {
     [NewObject] static DOMPointReadOnly fromPoint(optional DOMPointInit other);
diff --git a/third_party/WebKit/Source/core/events/PointerEventFactory.cpp b/third_party/WebKit/Source/core/events/PointerEventFactory.cpp
index c7ea4712..4293ed153 100644
--- a/third_party/WebKit/Source/core/events/PointerEventFactory.cpp
+++ b/third_party/WebKit/Source/core/events/PointerEventFactory.cpp
@@ -269,8 +269,10 @@
     for (const auto& coalescedMouseEvent : coalescedMouseEvents) {
       DCHECK_EQ(mouseEvent.pointerProperties().id,
                 coalescedMouseEvent.pointerProperties().id);
-      DCHECK_EQ(mouseEvent.pointerProperties().pointerType,
-                coalescedMouseEvent.pointerProperties().pointerType);
+      // TODO(crbug.com/684292): We need further investigation of why the
+      // following DCHECK fails.
+      // DCHECK_EQ(mouseEvent.pointerProperties().pointerType,
+      //          coalescedMouseEvent.pointerProperties().pointerType);
       PointerEventInit coalescedEventInit = pointerEventInit;
       updateMousePointerEventInit(coalescedMouseEvent, view,
                                   &coalescedEventInit);
diff --git a/third_party/WebKit/Source/core/frame/FrameView.cpp b/third_party/WebKit/Source/core/frame/FrameView.cpp
index 530e1224..fed6ff0 100644
--- a/third_party/WebKit/Source/core/frame/FrameView.cpp
+++ b/third_party/WebKit/Source/core/frame/FrameView.cpp
@@ -639,9 +639,6 @@
         m_frame->isMainFrame())
       return false;
   }
-
-  // FIXME: We need to update the scrollbar dynamically as documents change (or
-  // as doc elements and bodies get discovered that have custom styles).
   Document* doc = m_frame->document();
 
   // Try the <body> element first as a scrollbar source.
@@ -4089,15 +4086,32 @@
 }
 
 bool FrameView::needsScrollbarReconstruction() const {
-  Element* customScrollbarElement = nullptr;
-  bool shouldUseCustom = shouldUseCustomScrollbars(customScrollbarElement);
-
-  bool hasAnyScrollbar = horizontalScrollbar() || verticalScrollbar();
-  bool hasCustom =
-      (horizontalScrollbar() && horizontalScrollbar()->isCustomScrollbar()) ||
-      (verticalScrollbar() && verticalScrollbar()->isCustomScrollbar());
-
-  return hasAnyScrollbar && (shouldUseCustom != hasCustom);
+  Scrollbar* scrollbar = horizontalScrollbar();
+  if (!scrollbar)
+    scrollbar = verticalScrollbar();
+  if (!scrollbar) {
+    // We have no scrollbar to reconstruct.
+    return false;
+  }
+  Element* styleSource = nullptr;
+  bool needsCustom = shouldUseCustomScrollbars(styleSource);
+  bool isCustom = scrollbar->isCustomScrollbar();
+  if (needsCustom != isCustom) {
+    // We have a native scrollbar that should be custom, or vice versa.
+    return true;
+  }
+  if (!needsCustom) {
+    // We have a native scrollbar that should remain native.
+    return false;
+  }
+  DCHECK(needsCustom && isCustom);
+  DCHECK(styleSource);
+  if (toLayoutScrollbar(scrollbar)->owningLayoutObject() !=
+      styleSource->layoutObject()) {
+    // We have a custom scrollbar with a stale m_owner.
+    return true;
+  }
+  return false;
 }
 
 bool FrameView::shouldIgnoreOverflowHidden() const {
diff --git a/third_party/WebKit/Source/core/frame/FrameView.h b/third_party/WebKit/Source/core/frame/FrameView.h
index b427e64..7de27821 100644
--- a/third_party/WebKit/Source/core/frame/FrameView.h
+++ b/third_party/WebKit/Source/core/frame/FrameView.h
@@ -979,7 +979,7 @@
   bool shouldUseCustomScrollbars(Element*& customScrollbarElement) const;
 
   // Returns true if a scrollbar needs to go from native -> custom or vice
-  // versa.
+  // versa, or if a custom scrollbar has a stale owner.
   bool needsScrollbarReconstruction() const;
 
   bool shouldIgnoreOverflowHidden() const;
diff --git a/third_party/WebKit/Source/core/inspector/MainThreadDebugger.cpp b/third_party/WebKit/Source/core/inspector/MainThreadDebugger.cpp
index 68399b5e..ef59b8b 100644
--- a/third_party/WebKit/Source/core/inspector/MainThreadDebugger.cpp
+++ b/third_party/WebKit/Source/core/inspector/MainThreadDebugger.cpp
@@ -301,7 +301,7 @@
 
 void MainThreadDebugger::consoleAPIMessage(
     int contextGroupId,
-    v8_inspector::V8ConsoleAPIType type,
+    v8::Isolate::MessageErrorLevel level,
     const v8_inspector::StringView& message,
     const v8_inspector::StringView& url,
     unsigned lineNumber,
@@ -310,18 +310,24 @@
   LocalFrame* frame = WeakIdentifierMap<LocalFrame>::lookup(contextGroupId);
   if (!frame)
     return;
-  if (type == v8_inspector::V8ConsoleAPIType::kClear && frame->host())
-    frame->host()->consoleMessageStorage().clear();
   // TODO(dgozman): we can save a copy of message and url here by making
   // FrameConsole work with StringView.
   std::unique_ptr<SourceLocation> location =
       SourceLocation::create(toCoreString(url), lineNumber, columnNumber,
                              stackTrace ? stackTrace->clone() : nullptr, 0);
   frame->console().reportMessageToClient(ConsoleAPIMessageSource,
-                                         consoleAPITypeToMessageLevel(type),
+                                         v8MessageLevelToMessageLevel(level),
                                          toCoreString(message), location.get());
 }
 
+void MainThreadDebugger::consoleClear(int contextGroupId) {
+  LocalFrame* frame = WeakIdentifierMap<LocalFrame>::lookup(contextGroupId);
+  if (!frame)
+    return;
+  if (frame->host())
+    frame->host()->consoleMessageStorage().clear();
+}
+
 v8::MaybeLocal<v8::Value> MainThreadDebugger::memoryInfo(
     v8::Isolate* isolate,
     v8::Local<v8::Context> context) {
diff --git a/third_party/WebKit/Source/core/inspector/MainThreadDebugger.h b/third_party/WebKit/Source/core/inspector/MainThreadDebugger.h
index ad6ad9aa..5f99457 100644
--- a/third_party/WebKit/Source/core/inspector/MainThreadDebugger.h
+++ b/third_party/WebKit/Source/core/inspector/MainThreadDebugger.h
@@ -102,12 +102,13 @@
   bool canExecuteScripts(int contextGroupId) override;
   void runIfWaitingForDebugger(int contextGroupId) override;
   void consoleAPIMessage(int contextGroupId,
-                         v8_inspector::V8ConsoleAPIType,
+                         v8::Isolate::MessageErrorLevel,
                          const v8_inspector::StringView& message,
                          const v8_inspector::StringView& url,
                          unsigned lineNumber,
                          unsigned columnNumber,
                          v8_inspector::V8StackTrace*) override;
+  void consoleClear(int contextGroupId) override;
   void installAdditionalCommandLineAPI(v8::Local<v8::Context>,
                                        v8::Local<v8::Object>) override;
   v8::MaybeLocal<v8::Value> memoryInfo(v8::Isolate*,
diff --git a/third_party/WebKit/Source/core/inspector/ThreadDebugger.cpp b/third_party/WebKit/Source/core/inspector/ThreadDebugger.cpp
index 6e4ac06..1b552c8 100644
--- a/third_party/WebKit/Source/core/inspector/ThreadDebugger.cpp
+++ b/third_party/WebKit/Source/core/inspector/ThreadDebugger.cpp
@@ -45,21 +45,26 @@
 }
 
 // static
-MessageLevel ThreadDebugger::consoleAPITypeToMessageLevel(
-    v8_inspector::V8ConsoleAPIType type) {
-  switch (type) {
-    case v8_inspector::V8ConsoleAPIType::kDebug:
-      return VerboseMessageLevel;
-    case v8_inspector::V8ConsoleAPIType::kLog:
-    case v8_inspector::V8ConsoleAPIType::kInfo:
-      return InfoMessageLevel;
-    case v8_inspector::V8ConsoleAPIType::kWarning:
-      return WarningMessageLevel;
-    case v8_inspector::V8ConsoleAPIType::kError:
-      return ErrorMessageLevel;
+MessageLevel ThreadDebugger::v8MessageLevelToMessageLevel(
+    v8::Isolate::MessageErrorLevel level) {
+  MessageLevel result = InfoMessageLevel;
+  switch (level) {
+    case v8::Isolate::kMessageDebug:
+      result = VerboseMessageLevel;
+      break;
+    case v8::Isolate::kMessageWarning:
+      result = WarningMessageLevel;
+      break;
+    case v8::Isolate::kMessageError:
+      result = ErrorMessageLevel;
+      break;
+    case v8::Isolate::kMessageLog:
+    case v8::Isolate::kMessageInfo:
     default:
-      return InfoMessageLevel;
+      result = InfoMessageLevel;
+      break;
   }
+  return result;
 }
 
 void ThreadDebugger::willExecuteScript(v8::Isolate* isolate, int scriptId) {
diff --git a/third_party/WebKit/Source/core/inspector/ThreadDebugger.h b/third_party/WebKit/Source/core/inspector/ThreadDebugger.h
index cc687d13..6d49f1f 100644
--- a/third_party/WebKit/Source/core/inspector/ThreadDebugger.h
+++ b/third_party/WebKit/Source/core/inspector/ThreadDebugger.h
@@ -68,8 +68,8 @@
                                                    v8::Local<v8::Array>,
                                                    int index,
                                                    v8::Local<v8::Value>);
-  static MessageLevel consoleAPITypeToMessageLevel(
-      v8_inspector::V8ConsoleAPIType);
+  static MessageLevel v8MessageLevelToMessageLevel(
+      v8::Isolate::MessageErrorLevel);
 
   v8::Isolate* m_isolate;
 
diff --git a/third_party/WebKit/Source/core/inspector/WorkerThreadDebugger.cpp b/third_party/WebKit/Source/core/inspector/WorkerThreadDebugger.cpp
index 12752767..55707d7 100644
--- a/third_party/WebKit/Source/core/inspector/WorkerThreadDebugger.cpp
+++ b/third_party/WebKit/Source/core/inspector/WorkerThreadDebugger.cpp
@@ -194,7 +194,7 @@
 
 void WorkerThreadDebugger::consoleAPIMessage(
     int contextGroupId,
-    v8_inspector::V8ConsoleAPIType type,
+    v8::Isolate::MessageErrorLevel level,
     const v8_inspector::StringView& message,
     const v8_inspector::StringView& url,
     unsigned lineNumber,
@@ -202,17 +202,20 @@
     v8_inspector::V8StackTrace* stackTrace) {
   DCHECK(m_workerThreads.contains(contextGroupId));
   WorkerThread* workerThread = m_workerThreads.get(contextGroupId);
-
-  if (type == v8_inspector::V8ConsoleAPIType::kClear)
-    workerThread->consoleMessageStorage()->clear();
   std::unique_ptr<SourceLocation> location =
       SourceLocation::create(toCoreString(url), lineNumber, columnNumber,
                              stackTrace ? stackTrace->clone() : nullptr, 0);
   workerThread->workerReportingProxy().reportConsoleMessage(
-      ConsoleAPIMessageSource, consoleAPITypeToMessageLevel(type),
+      ConsoleAPIMessageSource, v8MessageLevelToMessageLevel(level),
       toCoreString(message), location.get());
 }
 
+void WorkerThreadDebugger::consoleClear(int contextGroupId) {
+  DCHECK(m_workerThreads.contains(contextGroupId));
+  WorkerThread* workerThread = m_workerThreads.get(contextGroupId);
+  workerThread->consoleMessageStorage()->clear();
+}
+
 v8::MaybeLocal<v8::Value> WorkerThreadDebugger::memoryInfo(
     v8::Isolate*,
     v8::Local<v8::Context>) {
diff --git a/third_party/WebKit/Source/core/inspector/WorkerThreadDebugger.h b/third_party/WebKit/Source/core/inspector/WorkerThreadDebugger.h
index 1313603..f5e87a2 100644
--- a/third_party/WebKit/Source/core/inspector/WorkerThreadDebugger.h
+++ b/third_party/WebKit/Source/core/inspector/WorkerThreadDebugger.h
@@ -77,12 +77,13 @@
   v8::MaybeLocal<v8::Value> memoryInfo(v8::Isolate*,
                                        v8::Local<v8::Context>) override;
   void consoleAPIMessage(int contextGroupId,
-                         v8_inspector::V8ConsoleAPIType,
+                         v8::Isolate::MessageErrorLevel,
                          const v8_inspector::StringView& message,
                          const v8_inspector::StringView& url,
                          unsigned lineNumber,
                          unsigned columnNumber,
                          v8_inspector::V8StackTrace*) override;
+  void consoleClear(int contextGroupId) override;
 
   int m_pausedContextGroupId;
   WTF::HashMap<int, WorkerThread*> m_workerThreads;
diff --git a/third_party/WebKit/Source/core/layout/LayoutTreeAsText.cpp b/third_party/WebKit/Source/core/layout/LayoutTreeAsText.cpp
index c23b5d93..f945e82 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTreeAsText.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTreeAsText.cpp
@@ -145,7 +145,7 @@
         result.append('\\');
         result.append('x');
         result.append('{');
-        appendUnsignedAsHex(c, result);
+        HexNumber::appendUnsignedAsHex(c, result);
         result.append('}');
       }
     }
diff --git a/third_party/WebKit/Source/core/streams/README.md b/third_party/WebKit/Source/core/streams/README.md
index 9069fd3..44a89f51 100644
--- a/third_party/WebKit/Source/core/streams/README.md
+++ b/third_party/WebKit/Source/core/streams/README.md
@@ -6,9 +6,11 @@
 - ByteLengthQueuingStrategy.js
 - CountQueuingStrategy.js
 - ReadableStream.js
+- ReadableStreamExperimentalPipeTo.js
 - ReadableStreamController.h
 - ReadableStreamOperations.{cpp,h}
 - UnderlyingSourceBase.{cpp,h,idl}
+- WritableStream.js
 
 These files implement ReadableStream using [V8 extras][1]. All new code should
 use this implementation.
diff --git a/third_party/WebKit/Source/core/streams/ReadableStream.js b/third_party/WebKit/Source/core/streams/ReadableStream.js
index b8d33caf..50b37750 100644
--- a/third_party/WebKit/Source/core/streams/ReadableStream.js
+++ b/third_party/WebKit/Source/core/streams/ReadableStream.js
@@ -49,6 +49,7 @@
   const defineProperty = global.Object.defineProperty;
   const hasOwnProperty = v8.uncurryThis(global.Object.hasOwnProperty);
   const callFunction = v8.uncurryThis(global.Function.prototype.call);
+  const applyFunction = v8.uncurryThis(global.Function.prototype.apply);
 
   const TypeError = global.TypeError;
   const RangeError = global.RangeError;
@@ -93,6 +94,9 @@
 
   const errTmplMustBeFunctionOrUndefined = name =>
       `${name} must be a function or undefined`;
+  const errCannotPipeLockedStream = 'Cannot pipe a locked stream';
+  const errCannotPipeToALockedStream = 'Cannot pipe to a locked stream';
+  const errDestinationStreamClosed = 'Destination stream closed';
 
   class ReadableStream {
     constructor() {
@@ -181,6 +185,207 @@
     }
   }
 
+  // TODO(ricea): Move this into the class definition once it ships.
+  function ReadableStream_prototype_pipeThrough({writable, readable}, options) {
+    this.pipeTo(writable, options);
+    return readable;
+  }
+
+  // TODO(ricea): Move this into the class definition once it ships.
+  function ReadableStream_prototype_pipeTo(
+      dest, {preventClose, preventAbort, preventCancel} = {}) {
+    if (!IsReadableStream(this)) {
+      return Promise_reject(new TypeError(streamErrors.illegalInvocation));
+    }
+
+    if (!binding.IsWritableStream(dest)) {
+      // TODO(ricea): Think about having a better error message.
+      return Promise_reject(new TypeError(streamErrors.illegalInvocation));
+    }
+
+    preventClose = Boolean(preventClose);
+    preventAbort = Boolean(preventAbort);
+    preventCancel = Boolean(preventCancel);
+
+    const readable = this;
+    if (IsReadableStreamLocked(readable)) {
+      return Promise_reject(new TypeError(errCannotPipeLockedStream));
+    }
+
+    if (binding.IsWritableStreamLocked(dest)) {
+      return Promise_reject(new TypeError(errCannotPipeToALockedStream));
+    }
+
+    const reader = AcquireReadableStreamDefaultReader(readable);
+    const writer = binding.AcquireWritableStreamDefaultWriter(dest);
+    let shuttingDown = false;
+    const promise = v8.createPromise();
+    let reading = false;
+
+    if (checkInitialState()) {
+      // Need to detect closing and error when we are not reading.
+      thenPromise(reader[_closedPromise], onReaderClosed, readableError);
+      // Need to detect error when we are not writing.
+      thenPromise(
+          binding.getWritableStreamDefaultWriterClosedPromise(writer),
+          undefined, writableError);
+      pump();
+    }
+
+    // Checks the state of the streams and executes the shutdown handlers if
+    // necessary. Returns true if piping can continue.
+    function checkInitialState() {
+      const state = ReadableStreamGetState(readable);
+
+      // Both streams can be errored or closed. To perform the right action the
+      // order of the checks must match the standard.
+      if (state === STATE_ERRORED) {
+        readableError(readable[_storedError]);
+        return false;
+      }
+
+      if (binding.isWritableStreamErrored(dest)) {
+        writableError(binding.getWritableStreamStoredError(dest));
+        return false;
+      }
+
+      if (state === STATE_CLOSED) {
+        readableClosed();
+        return false;
+      }
+
+      if (binding.isWritableStreamClosingOrClosed(dest)) {
+        writableStartedClosed();
+        return false;
+      }
+
+      return true;
+    }
+
+    function pump() {
+      if (shuttingDown) {
+        return;
+      }
+      const desiredSize =
+          binding.WritableStreamDefaultWriterGetDesiredSize(writer);
+      if (desiredSize === null) {
+        writableError(binding.getWritableStreamStoredError(dest));
+      }
+      if (desiredSize <= 0) {
+        thenPromise(
+            binding.getWritableStreamDefaultWriterReadyPromise(writer), pump,
+            writableError);
+        return;
+      }
+      reading = true;
+      // TODO(ricea): Delay reads heuristically when desiredSize is low.
+      thenPromise(
+          ReadableStreamDefaultReaderRead(reader), readFulfilled, readRejected);
+    }
+
+    function readFulfilled({value, done}) {
+      reading = false;
+      if (shuttingDown) {
+        return;
+      }
+      if (done) {
+        readableClosed();
+        return;
+      }
+      const write = binding.WritableStreamDefaultWriterWrite(writer, value);
+      thenPromise(write, undefined, writableError);
+      pump();
+    }
+
+    function readRejected() {
+      reading = false;
+      readableError(readable[_storedError]);
+    }
+
+    // If read() is in progress, then wait for it to tell us that the stream is
+    // closed so that we write all the data before shutdown.
+    function onReaderClosed() {
+      if (!reading) {
+        readableClosed();
+      }
+    }
+
+    // These steps are from "Errors must be propagated forward" in the
+    // standard.
+    function readableError(error) {
+      if (!preventAbort) {
+        shutdownWithAction(
+            binding.WritableStreamAbort, [dest, error], error, true);
+      } else {
+        shutdown(error, true);
+      }
+    }
+
+    // These steps are from "Errors must be propagated backward".
+    function writableError(error) {
+      if (!preventCancel) {
+        shutdownWithAction(
+            ReadableStreamCancel, [readable, error], error, true);
+      } else {
+        shutdown(error, true);
+      }
+    }
+
+    // These steps are from "Closing must be propagated forward".
+    function readableClosed() {
+      if (!preventClose) {
+        shutdownWithAction(
+            binding.WritableStreamDefaultWriterCloseWithErrorPropagation,
+            [writer]);
+      } else {
+        shutdown();
+      }
+    }
+
+    // These steps are from "Closing must be propagated backward".
+    function writableStartedClosed() {
+      const destClosed = new TypeError(errDestinationStreamClosed);
+      if (!preventCancel) {
+        shutdownWithAction(
+            ReadableStreamCancel, [readable, destClosed], destClosed, true);
+      } else {
+        shutdown(destClosed, true);
+      }
+    }
+
+    function shutdownWithAction(
+        action, args, originalError = undefined, errorGiven = false) {
+      if (shuttingDown) {
+        return;
+      }
+      shuttingDown = true;
+      const p = applyFunction(action, undefined, args);
+      thenPromise(
+          p, () => finalize(originalError, errorGiven),
+          newError => finalize(newError, true));
+    }
+
+    function shutdown(error = undefined, errorGiven = false) {
+      if (shuttingDown) {
+        return;
+      }
+      shuttingDown = true;
+      finalize(error, errorGiven);
+    }
+
+    function finalize(error, errorGiven) {
+      binding.WritableStreamDefaultWriterRelease(writer);
+      ReadableStreamReaderGenericRelease(reader);
+      if (errorGiven) {
+        v8.rejectPromise(promise, error);
+      } else {
+        v8.resolvePromise(promise, undefined);
+      }
+    }
+
+    return promise;
+  }
+
   class ReadableStreamDefaultController {
     constructor(stream, underlyingSource, size, highWaterMark, isExternallyControlled) {
       if (IsReadableStream(stream) === false) {
@@ -973,4 +1178,9 @@
         return new ReadableStream(
             underlyingSource, strategy, createWithExternalControllerSentinel);
       };
+
+  // Temporary exports while pipeTo() and pipeThrough() are behind flags
+  binding.ReadableStream_prototype_pipeThrough =
+      ReadableStream_prototype_pipeThrough;
+  binding.ReadableStream_prototype_pipeTo = ReadableStream_prototype_pipeTo;
 });
diff --git a/third_party/WebKit/Source/core/streams/ReadableStreamExperimentalPipeTo.js b/third_party/WebKit/Source/core/streams/ReadableStreamExperimentalPipeTo.js
new file mode 100644
index 0000000..870c18b7
--- /dev/null
+++ b/third_party/WebKit/Source/core/streams/ReadableStreamExperimentalPipeTo.js
@@ -0,0 +1,25 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Include pipeTo() and pipeThrough() on the global ReadableStream object when
+// the experimental flag is enabled.
+
+(function(global, binding, v8) {
+  'use strict';
+
+  const defineProperty = global.Object.defineProperty;
+  defineProperty(global.ReadableStream.prototype, 'pipeThrough', {
+    value: binding.ReadableStream_prototype_pipeThrough,
+    enumerable: false,
+    configurable: true,
+    writable: true
+  });
+
+  defineProperty(global.ReadableStream.prototype, 'pipeTo', {
+    value: binding.ReadableStream_prototype_pipeTo,
+    enumerable: false,
+    configurable: true,
+    writable: true
+  });
+});
diff --git a/third_party/WebKit/Source/core/streams/WritableStream.js b/third_party/WebKit/Source/core/streams/WritableStream.js
index e987cedd..38f7adc 100644
--- a/third_party/WebKit/Source/core/streams/WritableStream.js
+++ b/third_party/WebKit/Source/core/streams/WritableStream.js
@@ -364,6 +364,26 @@
     }
   }
 
+  // Functions to expose internals for ReadableStream.pipeTo. These are not
+  // part of the standard.
+  function isWritableStreamErrored(stream) {
+    TEMP_ASSERT(
+        IsWritableStream(stream), '! IsWritableStream(stream) is true.');
+    return stream[_state] === ERRORED;
+  }
+
+  function isWritableStreamClosingOrClosed(stream) {
+    TEMP_ASSERT(
+        IsWritableStream(stream), '! IsWritableStream(stream) is true.');
+    return stream[_state] === CLOSING || stream[_state] === CLOSED;
+  }
+
+  function getWritableStreamStoredError(stream) {
+    TEMP_ASSERT(
+        IsWritableStream(stream), '! IsWritableStream(stream) is true.');
+    return stream[_storedError];
+  }
+
   class WritableStreamDefaultWriter {
     constructor(stream) {
       if (!IsWritableStream(stream)) {
@@ -504,6 +524,20 @@
     return stream[_pendingCloseRequest];
   }
 
+  function WritableStreamDefaultWriterCloseWithErrorPropagation(writer) {
+    const stream = writer[_ownerWritableStream];
+    TEMP_ASSERT(stream !== undefined, 'stream is not undefined.');
+    const state = stream[_state];
+    if (state === CLOSING || state === CLOSED) {
+      return Promise_resolve(undefined);
+    }
+    if (state === ERRORED) {
+      return Promise_reject(stream[_storedError]);
+    }
+    TEMP_ASSERT(state === WRITABLE, 'state is "writable".');
+    return WritableStreamDefaultWriterClose(writer);
+  }
+
   function WritableStreamDefaultWriterGetDesiredSize(writer) {
     const stream = writer[_ownerWritableStream];
     const state = stream[_state];
@@ -563,6 +597,22 @@
     return promise;
   }
 
+  // Functions to expose internals for ReadableStream.pipeTo. These do not
+  // appear in the standard.
+  function getWritableStreamDefaultWriterClosedPromise(writer) {
+    TEMP_ASSERT(
+        IsWritableStreamDefaultWriter(writer),
+        'writer is a WritableStreamDefaultWriter.');
+    return writer[_closedPromise];
+  }
+
+  function getWritableStreamDefaultWriterReadyPromise(writer) {
+    TEMP_ASSERT(
+        IsWritableStreamDefaultWriter(writer),
+        'writer is a WritableStreamDefaultWriter.');
+    return writer[_readyPromise];
+  }
+
   class WritableStreamDefaultController {
     constructor(stream, underlyingSink, size, highWaterMark) {
       if (!IsWritableStream(stream)) {
@@ -934,4 +984,25 @@
   });
 
   // TODO(ricea): Exports to Blink
+
+  // Exports for ReadableStream
+  binding.AcquireWritableStreamDefaultWriter =
+      AcquireWritableStreamDefaultWriter;
+  binding.IsWritableStream = IsWritableStream;
+  binding.isWritableStreamClosingOrClosed = isWritableStreamClosingOrClosed;
+  binding.isWritableStreamErrored = isWritableStreamErrored;
+  binding.IsWritableStreamLocked = IsWritableStreamLocked;
+  binding.WritableStreamAbort = WritableStreamAbort;
+  binding.WritableStreamDefaultWriterCloseWithErrorPropagation =
+      WritableStreamDefaultWriterCloseWithErrorPropagation;
+  binding.getWritableStreamDefaultWriterClosedPromise =
+      getWritableStreamDefaultWriterClosedPromise;
+  binding.WritableStreamDefaultWriterGetDesiredSize =
+      WritableStreamDefaultWriterGetDesiredSize;
+  binding.getWritableStreamDefaultWriterReadyPromise =
+      getWritableStreamDefaultWriterReadyPromise;
+  binding.WritableStreamDefaultWriterRelease =
+      WritableStreamDefaultWriterRelease;
+  binding.WritableStreamDefaultWriterWrite = WritableStreamDefaultWriterWrite;
+  binding.getWritableStreamStoredError = getWritableStreamStoredError;
 });
diff --git a/third_party/WebKit/Source/modules/bluetooth/BluetoothUUID.cpp b/third_party/WebKit/Source/modules/bluetooth/BluetoothUUID.cpp
index 3e284b4..47c782e 100644
--- a/third_party/WebKit/Source/modules/bluetooth/BluetoothUUID.cpp
+++ b/third_party/WebKit/Source/modules/bluetooth/BluetoothUUID.cpp
@@ -366,8 +366,9 @@
 String BluetoothUUID::canonicalUUID(unsigned alias) {
   StringBuilder builder;
   builder.reserveCapacity(36 /* 36 chars or 128 bits, length of a UUID */);
-  appendUnsignedAsHexFixedSize(
-      alias, builder, 8 /* 8 chars or 32 bits, prefix length */, Lowercase);
+  HexNumber::appendUnsignedAsHexFixedSize(
+      alias, builder, 8 /* 8 chars or 32 bits, prefix length */,
+      HexNumber::Lowercase);
 
   builder.append("-0000-1000-8000-00805f9b34fb");
   return builder.toString();
diff --git a/third_party/WebKit/Source/platform/BUILD.gn b/third_party/WebKit/Source/platform/BUILD.gn
index 6d9c382..6cc8afe 100644
--- a/third_party/WebKit/Source/platform/BUILD.gn
+++ b/third_party/WebKit/Source/platform/BUILD.gn
@@ -1185,6 +1185,7 @@
     "scheduler/base/intrusive_heap.h",
     "scheduler/base/lazy_now.cc",
     "scheduler/base/lazy_now.h",
+    "scheduler/base/moveable_auto_lock.h",
     "scheduler/base/pollable_thread_safe_flag.cc",
     "scheduler/base/pollable_thread_safe_flag.h",
     "scheduler/base/queueing_time_estimator.cc",
diff --git a/third_party/WebKit/Source/platform/graphics/Color.cpp b/third_party/WebKit/Source/platform/graphics/Color.cpp
index 3b406bf..c82a1e0 100644
--- a/third_party/WebKit/Source/platform/graphics/Color.cpp
+++ b/third_party/WebKit/Source/platform/graphics/Color.cpp
@@ -231,9 +231,9 @@
     StringBuilder builder;
     builder.reserveCapacity(7);
     builder.append('#');
-    appendByteAsHex(red(), builder, Lowercase);
-    appendByteAsHex(green(), builder, Lowercase);
-    appendByteAsHex(blue(), builder, Lowercase);
+    HexNumber::appendByteAsHex(red(), builder, HexNumber::Lowercase);
+    HexNumber::appendByteAsHex(green(), builder, HexNumber::Lowercase);
+    HexNumber::appendByteAsHex(blue(), builder, HexNumber::Lowercase);
     return builder.toString();
   }
 
diff --git a/third_party/WebKit/Source/platform/graphics/ImageBuffer.cpp b/third_party/WebKit/Source/platform/graphics/ImageBuffer.cpp
index 4937207..da8c238 100644
--- a/third_party/WebKit/Source/platform/graphics/ImageBuffer.cpp
+++ b/third_party/WebKit/Source/platform/graphics/ImageBuffer.cpp
@@ -550,13 +550,19 @@
   sk_sp<SkImage> image =
       m_surface->newImageSnapshot(PreferNoAcceleration, SnapshotReasonPaint);
 
+  // image can be null if alloaction failed in which case we should just
+  // abort the surface switch to reatain the old surface which is still
+  // functional.
+  if (!image)
+    return;
+
   if (surface->isRecording()) {
     // Using a GPU-backed image with RecordingImageBufferSurface
     // will fail at playback time.
     image = image->makeNonTextureImage();
   }
-
   surface->canvas()->drawImage(image.get(), 0, 0);
+
   surface->setImageBuffer(this);
   if (m_client)
     m_client->restoreCanvasMatrixClipStack(surface->canvas());
diff --git a/third_party/WebKit/Source/platform/graphics/LoggingCanvas.cpp b/third_party/WebKit/Source/platform/graphics/LoggingCanvas.cpp
index 8de896ce..137e1847 100644
--- a/third_party/WebKit/Source/platform/graphics/LoggingCanvas.cpp
+++ b/third_party/WebKit/Source/platform/graphics/LoggingCanvas.cpp
@@ -326,7 +326,7 @@
   // #AARRGGBB.
   Vector<LChar, 9> result;
   result.push_back('#');
-  appendUnsignedAsHex(color, result);
+  HexNumber::appendUnsignedAsHex(color, result);
   return String(result.data(), result.size());
 }
 
diff --git a/third_party/WebKit/Source/platform/network/FormDataEncoder.cpp b/third_party/WebKit/Source/platform/network/FormDataEncoder.cpp
index d45201e..47cb531 100644
--- a/third_party/WebKit/Source/platform/network/FormDataEncoder.cpp
+++ b/third_party/WebKit/Source/platform/network/FormDataEncoder.cpp
@@ -48,7 +48,7 @@
 
 static inline void appendPercentEncoded(Vector<char>& buffer, unsigned char c) {
   append(buffer, '%');
-  appendByteAsHex(c, buffer);
+  HexNumber::appendByteAsHex(c, buffer);
 }
 
 static void appendQuotedString(Vector<char>& buffer, const CString& string) {
diff --git a/third_party/WebKit/Source/platform/scheduler/base/moveable_auto_lock.h b/third_party/WebKit/Source/platform/scheduler/base/moveable_auto_lock.h
new file mode 100644
index 0000000..ac2b8a8
--- /dev/null
+++ b/third_party/WebKit/Source/platform/scheduler/base/moveable_auto_lock.h
@@ -0,0 +1,41 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_BASE_MOVEABLE_AUTO_LOCK_H_
+#define THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_BASE_MOVEABLE_AUTO_LOCK_H_
+
+#include "base/synchronization/lock.h"
+
+namespace blink {
+namespace scheduler {
+
+class MoveableAutoLock {
+ public:
+  explicit MoveableAutoLock(base::Lock& lock) : lock_(lock), moved_(false) {
+    lock_.Acquire();
+  }
+
+  explicit MoveableAutoLock(MoveableAutoLock&& other)
+      : lock_(other.lock_), moved_(other.moved_) {
+    lock_.AssertAcquired();
+    other.moved_ = true;
+  }
+
+  ~MoveableAutoLock() {
+    if (moved_)
+      return;
+    lock_.AssertAcquired();
+    lock_.Release();
+  }
+
+ private:
+  base::Lock& lock_;
+  bool moved_;
+  DISALLOW_COPY_AND_ASSIGN(MoveableAutoLock);
+};
+
+}  // namespace scheduler
+}  // namespace blink
+
+#endif  // THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_BASE_MOVEABLE_AUTO_LOCK_H_
diff --git a/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.cc b/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.cc
index 94694b6..762f079 100644
--- a/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.cc
+++ b/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.cc
@@ -336,7 +336,7 @@
         RunsTasksOnCurrentThread() &&
         (!IsQueueEnabled() || main_thread_only().current_fence);
     any_thread().task_queue_manager->OnQueueHasIncomingImmediateWork(
-        this, queue_is_blocked);
+        this, sequence_number, queue_is_blocked);
     any_thread().time_domain->OnQueueHasImmediateWork(this);
   }
   any_thread().immediate_incoming_queue.emplace_back(
@@ -678,6 +678,16 @@
          main_thread_only().current_fence;
 }
 
+bool TaskQueueImpl::CouldTaskRun(EnqueueOrder enqueue_order) const {
+  if (!IsQueueEnabled())
+    return false;
+
+  if (!main_thread_only().current_fence)
+    return true;
+
+  return enqueue_order < main_thread_only().current_fence;
+}
+
 EnqueueOrder TaskQueueImpl::GetFenceForTest() const {
   return main_thread_only().current_fence;
 }
diff --git a/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.h b/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.h
index 209a86b2..8381157 100644
--- a/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.h
+++ b/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.h
@@ -140,6 +140,11 @@
   const char* GetName() const override;
   QueueType GetQueueType() const override;
 
+  // Returns true if a (potentially hypothetical) task with the specified
+  // |enqueue_order| could run on the queue. Must be called from the main
+  // thread.
+  bool CouldTaskRun(EnqueueOrder enqueue_order) const;
+
   // Must only be called from the thread this task queue was created on.
   void ReloadImmediateWorkQueueIfEmpty();
 
diff --git a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager.cc b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager.cc
index 16dc908..e42fee1 100644
--- a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager.cc
+++ b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager.cc
@@ -75,12 +75,10 @@
                                      "TaskQueueManager", this);
   selector_.SetTaskQueueSelectorObserver(this);
 
-  from_main_thread_immediate_do_work_closure_ =
-      base::Bind(&TaskQueueManager::DoWork, weak_factory_.GetWeakPtr(),
-                 base::TimeTicks(), true);
-  from_other_thread_immediate_do_work_closure_ =
-      base::Bind(&TaskQueueManager::DoWork, weak_factory_.GetWeakPtr(),
-                 base::TimeTicks(), false);
+  delayed_do_work_closure_ =
+      base::Bind(&TaskQueueManager::DoWork, weak_factory_.GetWeakPtr(), true);
+  immediate_do_work_closure_ =
+      base::Bind(&TaskQueueManager::DoWork, weak_factory_.GetWeakPtr(), false);
 
   // TODO(alexclarke): Change this to be a parameter that's passed in.
   RegisterTimeDomain(real_time_domain_.get());
@@ -100,7 +98,10 @@
   delegate_->RemoveNestingObserver(this);
 }
 
-TaskQueueManager::AnyThread::AnyThread() : other_thread_pending_wakeup(false) {}
+TaskQueueManager::AnyThread::AnyThread()
+    : do_work_running_count(0),
+      immediate_do_work_posted_count(0),
+      is_nested(false) {}
 
 void TaskQueueManager::RegisterTimeDomain(TimeDomain* time_domain) {
   time_domains_.insert(time_domain);
@@ -155,14 +156,13 @@
 }
 
 void TaskQueueManager::ReloadEmptyWorkQueues(
-    const std::unordered_set<internal::TaskQueueImpl*>& queues_to_reload)
-    const {
+    const IncomingImmediateWorkMap& queues_to_reload) const {
   // There are two cases where a queue needs reloading.  First, it might be
   // completely empty and we've just posted a task (this method handles that
   // case). Secondly if the work queue becomes empty in when calling
   // WorkQueue::TakeTaskFromWorkQueue (handled there).
-  for (internal::TaskQueueImpl* queue : queues_to_reload) {
-    queue->ReloadImmediateWorkQueueIfEmpty();
+  for (const auto& pair : queues_to_reload) {
+    pair.first->ReloadImmediateWorkQueueIfEmpty();
   }
 }
 
@@ -183,59 +183,49 @@
 void TaskQueueManager::OnBeginNestedMessageLoop() {
   // We just entered a nested message loop, make sure there's a DoWork posted or
   // the system will grind to a halt.
-  delegate_->PostTask(FROM_HERE, from_main_thread_immediate_do_work_closure_);
+  {
+    base::AutoLock lock(any_thread_lock_);
+    any_thread().immediate_do_work_posted_count++;
+    any_thread().is_nested = true;
+  }
+  delegate_->PostTask(FROM_HERE, immediate_do_work_closure_);
 }
 
 void TaskQueueManager::OnQueueHasIncomingImmediateWork(
     internal::TaskQueueImpl* queue,
+    internal::EnqueueOrder enqueue_order,
     bool queue_is_blocked) {
-  bool on_main_thread = delegate_->BelongsToCurrentThread();
-
-  {
-    base::AutoLock lock(any_thread_lock_);
-    any_thread().has_incoming_immediate_work.insert(queue);
-
-    if (queue_is_blocked)
-      return;
-
-    // De-duplicate DoWork posts.
-    if (on_main_thread) {
-      if (!main_thread_pending_wakeups_.insert(base::TimeTicks()).second)
-        return;
-    } else {
-      if (any_thread().other_thread_pending_wakeup)
-        return;
-      any_thread().other_thread_pending_wakeup = true;
-    }
-  }
-
-  if (on_main_thread) {
-    delegate_->PostTask(FROM_HERE, from_main_thread_immediate_do_work_closure_);
-  } else {
-    delegate_->PostTask(FROM_HERE,
-                        from_other_thread_immediate_do_work_closure_);
-  }
+  MoveableAutoLock lock(any_thread_lock_);
+  any_thread().has_incoming_immediate_work.insert(
+      std::make_pair(queue, enqueue_order));
+  if (!queue_is_blocked)
+    MaybeScheduleImmediateWorkLocked(FROM_HERE, std::move(lock));
 }
 
 void TaskQueueManager::MaybeScheduleImmediateWork(
     const tracked_objects::Location& from_here) {
-  bool on_main_thread = delegate_->BelongsToCurrentThread();
-  // De-duplicate DoWork posts.
-  if (on_main_thread) {
-    if (!main_thread_pending_wakeups_.insert(base::TimeTicks()).second) {
+  MoveableAutoLock lock(any_thread_lock_);
+  MaybeScheduleImmediateWorkLocked(from_here, std::move(lock));
+}
+
+void TaskQueueManager::MaybeScheduleImmediateWorkLocked(
+    const tracked_objects::Location& from_here,
+    MoveableAutoLock&& lock) {
+  {
+    MoveableAutoLock auto_lock(std::move(lock));
+    // Unless we're nested, try to avoid posting redundant DoWorks.
+    if (!any_thread().is_nested &&
+        (any_thread().do_work_running_count == 1 ||
+         any_thread().immediate_do_work_posted_count > 0)) {
       return;
     }
-    delegate_->PostTask(from_here, from_main_thread_immediate_do_work_closure_);
-  } else {
-    {
-      base::AutoLock lock(any_thread_lock_);
-      if (any_thread().other_thread_pending_wakeup)
-        return;
-      any_thread().other_thread_pending_wakeup = true;
-    }
-    delegate_->PostTask(from_here,
-                        from_other_thread_immediate_do_work_closure_);
+
+    any_thread().immediate_do_work_posted_count++;
   }
+
+  TRACE_EVENT0(disabled_by_default_tracing_category_,
+               "TaskQueueManager::MaybeScheduleImmediateWorkLocked::PostTask");
+  delegate_->PostTask(from_here, immediate_do_work_closure_);
 }
 
 void TaskQueueManager::MaybeScheduleDelayedWork(
@@ -244,54 +234,70 @@
     base::TimeDelta delay) {
   DCHECK(main_thread_checker_.CalledOnValidThread());
   DCHECK_GE(delay, base::TimeDelta());
+  {
+    base::AutoLock lock(any_thread_lock_);
 
-  // If there's a pending immediate DoWork then we rely on
-  // TryAdvanceTimeDomains getting the TimeDomain to call
-  // MaybeScheduleDelayedWork again when the immediate DoWork is complete.
-  if (main_thread_pending_wakeups_.find(base::TimeTicks()) !=
-      main_thread_pending_wakeups_.end()) {
-    return;
+    // Unless we're nested, don't post a delayed DoWork if there's an immediate
+    // DoWork in flight or we're inside a DoWork. We can rely on DoWork posting
+    // a delayed continuation as needed.
+    if (!any_thread().is_nested &&
+        (any_thread().immediate_do_work_posted_count > 0 ||
+         any_thread().do_work_running_count == 1)) {
+      return;
+    }
   }
+
   // De-duplicate DoWork posts.
   base::TimeTicks run_time = now + delay;
-  if (!main_thread_pending_wakeups_.empty() &&
-      *main_thread_pending_wakeups_.begin() <= run_time) {
+  if (next_scheduled_delayed_do_work_time_ <= run_time &&
+      !next_scheduled_delayed_do_work_time_.is_null())
     return;
-  }
-  main_thread_pending_wakeups_.insert(run_time);
+
+  TRACE_EVENT1(disabled_by_default_tracing_category_,
+               "TaskQueueManager::MaybeScheduleDelayedWork::PostDelayedTask",
+               "delay_ms", delay.InMillisecondsF());
+
+  cancelable_delayed_do_work_closure_.Reset(delayed_do_work_closure_);
+  next_scheduled_delayed_do_work_time_ = run_time;
   delegate_->PostDelayedTask(
-      from_here, base::Bind(&TaskQueueManager::DoWork,
-                            weak_factory_.GetWeakPtr(), run_time, true),
-      delay);
+      from_here, cancelable_delayed_do_work_closure_.callback(), delay);
 }
 
-void TaskQueueManager::DoWork(base::TimeTicks run_time, bool from_main_thread) {
+void TaskQueueManager::DoWork(bool delayed) {
   DCHECK(main_thread_checker_.CalledOnValidThread());
-  TRACE_EVENT1(tracing_category_, "TaskQueueManager::DoWork",
-               "from_main_thread", from_main_thread);
+  TRACE_EVENT1(tracing_category_, "TaskQueueManager::DoWork", "delayed",
+               delayed);
 
-  if (from_main_thread) {
-    main_thread_pending_wakeups_.erase(run_time);
-  } else {
-    base::AutoLock lock(any_thread_lock_);
-    any_thread().other_thread_pending_wakeup = false;
-  }
-
-  // Posting a DoWork while a DoWork is running leads to spurious DoWorks.
-  main_thread_pending_wakeups_.insert(base::TimeTicks());
-
+  LazyNow lazy_now(real_time_domain()->CreateLazyNow());
   bool is_nested = delegate_->IsNested();
   if (!is_nested)
     queues_to_delete_.clear();
 
-  LazyNow lazy_now(real_time_domain()->CreateLazyNow());
-  WakeupReadyDelayedQueues(&lazy_now);
+  // This must be done before running any tasks because they could invoke a
+  // nested message loop and we risk having a stale
+  // |next_scheduled_delayed_do_work_time_|.
+  if (delayed)
+    next_scheduled_delayed_do_work_time_ = base::TimeTicks();
 
   for (int i = 0; i < work_batch_size_; i++) {
-    std::unordered_set<internal::TaskQueueImpl*> queues_to_reload;
+    IncomingImmediateWorkMap queues_to_reload;
 
     {
       base::AutoLock lock(any_thread_lock_);
+      if (i == 0) {
+        any_thread().do_work_running_count++;
+
+        if (!delayed) {
+          any_thread().immediate_do_work_posted_count--;
+          DCHECK_GE(any_thread().immediate_do_work_posted_count, 0);
+        }
+      } else {
+        // Ideally we'd have an OnNestedMessageloopExit observer, but in it's
+        // absence we may need to clear this flag after running a task (which
+        // ran a nested messageloop).
+        any_thread().is_nested = is_nested;
+      }
+      DCHECK_EQ(any_thread().is_nested, delegate_->IsNested());
       std::swap(queues_to_reload, any_thread().has_incoming_immediate_work);
     }
 
@@ -299,10 +305,13 @@
     // avoid a lock order inversion.
     ReloadEmptyWorkQueues(queues_to_reload);
 
-    internal::WorkQueue* work_queue;
+    WakeupReadyDelayedQueues(&lazy_now);
+
+    internal::WorkQueue* work_queue = nullptr;
     if (!SelectWorkQueueToService(&work_queue))
       break;
 
+    // NB this may unregister |work_queue|.
     base::TimeTicks time_after_task;
     switch (ProcessTaskFromWorkQueue(work_queue, is_nested, lazy_now,
                                      &time_after_task)) {
@@ -315,11 +324,8 @@
         return;  // The TaskQueueManager got deleted, we must bail out.
     }
 
-    work_queue = nullptr;  // The queue may have been unregistered.
-
     lazy_now = time_after_task.is_null() ? real_time_domain()->CreateLazyNow()
                                          : LazyNow(time_after_task);
-    WakeupReadyDelayedQueues(&lazy_now);
 
     // Only run a single task per batch in nested run loops so that we can
     // properly exit the nested loop when someone calls RunLoop::Quit().
@@ -327,45 +333,104 @@
       break;
   }
 
-  main_thread_pending_wakeups_.erase(base::TimeTicks());
-
   // TODO(alexclarke): Consider refactoring the above loop to terminate only
   // when there's no more work left to be done, rather than posting a
   // continuation task.
-  base::Optional<base::TimeDelta> next_delay =
-      ComputeDelayTillNextTask(&lazy_now);
 
-  if (!next_delay)
-    return;
+  {
+    MoveableAutoLock lock(any_thread_lock_);
+    base::Optional<base::TimeDelta> next_delay =
+        ComputeDelayTillNextTaskLocked(&lazy_now);
 
-  base::TimeDelta delay = next_delay.value();
-  if (delay.is_zero()) {
-    MaybeScheduleImmediateWork(FROM_HERE);
-  } else {
-    MaybeScheduleDelayedWork(FROM_HERE, lazy_now.Now(), delay);
+    any_thread().do_work_running_count--;
+    DCHECK_GE(any_thread().do_work_running_count, 0);
+
+    any_thread().is_nested = is_nested;
+    DCHECK_EQ(any_thread().is_nested, delegate_->IsNested());
+
+    PostDoWorkContinuationLocked(next_delay, &lazy_now, std::move(lock));
   }
 }
 
-base::Optional<base::TimeDelta> TaskQueueManager::ComputeDelayTillNextTask(
-    LazyNow* lazy_now) {
+void TaskQueueManager::PostDoWorkContinuationLocked(
+    base::Optional<base::TimeDelta> next_delay,
+    LazyNow* lazy_now,
+    MoveableAutoLock&& lock) {
   DCHECK(main_thread_checker_.CalledOnValidThread());
+  base::TimeDelta delay;
 
-  std::unordered_set<internal::TaskQueueImpl*> queues_to_reload;
   {
-    base::AutoLock lock(any_thread_lock_);
-    std::swap(queues_to_reload, any_thread().has_incoming_immediate_work);
+    MoveableAutoLock auto_lock(std::move(lock));
+
+    // If there are no tasks left then we don't need to post a continuation.
+    if (!next_delay) {
+      // If there's a pending delayed DoWork, cancel it because it's not needed.
+      if (!next_scheduled_delayed_do_work_time_.is_null()) {
+        next_scheduled_delayed_do_work_time_ = base::TimeTicks();
+        cancelable_delayed_do_work_closure_.Cancel();
+      }
+      return;
+    }
+
+    // If an immediate DoWork is posted, we don't need to post a continuation.
+    if (any_thread().immediate_do_work_posted_count > 0)
+      return;
+
+    delay = next_delay.value();
+
+    // This isn't supposed to happen, but in case it does convert to
+    // non-delayed.
+    if (delay < base::TimeDelta())
+      delay = base::TimeDelta();
+
+    if (delay.is_zero()) {
+      // If a delayed DoWork is pending then we don't need to post a
+      // continuation because it should run immediately.
+      if (!next_scheduled_delayed_do_work_time_.is_null() &&
+          next_scheduled_delayed_do_work_time_ <= lazy_now->Now()) {
+        return;
+      }
+
+      any_thread().immediate_do_work_posted_count++;
+    } else {
+      base::TimeTicks run_time = lazy_now->Now() + delay;
+      if (next_scheduled_delayed_do_work_time_ == run_time)
+        return;
+
+      next_scheduled_delayed_do_work_time_ = run_time;
+    }
   }
 
-  // It's important we call ReloadEmptyWorkQueues out side of the lock to
-  // avoid a lock order inversion.
-  ReloadEmptyWorkQueues(queues_to_reload);
+  // We avoid holding |any_thread_lock_| while posting the task.
+  if (delay.is_zero()) {
+    delegate_->PostTask(FROM_HERE, immediate_do_work_closure_);
+  } else {
+    cancelable_delayed_do_work_closure_.Reset(delayed_do_work_closure_);
+    delegate_->PostDelayedTask(
+        FROM_HERE, cancelable_delayed_do_work_closure_.callback(), delay);
+  }
+}
+
+base::Optional<base::TimeDelta>
+TaskQueueManager::ComputeDelayTillNextTaskLocked(LazyNow* lazy_now) {
+  DCHECK(main_thread_checker_.CalledOnValidThread());
+
+  // Unfortunately because |any_thread_lock_| is held it's not safe to call
+  // ReloadEmptyWorkQueues here (possible lock order inversion), however this
+  // check is equavalent to calling ReloadEmptyWorkQueues first.
+  for (const auto& pair : any_thread().has_incoming_immediate_work) {
+    if (pair.first->CouldTaskRun(pair.second))
+      return base::TimeDelta();
+  }
 
   // If the selector has non-empty queues we trivially know there is immediate
   // work to be done.
   if (!selector_.EnabledWorkQueuesEmpty())
     return base::TimeDelta();
 
-  // Otherwise we need to find the shortest delay, if any.
+  // Otherwise we need to find the shortest delay, if any.  NB we don't need to
+  // call WakeupReadyDelayedQueues because it's assumed DelayTillNextTask will
+  // return base::TimeDelta>() if the delayed task is due to run now.
   base::Optional<base::TimeDelta> next_continuation;
   for (TimeDomain* time_domain : time_domains_) {
     base::Optional<base::TimeDelta> continuation =
@@ -578,10 +643,15 @@
   state->EndArray();
   {
     base::AutoLock lock(any_thread_lock_);
+    state->SetBoolean("is_nested", any_thread().is_nested);
+    state->SetInteger("do_work_running_count",
+                      any_thread().do_work_running_count);
+    state->SetInteger("immediate_do_work_posted_count",
+                      any_thread().immediate_do_work_posted_count);
+
     state->BeginArray("has_incoming_immediate_work");
-    for (internal::TaskQueueImpl* task_queue :
-         any_thread().has_incoming_immediate_work) {
-      state->AppendString(task_queue->GetName());
+    for (const auto& pair : any_thread().has_incoming_immediate_work) {
+      state->AppendString(pair.first->GetName());
     }
     state->EndArray();
   }
diff --git a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager.h b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager.h
index 8016827..21c4aedc 100644
--- a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager.h
+++ b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager.h
@@ -8,6 +8,7 @@
 #include <map>
 
 #include "base/atomic_sequence_num.h"
+#include "base/cancelable_callback.h"
 #include "base/debug/task_annotator.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
@@ -16,6 +17,7 @@
 #include "base/synchronization/lock.h"
 #include "base/threading/thread_checker.h"
 #include "platform/scheduler/base/enqueue_order.h"
+#include "platform/scheduler/base/moveable_auto_lock.h"
 #include "platform/scheduler/base/task_queue_impl.h"
 #include "platform/scheduler/base/task_queue_selector.h"
 
@@ -159,9 +161,6 @@
   };
 
   // Unregisters a TaskQueue previously created by |NewTaskQueue()|.
-  // NOTE we have to flush the queue from |newly_updatable_| which means as a
-  // side effect MoveNewlyUpdatableQueuesIntoUpdatableQueueSet is called by this
-  // function.
   void UnregisterTaskQueue(scoped_refptr<internal::TaskQueueImpl> task_queue);
 
   // TaskQueueSelector::Observer implementation:
@@ -176,7 +175,12 @@
   void DidQueueTask(const internal::TaskQueueImpl::Task& pending_task);
 
   // Use the selector to choose a pending task and run it.
-  void DoWork(base::TimeTicks run_time, bool from_main_thread);
+  void DoWork(bool delayed);
+
+  // Post a DoWork continuation if |next_delay| is not empty.
+  void PostDoWorkContinuationLocked(base::Optional<base::TimeDelta> next_delay,
+                                    LazyNow* lazy_now,
+                                    MoveableAutoLock&& lock);
 
   // Delayed Tasks with run_times <= Now() are enqueued onto the work queue and
   // reloads any empty work queues.
@@ -212,7 +216,8 @@
 
   // Calls DelayTillNextTask on all time domains and returns the smallest delay
   // requested if any.
-  base::Optional<base::TimeDelta> ComputeDelayTillNextTask(LazyNow* lazy_now);
+  base::Optional<base::TimeDelta> ComputeDelayTillNextTaskLocked(
+      LazyNow* lazy_now);
 
   void MaybeRecordTaskDelayHistograms(
       const internal::TaskQueueImpl::Task& pending_task,
@@ -222,16 +227,24 @@
   AsValueWithSelectorResult(bool should_run,
                             internal::WorkQueue* selected_work_queue) const;
 
+  void MaybeScheduleImmediateWorkLocked(
+      const tracked_objects::Location& from_here,
+      MoveableAutoLock&& lock);
+
   // Adds |queue| to |any_thread().has_incoming_immediate_work_| and if
   // |queue_is_blocked| is false it makes sure a DoWork is posted.
   // Can be called from any thread.
   void OnQueueHasIncomingImmediateWork(internal::TaskQueueImpl* queue,
+                                       internal::EnqueueOrder enqueue_order,
                                        bool queue_is_blocked);
 
+  using IncomingImmediateWorkMap =
+      std::unordered_map<internal::TaskQueueImpl*, internal::EnqueueOrder>;
+
   // Calls |ReloadImmediateWorkQueueIfEmpty| on all queues in
   // |queues_to_reload|.
-  void ReloadEmptyWorkQueues(const std::unordered_set<internal::TaskQueueImpl*>&
-                                 queues_to_reload) const;
+  void ReloadEmptyWorkQueues(
+      const IncomingImmediateWorkMap& queues_to_reload) const;
 
   std::set<TimeDomain*> time_domains_;
   std::unique_ptr<RealTimeDomain> real_time_domain_;
@@ -249,22 +262,21 @@
   scoped_refptr<TaskQueueManagerDelegate> delegate_;
   internal::TaskQueueSelector selector_;
 
-  base::Closure from_main_thread_immediate_do_work_closure_;
-  base::Closure from_other_thread_immediate_do_work_closure_;
+  base::Closure immediate_do_work_closure_;
+  base::Closure delayed_do_work_closure_;
+  base::CancelableClosure cancelable_delayed_do_work_closure_;
 
   bool task_was_run_on_quiescence_monitored_queue_;
 
-  // To reduce locking overhead we track pending calls to DoWork separately for
-  // the main thread and other threads.
-  std::set<base::TimeTicks> main_thread_pending_wakeups_;
-
   struct AnyThread {
     AnyThread();
 
-    // Set of task queues with newly available work on the incoming queue.
-    std::unordered_set<internal::TaskQueueImpl*> has_incoming_immediate_work;
+    // Task queues with newly available work on the incoming queue.
+    IncomingImmediateWorkMap has_incoming_immediate_work;
 
-    bool other_thread_pending_wakeup;
+    int do_work_running_count;
+    int immediate_do_work_posted_count;
+    bool is_nested;  // Whether or not the message loop is currently nested.
   };
 
   // TODO(alexclarke): Add a MainThreadOnly struct too.
@@ -281,6 +293,8 @@
     return any_thread_;
   }
 
+  base::TimeTicks next_scheduled_delayed_do_work_time_;
+
   bool record_task_delay_histograms_;
 
   int work_batch_size_;
diff --git a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_unittest.cc b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_unittest.cc
index d36cacb..fc290a3 100644
--- a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_unittest.cc
+++ b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_unittest.cc
@@ -121,9 +121,34 @@
   }
 
   base::Optional<base::TimeDelta> ComputeDelayTillNextTask(LazyNow* lazy_now) {
-    // TODO(alexclarke): Remove this once the DoWork refactor lands.
-    manager_->WakeupReadyDelayedQueues(lazy_now);
-    return manager_->ComputeDelayTillNextTask(lazy_now);
+    base::AutoLock lock(manager_->any_thread_lock_);
+    return manager_->ComputeDelayTillNextTaskLocked(lazy_now);
+  }
+
+  void PostDoWorkContinuation(base::Optional<base::TimeDelta> next_delay,
+                              LazyNow* lazy_now) {
+    MoveableAutoLock lock(manager_->any_thread_lock_);
+    return manager_->PostDoWorkContinuationLocked(next_delay, lazy_now,
+                                                  std::move(lock));
+  }
+
+  int immediate_do_work_posted_count() const {
+    base::AutoLock lock(manager_->any_thread_lock_);
+    return manager_->any_thread().immediate_do_work_posted_count;
+  }
+
+  base::TimeTicks next_scheduled_delayed_do_work_time() const {
+    return manager_->next_scheduled_delayed_do_work_time_;
+  }
+
+  EnqueueOrder GetNextSequenceNumber() const {
+    return manager_->GetNextSequenceNumber();
+  }
+
+  void MaybeScheduleImmediateWorkLocked(
+      const tracked_objects::Location& from_here) {
+    MoveableAutoLock lock(manager_->any_thread_lock_);
+    manager_->MaybeScheduleImmediateWorkLocked(from_here, std::move(lock));
   }
 
   // Runs all immediate tasks until there is no more work to do and advances
@@ -2330,7 +2355,19 @@
   manager_->UnregisterTimeDomain(domain2.get());
 }
 
-TEST_F(TaskQueueManagerTest, ComputeDelayTillNextTask_TaskBlocked) {
+TEST_F(TaskQueueManagerTest, ComputeDelayTillNextTask_Disabled) {
+  Initialize(1u);
+
+  std::unique_ptr<TaskQueue::QueueEnabledVoter> voter =
+      runners_[0]->CreateQueueEnabledVoter();
+  voter->SetQueueEnabled(false);
+  runners_[0]->PostTask(FROM_HERE, base::Bind(&NopTask));
+
+  LazyNow lazy_now(now_src_.get());
+  EXPECT_FALSE(ComputeDelayTillNextTask(&lazy_now));
+}
+
+TEST_F(TaskQueueManagerTest, ComputeDelayTillNextTask_Fence) {
   Initialize(1u);
 
   runners_[0]->InsertFence(TaskQueue::InsertFencePosition::NOW);
@@ -2340,6 +2377,131 @@
   EXPECT_FALSE(ComputeDelayTillNextTask(&lazy_now));
 }
 
+TEST_F(TaskQueueManagerTest, ComputeDelayTillNextTask_FenceUnblocking) {
+  Initialize(1u);
+
+  runners_[0]->InsertFence(TaskQueue::InsertFencePosition::NOW);
+  runners_[0]->PostTask(FROM_HERE, base::Bind(&NopTask));
+  runners_[0]->InsertFence(TaskQueue::InsertFencePosition::NOW);
+
+  LazyNow lazy_now(now_src_.get());
+  EXPECT_EQ(base::TimeDelta(), ComputeDelayTillNextTask(&lazy_now).value());
+}
+
+TEST_F(TaskQueueManagerTest, ComputeDelayTillNextTask_DelayedTaskReady) {
+  Initialize(1u);
+
+  runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask),
+                               base::TimeDelta::FromSeconds(1));
+
+  now_src_->Advance(base::TimeDelta::FromSeconds(10));
+
+  LazyNow lazy_now(now_src_.get());
+  EXPECT_EQ(base::TimeDelta(), ComputeDelayTillNextTask(&lazy_now).value());
+}
+
+TEST_F(TaskQueueManagerTest, PostDoWorkContinuation_NoMoreWork) {
+  Initialize(1u);
+
+  LazyNow lazy_now(now_src_.get());
+  PostDoWorkContinuation(base::Optional<base::TimeDelta>(), &lazy_now);
+
+  EXPECT_EQ(0u, test_task_runner_->NumPendingTasks());
+  EXPECT_EQ(0, immediate_do_work_posted_count());
+  EXPECT_TRUE(next_scheduled_delayed_do_work_time().is_null());
+}
+
+TEST_F(TaskQueueManagerTest, PostDoWorkContinuation_ImmediateWork) {
+  Initialize(1u);
+
+  LazyNow lazy_now(now_src_.get());
+  PostDoWorkContinuation(base::TimeDelta(), &lazy_now);
+
+  EXPECT_EQ(1u, test_task_runner_->NumPendingTasks());
+  EXPECT_EQ(base::TimeDelta(), test_task_runner_->DelayToNextTaskTime());
+  EXPECT_EQ(1, immediate_do_work_posted_count());
+  EXPECT_TRUE(next_scheduled_delayed_do_work_time().is_null());
+}
+
+TEST_F(TaskQueueManagerTest, PostDoWorkContinuation_DelayedWork) {
+  Initialize(1u);
+
+  LazyNow lazy_now(now_src_.get());
+  PostDoWorkContinuation(base::TimeDelta::FromSeconds(1), &lazy_now);
+
+  EXPECT_EQ(1u, test_task_runner_->NumPendingTasks());
+  EXPECT_EQ(base::TimeDelta::FromSeconds(1),
+            test_task_runner_->DelayToNextTaskTime());
+  EXPECT_EQ(0, immediate_do_work_posted_count());
+  EXPECT_EQ(lazy_now.Now() + base::TimeDelta::FromSeconds(1),
+            next_scheduled_delayed_do_work_time());
+}
+
+TEST_F(TaskQueueManagerTest,
+       PostDoWorkContinuation_DelayedWorkButImmediateDoWorkAlreadyPosted) {
+  Initialize(1u);
+
+  MaybeScheduleImmediateWorkLocked(FROM_HERE);
+  EXPECT_EQ(1u, test_task_runner_->NumPendingTasks());
+  EXPECT_EQ(base::TimeDelta(), test_task_runner_->DelayToNextTaskTime());
+  EXPECT_EQ(1, immediate_do_work_posted_count());
+
+  LazyNow lazy_now(now_src_.get());
+  PostDoWorkContinuation(base::TimeDelta::FromSeconds(1), &lazy_now);
+
+  // Test that a delayed task didn't get posted.
+  EXPECT_EQ(1u, test_task_runner_->NumPendingTasks());
+  EXPECT_EQ(base::TimeDelta(), test_task_runner_->DelayToNextTaskTime());
+  EXPECT_EQ(1, immediate_do_work_posted_count());
+  EXPECT_TRUE(next_scheduled_delayed_do_work_time().is_null());
+}
+
+TEST_F(TaskQueueManagerTest, PostDoWorkContinuation_DelayedWorkTimeChanges) {
+  Initialize(1u);
+
+  LazyNow lazy_now(now_src_.get());
+  PostDoWorkContinuation(base::TimeDelta::FromSeconds(1), &lazy_now);
+
+  EXPECT_TRUE(test_task_runner_->HasPendingTasks());
+  EXPECT_EQ(0, immediate_do_work_posted_count());
+  EXPECT_EQ(base::TimeDelta::FromSeconds(1),
+            test_task_runner_->DelayToNextTaskTime());
+  EXPECT_EQ(lazy_now.Now() + base::TimeDelta::FromSeconds(1),
+            next_scheduled_delayed_do_work_time());
+
+  PostDoWorkContinuation(base::TimeDelta::FromSeconds(10), &lazy_now);
+
+  // This should have resulted in the previous task getting canceled and a new
+  // one getting posted.
+  EXPECT_EQ(2u, test_task_runner_->NumPendingTasks());
+  test_task_runner_->RemoveCancelledTasks();
+  EXPECT_EQ(1u, test_task_runner_->NumPendingTasks());
+  EXPECT_EQ(base::TimeDelta::FromSeconds(10),
+            test_task_runner_->DelayToNextTaskTime());
+  EXPECT_EQ(0, immediate_do_work_posted_count());
+  EXPECT_EQ(lazy_now.Now() + base::TimeDelta::FromSeconds(10),
+            next_scheduled_delayed_do_work_time());
+}
+
+TEST_F(TaskQueueManagerTest,
+       PostDoWorkContinuation_ImmediateWorkButDelayedDoWorkPending) {
+  Initialize(1u);
+
+  LazyNow lazy_now(now_src_.get());
+  PostDoWorkContinuation(base::TimeDelta::FromSeconds(1), &lazy_now);
+
+  now_src_->Advance(base::TimeDelta::FromSeconds(1));
+  lazy_now = LazyNow(now_src_.get());
+  PostDoWorkContinuation(base::TimeDelta(), &lazy_now);
+
+  // Because the delayed DoWork was pending we don't expect an immediate DoWork
+  // to get posted.
+  EXPECT_EQ(1u, test_task_runner_->NumPendingTasks());
+  EXPECT_EQ(base::TimeDelta(), test_task_runner_->DelayToNextTaskTime());
+  EXPECT_EQ(0, immediate_do_work_posted_count());
+  EXPECT_EQ(lazy_now.Now(), next_scheduled_delayed_do_work_time());
+}
+
 namespace {
 void MessageLoopTaskWithDelayedQuit(
     base::MessageLoop* message_loop,
@@ -2395,5 +2557,48 @@
   run_loop.Run();
 }
 
+TEST_F(TaskQueueManagerTest, CouldTaskRun_DisableAndReenable) {
+  Initialize(1u);
+
+  EnqueueOrder enqueue_order = GetNextSequenceNumber();
+  EXPECT_TRUE(runners_[0]->CouldTaskRun(enqueue_order));
+
+  std::unique_ptr<TaskQueue::QueueEnabledVoter> voter =
+      runners_[0]->CreateQueueEnabledVoter();
+  voter->SetQueueEnabled(false);
+  EXPECT_FALSE(runners_[0]->CouldTaskRun(enqueue_order));
+
+  voter->SetQueueEnabled(true);
+  EXPECT_TRUE(runners_[0]->CouldTaskRun(enqueue_order));
+}
+
+TEST_F(TaskQueueManagerTest, CouldTaskRun_Fence) {
+  Initialize(1u);
+
+  EnqueueOrder enqueue_order = GetNextSequenceNumber();
+  EXPECT_TRUE(runners_[0]->CouldTaskRun(enqueue_order));
+
+  runners_[0]->InsertFence(TaskQueue::InsertFencePosition::NOW);
+  EXPECT_TRUE(runners_[0]->CouldTaskRun(enqueue_order));
+
+  runners_[0]->InsertFence(TaskQueue::InsertFencePosition::BEGINNING_OF_TIME);
+  EXPECT_FALSE(runners_[0]->CouldTaskRun(enqueue_order));
+
+  runners_[0]->RemoveFence();
+  EXPECT_TRUE(runners_[0]->CouldTaskRun(enqueue_order));
+}
+
+TEST_F(TaskQueueManagerTest, CouldTaskRun_FenceBeforeThenAfter) {
+  Initialize(1u);
+
+  runners_[0]->InsertFence(TaskQueue::InsertFencePosition::NOW);
+
+  EnqueueOrder enqueue_order = GetNextSequenceNumber();
+  EXPECT_FALSE(runners_[0]->CouldTaskRun(enqueue_order));
+
+  runners_[0]->InsertFence(TaskQueue::InsertFencePosition::NOW);
+  EXPECT_TRUE(runners_[0]->CouldTaskRun(enqueue_order));
+}
+
 }  // namespace scheduler
 }  // namespace blink
diff --git a/third_party/WebKit/Source/web/WebViewImpl.cpp b/third_party/WebKit/Source/web/WebViewImpl.cpp
index 0a5b5e9..0e621fd 100644
--- a/third_party/WebKit/Source/web/WebViewImpl.cpp
+++ b/third_party/WebKit/Source/web/WebViewImpl.cpp
@@ -1798,14 +1798,12 @@
 
   browserControls().updateConstraintsAndState(constraint, current, animate);
 
-  // If the controls are going from a locked hidden to unlocked state, or vice
-  // versa, the ICB size needs to change but we can't rely on getting a
-  // WebViewImpl::resize since the top controls shown state may not have
-  // changed.
-  if ((oldPermittedState == WebBrowserControlsHidden &&
-       constraint == WebBrowserControlsBoth) ||
-      (oldPermittedState == WebBrowserControlsBoth &&
-       constraint == WebBrowserControlsHidden)) {
+  // If the controls are going from a locked to an unlocked state, or
+  // vice-versa, then we need to force a recompute of the ICB size since that
+  // depends on the permitted browser controls state.
+  if (oldPermittedState != constraint &&
+      (oldPermittedState == WebBrowserControlsBoth ||
+       constraint == WebBrowserControlsBoth)) {
     performResize();
   }
 
diff --git a/third_party/WebKit/Source/wtf/HexNumber.h b/third_party/WebKit/Source/wtf/HexNumber.h
index 6956430..a0ea7b5c 100644
--- a/third_party/WebKit/Source/wtf/HexNumber.h
+++ b/third_party/WebKit/Source/wtf/HexNumber.h
@@ -24,66 +24,80 @@
 
 namespace WTF {
 
-enum HexConversionMode { Lowercase, Uppercase };
-
 namespace Internal {
 
 const LChar lowerHexDigits[17] = "0123456789abcdef";
 const LChar upperHexDigits[17] = "0123456789ABCDEF";
-inline const LChar* hexDigitsForMode(HexConversionMode mode) {
-  return mode == Lowercase ? lowerHexDigits : upperHexDigits;
-}
 
 }  // namespace Internal
 
-template <typename T>
-inline void appendByteAsHex(unsigned char byte,
-                            T& destination,
-                            HexConversionMode mode = Uppercase) {
-  const LChar* hexDigits = Internal::hexDigitsForMode(mode);
-  destination.append(hexDigits[byte >> 4]);
-  destination.append(hexDigits[byte & 0xF]);
-}
+class HexNumber final {
+  STATIC_ONLY(HexNumber);
 
-template <typename T>
-inline void appendUnsignedAsHex(unsigned number,
-                                T& destination,
-                                HexConversionMode mode = Uppercase) {
-  const LChar* hexDigits = Internal::hexDigitsForMode(mode);
-  Vector<LChar, 8> result;
-  do {
-    result.prepend(hexDigits[number % 16]);
-    number >>= 4;
-  } while (number > 0);
+ public:
+  enum HexConversionMode { Lowercase, Uppercase };
 
-  destination.append(result.data(), result.size());
-}
+  template <typename T>
+  static inline void appendByteAsHex(unsigned char byte,
+                                     T& destination,
+                                     HexConversionMode mode = Uppercase) {
+    const LChar* hexDigits = hexDigitsForMode(mode);
+    destination.append(hexDigits[byte >> 4]);
+    destination.append(hexDigits[byte & 0xF]);
+  }
 
-// Same as appendUnsignedAsHex, but using exactly 'desiredDigits' for the
-// conversion.
-template <typename T>
-inline void appendUnsignedAsHexFixedSize(unsigned number,
+  static inline void appendByteAsHex(unsigned char byte,
+                                     Vector<LChar>& destination,
+                                     HexConversionMode mode = Uppercase) {
+    const LChar* hexDigits = hexDigitsForMode(mode);
+    destination.push_back(hexDigits[byte >> 4]);
+    destination.push_back(hexDigits[byte & 0xF]);
+  }
+
+  template <typename T>
+  static inline void appendUnsignedAsHex(unsigned number,
                                          T& destination,
-                                         unsigned desiredDigits,
                                          HexConversionMode mode = Uppercase) {
-  DCHECK(desiredDigits);
+    const LChar* hexDigits = hexDigitsForMode(mode);
+    Vector<LChar, 8> result;
+    do {
+      result.prepend(hexDigits[number % 16]);
+      number >>= 4;
+    } while (number > 0);
 
-  const LChar* hexDigits = Internal::hexDigitsForMode(mode);
-  Vector<LChar, 8> result;
-  do {
-    result.prepend(hexDigits[number % 16]);
-    number >>= 4;
-  } while (result.size() < desiredDigits);
+    destination.append(result.data(), result.size());
+  }
 
-  DCHECK_EQ(result.size(), desiredDigits);
-  destination.append(result.data(), result.size());
-}
+  // Same as appendUnsignedAsHex, but using exactly 'desiredDigits' for the
+  // conversion.
+  template <typename T>
+  static inline void appendUnsignedAsHexFixedSize(
+      unsigned number,
+      T& destination,
+      unsigned desiredDigits,
+      HexConversionMode mode = Uppercase) {
+    DCHECK(desiredDigits);
+
+    const LChar* hexDigits = hexDigitsForMode(mode);
+    Vector<LChar, 8> result;
+    do {
+      result.prepend(hexDigits[number % 16]);
+      number >>= 4;
+    } while (result.size() < desiredDigits);
+
+    DCHECK_EQ(result.size(), desiredDigits);
+    destination.append(result.data(), result.size());
+  }
+
+ private:
+  static inline const LChar* hexDigitsForMode(HexConversionMode mode) {
+    return mode == Lowercase ? Internal::lowerHexDigits
+                             : Internal::upperHexDigits;
+  }
+};
 
 }  // namespace WTF
 
-using WTF::appendByteAsHex;
-using WTF::appendUnsignedAsHex;
-using WTF::appendUnsignedAsHexFixedSize;
-using WTF::Lowercase;
+using WTF::HexNumber;
 
 #endif  // HexNumber_h
diff --git a/third_party/WebKit/Source/wtf/text/WTFString.cpp b/third_party/WebKit/Source/wtf/text/WTFString.cpp
index 0cfe473..bc751f5a 100644
--- a/third_party/WebKit/Source/wtf/text/WTFString.cpp
+++ b/third_party/WebKit/Source/wtf/text/WTFString.cpp
@@ -58,7 +58,7 @@
     } else {
       buffer.push_back('\\');
       buffer.push_back('u');
-      appendUnsignedAsHexFixedSize(ch, buffer, 4);
+      HexNumber::appendUnsignedAsHexFixedSize(ch, buffer, 4);
     }
   }
   buffer.push_back('\0');
diff --git a/third_party/libjingle_xmpp/BUILD.gn b/third_party/libjingle_xmpp/BUILD.gn
index f359263a..c44fbab 100644
--- a/third_party/libjingle_xmpp/BUILD.gn
+++ b/third_party/libjingle_xmpp/BUILD.gn
@@ -3,7 +3,7 @@
 # found in the LICENSE file.
 
 # TODO(kjellander): Remove remaining dependencies on the WebRTC codebase.
-import("../webrtc/build/webrtc.gni")
+import("../webrtc/webrtc.gni")
 
 group("libjingle_xmpp") {
   public_deps = [
diff --git a/tools/chrome_proxy/webdriver/html5.py b/tools/chrome_proxy/webdriver/html5.py
new file mode 100644
index 0000000..036b019e
--- /dev/null
+++ b/tools/chrome_proxy/webdriver/html5.py
@@ -0,0 +1,30 @@
+# Copyright 2017 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import common
+from common import TestDriver
+from common import IntegrationTest
+
+
+class HTML5(IntegrationTest):
+
+  # This test site has a div with id="pointsPanel" that is rendered if the
+  # browser is capable of using HTML5.
+  def testHTML5(self):
+    with TestDriver() as t:
+      t.AddChromeArg('--enable-spdy-proxy-auth')
+      t.LoadURL('http://html5test.com/')
+      t.WaitForJavascriptExpression(
+        'document.getElementsByClassName("pointsPanel")', 15)
+      checked_main_page = False
+      for response in t.GetHTTPResponses():
+        # Site has a lot on it, just check the main page.
+        if (response.url == 'http://html5test.com/'
+            or response.url == 'http://html5test.com/index.html'):
+          self.assertHasChromeProxyViaHeader(response)
+          checked_main_page = True
+      if not checked_main_page:
+        self.fail("Did not check any page!")
+if __name__ == '__main__':
+  IntegrationTest.RunAllTests()
diff --git a/tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp b/tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp
index 82d41d3..a8b8f4b 100644
--- a/tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp
+++ b/tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp
@@ -1215,28 +1215,29 @@
     // Find location of the gmock_##MockedMethod identifier.
     clang::SourceLocation target_loc = Base::GetTargetLoc(result);
 
-    // Find location of EXPECT_CALL macro invocation.
+    // Find location of EXPECT_CALL or ON_CALL macro invocation.
     clang::SourceLocation macro_call_loc =
         result.SourceManager->getExpansionLoc(target_loc);
 
     // Map |macro_call_loc| to argument location (location of the method name
     // that needs renaming).
-    auto it = expect_call_to_2nd_arg.find(macro_call_loc);
-    if (it == expect_call_to_2nd_arg.end())
+    auto it = gmock_macro_call_to_2nd_arg.find(macro_call_loc);
+    if (it == gmock_macro_call_to_2nd_arg.end())
       return clang::SourceLocation();
     return it->second;
   }
 
  private:
-  std::map<clang::SourceLocation, clang::SourceLocation> expect_call_to_2nd_arg;
+  std::map<clang::SourceLocation, clang::SourceLocation>
+      gmock_macro_call_to_2nd_arg;
 
-  // Called from PPCallbacks with the locations of EXPECT_CALL macro invocation:
-  // Example:
+  // Called from PPCallbacks with the locations of EXPECT_CALL and ON_CALL macro
+  // invocation.  Example:
   //   EXPECT_CALL(my_mock, myMethod(123, 456));
   //   ^- expansion_loc     ^- actual_arg_loc
-  void RecordExpectCallMacroInvocation(clang::SourceLocation expansion_loc,
-                                       clang::SourceLocation second_arg_loc) {
-    expect_call_to_2nd_arg[expansion_loc] = second_arg_loc;
+  void RecordGMockMacroInvocation(clang::SourceLocation expansion_loc,
+                                  clang::SourceLocation second_arg_loc) {
+    gmock_macro_call_to_2nd_arg[expansion_loc] = second_arg_loc;
   }
 
   class PPCallbacks : public clang::PPCallbacks {
@@ -1251,7 +1252,7 @@
       if (!id)
         return;
 
-      if (id->getName() != "EXPECT_CALL")
+      if (id->getName() != "EXPECT_CALL" && id->getName() != "ON_CALL")
         return;
 
       if (def.getMacroInfo()->getNumArgs() != 2)
@@ -1261,7 +1262,7 @@
       // is in testing/gmock/include/gmock/gmock-spec-builders.h but I don't
       // know how to get clang::SourceManager to call getFileName.
 
-      rewriter_->RecordExpectCallMacroInvocation(
+      rewriter_->RecordGMockMacroInvocation(
           name.getLocation(), args->getUnexpArgument(1)->getLocation());
     }
 
@@ -1824,7 +1825,9 @@
   // GMock calls lookup ========
   // Given
   //   EXPECT_CALL(obj, myMethod(...))
-  // will match obj.gmock_myMethod(...) call generated by the macro
+  // or
+  //   ON_CALL(obj, myMethod(...))
+  // will match obj.gmock_myMethod(...) call generated by the macros
   // (but only if it mocks a Blink method).
   auto gmock_member_matcher =
       id("expr", memberExpr(hasDeclaration(
diff --git a/tools/clang/rewrite_to_chrome_style/tests/gmock-expected.cc b/tools/clang/rewrite_to_chrome_style/tests/gmock-expected.cc
index 66b6fc3..e4f199b 100644
--- a/tools/clang/rewrite_to_chrome_style/tests/gmock-expected.cc
+++ b/tools/clang/rewrite_to_chrome_style/tests/gmock-expected.cc
@@ -25,6 +25,10 @@
       mocked_interface,  // A comment to prevent reformatting into single line.
       MyMethod(1));
   mocked_interface.MyMethod(123);
+
+  int arg;
+  ON_CALL(mocked_interface, MyMethod(1))
+      .WillByDefault(testing::SaveArg<0>(&arg));
 }
 
 }  // namespace simple_test
diff --git a/tools/clang/rewrite_to_chrome_style/tests/gmock-original.cc b/tools/clang/rewrite_to_chrome_style/tests/gmock-original.cc
index 81150e11..71eda686 100644
--- a/tools/clang/rewrite_to_chrome_style/tests/gmock-original.cc
+++ b/tools/clang/rewrite_to_chrome_style/tests/gmock-original.cc
@@ -25,6 +25,10 @@
       mockedInterface,  // A comment to prevent reformatting into single line.
       myMethod(1));
   mockedInterface.myMethod(123);
+
+  int arg;
+  ON_CALL(mockedInterface, myMethod(1))
+      .WillByDefault(testing::SaveArg<0>(&arg));
 }
 
 }  // namespace simple_test
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index ae1a8e6..35b3c77 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -8368,7 +8368,7 @@
   <summary>The exception code encountered in a crash on Mac OS X.</summary>
 </histogram>
 
-<histogram name="Crashpad.ExceptionCode.Win" enum="CrashExitCodes">
+<histogram name="Crashpad.ExceptionCode.Win" enum="CrashpadWinExceptionCodes">
   <owner>crashpad-dev@chromium.org</owner>
   <summary>The exception code encountered in a crash on Windows.</summary>
 </histogram>
@@ -8391,7 +8391,8 @@
   </summary>
 </histogram>
 
-<histogram name="Crashpad.HandlerCrash.ExceptionCode.Win" enum="CrashExitCodes">
+<histogram name="Crashpad.HandlerCrash.ExceptionCode.Win"
+    enum="CrashpadWinExceptionCodes">
   <owner>crashpad-dev@chromium.org</owner>
   <summary>
     The exception code encountered for a crash of the crash handler process on
@@ -82654,7 +82655,7 @@
   <int value="786949" label="EXC_GUARD/GUARD_TYPE_FD/kGUARD_EXC_MISMATCH"/>
   <int value="786950" label="EXC_GUARD/GUARD_TYPE_FD/kGUARD_EXC_WRITE"/>
   <int value="851968" label="EXC_CORPSE_NOTIFY/0"/>
-  <int value="1129345912" label="kMachExceptionSimulated"/>
+  <int value="1129345912" label="crashpad::kMachExceptionSimulated"/>
 </enum>
 
 <enum name="CrashpadReportPending" type="int">
@@ -82675,6 +82676,73 @@
   <int value="4" label="kUploadFailed"/>
 </enum>
 
+<enum name="CrashpadWinExceptionCodes" type="int">
+  <int value="-2147483647" label="EXCEPTION_GUARD_PAGE"/>
+  <int value="-2147483646" label="EXCEPTION_DATATYPE_MISALIGNMENT"/>
+  <int value="-2147483645" label="EXCEPTION_BREAKPOINT"/>
+  <int value="-2147483644" label="EXCEPTION_SINGLE_STEP"/>
+  <int value="-1073741822" label="STATUS_NOT_IMPLEMENTED"/>
+  <int value="-1073741819" label="EXCEPTION_ACCESS_VIOLATION"/>
+  <int value="-1073741818" label="EXCEPTION_IN_PAGE_ERROR"/>
+  <int value="-1073741816" label="EXCEPTION_INVALID_HANDLE"/>
+  <int value="-1073741811" label="STATUS_INVALID_PARAMETER"/>
+  <int value="-1073741803" label="STATUS_NONEXISTENT_SECTOR"/>
+  <int value="-1073741801" label="STATUS_NO_MEMORY"/>
+  <int value="-1073741795" label="EXCEPTION_ILLEGAL_INSTRUCTION"/>
+  <int value="-1073741794" label="STATUS_INVALID_LOCK_SEQUENCE"/>
+  <int value="-1073741790" label="STATUS_ACCESS_DENIED"/>
+  <int value="-1073741788" label="STATUS_OBJECT_TYPE_MISMATCH"/>
+  <int value="-1073741739" label="STATUS_LOCK_NOT_GRANTED"/>
+  <int value="-1073741684" label="EXCEPTION_ARRAY_BOUNDS_EXCEEDED"/>
+  <int value="-1073741682" label="EXCEPTION_FLT_DIVIDE_BY_ZERO"/>
+  <int value="-1073741681" label="EXCEPTION_FLT_INEXACT_RESULT"/>
+  <int value="-1073741680" label="EXCEPTION_FLT_INVALID_OPERATION"/>
+  <int value="-1073741679" label="EXCEPTION_FLT_OVERFLOW"/>
+  <int value="-1073741678" label="EXCEPTION_FLT_STACK_CHECK"/>
+  <int value="-1073741677" label="EXCEPTION_FLT_UNDERFLOW"/>
+  <int value="-1073741676" label="EXCEPTION_INT_DIVIDE_BY_ZERO"/>
+  <int value="-1073741675" label="EXCEPTION_INT_OVERFLOW"/>
+  <int value="-1073741674" label="EXCEPTION_PRIV_INSTRUCTION"/>
+  <int value="-1073741571" label="EXCEPTION_STACK_OVERFLOW"/>
+  <int value="-1073741569" label="STATUS_BAD_FUNCTION_TABLE"/>
+  <int value="-1073741420" label="EXCEPTION_POSSIBLE_DEADLOCK"/>
+  <int value="-1073741224" label="STATUS_NO_CALLBACK_ACTIVE"/>
+  <int value="-1073741212" label="STATUS_RESOURCE_NOT_OWNED"/>
+  <int value="-1073741132" label="STATUS_FLOAT_MULTIPLE_FAULTS"/>
+  <int value="-1073741131" label="STATUS_FLOAT_MULTIPLE_TRAPS"/>
+  <int value="-1073740791" label="STATUS_STACK_BUFFER_OVERRUN"/>
+  <int value="-1073740022" label="STATUS_THREADPOOL_HANDLE_EXCEPTION"/>
+  <int value="-1073740021"
+      label="STATUS_THREADPOOL_SET_EVENT_ON_COMPLETION_FAILED"/>
+  <int value="-1073740020"
+      label="STATUS_THREADPOOL_RELEASE_SEMAPHORE_ON_COMPLETION_FAILED"/>
+  <int value="-1073740018"
+      label="STATUS_THREADPOOL_FREE_LIBRARY_ON_COMPLETION_FAILED"/>
+  <int value="-1073740016"
+      label="STATUS_CALLBACK_RETURNED_WHILE_IMPERSONATING"/>
+  <int value="-1073740004" label="STATUS_INVALID_THREAD"/>
+  <int value="-1073740003" label="STATUS_CALLBACK_RETURNED_TRANSACTION"/>
+  <int value="-1073740002" label="STATUS_CALLBACK_RETURNED_LDR_LOCK"/>
+  <int value="-1073740001" label="STATUS_CALLBACK_RETURNED_LANG"/>
+  <int value="-1073610685" label="RPC_NT_INTERNAL_ERROR"/>
+  <int value="-1072365553" label="STATUS_SXS_EARLY_DEACTIVATION"/>
+  <int value="-1072365552" label="STATUS_SXS_INVALID_DEACTIVATION"/>
+  <int value="-1072365551" label="STATUS_SXS_MULTIPLE_DEACTIVATION"/>
+  <int value="-1072365548" label="STATUS_SXS_CORRUPT_ACTIVATION_STACK"/>
+  <int value="-1066598274" label="FACILITY_VISUALCPP/ERROR_MOD_NOT_FOUND"/>
+  <int value="-1066598273" label="FACILITY_VISUALCPP/ERROR_PROC_NOT_FOUND"/>
+  <int value="-536870904" label="base::win::kOomExceptionCode"/>
+  <int value="-529697949" label="EH_EXCEPTION_NUMBER"/>
+  <int value="1285" label="ERROR_DELAY_LOAD_FAILED"/>
+  <int value="1717" label="RPC_S_UNKNOWN_IF"/>
+  <int value="1722" label="RPC_S_SERVER_UNAVAILABLE"/>
+  <int value="1726" label="RPC_S_CALL_FAILED"/>
+  <int value="1766" label="RPC_S_INTERNAL_ERROR"/>
+  <int value="1783" label="RPC_X_BAD_STUB_DATA"/>
+  <int value="1818" label="RPC_S_CALL_CANCELLED"/>
+  <int value="85436397" label="crashpad::kSimulatedExceptionCode"/>
+</enum>
+
 <enum name="CreatePersistentHistogramResult" type="int">
   <int value="0" label="Success: Histogram created in persistent space."/>
   <int value="1" label="Error: Invalid metadata pointer. (coding error)"/>