diff --git a/DEPS b/DEPS
index ed5c4583..7ea40e9 100644
--- a/DEPS
+++ b/DEPS
@@ -44,7 +44,7 @@
   # 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': '70df7e4d5c7d060da15204150368406da0a3ae74',
+  'v8_revision': '21cc02a8f9528f7e03c4f58cede6a102b08dc336',
   # 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.
diff --git a/base/BUILD.gn b/base/BUILD.gn
index 88d5d7f..244aec4 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -1234,6 +1234,17 @@
       "rand_util_nacl.cc",
       "synchronization/read_write_lock_nacl.cc",
     ]
+
+    # Add stuff that doesn't work in NaCl.
+    sources += [
+      # PartitionAlloc uses SpinLock, which doesn't work in NaCl (see below).
+      "allocator/partition_allocator/address_space_randomization.cc",
+      "allocator/partition_allocator/address_space_randomization.h",
+      "allocator/partition_allocator/page_allocator.cc",
+      "allocator/partition_allocator/page_allocator.h",
+      "allocator/partition_allocator/partition_alloc.cc",
+      "allocator/partition_allocator/partition_alloc.h",
+    ]
   }
 
   # SpinLock uses inline assembly that doesn't work on NaCl, and for which there
@@ -1796,6 +1807,7 @@
 
 test("base_unittests") {
   sources = [
+    "allocator/partition_allocator/partition_alloc_unittest.cc",
     "allocator/tcmalloc_unittest.cc",
     "android/application_status_listener_unittest.cc",
     "android/content_uri_utils_unittest.cc",
diff --git a/base/allocator/oom.h b/base/allocator/oom.h
new file mode 100644
index 0000000..68dfae7
--- /dev/null
+++ b/base/allocator/oom.h
@@ -0,0 +1,26 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_ALLOCATOR_OOM_H
+#define BASE_ALLOCATOR_OOM_H
+
+#include "base/logging.h"
+
+#if defined(OS_WIN)
+#include <windows.h>
+#endif
+
+// OOM_CRASH() - Specialization of IMMEDIATE_CRASH which will raise a custom
+// exception on Windows to signal this is OOM and not a normal assert.
+#if defined(OS_WIN)
+#define OOM_CRASH()                                                     \
+  do {                                                                  \
+    ::RaiseException(0xE0000008, EXCEPTION_NONCONTINUABLE, 0, nullptr); \
+    IMMEDIATE_CRASH();                                                  \
+  } while (0)
+#else
+#define OOM_CRASH() IMMEDIATE_CRASH()
+#endif
+
+#endif  // BASE_ALLOCATOR_OOM_H
diff --git a/base/allocator/partition_allocator/OWNERS b/base/allocator/partition_allocator/OWNERS
new file mode 100644
index 0000000..8e7c87c1
--- /dev/null
+++ b/base/allocator/partition_allocator/OWNERS
@@ -0,0 +1,2 @@
+haraken@chromium.org
+palmer@chromium.org
diff --git a/third_party/WebKit/Source/wtf/allocator/PartitionAlloc.md b/base/allocator/partition_allocator/PartitionAlloc.md
similarity index 100%
rename from third_party/WebKit/Source/wtf/allocator/PartitionAlloc.md
rename to base/allocator/partition_allocator/PartitionAlloc.md
diff --git a/third_party/WebKit/Source/wtf/allocator/AddressSpaceRandomization.cpp b/base/allocator/partition_allocator/address_space_randomization.cc
similarity index 74%
rename from third_party/WebKit/Source/wtf/allocator/AddressSpaceRandomization.cpp
rename to base/allocator/partition_allocator/address_space_randomization.cc
index 4fca267..fd66b1b0 100644
--- a/third_party/WebKit/Source/wtf/allocator/AddressSpaceRandomization.cpp
+++ b/base/allocator/partition_allocator/address_space_randomization.cc
@@ -2,26 +2,27 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "wtf/allocator/AddressSpaceRandomization.h"
+#include "base/allocator/partition_allocator/address_space_randomization.h"
 
-#include "wtf/SpinLock.h"
-#include "wtf/allocator/PageAllocator.h"
+#include "base/allocator/partition_allocator/page_allocator.h"
+#include "base/synchronization/spin_lock.h"
+#include "build/build_config.h"
 
-#if OS(WIN)
+#if defined(OS_WIN)
 #include <windows.h>
 #else
 #include <sys/time.h>
 #include <unistd.h>
 #endif
 
-namespace WTF {
+namespace base {
 
 namespace {
 
 // This is the same PRNG as used by tcmalloc for mapping address randomness;
 // see http://burtleburtle.net/bob/rand/smallprng.html
 struct ranctx {
-  SpinLock lock;
+  subtle::SpinLock lock;
   bool initialized;
   uint32_t a;
   uint32_t b;
@@ -43,14 +44,14 @@
 #undef rot
 
 uint32_t ranval(ranctx* x) {
-  SpinLock::Guard guard(x->lock);
+  subtle::SpinLock::Guard guard(x->lock);
   if (UNLIKELY(!x->initialized)) {
     x->initialized = true;
     char c;
     uint32_t seed = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(&c));
     uint32_t pid;
     uint32_t usec;
-#if OS(WIN)
+#if defined(OS_WIN)
     pid = GetCurrentProcessId();
     SYSTEMTIME st;
     GetSystemTime(&st);
@@ -77,21 +78,20 @@
 
 }  // namespace
 
-// Calculates a random preferred mapping address. In calculating an
-// address, we balance good ASLR against not fragmenting the address
-// space too badly.
+// Calculates a random preferred mapping address. In calculating an address, we
+// balance good ASLR against not fragmenting the address space too badly.
 void* getRandomPageBase() {
   uintptr_t random;
   random = static_cast<uintptr_t>(ranval(&s_ranctx));
-#if CPU(X86_64)
+#if defined(ARCH_CPU_X86_64)
   random <<= 32UL;
   random |= static_cast<uintptr_t>(ranval(&s_ranctx));
-// This address mask gives a low liklihood of address space collisions.
-// We handle the situation gracefully if there is a collision.
-#if OS(WIN)
-  // 64-bit Windows has a bizarrely small 8TB user address space.
-  // Allocates in the 1-5TB region.
-  // TODO(cevans): I think Win 8.1 has 47-bits like Linux.
+// This address mask gives a low likelihood of address space collisions. We
+// handle the situation gracefully if there is a collision.
+#if defined(OS_WIN)
+  // 64-bit Windows has a bizarrely small 8TB user address space. Allocates in
+  // the 1-5TB region. TODO(palmer): See if Windows >= 8.1 has the full 47 bits,
+  // and use it if so. crbug.com/672219
   random &= 0x3ffffffffffUL;
   random += 0x10000000000UL;
 #elif defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
@@ -102,12 +102,12 @@
   // Linux and OS X support the full 47-bit user space of x64 processors.
   random &= 0x3fffffffffffUL;
 #endif
-#elif CPU(ARM64)
+#elif defined(ARCH_CPU_ARM64)
   // ARM64 on Linux has 39-bit user space.
   random &= 0x3fffffffffUL;
   random += 0x1000000000UL;
-#else  // !CPU(X86_64) && !CPU(ARM64)
-#if OS(WIN)
+#else  // !defined(ARCH_CPU_X86_64) && !defined(ARCH_CPU_ARM64)
+#if defined(OS_WIN)
   // On win32 host systems the randomization plus huge alignment causes
   // excessive fragmentation. Plus most of these systems lack ASLR, so the
   // randomization isn't buying anything. In that case we just skip it.
@@ -117,14 +117,14 @@
     isWow64 = FALSE;
   if (!isWow64)
     return nullptr;
-#endif  // OS(WIN)
+#endif  // defined(OS_WIN)
   // This is a good range on Windows, Linux and Mac.
   // Allocates in the 0.5-1.5GB region.
   random &= 0x3fffffff;
   random += 0x20000000;
-#endif  // CPU(X86_64)
+#endif  // defined(ARCH_CPU_X86_64)
   random &= kPageAllocationGranularityBaseMask;
   return reinterpret_cast<void*>(random);
 }
 
-}  // namespace WTF
+}  // namespace base
diff --git a/base/allocator/partition_allocator/address_space_randomization.h b/base/allocator/partition_allocator/address_space_randomization.h
new file mode 100644
index 0000000..4455cc4
--- /dev/null
+++ b/base/allocator/partition_allocator/address_space_randomization.h
@@ -0,0 +1,16 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_ALLOCATOR_PARTITION_ALLOCATOR_ADDRESS_SPACE_RANDOMIZATION
+#define BASE_ALLOCATOR_PARTITION_ALLOCATOR_ADDRESS_SPACE_RANDOMIZATION
+
+namespace base {
+
+// Calculates a random preferred mapping address. In calculating an address, we
+// balance good ASLR against not fragmenting the address space too badly.
+void* getRandomPageBase();
+
+}  // namespace base
+
+#endif  // BASE_ALLOCATOR_PARTITION_ALLOCATOR_ADDRESS_SPACE_RANDOMIZATION
diff --git a/third_party/WebKit/Source/wtf/allocator/PageAllocator.cpp b/base/allocator/partition_allocator/page_allocator.cc
similarity index 61%
rename from third_party/WebKit/Source/wtf/allocator/PageAllocator.cpp
rename to base/allocator/partition_allocator/page_allocator.cc
index 22e12d33..9678488e 100644
--- a/third_party/WebKit/Source/wtf/allocator/PageAllocator.cpp
+++ b/base/allocator/partition_allocator/page_allocator.cc
@@ -1,42 +1,18 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * 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.
- *     * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
- * OWNER OR 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.
- */
+// Copyright (c) 2013 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 "wtf/allocator/PageAllocator.h"
-
-#include "wtf/Assertions.h"
-#include "wtf/Atomics.h"
-#include "wtf/allocator/AddressSpaceRandomization.h"
+#include "base/allocator/partition_allocator/page_allocator.h"
 
 #include <limits.h>
 
-#if OS(POSIX)
+#include "base/allocator/partition_allocator/address_space_randomization.h"
+#include "base/atomicops.h"
+#include "base/base_export.h"
+#include "base/logging.h"
+#include "build/build_config.h"
+
+#if defined(OS_POSIX)
 
 #include <errno.h>
 #include <sys/mman.h>
@@ -49,50 +25,47 @@
 #define MAP_ANONYMOUS MAP_ANON
 #endif
 
-// On POSIX memmap uses a nearby address if the hint address is blocked.
+// On POSIX |mmap| uses a nearby address if the hint address is blocked.
 static const bool kHintIsAdvisory = true;
-static uint32_t s_allocPageErrorCode = 0;
+static volatile base::subtle::Atomic32 s_allocPageErrorCode = 0;
 
-#elif OS(WIN)
+#elif defined(OS_WIN)
 
 #include <windows.h>
 
-// VirtualAlloc will fail if allocation at the hint address is blocked.
+// |VirtualAlloc| will fail if allocation at the hint address is blocked.
 static const bool kHintIsAdvisory = false;
-static uint32_t s_allocPageErrorCode = ERROR_SUCCESS;
+static base::subtle::Atomic32 s_allocPageErrorCode = ERROR_SUCCESS;
 
 #else
 #error Unknown OS
-#endif  // OS(POSIX)
+#endif  // defined(OS_POSIX)
 
-namespace WTF {
+namespace base {
 
-// This internal function wraps the OS-specific page allocation call. The
-// behavior of the hint address is determined by the kHintIsAdvisory constant.
-// If true, a non-zero hint is advisory and the returned address may differ from
-// the hint. If false, the hint is mandatory and a successful allocation will
-// not differ from the hint.
+// This internal function wraps the OS-specific page allocation call:
+// |VirtualAlloc| on Windows, and |mmap| on POSIX.
 static void* systemAllocPages(
     void* hint,
     size_t len,
     PageAccessibilityConfiguration pageAccessibility) {
-  ASSERT(!(len & kPageAllocationGranularityOffsetMask));
-  ASSERT(!(reinterpret_cast<uintptr_t>(hint) &
+  DCHECK(!(len & kPageAllocationGranularityOffsetMask));
+  DCHECK(!(reinterpret_cast<uintptr_t>(hint) &
            kPageAllocationGranularityOffsetMask));
   void* ret;
-#if OS(WIN)
+#if defined(OS_WIN)
   DWORD accessFlag =
       pageAccessibility == PageAccessible ? PAGE_READWRITE : PAGE_NOACCESS;
   ret = VirtualAlloc(hint, len, MEM_RESERVE | MEM_COMMIT, accessFlag);
   if (!ret)
-    releaseStore(&s_allocPageErrorCode, GetLastError());
+    base::subtle::Release_Store(&s_allocPageErrorCode, GetLastError());
 #else
   int accessFlag = pageAccessibility == PageAccessible
                        ? (PROT_READ | PROT_WRITE)
                        : PROT_NONE;
   ret = mmap(hint, len, accessFlag, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
   if (ret == MAP_FAILED) {
-    releaseStore(&s_allocPageErrorCode, errno);
+    base::subtle::Release_Store(&s_allocPageErrorCode, errno);
     ret = 0;
   }
 #endif
@@ -110,21 +83,21 @@
   if (preSlack)
     preSlack = align - preSlack;
   size_t postSlack = baseLen - preSlack - trimLen;
-  ASSERT(baseLen >= trimLen || preSlack || postSlack);
-  ASSERT(preSlack < baseLen);
-  ASSERT(postSlack < baseLen);
+  DCHECK(baseLen >= trimLen || preSlack || postSlack);
+  DCHECK(preSlack < baseLen);
+  DCHECK(postSlack < baseLen);
   void* ret = base;
 
-#if OS(POSIX)  // On POSIX we can resize the allocation run.
+#if defined(OS_POSIX)  // On POSIX we can resize the allocation run.
   (void)pageAccessibility;
   if (preSlack) {
     int res = munmap(base, preSlack);
-    RELEASE_ASSERT(!res);
+    CHECK(!res);
     ret = reinterpret_cast<char*>(base) + preSlack;
   }
   if (postSlack) {
     int res = munmap(reinterpret_cast<char*>(ret) + trimLen, postSlack);
-    RELEASE_ASSERT(!res);
+    CHECK(!res);
   }
 #else  // On Windows we can't resize the allocation run.
   if (preSlack || postSlack) {
@@ -141,15 +114,15 @@
                  size_t len,
                  size_t align,
                  PageAccessibilityConfiguration pageAccessibility) {
-  ASSERT(len >= kPageAllocationGranularity);
-  ASSERT(!(len & kPageAllocationGranularityOffsetMask));
-  ASSERT(align >= kPageAllocationGranularity);
-  ASSERT(!(align & kPageAllocationGranularityOffsetMask));
-  ASSERT(!(reinterpret_cast<uintptr_t>(addr) &
+  DCHECK(len >= kPageAllocationGranularity);
+  DCHECK(!(len & kPageAllocationGranularityOffsetMask));
+  DCHECK(align >= kPageAllocationGranularity);
+  DCHECK(!(align & kPageAllocationGranularityOffsetMask));
+  DCHECK(!(reinterpret_cast<uintptr_t>(addr) &
            kPageAllocationGranularityOffsetMask));
   uintptr_t alignOffsetMask = align - 1;
   uintptr_t alignBaseMask = ~alignOffsetMask;
-  ASSERT(!(reinterpret_cast<uintptr_t>(addr) & alignOffsetMask));
+  DCHECK(!(reinterpret_cast<uintptr_t>(addr) & alignOffsetMask));
 
   // If the client passed null as the address, choose a good one.
   if (!addr) {
@@ -166,7 +139,7 @@
       if (!(reinterpret_cast<uintptr_t>(ret) & alignOffsetMask))
         return ret;
       freePages(ret, len);
-#if CPU(32BIT)
+#if defined(ARCH_CPU_32_BITS)
       addr = reinterpret_cast<void*>(
           (reinterpret_cast<uintptr_t>(ret) + align) & alignBaseMask);
 #endif
@@ -174,12 +147,12 @@
       return nullptr;
 
     } else {
-#if CPU(32BIT)
+#if defined(ARCH_CPU_32_BITS)
       addr = reinterpret_cast<char*>(addr) + align;
 #endif
     }
 
-#if !CPU(32BIT)
+#if !defined(ARCH_CPU_32_BITS)
     // Keep trying random addresses on systems that have a large address space.
     addr = getRandomPageBase();
     addr = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(addr) &
@@ -190,7 +163,7 @@
   // Map a larger allocation so we can force alignment, but continue randomizing
   // only on 64-bit POSIX.
   size_t tryLen = len + (align - kPageAllocationGranularity);
-  RELEASE_ASSERT(tryLen >= len);
+  CHECK(tryLen >= len);
   void* ret;
 
   do {
@@ -200,38 +173,39 @@
     // The retries are for Windows, where a race can steal our mapping on
     // resize.
   } while (ret &&
-           !(ret = trimMapping(ret, tryLen, len, align, pageAccessibility)));
+           (ret = trimMapping(ret, tryLen, len, align, pageAccessibility)) ==
+               nullptr);
 
   return ret;
 }
 
 void freePages(void* addr, size_t len) {
-  ASSERT(!(reinterpret_cast<uintptr_t>(addr) &
+  DCHECK(!(reinterpret_cast<uintptr_t>(addr) &
            kPageAllocationGranularityOffsetMask));
-  ASSERT(!(len & kPageAllocationGranularityOffsetMask));
-#if OS(POSIX)
+  DCHECK(!(len & kPageAllocationGranularityOffsetMask));
+#if defined(OS_POSIX)
   int ret = munmap(addr, len);
-  RELEASE_ASSERT(!ret);
+  CHECK(!ret);
 #else
   BOOL ret = VirtualFree(addr, 0, MEM_RELEASE);
-  RELEASE_ASSERT(ret);
+  CHECK(ret);
 #endif
 }
 
 void setSystemPagesInaccessible(void* addr, size_t len) {
-  ASSERT(!(len & kSystemPageOffsetMask));
-#if OS(POSIX)
+  DCHECK(!(len & kSystemPageOffsetMask));
+#if defined(OS_POSIX)
   int ret = mprotect(addr, len, PROT_NONE);
-  RELEASE_ASSERT(!ret);
+  CHECK(!ret);
 #else
   BOOL ret = VirtualFree(addr, len, MEM_DECOMMIT);
-  RELEASE_ASSERT(ret);
+  CHECK(ret);
 #endif
 }
 
 bool setSystemPagesAccessible(void* addr, size_t len) {
-  ASSERT(!(len & kSystemPageOffsetMask));
-#if OS(POSIX)
+  DCHECK(!(len & kSystemPageOffsetMask));
+#if defined(OS_POSIX)
   return !mprotect(addr, len, PROT_READ | PROT_WRITE);
 #else
   return !!VirtualAlloc(addr, len, MEM_COMMIT, PAGE_READWRITE);
@@ -239,27 +213,27 @@
 }
 
 void decommitSystemPages(void* addr, size_t len) {
-  ASSERT(!(len & kSystemPageOffsetMask));
-#if OS(POSIX)
+  DCHECK(!(len & kSystemPageOffsetMask));
+#if defined(OS_POSIX)
   int ret = madvise(addr, len, MADV_FREE);
-  RELEASE_ASSERT(!ret);
+  CHECK(!ret);
 #else
   setSystemPagesInaccessible(addr, len);
 #endif
 }
 
 void recommitSystemPages(void* addr, size_t len) {
-  ASSERT(!(len & kSystemPageOffsetMask));
-#if OS(POSIX)
+  DCHECK(!(len & kSystemPageOffsetMask));
+#if defined(OS_POSIX)
   (void)addr;
 #else
-  RELEASE_ASSERT(setSystemPagesAccessible(addr, len));
+  CHECK(setSystemPagesAccessible(addr, len));
 #endif
 }
 
 void discardSystemPages(void* addr, size_t len) {
-  ASSERT(!(len & kSystemPageOffsetMask));
-#if OS(POSIX)
+  DCHECK(!(len & kSystemPageOffsetMask));
+#if defined(OS_POSIX)
   // On POSIX, the implementation detail is that discard and decommit are the
   // same, and lead to pages that are returned to the system immediately and
   // get replaced with zeroed pages when touched. So we just call
@@ -286,13 +260,13 @@
   // failure.
   if (ret) {
     void* ret = VirtualAlloc(addr, len, MEM_RESET, PAGE_READWRITE);
-    RELEASE_ASSERT(ret);
+    CHECK(ret);
   }
 #endif
 }
 
 uint32_t getAllocPageErrorCode() {
-  return acquireLoad(&s_allocPageErrorCode);
+  return base::subtle::Acquire_Load(&s_allocPageErrorCode);
 }
 
-}  // namespace WTF
+}  // namespace base
diff --git a/base/allocator/partition_allocator/page_allocator.h b/base/allocator/partition_allocator/page_allocator.h
new file mode 100644
index 0000000..d520505
--- /dev/null
+++ b/base/allocator/partition_allocator/page_allocator.h
@@ -0,0 +1,124 @@
+// Copyright (c) 2013 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_PARTITION_ALLOCATOR_PAGE_ALLOCATOR_H
+#define BASE_ALLOCATOR_PARTITION_ALLOCATOR_PAGE_ALLOCATOR_H
+
+#include <stdint.h>
+
+#include <cstddef>
+
+#include "base/base_export.h"
+#include "base/compiler_specific.h"
+#include "build/build_config.h"
+
+namespace base {
+
+#if defined(OS_WIN)
+static const size_t kPageAllocationGranularityShift = 16;  // 64KB
+#else
+static const size_t kPageAllocationGranularityShift = 12;  // 4KB
+#endif
+static const size_t kPageAllocationGranularity =
+    1 << kPageAllocationGranularityShift;
+static const size_t kPageAllocationGranularityOffsetMask =
+    kPageAllocationGranularity - 1;
+static const size_t kPageAllocationGranularityBaseMask =
+    ~kPageAllocationGranularityOffsetMask;
+
+// All Blink-supported systems have 4096 sized system pages and can handle
+// permissions and commit / decommit at this granularity.
+static const size_t kSystemPageSize = 4096;
+static const size_t kSystemPageOffsetMask = kSystemPageSize - 1;
+static const size_t kSystemPageBaseMask = ~kSystemPageOffsetMask;
+
+enum PageAccessibilityConfiguration {
+  PageAccessible,
+  PageInaccessible,
+};
+
+// Allocate one or more pages.
+// The requested address is just a hint; the actual address returned may
+// differ. The returned address will be aligned at least to align bytes.
+// len is in bytes, and must be a multiple of kPageAllocationGranularity.
+// align is in bytes, and must be a power-of-two multiple of
+// kPageAllocationGranularity.
+// If addr is null, then a suitable and randomized address will be chosen
+// automatically.
+// PageAccessibilityConfiguration controls the permission of the
+// allocated pages.
+// This call will return null if the allocation cannot be satisfied.
+BASE_EXPORT void* allocPages(void* addr,
+                             size_t len,
+                             size_t align,
+                             PageAccessibilityConfiguration);
+
+// Free one or more pages.
+// addr and len must match a previous call to allocPages().
+BASE_EXPORT void freePages(void* addr, size_t len);
+
+// Mark one or more system pages as being inaccessible.
+// Subsequently accessing any address in the range will fault, and the
+// addresses will not be re-used by future allocations.
+// len must be a multiple of kSystemPageSize bytes.
+BASE_EXPORT void setSystemPagesInaccessible(void* addr, size_t len);
+
+// Mark one or more system pages as being accessible.
+// The pages will be readable and writeable.
+// len must be a multiple of kSystemPageSize bytes.
+// The result bool value indicates whether the permission
+// change succeeded or not. You must check the result
+// (in most cases you need to CHECK that it is true).
+BASE_EXPORT WARN_UNUSED_RESULT bool setSystemPagesAccessible(void* addr,
+                                                             size_t len);
+
+// Decommit one or more system pages. Decommitted means that the physical memory
+// is released to the system, but the virtual address space remains reserved.
+// System pages are re-committed by calling recommitSystemPages(). Touching
+// a decommitted page _may_ fault.
+// Clients should not make any assumptions about the contents of decommitted
+// system pages, before or after they write to the page. The only guarantee
+// provided is that the contents of the system page will be deterministic again
+// after recommitting and writing to it. In particlar note that system pages are
+// not guaranteed to be zero-filled upon re-commit. len must be a multiple of
+// kSystemPageSize bytes.
+BASE_EXPORT void decommitSystemPages(void* addr, size_t len);
+
+// Recommit one or more system pages. Decommitted system pages must be
+// recommitted before they are read are written again.
+// Note that this operation may be a no-op on some platforms.
+// len must be a multiple of kSystemPageSize bytes.
+BASE_EXPORT void recommitSystemPages(void* addr, size_t len);
+
+// Discard one or more system pages. Discarding is a hint to the system that
+// the page is no longer required. The hint may:
+// - Do nothing.
+// - Discard the page immediately, freeing up physical pages.
+// - Discard the page at some time in the future in response to memory pressure.
+// Only committed pages should be discarded. Discarding a page does not
+// decommit it, and it is valid to discard an already-discarded page.
+// A read or write to a discarded page will not fault.
+// Reading from a discarded page may return the original page content, or a
+// page full of zeroes.
+// Writing to a discarded page is the only guaranteed way to tell the system
+// that the page is required again. Once written to, the content of the page is
+// guaranteed stable once more. After being written to, the page content may be
+// based on the original page content, or a page of zeroes.
+// len must be a multiple of kSystemPageSize bytes.
+BASE_EXPORT void discardSystemPages(void* addr, size_t len);
+
+ALWAYS_INLINE uintptr_t roundUpToSystemPage(uintptr_t address) {
+  return (address + kSystemPageOffsetMask) & kSystemPageBaseMask;
+}
+
+ALWAYS_INLINE uintptr_t roundDownToSystemPage(uintptr_t address) {
+  return address & kSystemPageBaseMask;
+}
+
+// Returns errno (or GetLastError code) when mmap (or VirtualAlloc) fails.
+BASE_EXPORT uint32_t getAllocPageErrorCode();
+
+}  // namespace base
+
+#endif  // BASE_ALLOCATOR_PARTITION_ALLOCATOR_PAGE_ALLOCATOR_H
diff --git a/third_party/WebKit/Source/wtf/allocator/PartitionAlloc.cpp b/base/allocator/partition_allocator/partition_alloc.cc
similarity index 84%
rename from third_party/WebKit/Source/wtf/allocator/PartitionAlloc.cpp
rename to base/allocator/partition_allocator/partition_alloc.cc
index 03978e8..d5c4f6a 100644
--- a/third_party/WebKit/Source/wtf/allocator/PartitionAlloc.cpp
+++ b/base/allocator/partition_allocator/partition_alloc.cc
@@ -1,72 +1,46 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * 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.
- *     * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
- * OWNER OR 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.
- */
+// Copyright (c) 2013 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 "wtf/allocator/PartitionAlloc.h"
+#include "base/allocator/partition_allocator/partition_alloc.h"
 
 #include <string.h>
 
-#ifndef NDEBUG
-#include <stdio.h>
-#endif
+#include "base/allocator/oom.h"
+#include "base/compiler_specific.h"
+#include "base/synchronization/spin_lock.h"
 
 // Two partition pages are used as guard / metadata page so make sure the super
 // page size is bigger.
-static_assert(WTF::kPartitionPageSize * 4 <= WTF::kSuperPageSize,
+static_assert(base::kPartitionPageSize * 4 <= base::kSuperPageSize,
               "ok super page size");
-static_assert(!(WTF::kSuperPageSize % WTF::kPartitionPageSize),
+static_assert(!(base::kSuperPageSize % base::kPartitionPageSize),
               "ok super page multiple");
 // Four system pages gives us room to hack out a still-guard-paged piece
 // of metadata in the middle of a guard partition page.
-static_assert(WTF::kSystemPageSize * 4 <= WTF::kPartitionPageSize,
+static_assert(base::kSystemPageSize * 4 <= base::kPartitionPageSize,
               "ok partition page size");
-static_assert(!(WTF::kPartitionPageSize % WTF::kSystemPageSize),
+static_assert(!(base::kPartitionPageSize % base::kSystemPageSize),
               "ok partition page multiple");
-static_assert(sizeof(WTF::PartitionPage) <= WTF::kPageMetadataSize,
+static_assert(sizeof(base::PartitionPage) <= base::kPageMetadataSize,
               "PartitionPage should not be too big");
-static_assert(sizeof(WTF::PartitionBucket) <= WTF::kPageMetadataSize,
+static_assert(sizeof(base::PartitionBucket) <= base::kPageMetadataSize,
               "PartitionBucket should not be too big");
-static_assert(sizeof(WTF::PartitionSuperPageExtentEntry) <=
-                  WTF::kPageMetadataSize,
+static_assert(sizeof(base::PartitionSuperPageExtentEntry) <=
+                  base::kPageMetadataSize,
               "PartitionSuperPageExtentEntry should not be too big");
-static_assert(WTF::kPageMetadataSize * WTF::kNumPartitionPagesPerSuperPage <=
-                  WTF::kSystemPageSize,
+static_assert(base::kPageMetadataSize * base::kNumPartitionPagesPerSuperPage <=
+                  base::kSystemPageSize,
               "page metadata fits in hole");
 // Check that some of our zanier calculations worked out as expected.
-static_assert(WTF::kGenericSmallestBucket == 8, "generic smallest bucket");
-static_assert(WTF::kGenericMaxBucketed == 983040, "generic max bucketed");
-static_assert(WTF::kMaxSystemPagesPerSlotSpan < (1 << 8),
+static_assert(base::kGenericSmallestBucket == 8, "generic smallest bucket");
+static_assert(base::kGenericMaxBucketed == 983040, "generic max bucketed");
+static_assert(base::kMaxSystemPagesPerSlotSpan < (1 << 8),
               "System pages per slot span must be less than 128.");
 
-namespace WTF {
+namespace base {
 
-SpinLock PartitionRootBase::gInitializedLock;
+subtle::SpinLock PartitionRootBase::gInitializedLock;
 bool PartitionRootBase::gInitialized = false;
 PartitionPage PartitionRootBase::gSeedPage;
 PartitionBucket PartitionRootBase::gPagedBucket;
@@ -89,12 +63,12 @@
   double bestWasteRatio = 1.0f;
   uint16_t bestPages = 0;
   if (size > kMaxSystemPagesPerSlotSpan * kSystemPageSize) {
-    ASSERT(!(size % kSystemPageSize));
+    DCHECK(!(size % kSystemPageSize));
     bestPages = static_cast<uint16_t>(size / kSystemPageSize);
-    RELEASE_ASSERT(bestPages < (1 << 8));
+    CHECK(bestPages < (1 << 8));
     return static_cast<uint8_t>(bestPages);
   }
-  ASSERT(size <= kMaxSystemPagesPerSlotSpan * kSystemPageSize);
+  DCHECK(size <= kMaxSystemPagesPerSlotSpan * kSystemPageSize);
   for (uint16_t i = kNumSystemPagesPerPartitionPage - 1;
        i <= kMaxSystemPagesPerSlotSpan; ++i) {
     size_t pageSize = kSystemPageSize * i;
@@ -114,15 +88,15 @@
       bestPages = i;
     }
   }
-  ASSERT(bestPages > 0);
-  RELEASE_ASSERT(bestPages <= kMaxSystemPagesPerSlotSpan);
+  DCHECK(bestPages > 0);
+  CHECK(bestPages <= kMaxSystemPagesPerSlotSpan);
   return static_cast<uint8_t>(bestPages);
 }
 
 static void partitionAllocBaseInit(PartitionRootBase* root) {
-  ASSERT(!root->initialized);
+  DCHECK(!root->initialized);
   {
-    SpinLock::Guard guard(PartitionRootBase::gInitializedLock);
+    subtle::SpinLock::Guard guard(PartitionRootBase::gInitializedLock);
     if (!PartitionRootBase::gInitialized) {
       PartitionRootBase::gInitialized = true;
       // We mark the seed page as free to make sure it is skipped by our
@@ -161,7 +135,7 @@
 }
 
 void partitionAllocGlobalInit(void (*oomHandlingFunction)()) {
-  ASSERT(oomHandlingFunction);
+  DCHECK(oomHandlingFunction);
   PartitionRootBase::gOomHandlingFunction = oomHandlingFunction;
 }
 
@@ -184,7 +158,7 @@
 }
 
 void partitionAllocGenericInit(PartitionRootGeneric* root) {
-  SpinLock::Guard guard(root->lock);
+  subtle::SpinLock::Guard guard(root->lock);
 
   partitionAllocBaseInit(root);
 
@@ -237,8 +211,8 @@
     }
     currentIncrement <<= 1;
   }
-  ASSERT(currentSize == 1 << kGenericMaxBucketedOrder);
-  ASSERT(bucket == &root->buckets[0] + kGenericNumBuckets);
+  DCHECK(currentSize == 1 << kGenericMaxBucketedOrder);
+  DCHECK(bucket == &root->buckets[0] + kGenericNumBuckets);
 
   // Then set up the fast size -> bucket lookup table.
   bucket = &root->buckets[0];
@@ -260,8 +234,8 @@
       }
     }
   }
-  ASSERT(bucket == &root->buckets[0] + kGenericNumBuckets);
-  ASSERT(bucketPtr ==
+  DCHECK(bucket == &root->buckets[0] + kGenericNumBuckets);
+  DCHECK(bucketPtr ==
          &root->bucketLookups[0] +
              ((kBitsPerSizet + 1) * kGenericNumBucketsPerOrder));
   // And there's one last bucket lookup that will be hit for e.g. malloc(-1),
@@ -271,7 +245,7 @@
 
 static bool partitionAllocShutdownBucket(PartitionBucket* bucket) {
   // Failure here indicates a memory leak.
-  bool foundLeak = bucket->numFullPages;
+  bool foundLeak = bucket->numFullPages != 0;
   for (PartitionPage* page = bucket->activePagesHead; page;
        page = page->nextPage)
     foundLeak |= (page->numAllocatedSlots > 0);
@@ -279,7 +253,7 @@
 }
 
 static bool partitionAllocBaseShutdown(PartitionRootBase* root) {
-  ASSERT(root->initialized);
+  DCHECK(root->initialized);
   root->initialized = false;
 
   // Now that we've examined all partition pages in all buckets, it's safe
@@ -297,7 +271,7 @@
     }
     entry = nextEntry;
   }
-  return root->directMapList;
+  return root->directMapList != nullptr;
 }
 
 bool partitionAllocShutdown(PartitionRoot* root) {
@@ -312,7 +286,7 @@
 }
 
 bool partitionAllocGenericShutdown(PartitionRootGeneric* root) {
-  SpinLock::Guard guard(root->lock);
+  subtle::SpinLock::Guard guard(root->lock);
   bool foundLeak = false;
   size_t i;
   for (i = 0; i < kGenericNumBuckets; ++i) {
@@ -323,14 +297,14 @@
   return !foundLeak;
 }
 
-#if !CPU(64BIT)
-static NEVER_INLINE void partitionOutOfMemoryWithLotsOfUncommitedPages() {
+#if !defined(ARCH_CPU_64_BITS)
+static NOINLINE void partitionOutOfMemoryWithLotsOfUncommitedPages() {
   OOM_CRASH();
 }
 #endif
 
-static NEVER_INLINE void partitionOutOfMemory(const PartitionRootBase* root) {
-#if !CPU(64BIT)
+static NOINLINE void partitionOutOfMemory(const PartitionRootBase* root) {
+#if !defined(ARCH_CPU_64_BITS)
   // Check whether this OOM is due to a lot of super pages that are allocated
   // but not committed, probably due to http://crbug.com/421387.
   if (root->totalSizeOfSuperPages + root->totalSizeOfDirectMappedPages -
@@ -344,11 +318,11 @@
   OOM_CRASH();
 }
 
-static NEVER_INLINE void partitionExcessiveAllocationSize() {
+static NOINLINE void partitionExcessiveAllocationSize() {
   OOM_CRASH();
 }
 
-static NEVER_INLINE void partitionBucketFull() {
+static NOINLINE void partitionBucketFull() {
   OOM_CRASH();
 }
 
@@ -358,37 +332,37 @@
 // that were detached from the active list.
 static bool ALWAYS_INLINE
 partitionPageStateIsActive(const PartitionPage* page) {
-  ASSERT(page != &PartitionRootGeneric::gSeedPage);
-  ASSERT(!page->pageOffset);
+  DCHECK(page != &PartitionRootGeneric::gSeedPage);
+  DCHECK(!page->pageOffset);
   return (page->numAllocatedSlots > 0 &&
           (page->freelistHead || page->numUnprovisionedSlots));
 }
 
 static bool ALWAYS_INLINE partitionPageStateIsFull(const PartitionPage* page) {
-  ASSERT(page != &PartitionRootGeneric::gSeedPage);
-  ASSERT(!page->pageOffset);
+  DCHECK(page != &PartitionRootGeneric::gSeedPage);
+  DCHECK(!page->pageOffset);
   bool ret = (page->numAllocatedSlots == partitionBucketSlots(page->bucket));
   if (ret) {
-    ASSERT(!page->freelistHead);
-    ASSERT(!page->numUnprovisionedSlots);
+    DCHECK(!page->freelistHead);
+    DCHECK(!page->numUnprovisionedSlots);
   }
   return ret;
 }
 
 static bool ALWAYS_INLINE partitionPageStateIsEmpty(const PartitionPage* page) {
-  ASSERT(page != &PartitionRootGeneric::gSeedPage);
-  ASSERT(!page->pageOffset);
+  DCHECK(page != &PartitionRootGeneric::gSeedPage);
+  DCHECK(!page->pageOffset);
   return (!page->numAllocatedSlots && page->freelistHead);
 }
 
 static bool ALWAYS_INLINE
 partitionPageStateIsDecommitted(const PartitionPage* page) {
-  ASSERT(page != &PartitionRootGeneric::gSeedPage);
-  ASSERT(!page->pageOffset);
+  DCHECK(page != &PartitionRootGeneric::gSeedPage);
+  DCHECK(!page->pageOffset);
   bool ret = (!page->numAllocatedSlots && !page->freelistHead);
   if (ret) {
-    ASSERT(!page->numUnprovisionedSlots);
-    ASSERT(page->emptyCacheIndex == -1);
+    DCHECK(!page->numUnprovisionedSlots);
+    DCHECK(page->emptyCacheIndex == -1);
   }
   return ret;
 }
@@ -396,14 +370,14 @@
 static void partitionIncreaseCommittedPages(PartitionRootBase* root,
                                             size_t len) {
   root->totalSizeOfCommittedPages += len;
-  ASSERT(root->totalSizeOfCommittedPages <=
+  DCHECK(root->totalSizeOfCommittedPages <=
          root->totalSizeOfSuperPages + root->totalSizeOfDirectMappedPages);
 }
 
 static void partitionDecreaseCommittedPages(PartitionRootBase* root,
                                             size_t len) {
   root->totalSizeOfCommittedPages -= len;
-  ASSERT(root->totalSizeOfCommittedPages <=
+  DCHECK(root->totalSizeOfCommittedPages <=
          root->totalSizeOfSuperPages + root->totalSizeOfDirectMappedPages);
 }
 
@@ -425,11 +399,11 @@
     PartitionRootBase* root,
     int flags,
     uint16_t numPartitionPages) {
-  ASSERT(!(reinterpret_cast<uintptr_t>(root->nextPartitionPage) %
+  DCHECK(!(reinterpret_cast<uintptr_t>(root->nextPartitionPage) %
            kPartitionPageSize));
-  ASSERT(!(reinterpret_cast<uintptr_t>(root->nextPartitionPageEnd) %
+  DCHECK(!(reinterpret_cast<uintptr_t>(root->nextPartitionPageEnd) %
            kPartitionPageSize));
-  ASSERT(numPartitionPages <= kNumPartitionPagesPerSuperPage);
+  DCHECK(numPartitionPages <= kNumPartitionPagesPerSuperPage);
   size_t totalSize = kPartitionPageSize * numPartitionPages;
   size_t numPartitionPagesLeft =
       (root->nextPartitionPageEnd - root->nextPartitionPage) >>
@@ -499,10 +473,10 @@
   bool isNewExtent = (superPage != requestedAddress);
   if (UNLIKELY(isNewExtent)) {
     if (UNLIKELY(!currentExtent)) {
-      ASSERT(!root->firstExtent);
+      DCHECK(!root->firstExtent);
       root->firstExtent = latestExtent;
     } else {
-      ASSERT(currentExtent->superPageBase);
+      DCHECK(currentExtent->superPageBase);
       currentExtent->next = latestExtent;
     }
     root->currentExtent = latestExtent;
@@ -511,9 +485,9 @@
   } else {
     // We allocated next to an existing extent so just nudge the size up a
     // little.
-    ASSERT(currentExtent->superPagesEnd);
+    DCHECK(currentExtent->superPagesEnd);
     currentExtent->superPagesEnd += kSuperPageSize;
-    ASSERT(ret >= currentExtent->superPageBase &&
+    DCHECK(ret >= currentExtent->superPageBase &&
            ret < currentExtent->superPagesEnd);
   }
   return ret;
@@ -527,10 +501,10 @@
 }
 
 static ALWAYS_INLINE void partitionPageReset(PartitionPage* page) {
-  ASSERT(partitionPageStateIsDecommitted(page));
+  DCHECK(partitionPageStateIsDecommitted(page));
 
   page->numUnprovisionedSlots = partitionBucketSlots(page->bucket);
-  ASSERT(page->numUnprovisionedSlots);
+  DCHECK(page->numUnprovisionedSlots);
 
   page->nextPage = nullptr;
 }
@@ -561,17 +535,17 @@
 
 static ALWAYS_INLINE char* partitionPageAllocAndFillFreelist(
     PartitionPage* page) {
-  ASSERT(page != &PartitionRootGeneric::gSeedPage);
+  DCHECK(page != &PartitionRootGeneric::gSeedPage);
   uint16_t numSlots = page->numUnprovisionedSlots;
-  ASSERT(numSlots);
+  DCHECK(numSlots);
   PartitionBucket* bucket = page->bucket;
   // We should only get here when _every_ slot is either used or unprovisioned.
   // (The third state is "on the freelist". If we have a non-empty freelist, we
   // should not get here.)
-  ASSERT(numSlots + page->numAllocatedSlots == partitionBucketSlots(bucket));
+  DCHECK(numSlots + page->numAllocatedSlots == partitionBucketSlots(bucket));
   // Similarly, make explicitly sure that the freelist is empty.
-  ASSERT(!page->freelistHead);
-  ASSERT(page->numAllocatedSlots >= 0);
+  DCHECK(!page->freelistHead);
+  DCHECK(page->numAllocatedSlots >= 0);
 
   size_t size = bucket->slotSize;
   char* base = reinterpret_cast<char*>(partitionPageToPointer(page));
@@ -583,7 +557,7 @@
   // page containing the "end" of the returned slot, and then allow freelist
   // pointers to be written up to the end of that page.
   char* subPageLimit = reinterpret_cast<char*>(
-      WTF::roundUpToSystemPage(reinterpret_cast<size_t>(firstFreelistPointer)));
+      roundUpToSystemPage(reinterpret_cast<size_t>(firstFreelistPointer)));
   char* slotsLimit = returnObject + (size * numSlots);
   char* freelistLimit = subPageLimit;
   if (UNLIKELY(slotsLimit < freelistLimit))
@@ -604,7 +578,7 @@
   // We always return an object slot -- that's the +1 below.
   // We do not neccessarily create any new freelist entries, because we cross
   // sub page boundaries frequently for large bucket sizes.
-  ASSERT(numNewFreelistEntries + 1 <= numSlots);
+  DCHECK(numNewFreelistEntries + 1 <= numSlots);
   numSlots -= (numNewFreelistEntries + 1);
   page->numUnprovisionedSlots = numSlots;
   page->numAllocatedSlots++;
@@ -645,9 +619,9 @@
 
   for (; page; page = nextPage) {
     nextPage = page->nextPage;
-    ASSERT(page->bucket == bucket);
-    ASSERT(page != bucket->emptyPagesHead);
-    ASSERT(page != bucket->decommittedPagesHead);
+    DCHECK(page->bucket == bucket);
+    DCHECK(page != bucket->emptyPagesHead);
+    DCHECK(page != bucket->decommittedPagesHead);
 
     // Deal with empty and decommitted pages.
     if (LIKELY(partitionPageStateIsActive(page))) {
@@ -663,7 +637,7 @@
       page->nextPage = bucket->decommittedPagesHead;
       bucket->decommittedPagesHead = page;
     } else {
-      ASSERT(partitionPageStateIsFull(page));
+      DCHECK(partitionPageStateIsFull(page));
       // If we get here, we found a full page. Skip over it too, and also
       // tag it as full (via a negative value). We need it tagged so that
       // free'ing can tell, and move it back into the active page list.
@@ -684,7 +658,7 @@
 
 static ALWAYS_INLINE PartitionDirectMapExtent* partitionPageToDirectMapExtent(
     PartitionPage* page) {
-  ASSERT(partitionBucketIsDirectMapped(page->bucket));
+  DCHECK(partitionBucketIsDirectMapped(page->bucket));
   return reinterpret_cast<PartitionDirectMapExtent*>(
       reinterpret_cast<char*>(page) + 3 * kPageMetadataSize);
 }
@@ -709,7 +683,7 @@
   // - We add a trailing guard page on 32-bit (on 64-bit we rely on the
   // massive address space plus randomization instead).
   size_t mapSize = size + kPartitionPageSize;
-#if !CPU(64BIT)
+#if !defined(ARCH_CPU_64_BITS)
   mapSize += kSystemPageSize;
 #endif
   // Round up to the allocation granularity.
@@ -730,7 +704,7 @@
   char* slot = ptr + kPartitionPageSize;
   setSystemPagesInaccessible(ptr + (kSystemPageSize * 2),
                              kPartitionPageSize - (kSystemPageSize * 2));
-#if !CPU(64BIT)
+#if !defined(ARCH_CPU_64_BITS)
   setSystemPagesInaccessible(ptr, kSystemPageSize);
   setSystemPagesInaccessible(slot + size, kSystemPageSize);
 #endif
@@ -740,29 +714,29 @@
           partitionSuperPageToMetadataArea(ptr));
   extent->root = root;
   // The new structures are all located inside a fresh system page so they
-  // will all be zeroed out. These ASSERTs are for documentation.
-  ASSERT(!extent->superPageBase);
-  ASSERT(!extent->superPagesEnd);
-  ASSERT(!extent->next);
+  // will all be zeroed out. These DCHECKs are for documentation.
+  DCHECK(!extent->superPageBase);
+  DCHECK(!extent->superPagesEnd);
+  DCHECK(!extent->next);
   PartitionPage* page = partitionPointerToPageNoAlignmentCheck(slot);
   PartitionBucket* bucket = reinterpret_cast<PartitionBucket*>(
       reinterpret_cast<char*>(page) + (kPageMetadataSize * 2));
-  ASSERT(!page->nextPage);
-  ASSERT(!page->numAllocatedSlots);
-  ASSERT(!page->numUnprovisionedSlots);
-  ASSERT(!page->pageOffset);
-  ASSERT(!page->emptyCacheIndex);
+  DCHECK(!page->nextPage);
+  DCHECK(!page->numAllocatedSlots);
+  DCHECK(!page->numUnprovisionedSlots);
+  DCHECK(!page->pageOffset);
+  DCHECK(!page->emptyCacheIndex);
   page->bucket = bucket;
   page->freelistHead = reinterpret_cast<PartitionFreelistEntry*>(slot);
   PartitionFreelistEntry* nextEntry =
       reinterpret_cast<PartitionFreelistEntry*>(slot);
   nextEntry->next = partitionFreelistMask(0);
 
-  ASSERT(!bucket->activePagesHead);
-  ASSERT(!bucket->emptyPagesHead);
-  ASSERT(!bucket->decommittedPagesHead);
-  ASSERT(!bucket->numSystemPagesPerSlotSpan);
-  ASSERT(!bucket->numFullPages);
+  DCHECK(!bucket->activePagesHead);
+  DCHECK(!bucket->emptyPagesHead);
+  DCHECK(!bucket->decommittedPagesHead);
+  DCHECK(!bucket->numSystemPagesPerSlotSpan);
+  DCHECK(!bucket->numFullPages);
   bucket->slotSize = size;
 
   PartitionDirectMapExtent* mapExtent = partitionPageToDirectMapExtent(page);
@@ -786,13 +760,13 @@
 
   // Maintain the doubly-linked list of all direct mappings.
   if (extent->prevExtent) {
-    ASSERT(extent->prevExtent->nextExtent == extent);
+    DCHECK(extent->prevExtent->nextExtent == extent);
     extent->prevExtent->nextExtent = extent->nextExtent;
   } else {
     root->directMapList = extent->nextExtent;
   }
   if (extent->nextExtent) {
-    ASSERT(extent->nextExtent->prevExtent == extent);
+    DCHECK(extent->nextExtent->prevExtent == extent);
     extent->nextExtent->prevExtent = extent->prevExtent;
   }
 
@@ -802,10 +776,10 @@
 
   size_t uncommittedPageSize = page->bucket->slotSize + kSystemPageSize;
   partitionDecreaseCommittedPages(root, uncommittedPageSize);
-  ASSERT(root->totalSizeOfDirectMappedPages >= uncommittedPageSize);
+  DCHECK(root->totalSizeOfDirectMappedPages >= uncommittedPageSize);
   root->totalSizeOfDirectMappedPages -= uncommittedPageSize;
 
-  ASSERT(!(unmapSize & kPageAllocationGranularityOffsetMask));
+  DCHECK(!(unmapSize & kPageAllocationGranularityOffsetMask));
 
   char* ptr = reinterpret_cast<char*>(partitionPageToPointer(page));
   // Account for the mapping starting a partition page before the actual
@@ -820,7 +794,7 @@
                              size_t size,
                              PartitionBucket* bucket) {
   // The slow path is called when the freelist is empty.
-  ASSERT(!bucket->activePagesHead->freelistHead);
+  DCHECK(!bucket->activePagesHead->freelistHead);
 
   PartitionPage* newPage = nullptr;
 
@@ -830,9 +804,9 @@
   // branches.
   bool returnNull = flags & PartitionAllocReturnNull;
   if (UNLIKELY(partitionBucketIsDirectMapped(bucket))) {
-    ASSERT(size > kGenericMaxBucketed);
-    ASSERT(bucket == &PartitionRootBase::gPagedBucket);
-    ASSERT(bucket->activePagesHead == &PartitionRootGeneric::gSeedPage);
+    DCHECK(size > kGenericMaxBucketed);
+    DCHECK(bucket == &PartitionRootBase::gPagedBucket);
+    DCHECK(bucket->activePagesHead == &PartitionRootGeneric::gSeedPage);
     if (size > kGenericMaxDirectMapped) {
       if (returnNull)
         return nullptr;
@@ -842,15 +816,15 @@
   } else if (LIKELY(partitionSetNewActivePage(bucket))) {
     // First, did we find an active page in the active pages list?
     newPage = bucket->activePagesHead;
-    ASSERT(partitionPageStateIsActive(newPage));
+    DCHECK(partitionPageStateIsActive(newPage));
   } else if (LIKELY(bucket->emptyPagesHead != nullptr) ||
              LIKELY(bucket->decommittedPagesHead != nullptr)) {
     // Second, look in our lists of empty and decommitted pages.
     // Check empty pages first, which are preferred, but beware that an
     // empty page might have been decommitted.
     while (LIKELY((newPage = bucket->emptyPagesHead) != nullptr)) {
-      ASSERT(newPage->bucket == bucket);
-      ASSERT(partitionPageStateIsEmpty(newPage) ||
+      DCHECK(newPage->bucket == bucket);
+      DCHECK(partitionPageStateIsEmpty(newPage) ||
              partitionPageStateIsDecommitted(newPage));
       bucket->emptyPagesHead = newPage->nextPage;
       // Accept the empty page unless it got decommitted.
@@ -858,21 +832,21 @@
         newPage->nextPage = nullptr;
         break;
       }
-      ASSERT(partitionPageStateIsDecommitted(newPage));
+      DCHECK(partitionPageStateIsDecommitted(newPage));
       newPage->nextPage = bucket->decommittedPagesHead;
       bucket->decommittedPagesHead = newPage;
     }
     if (UNLIKELY(!newPage) && LIKELY(bucket->decommittedPagesHead != nullptr)) {
       newPage = bucket->decommittedPagesHead;
-      ASSERT(newPage->bucket == bucket);
-      ASSERT(partitionPageStateIsDecommitted(newPage));
+      DCHECK(newPage->bucket == bucket);
+      DCHECK(partitionPageStateIsDecommitted(newPage));
       bucket->decommittedPagesHead = newPage->nextPage;
       void* addr = partitionPageToPointer(newPage);
       partitionRecommitSystemPages(root, addr,
                                    partitionBucketBytes(newPage->bucket));
       partitionPageReset(newPage);
     }
-    ASSERT(newPage);
+    DCHECK(newPage);
   } else {
     // Third. If we get here, we need a brand new page.
     uint16_t numPartitionPages = partitionBucketPartitionPages(bucket);
@@ -886,14 +860,14 @@
 
   // Bail if we had a memory allocation failure.
   if (UNLIKELY(!newPage)) {
-    ASSERT(bucket->activePagesHead == &PartitionRootGeneric::gSeedPage);
+    DCHECK(bucket->activePagesHead == &PartitionRootGeneric::gSeedPage);
     if (returnNull)
       return nullptr;
     partitionOutOfMemory(root);
   }
 
   bucket = newPage->bucket;
-  ASSERT(bucket != &PartitionRootBase::gPagedBucket);
+  DCHECK(bucket != &PartitionRootBase::gPagedBucket);
   bucket->activePagesHead = newPage;
   partitionPageSetRawSize(newPage, size);
 
@@ -907,14 +881,14 @@
     return entry;
   }
   // Otherwise, we need to build the freelist.
-  ASSERT(newPage->numUnprovisionedSlots);
+  DCHECK(newPage->numUnprovisionedSlots);
   return partitionPageAllocAndFillFreelist(newPage);
 }
 
 static ALWAYS_INLINE void partitionDecommitPage(PartitionRootBase* root,
                                                 PartitionPage* page) {
-  ASSERT(partitionPageStateIsEmpty(page));
-  ASSERT(!partitionBucketIsDirectMapped(page->bucket));
+  DCHECK(partitionPageStateIsEmpty(page));
+  DCHECK(!partitionBucketIsDirectMapped(page->bucket));
   void* addr = partitionPageToPointer(page);
   partitionDecommitSystemPages(root, addr, partitionBucketBytes(page->bucket));
 
@@ -926,28 +900,28 @@
   // 32 bytes in size.
   page->freelistHead = 0;
   page->numUnprovisionedSlots = 0;
-  ASSERT(partitionPageStateIsDecommitted(page));
+  DCHECK(partitionPageStateIsDecommitted(page));
 }
 
 static void partitionDecommitPageIfPossible(PartitionRootBase* root,
                                             PartitionPage* page) {
-  ASSERT(page->emptyCacheIndex >= 0);
-  ASSERT(static_cast<unsigned>(page->emptyCacheIndex) < kMaxFreeableSpans);
-  ASSERT(page == root->globalEmptyPageRing[page->emptyCacheIndex]);
+  DCHECK(page->emptyCacheIndex >= 0);
+  DCHECK(static_cast<unsigned>(page->emptyCacheIndex) < kMaxFreeableSpans);
+  DCHECK(page == root->globalEmptyPageRing[page->emptyCacheIndex]);
   page->emptyCacheIndex = -1;
   if (partitionPageStateIsEmpty(page))
     partitionDecommitPage(root, page);
 }
 
 static ALWAYS_INLINE void partitionRegisterEmptyPage(PartitionPage* page) {
-  ASSERT(partitionPageStateIsEmpty(page));
+  DCHECK(partitionPageStateIsEmpty(page));
   PartitionRootBase* root = partitionPageToRoot(page);
 
   // If the page is already registered as empty, give it another life.
   if (page->emptyCacheIndex != -1) {
-    ASSERT(page->emptyCacheIndex >= 0);
-    ASSERT(static_cast<unsigned>(page->emptyCacheIndex) < kMaxFreeableSpans);
-    ASSERT(root->globalEmptyPageRing[page->emptyCacheIndex] == page);
+    DCHECK(page->emptyCacheIndex >= 0);
+    DCHECK(static_cast<unsigned>(page->emptyCacheIndex) < kMaxFreeableSpans);
+    DCHECK(root->globalEmptyPageRing[page->emptyCacheIndex] == page);
     root->globalEmptyPageRing[page->emptyCacheIndex] = 0;
   }
 
@@ -981,7 +955,7 @@
 
 void partitionFreeSlowPath(PartitionPage* page) {
   PartitionBucket* bucket = page->bucket;
-  ASSERT(page != &PartitionRootGeneric::gSeedPage);
+  DCHECK(page != &PartitionRootGeneric::gSeedPage);
   if (LIKELY(page->numAllocatedSlots == 0)) {
     // Page became fully unused.
     if (UNLIKELY(partitionBucketIsDirectMapped(bucket))) {
@@ -992,27 +966,27 @@
     // the empty list as a force towards defragmentation.
     if (LIKELY(page == bucket->activePagesHead))
       (void)partitionSetNewActivePage(bucket);
-    ASSERT(bucket->activePagesHead != page);
+    DCHECK(bucket->activePagesHead != page);
 
     partitionPageSetRawSize(page, 0);
-    ASSERT(!partitionPageGetRawSize(page));
+    DCHECK(!partitionPageGetRawSize(page));
 
     partitionRegisterEmptyPage(page);
   } else {
-    ASSERT(!partitionBucketIsDirectMapped(bucket));
+    DCHECK(!partitionBucketIsDirectMapped(bucket));
     // Ensure that the page is full. That's the only valid case if we
     // arrive here.
-    ASSERT(page->numAllocatedSlots < 0);
+    DCHECK(page->numAllocatedSlots < 0);
     // A transition of numAllocatedSlots from 0 to -1 is not legal, and
     // likely indicates a double-free.
-    SECURITY_CHECK(page->numAllocatedSlots != -1);
+    CHECK(page->numAllocatedSlots != -1);
     page->numAllocatedSlots = -page->numAllocatedSlots - 2;
-    ASSERT(page->numAllocatedSlots == partitionBucketSlots(bucket) - 1);
+    DCHECK(page->numAllocatedSlots == partitionBucketSlots(bucket) - 1);
     // Fully used page became partially used. It must be put back on the
     // non-full page list. Also make it the current page to increase the
     // chances of it being filled up again. The old current page will be
     // the next page.
-    ASSERT(!page->nextPage);
+    DCHECK(!page->nextPage);
     if (LIKELY(bucket->activePagesHead != &PartitionRootGeneric::gSeedPage))
       page->nextPage = bucket->activePagesHead;
     bucket->activePagesHead = page;
@@ -1027,7 +1001,7 @@
 bool partitionReallocDirectMappedInPlace(PartitionRootGeneric* root,
                                          PartitionPage* page,
                                          size_t rawSize) {
-  ASSERT(partitionBucketIsDirectMapped(page->bucket));
+  DCHECK(partitionBucketIsDirectMapped(page->bucket));
 
   rawSize = partitionCookieSizeAdjustAdd(rawSize);
 
@@ -1061,10 +1035,10 @@
     // pages accessible again.
     size_t recommitSize = newSize - currentSize;
     bool ret = setSystemPagesAccessible(charPtr + currentSize, recommitSize);
-    RELEASE_ASSERT(ret);
+    CHECK(ret);
     partitionRecommitSystemPages(root, charPtr + currentSize, recommitSize);
 
-#if ENABLE(ASSERT)
+#if DCHECK_IS_ON()
     memset(charPtr + currentSize, kUninitializedByte, recommitSize);
 #endif
   } else {
@@ -1073,13 +1047,13 @@
     return false;
   }
 
-#if ENABLE(ASSERT)
+#if DCHECK_IS_ON()
   // Write a new trailing cookie.
   partitionCookieWriteValue(charPtr + rawSize - kCookieSize);
 #endif
 
   partitionPageSetRawSize(page, rawSize);
-  ASSERT(partitionPageGetRawSize(page) == rawSize);
+  DCHECK(partitionPageGetRawSize(page) == rawSize);
 
   page->bucket->slotSize = newSize;
   return true;
@@ -1102,7 +1076,7 @@
   if (newSize > kGenericMaxDirectMapped)
     partitionExcessiveAllocationSize();
 
-  ASSERT(partitionPointerIsValid(partitionCookieFreePointerAdjust(ptr)));
+  DCHECK(partitionPointerIsValid(partitionCookieFreePointerAdjust(ptr)));
 
   PartitionPage* page =
       partitionPointerToPage(partitionCookieFreePointerAdjust(ptr));
@@ -1153,8 +1127,7 @@
 
   size_t rawSize = partitionPageGetRawSize(const_cast<PartitionPage*>(page));
   if (rawSize) {
-    uint32_t usedBytes =
-        static_cast<uint32_t>(WTF::roundUpToSystemPage(rawSize));
+    uint32_t usedBytes = static_cast<uint32_t>(roundUpToSystemPage(rawSize));
     discardableBytes = bucket->slotSize - usedBytes;
     if (discardableBytes && discard) {
       char* ptr = reinterpret_cast<char*>(partitionPageToPointer(page));
@@ -1166,8 +1139,8 @@
 
   const size_t maxSlotCount =
       (kPartitionPageSize * kMaxPartitionPagesPerSlotSpan) / kSystemPageSize;
-  ASSERT(bucketNumSlots <= maxSlotCount);
-  ASSERT(page->numUnprovisionedSlots < bucketNumSlots);
+  DCHECK(bucketNumSlots <= maxSlotCount);
+  DCHECK(page->numUnprovisionedSlots < bucketNumSlots);
   size_t numSlots = bucketNumSlots - page->numUnprovisionedSlots;
   char slotUsage[maxSlotCount];
   size_t lastSlot = static_cast<size_t>(-1);
@@ -1178,7 +1151,7 @@
   // are not in use.
   while (entry) {
     size_t slotIndex = (reinterpret_cast<char*>(entry) - ptr) / slotSize;
-    ASSERT(slotIndex < numSlots);
+    DCHECK(slotIndex < numSlots);
     slotUsage[slotIndex] = 0;
     entry = partitionFreelistMask(entry->next);
     // If we have a slot where the masked freelist entry is 0, we can
@@ -1196,7 +1169,7 @@
   while (!slotUsage[numSlots - 1]) {
     truncatedSlots++;
     numSlots--;
-    ASSERT(numSlots);
+    DCHECK(numSlots);
   }
   // First, do the work of calculating the discardable bytes. Don't actually
   // discard anything unless the discard flag was passed in.
@@ -1207,19 +1180,19 @@
     beginPtr = ptr + (numSlots * slotSize);
     endPtr = beginPtr + (slotSize * truncatedSlots);
     beginPtr = reinterpret_cast<char*>(
-        WTF::roundUpToSystemPage(reinterpret_cast<size_t>(beginPtr)));
+        roundUpToSystemPage(reinterpret_cast<size_t>(beginPtr)));
     // We round the end pointer here up and not down because we're at the
     // end of a slot span, so we "own" all the way up the page boundary.
     endPtr = reinterpret_cast<char*>(
-        WTF::roundUpToSystemPage(reinterpret_cast<size_t>(endPtr)));
-    ASSERT(endPtr <= ptr + partitionBucketBytes(bucket));
+        roundUpToSystemPage(reinterpret_cast<size_t>(endPtr)));
+    DCHECK(endPtr <= ptr + partitionBucketBytes(bucket));
     if (beginPtr < endPtr) {
       unprovisionedBytes = endPtr - beginPtr;
       discardableBytes += unprovisionedBytes;
     }
   }
   if (unprovisionedBytes && discard) {
-    ASSERT(truncatedSlots > 0);
+    DCHECK(truncatedSlots > 0);
     size_t numNewEntries = 0;
     page->numUnprovisionedSlots += static_cast<uint16_t>(truncatedSlots);
     // Rewrite the freelist.
@@ -1237,7 +1210,7 @@
     *entryPtr = nullptr;
     // The freelist head is stored unmasked.
     page->freelistHead = partitionFreelistMask(page->freelistHead);
-    ASSERT(numNewEntries == numSlots - page->numAllocatedSlots);
+    DCHECK(numNewEntries == numSlots - page->numAllocatedSlots);
     // Discard the memory.
     discardSystemPages(beginPtr, unprovisionedBytes);
   }
@@ -1257,9 +1230,9 @@
     if (i != lastSlot)
       beginPtr += sizeof(PartitionFreelistEntry);
     beginPtr = reinterpret_cast<char*>(
-        WTF::roundUpToSystemPage(reinterpret_cast<size_t>(beginPtr)));
+        roundUpToSystemPage(reinterpret_cast<size_t>(beginPtr)));
     endPtr = reinterpret_cast<char*>(
-        WTF::roundDownToSystemPage(reinterpret_cast<size_t>(endPtr)));
+        roundDownToSystemPage(reinterpret_cast<size_t>(endPtr)));
     if (beginPtr < endPtr) {
       size_t partialSlotBytes = endPtr - beginPtr;
       discardableBytes += partialSlotBytes;
@@ -1274,7 +1247,7 @@
   if (bucket->activePagesHead != &PartitionRootGeneric::gSeedPage) {
     for (PartitionPage* page = bucket->activePagesHead; page;
          page = page->nextPage) {
-      ASSERT(page != &PartitionRootGeneric::gSeedPage);
+      DCHECK(page != &PartitionRootGeneric::gSeedPage);
       (void)partitionPurgePage(page, true);
     }
   }
@@ -1290,7 +1263,7 @@
 }
 
 void partitionPurgeMemoryGeneric(PartitionRootGeneric* root, int flags) {
-  SpinLock::Guard guard(root->lock);
+  subtle::SpinLock::Guard guard(root->lock);
   if (flags & PartitionPurgeDecommitEmptyPages)
     partitionDecommitEmptyPages(root);
   if (flags & PartitionPurgeDiscardUnusedSystemPages) {
@@ -1322,8 +1295,8 @@
         (page->numAllocatedSlots * statsOut->bucketSlotSize);
 
   size_t pageBytesResident =
-      WTF::roundUpToSystemPage((bucketNumSlots - page->numUnprovisionedSlots) *
-                               statsOut->bucketSlotSize);
+      roundUpToSystemPage((bucketNumSlots - page->numUnprovisionedSlots) *
+                          statsOut->bucketSlotSize);
   statsOut->residentBytes += pageBytesResident;
   if (partitionPageStateIsEmpty(page)) {
     statsOut->decommittableBytes += pageBytesResident;
@@ -1331,14 +1304,14 @@
   } else if (partitionPageStateIsFull(page)) {
     ++statsOut->numFullPages;
   } else {
-    ASSERT(partitionPageStateIsActive(page));
+    DCHECK(partitionPageStateIsActive(page));
     ++statsOut->numActivePages;
   }
 }
 
 static void partitionDumpBucketStats(PartitionBucketMemoryStats* statsOut,
                                      const PartitionBucket* bucket) {
-  ASSERT(!partitionBucketIsDirectMapped(bucket));
+  DCHECK(!partitionBucketIsDirectMapped(bucket));
   statsOut->isValid = false;
   // If the active page list is empty (== &PartitionRootGeneric::gSeedPage),
   // the bucket might still need to be reported if it has a list of empty,
@@ -1361,20 +1334,20 @@
 
   for (const PartitionPage* page = bucket->emptyPagesHead; page;
        page = page->nextPage) {
-    ASSERT(partitionPageStateIsEmpty(page) ||
+    DCHECK(partitionPageStateIsEmpty(page) ||
            partitionPageStateIsDecommitted(page));
     partitionDumpPageStats(statsOut, page);
   }
   for (const PartitionPage* page = bucket->decommittedPagesHead; page;
        page = page->nextPage) {
-    ASSERT(partitionPageStateIsDecommitted(page));
+    DCHECK(partitionPageStateIsDecommitted(page));
     partitionDumpPageStats(statsOut, page);
   }
 
   if (bucket->activePagesHead != &PartitionRootGeneric::gSeedPage) {
     for (const PartitionPage* page = bucket->activePagesHead; page;
          page = page->nextPage) {
-      ASSERT(page != &PartitionRootGeneric::gSeedPage);
+      DCHECK(page != &PartitionRootGeneric::gSeedPage);
       partitionDumpPageStats(statsOut, page);
     }
   }
@@ -1390,7 +1363,7 @@
   size_t numDirectMappedAllocations = 0;
 
   {
-    SpinLock::Guard guard(partition->lock);
+    subtle::SpinLock::Guard guard(partition->lock);
 
     for (size_t i = 0; i < kGenericNumBuckets; ++i) {
       const PartitionBucket* bucket = &partition->buckets[i];
@@ -1405,7 +1378,7 @@
 
     for (PartitionDirectMapExtent* extent = partition->directMapList; extent;
          extent = extent->nextExtent) {
-      ASSERT(!extent->nextExtent || extent->nextExtent->prevExtent == extent);
+      DCHECK(!extent->nextExtent || extent->nextExtent->prevExtent == extent);
       directMapLengths[numDirectMappedAllocations] = extent->bucket->slotSize;
       ++numDirectMappedAllocations;
       if (numDirectMappedAllocations == kMaxReportableDirectMaps)
@@ -1463,7 +1436,7 @@
   static const size_t kMaxReportableBuckets = 4096 / sizeof(void*);
   PartitionBucketMemoryStats memoryStats[kMaxReportableBuckets];
   const size_t partitionNumBuckets = partition->numBuckets;
-  ASSERT(partitionNumBuckets <= kMaxReportableBuckets);
+  DCHECK(partitionNumBuckets <= kMaxReportableBuckets);
 
   for (size_t i = 0; i < partitionNumBuckets; ++i)
     partitionDumpBucketStats(&memoryStats[i], &partition->buckets()[i]);
@@ -1473,7 +1446,7 @@
   PartitionMemoryStats partitionStats = {0};
   partitionStats.totalMmappedBytes = partition->totalSizeOfSuperPages;
   partitionStats.totalCommittedBytes = partition->totalSizeOfCommittedPages;
-  ASSERT(!partition->totalSizeOfDirectMappedPages);
+  DCHECK(!partition->totalSizeOfDirectMappedPages);
   for (size_t i = 0; i < partitionNumBuckets; ++i) {
     if (memoryStats[i].isValid) {
       partitionStats.totalResidentBytes += memoryStats[i].residentBytes;
@@ -1489,4 +1462,4 @@
   partitionStatsDumper->partitionDumpTotals(partitionName, &partitionStats);
 }
 
-}  // namespace WTF
+}  // namespace base
diff --git a/third_party/WebKit/Source/wtf/allocator/PartitionAlloc.h b/base/allocator/partition_allocator/partition_alloc.h
similarity index 82%
rename from third_party/WebKit/Source/wtf/allocator/PartitionAlloc.h
rename to base/allocator/partition_allocator/partition_alloc.h
index aa3c0bbc..4c36435 100644
--- a/third_party/WebKit/Source/wtf/allocator/PartitionAlloc.h
+++ b/base/allocator/partition_allocator/partition_alloc.h
@@ -1,35 +1,9 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * 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.
- *     * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
- * OWNER OR 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.
- */
+// Copyright (c) 2013 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 WTF_PartitionAlloc_h
-#define WTF_PartitionAlloc_h
+#ifndef BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_ALLOC_H
+#define BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_ALLOC_H
 
 // DESCRIPTION
 // partitionAlloc() / partitionAllocGeneric() and partitionFree() /
@@ -85,25 +59,21 @@
 // - Better checking for wild pointers in free().
 // - Better freelist masking function to guarantee fault on 32-bit.
 
-#include "wtf/Assertions.h"
-#include "wtf/BitwiseOperations.h"
-#include "wtf/ByteSwap.h"
-#include "wtf/CPU.h"
-#include "wtf/SpinLock.h"
-#include "wtf/TypeTraits.h"
-#include "wtf/allocator/PageAllocator.h"
-
 #include <limits.h>
 
+#include "base/allocator/partition_allocator/page_allocator.h"
+#include "base/bits.h"
+#include "base/compiler_specific.h"
+#include "base/logging.h"
+#include "base/synchronization/spin_lock.h"
+#include "base/sys_byteorder.h"
+#include "build/build_config.h"
+
 #if defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
 #include <stdlib.h>
 #endif
 
-#if ENABLE(ASSERT)
-#include <string.h>
-#endif
-
-namespace WTF {
+namespace base {
 
 // Allocation granularity of sizeof(void*) bytes.
 static const size_t kAllocationGranularity = sizeof(void*);
@@ -241,7 +211,7 @@
 // "out of physical memory" in crash reports.
 static const size_t kReasonableSizeOfUnusedPages = 1024 * 1024 * 1024;  // 1GiB
 
-#if ENABLE(ASSERT)
+#if DCHECK_IS_ON()
 // These two byte values match tcmalloc.
 static const unsigned char kUninitializedByte = 0xAB;
 static const unsigned char kFreedByte = 0xCD;
@@ -321,7 +291,7 @@
   size_t mapSize;  // Mapped size, not including guard pages and meta-data.
 };
 
-struct WTF_EXPORT PartitionRootBase {
+struct BASE_EXPORT PartitionRootBase {
   size_t totalSizeOfCommittedPages;
   size_t totalSizeOfSuperPages;
   size_t totalSizeOfDirectMappedPages;
@@ -340,7 +310,7 @@
   int16_t globalEmptyPageRingIndex;
   uintptr_t invertedSelf;
 
-  static SpinLock gInitializedLock;
+  static subtle::SpinLock gInitializedLock;
   static bool gInitialized;
   // gSeedPage is used as a sentinel to indicate that there is no page
   // in the active page list. We can use nullptr, but in that case we need
@@ -366,7 +336,7 @@
 // Never instantiate a PartitionRootGeneric directly, instead use
 // PartitionAllocatorGeneric.
 struct PartitionRootGeneric : public PartitionRootBase {
-  SpinLock lock;
+  subtle::SpinLock lock;
   // Some pre-computed constants.
   size_t orderIndexShifts[kBitsPerSizet + 1];
   size_t orderSubIndexMasks[kBitsPerSizet + 1];
@@ -420,7 +390,7 @@
 
 // Interface that is passed to partitionDumpStats and
 // partitionDumpStatsGeneric for using the memory statistics.
-class WTF_EXPORT PartitionStatsDumper {
+class BASE_EXPORT PartitionStatsDumper {
  public:
   // Called to dump total memory used by partition, once per partition.
   virtual void partitionDumpTotals(const char* partitionName,
@@ -431,13 +401,13 @@
                                          const PartitionBucketMemoryStats*) = 0;
 };
 
-WTF_EXPORT void partitionAllocGlobalInit(void (*oomHandlingFunction)());
-WTF_EXPORT void partitionAllocInit(PartitionRoot*,
-                                   size_t numBuckets,
-                                   size_t maxAllocation);
-WTF_EXPORT bool partitionAllocShutdown(PartitionRoot*);
-WTF_EXPORT void partitionAllocGenericInit(PartitionRootGeneric*);
-WTF_EXPORT bool partitionAllocGenericShutdown(PartitionRootGeneric*);
+BASE_EXPORT void partitionAllocGlobalInit(void (*oomHandlingFunction)());
+BASE_EXPORT void partitionAllocInit(PartitionRoot*,
+                                    size_t numBuckets,
+                                    size_t maxAllocation);
+BASE_EXPORT bool partitionAllocShutdown(PartitionRoot*);
+BASE_EXPORT void partitionAllocGenericInit(PartitionRootGeneric*);
+BASE_EXPORT bool partitionAllocGenericShutdown(PartitionRootGeneric*);
 
 enum PartitionPurgeFlags {
   // Decommitting the ring list of empty pages is reasonably fast.
@@ -449,29 +419,29 @@
   PartitionPurgeDiscardUnusedSystemPages = 1 << 1,
 };
 
-WTF_EXPORT void partitionPurgeMemory(PartitionRoot*, int);
-WTF_EXPORT void partitionPurgeMemoryGeneric(PartitionRootGeneric*, int);
+BASE_EXPORT void partitionPurgeMemory(PartitionRoot*, int);
+BASE_EXPORT void partitionPurgeMemoryGeneric(PartitionRootGeneric*, int);
 
-WTF_EXPORT NEVER_INLINE void* partitionAllocSlowPath(PartitionRootBase*,
-                                                     int,
-                                                     size_t,
-                                                     PartitionBucket*);
-WTF_EXPORT NEVER_INLINE void partitionFreeSlowPath(PartitionPage*);
-WTF_EXPORT NEVER_INLINE void* partitionReallocGeneric(PartitionRootGeneric*,
-                                                      void*,
-                                                      size_t,
-                                                      const char* typeName);
+BASE_EXPORT NOINLINE void* partitionAllocSlowPath(PartitionRootBase*,
+                                                  int,
+                                                  size_t,
+                                                  PartitionBucket*);
+BASE_EXPORT NOINLINE void partitionFreeSlowPath(PartitionPage*);
+BASE_EXPORT NOINLINE void* partitionReallocGeneric(PartitionRootGeneric*,
+                                                   void*,
+                                                   size_t,
+                                                   const char* typeName);
 
-WTF_EXPORT void partitionDumpStats(PartitionRoot*,
-                                   const char* partitionName,
-                                   bool isLightDump,
-                                   PartitionStatsDumper*);
-WTF_EXPORT void partitionDumpStatsGeneric(PartitionRootGeneric*,
-                                          const char* partitionName,
-                                          bool isLightDump,
-                                          PartitionStatsDumper*);
+BASE_EXPORT void partitionDumpStats(PartitionRoot*,
+                                    const char* partitionName,
+                                    bool isLightDump,
+                                    PartitionStatsDumper*);
+BASE_EXPORT void partitionDumpStatsGeneric(PartitionRootGeneric*,
+                                           const char* partitionName,
+                                           bool isLightDump,
+                                           PartitionStatsDumper*);
 
-class WTF_EXPORT PartitionAllocHooks {
+class BASE_EXPORT PartitionAllocHooks {
  public:
   typedef void AllocationHook(void* address, size_t, const char* typeName);
   typedef void FreeHook(void* address);
@@ -515,14 +485,6 @@
   static FreeHook* m_freeHook;
 };
 
-// In official builds, do not include type info string literals to avoid
-// bloating the binary.
-#if defined(OFFICIAL_BUILD)
-#define WTF_HEAP_PROFILER_TYPE_NAME(T) nullptr
-#else
-#define WTF_HEAP_PROFILER_TYPE_NAME(T) ::WTF::getStringWithTypeName<T>()
-#endif
-
 ALWAYS_INLINE PartitionFreelistEntry* partitionFreelistMask(
     PartitionFreelistEntry* ptr) {
 // We use bswap on little endian as a fast mask for two reasons:
@@ -533,34 +495,34 @@
 // corrupt a freelist pointer, partial pointer overwrite attacks are
 // thwarted.
 // For big endian, similar guarantees are arrived at with a negation.
-#if CPU(BIG_ENDIAN)
+#if defined(ARCH_CPU_BIG_ENDIAN)
   uintptr_t masked = ~reinterpret_cast<uintptr_t>(ptr);
 #else
-  uintptr_t masked = bswapuintptrt(reinterpret_cast<uintptr_t>(ptr));
+  uintptr_t masked = ByteSwapUintPtrT(reinterpret_cast<uintptr_t>(ptr));
 #endif
   return reinterpret_cast<PartitionFreelistEntry*>(masked);
 }
 
 ALWAYS_INLINE size_t partitionCookieSizeAdjustAdd(size_t size) {
-#if ENABLE(ASSERT)
+#if DCHECK_IS_ON()
   // Add space for cookies, checking for integer overflow.
-  ASSERT(size + (2 * kCookieSize) > size);
+  DCHECK(size + (2 * kCookieSize) > size);
   size += 2 * kCookieSize;
 #endif
   return size;
 }
 
 ALWAYS_INLINE size_t partitionCookieSizeAdjustSubtract(size_t size) {
-#if ENABLE(ASSERT)
+#if DCHECK_IS_ON()
   // Remove space for cookies.
-  ASSERT(size >= 2 * kCookieSize);
+  DCHECK(size >= 2 * kCookieSize);
   size -= 2 * kCookieSize;
 #endif
   return size;
 }
 
 ALWAYS_INLINE void* partitionCookieFreePointerAdjust(void* ptr) {
-#if ENABLE(ASSERT)
+#if DCHECK_IS_ON()
   // The value given to the application is actually just after the cookie.
   ptr = static_cast<char*>(ptr) - kCookieSize;
 #endif
@@ -568,7 +530,7 @@
 }
 
 ALWAYS_INLINE void partitionCookieWriteValue(void* ptr) {
-#if ENABLE(ASSERT)
+#if DCHECK_IS_ON()
   unsigned char* cookiePtr = reinterpret_cast<unsigned char*>(ptr);
   for (size_t i = 0; i < kCookieSize; ++i, ++cookiePtr)
     *cookiePtr = kCookieValue[i];
@@ -576,16 +538,16 @@
 }
 
 ALWAYS_INLINE void partitionCookieCheckValue(void* ptr) {
-#if ENABLE(ASSERT)
+#if DCHECK_IS_ON()
   unsigned char* cookiePtr = reinterpret_cast<unsigned char*>(ptr);
   for (size_t i = 0; i < kCookieSize; ++i, ++cookiePtr)
-    ASSERT(*cookiePtr == kCookieValue[i]);
+    DCHECK(*cookiePtr == kCookieValue[i]);
 #endif
 }
 
 ALWAYS_INLINE char* partitionSuperPageToMetadataArea(char* ptr) {
   uintptr_t pointerAsUint = reinterpret_cast<uintptr_t>(ptr);
-  ASSERT(!(pointerAsUint & kSuperPageOffsetMask));
+  DCHECK(!(pointerAsUint & kSuperPageOffsetMask));
   // The metadata area is exactly one system page (the guard page) into the
   // super page.
   return reinterpret_cast<char*>(pointerAsUint + kSystemPageSize);
@@ -599,8 +561,8 @@
       (pointerAsUint & kSuperPageOffsetMask) >> kPartitionPageShift;
   // Index 0 is invalid because it is the metadata and guard area and
   // the last index is invalid because it is a guard page.
-  ASSERT(partitionPageIndex);
-  ASSERT(partitionPageIndex < kNumPartitionPagesPerSuperPage - 1);
+  DCHECK(partitionPageIndex);
+  DCHECK(partitionPageIndex < kNumPartitionPagesPerSuperPage - 1);
   PartitionPage* page = reinterpret_cast<PartitionPage*>(
       partitionSuperPageToMetadataArea(superPagePtr) +
       (partitionPageIndex << kPageMetadataShift));
@@ -615,15 +577,15 @@
 ALWAYS_INLINE void* partitionPageToPointer(const PartitionPage* page) {
   uintptr_t pointerAsUint = reinterpret_cast<uintptr_t>(page);
   uintptr_t superPageOffset = (pointerAsUint & kSuperPageOffsetMask);
-  ASSERT(superPageOffset > kSystemPageSize);
-  ASSERT(superPageOffset < kSystemPageSize + (kNumPartitionPagesPerSuperPage *
+  DCHECK(superPageOffset > kSystemPageSize);
+  DCHECK(superPageOffset < kSystemPageSize + (kNumPartitionPagesPerSuperPage *
                                               kPageMetadataSize));
   uintptr_t partitionPageIndex =
       (superPageOffset - kSystemPageSize) >> kPageMetadataShift;
   // Index 0 is invalid because it is the metadata area and the last index is
   // invalid because it is a guard page.
-  ASSERT(partitionPageIndex);
-  ASSERT(partitionPageIndex < kNumPartitionPagesPerSuperPage - 1);
+  DCHECK(partitionPageIndex);
+  DCHECK(partitionPageIndex < kNumPartitionPagesPerSuperPage - 1);
   uintptr_t superPageBase = (pointerAsUint & kSuperPageBaseMask);
   void* ret = reinterpret_cast<void*>(
       superPageBase + (partitionPageIndex << kPartitionPageShift));
@@ -633,7 +595,7 @@
 ALWAYS_INLINE PartitionPage* partitionPointerToPage(void* ptr) {
   PartitionPage* page = partitionPointerToPageNoAlignmentCheck(ptr);
   // Checks that the pointer is a multiple of bucket size.
-  ASSERT(!((reinterpret_cast<uintptr_t>(ptr) -
+  DCHECK(!((reinterpret_cast<uintptr_t>(ptr) -
             reinterpret_cast<uintptr_t>(partitionPageToPointer(page))) %
            page->bucket->slotSize));
   return page;
@@ -660,8 +622,8 @@
   if (bucket->slotSize <= kMaxSystemPagesPerSlotSpan * kSystemPageSize)
     return nullptr;
 
-  ASSERT((bucket->slotSize % kSystemPageSize) == 0);
-  ASSERT(partitionBucketIsDirectMapped(bucket) ||
+  DCHECK((bucket->slotSize % kSystemPageSize) == 0);
+  DCHECK(partitionBucketIsDirectMapped(bucket) ||
          partitionBucketSlots(bucket) == 1);
   page++;
   return reinterpret_cast<size_t*>(&page->freelistHead);
@@ -693,23 +655,23 @@
                                          PartitionBucket* bucket) {
   PartitionPage* page = bucket->activePagesHead;
   // Check that this page is neither full nor freed.
-  ASSERT(page->numAllocatedSlots >= 0);
+  DCHECK(page->numAllocatedSlots >= 0);
   void* ret = page->freelistHead;
   if (LIKELY(ret != 0)) {
     // If these asserts fire, you probably corrupted memory.
-    ASSERT(partitionPointerIsValid(ret));
+    DCHECK(partitionPointerIsValid(ret));
     // All large allocations must go through the slow path to correctly
     // update the size metadata.
-    ASSERT(partitionPageGetRawSize(page) == 0);
+    DCHECK(partitionPageGetRawSize(page) == 0);
     PartitionFreelistEntry* newHead =
         partitionFreelistMask(static_cast<PartitionFreelistEntry*>(ret)->next);
     page->freelistHead = newHead;
     page->numAllocatedSlots++;
   } else {
     ret = partitionAllocSlowPath(root, flags, size, bucket);
-    ASSERT(!ret || partitionPointerIsValid(ret));
+    DCHECK(!ret || partitionPointerIsValid(ret));
   }
-#if ENABLE(ASSERT)
+#if DCHECK_IS_ON()
   if (!ret)
     return 0;
   // Fill the uninitialized pattern, and write the cookies.
@@ -717,7 +679,7 @@
   size_t slotSize = page->bucket->slotSize;
   size_t rawSize = partitionPageGetRawSize(page);
   if (rawSize) {
-    ASSERT(rawSize == size);
+    DCHECK(rawSize == size);
     slotSize = rawSize;
   }
   size_t noCookieSize = partitionCookieSizeAdjustSubtract(slotSize);
@@ -736,15 +698,15 @@
                                    const char* typeName) {
 #if defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
   void* result = malloc(size);
-  RELEASE_ASSERT(result);
+  CHECK(result);
   return result;
 #else
   size_t requestedSize = size;
   size = partitionCookieSizeAdjustAdd(size);
-  ASSERT(root->initialized);
+  DCHECK(root->initialized);
   size_t index = size >> kBucketShift;
-  ASSERT(index < root->numBuckets);
-  ASSERT(size == index << kBucketShift);
+  DCHECK(index < root->numBuckets);
+  DCHECK(size == index << kBucketShift);
   PartitionBucket* bucket = &root->buckets()[index];
   void* result = partitionBucketAlloc(root, 0, size, bucket);
   PartitionAllocHooks::allocationHookIfEnabled(result, requestedSize, typeName);
@@ -754,7 +716,7 @@
 
 ALWAYS_INLINE void partitionFreeWithPage(void* ptr, PartitionPage* page) {
 // If these asserts fire, you probably corrupted memory.
-#if ENABLE(ASSERT)
+#if DCHECK_IS_ON()
   size_t slotSize = page->bucket->slotSize;
   size_t rawSize = partitionPageGetRawSize(page);
   if (rawSize)
@@ -764,13 +726,12 @@
                             kCookieSize);
   memset(ptr, kFreedByte, slotSize);
 #endif
-  ASSERT(page->numAllocatedSlots);
+  DCHECK(page->numAllocatedSlots);
   PartitionFreelistEntry* freelistHead = page->freelistHead;
-  ASSERT(!freelistHead || partitionPointerIsValid(freelistHead));
-  SECURITY_CHECK(ptr != freelistHead);  // Catches an immediate double free.
+  DCHECK(!freelistHead || partitionPointerIsValid(freelistHead));
+  CHECK(ptr != freelistHead);  // Catches an immediate double free.
   // Look for double free one level deeper in debug.
-  SECURITY_DCHECK(!freelistHead ||
-                  ptr != partitionFreelistMask(freelistHead->next));
+  DCHECK(!freelistHead || ptr != partitionFreelistMask(freelistHead->next));
   PartitionFreelistEntry* entry = static_cast<PartitionFreelistEntry*>(ptr);
   entry->next = partitionFreelistMask(freelistHead);
   page->freelistHead = entry;
@@ -780,7 +741,7 @@
   } else {
     // All single-slot allocations must go through the slow path to
     // correctly update the size metadata.
-    ASSERT(partitionPageGetRawSize(page) == 0);
+    DCHECK(partitionPageGetRawSize(page) == 0);
   }
 }
 
@@ -790,7 +751,7 @@
 #else
   PartitionAllocHooks::freeHookIfEnabled(ptr);
   ptr = partitionCookieFreePointerAdjust(ptr);
-  ASSERT(partitionPointerIsValid(ptr));
+  DCHECK(partitionPointerIsValid(ptr));
   PartitionPage* page = partitionPointerToPage(ptr);
   partitionFreeWithPage(ptr, page);
 #endif
@@ -799,7 +760,7 @@
 ALWAYS_INLINE PartitionBucket* partitionGenericSizeToBucket(
     PartitionRootGeneric* root,
     size_t size) {
-  size_t order = kBitsPerSizet - CountLeadingZeroBitsSizeT(size);
+  size_t order = kBitsPerSizet - bits::CountLeadingZeroBitsSizeT(size);
   // The order index is simply the next few bits after the most significant bit.
   size_t orderIndex = (size >> root->orderIndexShifts[order]) &
                       (kGenericNumBucketsPerOrder - 1);
@@ -808,8 +769,8 @@
   PartitionBucket* bucket =
       root->bucketLookups[(order << kGenericNumBucketsPerOrderBits) +
                           orderIndex + !!subOrderIndex];
-  ASSERT(!bucket->slotSize || bucket->slotSize >= size);
-  ASSERT(!(bucket->slotSize % kGenericSmallestBucket));
+  DCHECK(!bucket->slotSize || bucket->slotSize >= size);
+  DCHECK(!(bucket->slotSize % kGenericSmallestBucket));
   return bucket;
 }
 
@@ -819,16 +780,16 @@
                                                const char* typeName) {
 #if defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
   void* result = malloc(size);
-  RELEASE_ASSERT(result || flags & PartitionAllocReturnNull);
+  CHECK(result || flags & PartitionAllocReturnNull);
   return result;
 #else
-  ASSERT(root->initialized);
+  DCHECK(root->initialized);
   size_t requestedSize = size;
   size = partitionCookieSizeAdjustAdd(size);
   PartitionBucket* bucket = partitionGenericSizeToBucket(root, size);
   void* ret = nullptr;
   {
-    SpinLock::Guard guard(root->lock);
+    subtle::SpinLock::Guard guard(root->lock);
     ret = partitionBucketAlloc(root, flags, size, bucket);
   }
   PartitionAllocHooks::allocationHookIfEnabled(ret, requestedSize, typeName);
@@ -846,17 +807,17 @@
 #if defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
   free(ptr);
 #else
-  ASSERT(root->initialized);
+  DCHECK(root->initialized);
 
   if (UNLIKELY(!ptr))
     return;
 
   PartitionAllocHooks::freeHookIfEnabled(ptr);
   ptr = partitionCookieFreePointerAdjust(ptr);
-  ASSERT(partitionPointerIsValid(ptr));
+  DCHECK(partitionPointerIsValid(ptr));
   PartitionPage* page = partitionPointerToPage(ptr);
   {
-    SpinLock::Guard guard(root->lock);
+    subtle::SpinLock::Guard guard(root->lock);
     partitionFreeWithPage(ptr, page);
   }
 #endif
@@ -866,7 +827,7 @@
   // Caller must check that the size is not above the kGenericMaxDirectMapped
   // limit before calling. This also guards against integer overflow in the
   // calculation here.
-  ASSERT(size <= kGenericMaxDirectMapped);
+  DCHECK(size <= kGenericMaxDirectMapped);
   return (size + kSystemPageOffsetMask) & kSystemPageBaseMask;
 }
 
@@ -875,7 +836,7 @@
 #if defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
   return size;
 #else
-  ASSERT(root->initialized);
+  DCHECK(root->initialized);
   size = partitionCookieSizeAdjustAdd(size);
   PartitionBucket* bucket = partitionGenericSizeToBucket(root, size);
   if (LIKELY(!partitionBucketIsDirectMapped(bucket))) {
@@ -883,7 +844,7 @@
   } else if (size > kGenericMaxDirectMapped) {
     // Too large to allocate => return the size unchanged.
   } else {
-    ASSERT(bucket == &PartitionRootBase::gPagedBucket);
+    DCHECK(bucket == &PartitionRootBase::gPagedBucket);
     size = partitionDirectMapSize(size);
   }
   return partitionCookieSizeAdjustSubtract(size);
@@ -901,9 +862,9 @@
 ALWAYS_INLINE size_t partitionAllocGetSize(void* ptr) {
   // No need to lock here. Only 'ptr' being freed by another thread could
   // cause trouble, and the caller is responsible for that not happening.
-  ASSERT(partitionAllocSupportsGetSize());
+  DCHECK(partitionAllocSupportsGetSize());
   ptr = partitionCookieFreePointerAdjust(ptr);
-  ASSERT(partitionPointerIsValid(ptr));
+  DCHECK(partitionPointerIsValid(ptr));
   PartitionPage* page = partitionPointerToPage(ptr);
   size_t size = page->bucket->slotSize;
   return partitionCookieSizeAdjustSubtract(size);
@@ -938,20 +899,6 @@
   PartitionRootGeneric m_partitionRoot;
 };
 
-}  // namespace WTF
+}  // namespace base
 
-using WTF::SizeSpecificPartitionAllocator;
-using WTF::PartitionAllocatorGeneric;
-using WTF::PartitionRoot;
-using WTF::partitionAllocInit;
-using WTF::partitionAllocShutdown;
-using WTF::partitionAlloc;
-using WTF::partitionFree;
-using WTF::partitionAllocGeneric;
-using WTF::partitionFreeGeneric;
-using WTF::partitionReallocGeneric;
-using WTF::partitionAllocActualSize;
-using WTF::partitionAllocSupportsGetSize;
-using WTF::partitionAllocGetSize;
-
-#endif  // WTF_PartitionAlloc_h
+#endif  // BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_ALLOC_H
diff --git a/third_party/WebKit/Source/wtf/allocator/PartitionAllocTest.cpp b/base/allocator/partition_allocator/partition_alloc_unittest.cc
similarity index 95%
rename from third_party/WebKit/Source/wtf/allocator/PartitionAllocTest.cpp
rename to base/allocator/partition_allocator/partition_alloc_unittest.cc
index 589d6e9..dbc8ed21 100644
--- a/third_party/WebKit/Source/wtf/allocator/PartitionAllocTest.cpp
+++ b/base/allocator/partition_allocator/partition_alloc_unittest.cc
@@ -1,45 +1,20 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * 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.
- *     * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
- * OWNER OR 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.
- */
+// Copyright (c) 2013 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 "wtf/allocator/PartitionAlloc.h"
+#include "base/allocator/partition_allocator/partition_alloc.h"
 
-#include "testing/gtest/include/gtest/gtest.h"
-#include "wtf/BitwiseOperations.h"
-#include "wtf/CPU.h"
-#include "wtf/PtrUtil.h"
-#include "wtf/Vector.h"
-#include <memory>
 #include <stdlib.h>
 #include <string.h>
 
-#if OS(POSIX)
+#include <memory>
+#include <vector>
+
+#include "base/bits.h"
+#include "build/build_config.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+#if defined(OS_POSIX)
 #include <sys/mman.h>
 #include <sys/resource.h>
 #include <sys/time.h>
@@ -47,11 +22,18 @@
 #ifndef MAP_ANONYMOUS
 #define MAP_ANONYMOUS MAP_ANON
 #endif
-#endif  // OS(POSIX)
+#endif  // defined(OS_POSIX)
+
+namespace {
+template <typename T>
+std::unique_ptr<T[]> WrapArrayUnique(T* ptr) {
+  return std::unique_ptr<T[]>(ptr);
+}
+}  // namespace
 
 #if !defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
 
-namespace WTF {
+namespace base {
 
 namespace {
 
@@ -60,15 +42,15 @@
 PartitionAllocatorGeneric genericAllocator;
 
 const size_t kTestAllocSize = 16;
-#if !ENABLE(ASSERT)
+#if !DCHECK_IS_ON()
 const size_t kPointerOffset = 0;
 const size_t kExtraAllocSize = 0;
 #else
-const size_t kPointerOffset = WTF::kCookieSize;
-const size_t kExtraAllocSize = WTF::kCookieSize * 2;
+const size_t kPointerOffset = kCookieSize;
+const size_t kExtraAllocSize = kCookieSize * 2;
 #endif
 const size_t kRealAllocSize = kTestAllocSize + kExtraAllocSize;
-const size_t kTestBucketIndex = kRealAllocSize >> WTF::kBucketShift;
+const size_t kTestBucketIndex = kRealAllocSize >> kBucketShift;
 
 const char* typeName = nullptr;
 
@@ -84,12 +66,12 @@
   EXPECT_TRUE(genericAllocator.shutdown());
 }
 
-#if !CPU(64BIT) || OS(POSIX)
+#if !defined(ARCH_CPU_64_BITS) || defined(OS_POSIX)
 bool SetAddressSpaceLimit() {
-#if !CPU(64BIT)
+#if !defined(ARCH_CPU_64_BITS)
   // 32 bits => address space is limited already.
   return true;
-#elif OS(POSIX) && !OS(MACOSX)
+#elif defined(OS_POSIX) && !defined(OS_MACOSX)
   // Mac will accept RLIMIT_AS changes but it is not enforced.
   // See https://crbug.com/435269 and rdar://17576114.
   const size_t kAddressSpaceLimit = static_cast<size_t>(4096) * 1024 * 1024;
@@ -108,9 +90,9 @@
 }
 
 bool ClearAddressSpaceLimit() {
-#if !CPU(64BIT)
+#if !defined(ARCH_CPU_64_BITS)
   return true;
-#elif OS(POSIX)
+#elif defined(OS_POSIX)
   struct rlimit limit;
   if (getrlimit(RLIMIT_AS, &limit) != 0)
     return false;
@@ -170,7 +152,7 @@
   size_t realSize = size + kExtraAllocSize;
   size_t bucketIdx = realSize >> kBucketShift;
   PartitionBucket* bucket = &allocator.root()->buckets()[bucketIdx];
-  ASSERT(!bucket->activePagesHead->numAllocatedSlots);
+  DCHECK(!bucket->activePagesHead->numAllocatedSlots);
 
   for (size_t i = 0; i < kMaxFreeableSpans; ++i) {
     void* ptr = partitionAlloc(allocator.root(), size, typeName);
@@ -195,7 +177,7 @@
 }
 
 void CheckPageInCore(void* ptr, bool inCore) {
-#if OS(LINUX)
+#if defined(OS_LINUX)
   unsigned char ret;
   EXPECT_EQ(0, mincore(ptr, kSystemPageSize, &ret));
   EXPECT_EQ(inCore, ret);
@@ -225,7 +207,7 @@
     (void)partitionName;
     EXPECT_TRUE(memoryStats->isValid);
     EXPECT_EQ(0u, memoryStats->bucketSlotSize & kAllocationGranularityMask);
-    m_bucketStats.append(*memoryStats);
+    m_bucketStats.push_back(*memoryStats);
     m_totalResidentBytes += memoryStats->residentBytes;
     m_totalActiveBytes += memoryStats->activeBytes;
     m_totalDecommittableBytes += memoryStats->decommittableBytes;
@@ -250,7 +232,7 @@
   size_t m_totalDecommittableBytes;
   size_t m_totalDiscardableBytes;
 
-  Vector<PartitionBucketMemoryStats> m_bucketStats;
+  std::vector<PartitionBucketMemoryStats> m_bucketStats;
 };
 
 }  // anonymous namespace
@@ -453,7 +435,7 @@
   // never gets thrown on the freelist.
   ++numToFillFreeListPage;
   std::unique_ptr<PartitionPage* []> pages =
-      wrapArrayUnique(new PartitionPage*[numToFillFreeListPage]);
+      WrapArrayUnique(new PartitionPage*[numToFillFreeListPage]);
 
   size_t i;
   for (i = 0; i < numToFillFreeListPage; ++i) {
@@ -499,7 +481,7 @@
 
   EXPECT_GT(numPagesNeeded, 1u);
   std::unique_ptr<PartitionPage* []> pages;
-  pages = wrapArrayUnique(new PartitionPage*[numPagesNeeded]);
+  pages = WrapArrayUnique(new PartitionPage*[numPagesNeeded]);
   uintptr_t firstSuperPageBase = 0;
   size_t i;
   for (i = 0; i < numPagesNeeded; ++i) {
@@ -560,7 +542,7 @@
   // Check that the realloc copied correctly.
   char* newCharPtr = static_cast<char*>(newPtr);
   EXPECT_EQ(*newCharPtr, 'A');
-#if ENABLE(ASSERT)
+#if DCHECK_IS_ON()
   // Subtle: this checks for an old bug where we copied too much from the
   // source of the realloc. The condition can be detected by a trashing of
   // the uninitialized value in the space of the upsized allocation.
@@ -671,7 +653,7 @@
   EXPECT_EQ(ptr3, newPtr);
   newPtr = partitionAllocGeneric(genericAllocator.root(), size, typeName);
   EXPECT_EQ(ptr2, newPtr);
-#if OS(LINUX) && !ENABLE(ASSERT)
+#if defined(OS_LINUX) && !DCHECK_IS_ON()
   // On Linux, we have a guarantee that freelisting a page should cause its
   // contents to be nulled out. We check for null here to detect an bug we
   // had where a large slot size was causing us to not properly free all
@@ -807,7 +789,7 @@
   char* charPtr2 = static_cast<char*>(ptr2);
   EXPECT_EQ('A', charPtr2[0]);
   EXPECT_EQ('A', charPtr2[size - 1]);
-#if ENABLE(ASSERT)
+#if DCHECK_IS_ON()
   EXPECT_EQ(kUninitializedByte, static_cast<unsigned char>(charPtr2[size]));
 #endif
 
@@ -819,7 +801,7 @@
   char* charPtr = static_cast<char*>(ptr);
   EXPECT_EQ('A', charPtr[0]);
   EXPECT_EQ('A', charPtr[size - 2]);
-#if ENABLE(ASSERT)
+#if DCHECK_IS_ON()
   EXPECT_EQ(kUninitializedByte, static_cast<unsigned char>(charPtr[size - 1]));
 #endif
 
@@ -1073,9 +1055,9 @@
   // guard pages.
   size_t numPartitionPagesNeeded = kNumPartitionPagesPerSuperPage - 2;
   std::unique_ptr<PartitionPage* []> firstSuperPagePages =
-      wrapArrayUnique(new PartitionPage*[numPartitionPagesNeeded]);
+      WrapArrayUnique(new PartitionPage*[numPartitionPagesNeeded]);
   std::unique_ptr<PartitionPage* []> secondSuperPagePages =
-      wrapArrayUnique(new PartitionPage*[numPartitionPagesNeeded]);
+      WrapArrayUnique(new PartitionPage*[numPartitionPagesNeeded]);
 
   size_t i;
   for (i = 0; i < numPartitionPagesNeeded; ++i)
@@ -1266,7 +1248,7 @@
   TestShutdown();
 }
 
-#if !CPU(64BIT) || OS(POSIX)
+#if !defined(ARCH_CPU_64_BITS) || defined(OS_POSIX)
 
 static void DoReturnNullTest(size_t allocSize) {
   TestSetup();
@@ -1319,7 +1301,10 @@
 // crash, and still returns null. The test tries to allocate 6 GB of memory in
 // 512 kB blocks. On 64-bit POSIX systems, the address space is limited to 4 GB
 // using setrlimit() first.
-#if OS(MACOSX)
+//
+// Disable this test on Android because, due to its allocation-heavy behavior,
+// it tends to get OOM-killed rather than pass.
+#if defined(OS_MACOSX) || defined(OS_ANDROID)
 #define MAYBE_RepeatedReturnNull DISABLED_RepeatedReturnNull
 #else
 #define MAYBE_RepeatedReturnNull RepeatedReturnNull
@@ -1330,7 +1315,10 @@
 }
 
 // Another "return null" test but for larger, direct-mapped allocations.
-#if OS(MACOSX)
+//
+// Disable this test on Android because, due to its allocation-heavy behavior,
+// it tends to get OOM-killed rather than pass.
+#if defined(OS_MACOSX) || defined(OS_ANDROID)
 #define MAYBE_RepeatedReturnNullDirect DISABLED_RepeatedReturnNullDirect
 #else
 #define MAYBE_RepeatedReturnNullDirect RepeatedReturnNullDirect
@@ -1340,9 +1328,10 @@
   DoReturnNullTest(256 * 1024 * 1024);
 }
 
-#endif  // !CPU(64BIT) || OS(POSIX)
+#endif  // !defined(ARCH_CPU_64_BITS) || defined(OS_POSIX)
 
-#if !OS(ANDROID)
+// Death tests misbehave on Android, http://crbug.com/643760.
+#if defined(GTEST_HAS_DEATH_TEST) && !defined(OS_ANDROID)
 
 // Make sure that malloc(-1) dies.
 // In the past, we had an integer overflow that would alias malloc(-1) to
@@ -1452,7 +1441,7 @@
   TestShutdown();
 }
 
-#endif  // !OS(ANDROID)
+#endif  // !defined(OS_ANDROID) && !defined(OS_IOS)
 
 // Tests that partitionDumpStatsGeneric and partitionDumpStats runs without
 // crashing and returns non zero values when memory is allocated.
@@ -2113,6 +2102,6 @@
   TestShutdown();
 }
 
-}  // namespace WTF
+}  // namespace base
 
 #endif  // !defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
diff --git a/base/logging.cc b/base/logging.cc
index c1f5f38..cea6edae 100644
--- a/base/logging.cc
+++ b/base/logging.cc
@@ -13,7 +13,6 @@
 
 #if defined(OS_WIN)
 #include <io.h>
-#include <windows.h>
 typedef HANDLE FileHandle;
 typedef HANDLE MutexHandle;
 // Windows warns on using write().  It prefers _write().
diff --git a/base/logging.h b/base/logging.h
index fb7a3ebb..2d1a83e 100644
--- a/base/logging.h
+++ b/base/logging.h
@@ -466,18 +466,6 @@
 #define IMMEDIATE_CRASH() ((void)(*(volatile char*)0 = 0))
 #endif
 
-// Specialization of IMMEDIATE_CRASH which will raise a custom exception on
-// Windows to signal this is OOM and not a normal assert.
-#if defined(OS_WIN)
-#define OOM_CRASH()                                                     \
-  do {                                                                  \
-    ::RaiseException(0xE0000008, EXCEPTION_NONCONTINUABLE, 0, nullptr); \
-    IMMEDIATE_CRASH();                                                  \
-  } while (0)
-#else
-#define OOM_CRASH() IMMEDIATE_CRASH()
-#endif
-
 // CHECK dies with a fatal error if condition is not true.  It is *not*
 // controlled by NDEBUG, so the check will be executed regardless of
 // compilation mode.
diff --git a/base/sys_byteorder.h b/base/sys_byteorder.h
index 8d9066c..9ee1827e 100644
--- a/base/sys_byteorder.h
+++ b/base/sys_byteorder.h
@@ -13,6 +13,7 @@
 
 #include <stdint.h>
 
+#include "base/logging.h"
 #include "build/build_config.h"
 
 #if defined(COMPILER_MSVC)
@@ -46,6 +47,21 @@
 #endif
 }
 
+inline uintptr_t ByteSwapUintPtrT(uintptr_t x) {
+  // We do it this way because some build configurations are ILP32 even when
+  // defined(ARCH_CPU_64_BITS). Unfortunately, we can't use sizeof in #ifs. But,
+  // because these conditionals are constexprs, the irrelevant branches will
+  // likely be optimized away, so this construction should not result in code
+  // bloat.
+  if (sizeof(uintptr_t) == 4) {
+    return ByteSwap(static_cast<uint32_t>(x));
+  } else if (sizeof(uintptr_t) == 8) {
+    return ByteSwap(static_cast<uint64_t>(x));
+  } else {
+    NOTREACHED();
+  }
+}
+
 // Converts the bytes in |x| from host order (endianness) to little endian, and
 // returns the result.
 inline uint16_t ByteSwapToLE16(uint16_t x) {
diff --git a/base/sys_byteorder_unittest.cc b/base/sys_byteorder_unittest.cc
index 0352c2a..8167be3 100644
--- a/base/sys_byteorder_unittest.cc
+++ b/base/sys_byteorder_unittest.cc
@@ -6,6 +6,7 @@
 
 #include <stdint.h>
 
+#include "build/build_config.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace {
@@ -40,6 +41,25 @@
   EXPECT_EQ(k64BitTestData, reswapped);
 }
 
+TEST(ByteOrderTest, ByteSwapUintPtrT) {
+#if defined(ARCH_CPU_64_BITS)
+  const uintptr_t test_data = static_cast<uintptr_t>(k64BitTestData);
+  const uintptr_t swapped_test_data =
+      static_cast<uintptr_t>(k64BitSwappedTestData);
+#elif defined(ARCH_CPU_32_BITS)
+  const uintptr_t test_data = static_cast<uintptr_t>(k32BitTestData);
+  const uintptr_t swapped_test_data =
+      static_cast<uintptr_t>(k32BitSwappedTestData);
+#else
+#error architecture not supported
+#endif
+
+  uintptr_t swapped = base::ByteSwapUintPtrT(test_data);
+  EXPECT_EQ(swapped_test_data, swapped);
+  uintptr_t reswapped = base::ByteSwapUintPtrT(swapped);
+  EXPECT_EQ(test_data, reswapped);
+}
+
 TEST(ByteOrderTest, ByteSwapToLE16) {
   uint16_t le = base::ByteSwapToLE16(k16BitTestData);
 #if defined(ARCH_CPU_LITTLE_ENDIAN)
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/banners/AppBannerManager.java b/chrome/android/java/src/org/chromium/chrome/browser/banners/AppBannerManager.java
index 781d36f70..8aa2d7b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/banners/AppBannerManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/banners/AppBannerManager.java
@@ -157,22 +157,28 @@
         sIsSupported = state;
     }
 
+    /** Returns whether the native AppBannerManager is working. */
+    @VisibleForTesting
+    public boolean isActiveForTesting() {
+        return nativeIsActiveForTesting(mNativePointer);
+    }
+
+    /** Sets constants (in days) the banner should be blocked for after dismissing and ignoring. */
+    @VisibleForTesting
+    static void setDaysAfterDismissAndIgnoreForTesting(int dismissDays, int ignoreDays) {
+        nativeSetDaysAfterDismissAndIgnoreToTrigger(dismissDays, ignoreDays);
+    }
+
     /** Sets a constant (in days) that gets added to the time when the current time is requested. */
     @VisibleForTesting
     static void setTimeDeltaForTesting(int days) {
         nativeSetTimeDeltaForTesting(days);
     }
 
-    /** Sets the weights of direct and indirect page navigations for testing. */
+    /** Sets the total required engagement to trigger the banner. */
     @VisibleForTesting
-    static void setEngagementWeights(double directEngagement, double indirectEngagement) {
-        nativeSetEngagementWeights(directEngagement, indirectEngagement);
-    }
-
-    /** Returns whether the native AppBannerManager is working. */
-    @VisibleForTesting
-    public boolean isActiveForTesting() {
-        return nativeIsActiveForTesting(mNativePointer);
+    static void setTotalEngagementForTesting(double engagement) {
+        nativeSetTotalEngagementToTrigger(engagement);
     }
 
     /** Returns the AppBannerManager object. This is owned by the C++ banner manager. */
@@ -187,8 +193,9 @@
             AppData data, String title, String packageName, String imageUrl);
 
     // Testing methods.
-    private static native void nativeSetTimeDeltaForTesting(int days);
-    private static native void nativeSetEngagementWeights(double directEngagement,
-            double indirectEngagement);
     private native boolean nativeIsActiveForTesting(long nativeAppBannerManagerAndroid);
+    private static native void nativeSetDaysAfterDismissAndIgnoreToTrigger(
+            int dismissDays, int ignoreDays);
+    private static native void nativeSetTimeDeltaForTesting(int days);
+    private static native void nativeSetTotalEngagementToTrigger(double engagement);
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java
index 8c04ebb..cbd5f16 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java
@@ -22,14 +22,15 @@
 
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.util.Feature;
-import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ShortcutHelper;
+import org.chromium.chrome.browser.engagement.SiteEngagementService;
 import org.chromium.chrome.browser.infobar.AppBannerInfoBarAndroid;
 import org.chromium.chrome.browser.infobar.AppBannerInfoBarDelegateAndroid;
 import org.chromium.chrome.browser.infobar.InfoBar;
 import org.chromium.chrome.browser.infobar.InfoBarContainer;
 import org.chromium.chrome.browser.infobar.InfoBarContainer.InfoBarAnimationListener;
+import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.webapps.WebappDataStorage;
 import org.chromium.chrome.test.ChromeTabbedActivityTestBase;
 import org.chromium.chrome.test.util.browser.TabLoadObserver;
@@ -38,6 +39,7 @@
 import org.chromium.content.browser.test.util.CriteriaHelper;
 import org.chromium.content.browser.test.util.TouchCommon;
 import org.chromium.net.test.EmbeddedTestServer;
+import org.chromium.ui.base.PageTransition;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -193,10 +195,7 @@
             }
         });
 
-        // Navigations in this test are all of type ui::PAGE_TRANSITION_LINK, i.e. indirect.
-        // Force indirect navigations to be worth the same as direct for testing.
-        AppBannerManager.setEngagementWeights(1, 1);
-
+        AppBannerManager.setTotalEngagementForTesting(10);
         mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
         mNativeAppUrl = mTestServer.getURL(NATIVE_APP_PATH);
         mWebAppUrl = mTestServer.getURL(WEB_APP_PATH);
@@ -208,6 +207,16 @@
         super.tearDown();
     }
 
+    private void resetEngagementForUrl(final String url, final double engagement) {
+        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
+            @Override
+            public void run() {
+                SiteEngagementService.getForProfile(Profile.getLastUsedProfile())
+                        .resetScoreForUrl(url, engagement);
+            }
+        });
+    }
+
     private void waitUntilNoInfoBarsExist() throws Exception {
         CriteriaHelper.pollUiThread(new Criteria() {
             @Override
@@ -246,18 +255,18 @@
 
     private void runFullNativeInstallPathway(String url, String expectedReferrer) throws Exception {
         // Visit a site that requests a banner.
-        new TabLoadObserver(getActivity().getActivityTab()).fullyLoadUrl(url);
-        waitUntilAppDetailsRetrieved(1);
-        assertEquals(mDetailsDelegate.mReferrer, expectedReferrer);
+        resetEngagementForUrl(url, 0);
+        new TabLoadObserver(getActivity().getActivityTab()).fullyLoadUrl(url, PageTransition.TYPED);
         waitUntilNoInfoBarsExist();
 
-        // Indicate a day has passed, then revisit the page to get the banner to appear.
+        // Update engagement, then revisit the page to get the banner to appear.
+        resetEngagementForUrl(url, 10);
         InfoBarContainer container = getActivity().getActivityTab().getInfoBarContainer();
         final InfobarListener listener = new InfobarListener();
         container.setAnimationListener(listener);
-        AppBannerManager.setTimeDeltaForTesting(1);
-        new TabLoadObserver(getActivity().getActivityTab()).fullyLoadUrl(url);
-        waitUntilAppDetailsRetrieved(2);
+        new TabLoadObserver(getActivity().getActivityTab()).fullyLoadUrl(url, PageTransition.TYPED);
+        waitUntilAppDetailsRetrieved(1);
+        assertEquals(mDetailsDelegate.mReferrer, expectedReferrer);
         waitUntilAppBannerInfoBarAppears(NATIVE_APP_TITLE);
         CriteriaHelper.pollUiThread(new Criteria() {
             @Override
@@ -305,8 +314,9 @@
     public void triggerWebAppBanner(String url, String expectedTitle, boolean installApp)
             throws Exception {
         // Visit the site in a new tab.
+        resetEngagementForUrl(url, 0);
         loadUrlInNewTab("about:blank");
-        new TabLoadObserver(getActivity().getActivityTab()).fullyLoadUrl(url);
+        new TabLoadObserver(getActivity().getActivityTab()).fullyLoadUrl(url, PageTransition.TYPED);
 
         CriteriaHelper.pollUiThread(new Criteria() {
             @Override
@@ -322,9 +332,9 @@
         final InfobarListener listener = new InfobarListener();
         container.setAnimationListener(listener);
 
-        // Indicate a day has passed, then revisit the page to show the banner.
-        AppBannerManager.setTimeDeltaForTesting(1);
-        new TabLoadObserver(getActivity().getActivityTab()).fullyLoadUrl(url);
+        // Update engagement, then revisit the page to get the banner to appear.
+        resetEngagementForUrl(url, 10);
+        new TabLoadObserver(getActivity().getActivityTab()).fullyLoadUrl(url, PageTransition.TYPED);
         CriteriaHelper.pollUiThread(new Criteria() {
             @Override
             public boolean isSatisfied() {
@@ -351,7 +361,6 @@
 
     @SmallTest
     @Feature({"AppBanners"})
-    @RetryOnFailure
     public void testFullNativeInstallPathwayFromId() throws Exception {
         runFullNativeInstallPathway(mNativeAppUrl, NATIVE_APP_BLANK_REFERRER);
     }
@@ -365,63 +374,84 @@
 
     @MediumTest
     @Feature({"AppBanners"})
-    @RetryOnFailure
     public void testBannerAppearsThenDoesNotAppearAgainForWeeks() throws Exception {
         // Visit a site that requests a banner.
-        new TabLoadObserver(getActivity().getActivityTab()).fullyLoadUrl(mNativeAppUrl);
-        waitUntilAppDetailsRetrieved(1);
+        resetEngagementForUrl(mNativeAppUrl, 0);
+        new TabLoadObserver(getActivity().getActivityTab())
+                .fullyLoadUrl(mNativeAppUrl, PageTransition.TYPED);
         waitUntilNoInfoBarsExist();
 
-        // Indicate a day has passed, then revisit the page.
-        AppBannerManager.setTimeDeltaForTesting(1);
-        new TabLoadObserver(getActivity().getActivityTab()).fullyLoadUrl(mNativeAppUrl);
-        waitUntilAppDetailsRetrieved(2);
+        // Update engagement, then revisit the page.
+        resetEngagementForUrl(mNativeAppUrl, 10);
+        new TabLoadObserver(getActivity().getActivityTab())
+                .fullyLoadUrl(mNativeAppUrl, PageTransition.TYPED);
+        waitUntilAppDetailsRetrieved(1);
         waitUntilAppBannerInfoBarAppears(NATIVE_APP_TITLE);
 
         // Revisit the page to make the banner go away, but don't explicitly dismiss it.
         // This hides the banner for two weeks.
-        new TabLoadObserver(getActivity().getActivityTab()).fullyLoadUrl(mNativeAppUrl);
-        waitUntilAppDetailsRetrieved(3);
+        new TabLoadObserver(getActivity().getActivityTab())
+                .fullyLoadUrl(mNativeAppUrl, PageTransition.TYPED);
+        waitUntilAppDetailsRetrieved(2);
         waitUntilNoInfoBarsExist();
 
         // Wait a week until revisiting the page.
         AppBannerManager.setTimeDeltaForTesting(7);
-        new TabLoadObserver(getActivity().getActivityTab()).fullyLoadUrl(mNativeAppUrl);
-        waitUntilAppDetailsRetrieved(4);
+        new TabLoadObserver(getActivity().getActivityTab())
+                .fullyLoadUrl(mNativeAppUrl, PageTransition.TYPED);
+        waitUntilAppDetailsRetrieved(3);
         waitUntilNoInfoBarsExist();
 
         AppBannerManager.setTimeDeltaForTesting(8);
-        new TabLoadObserver(getActivity().getActivityTab()).fullyLoadUrl(mNativeAppUrl);
-        waitUntilAppDetailsRetrieved(5);
+        new TabLoadObserver(getActivity().getActivityTab())
+                .fullyLoadUrl(mNativeAppUrl, PageTransition.TYPED);
+        waitUntilAppDetailsRetrieved(4);
         waitUntilNoInfoBarsExist();
 
         // Wait two weeks until revisiting the page, which should pop up the banner.
-        AppBannerManager.setTimeDeltaForTesting(14);
-        new TabLoadObserver(getActivity().getActivityTab()).fullyLoadUrl(mNativeAppUrl);
-        waitUntilAppDetailsRetrieved(6);
+        AppBannerManager.setTimeDeltaForTesting(15);
+        new TabLoadObserver(getActivity().getActivityTab())
+                .fullyLoadUrl(mNativeAppUrl, PageTransition.TYPED);
+        waitUntilAppDetailsRetrieved(5);
+        waitUntilAppBannerInfoBarAppears(NATIVE_APP_TITLE);
+    }
+
+    @MediumTest
+    @Feature({"AppBanners"})
+    public void testBannerAppearsThenDoesNotAppearAgainForCustomTime() throws Exception {
+        AppBannerManager.setDaysAfterDismissAndIgnoreForTesting(7, 7);
+        triggerWebAppBanner(mWebAppUrl, WEB_APP_TITLE, false);
+
+        // Revisit the page to make the banner go away, but don't explicitly dismiss it.
+        // This hides the banner for two weeks.
+        new TabLoadObserver(getActivity().getActivityTab())
+                .fullyLoadUrl(mWebAppUrl, PageTransition.TYPED);
         waitUntilNoInfoBarsExist();
 
-        AppBannerManager.setTimeDeltaForTesting(15);
-        new TabLoadObserver(getActivity().getActivityTab()).fullyLoadUrl(mNativeAppUrl);
-        waitUntilAppDetailsRetrieved(7);
-        waitUntilAppBannerInfoBarAppears(NATIVE_APP_TITLE);
+        // Wait a week until revisiting the page. This should allow the banner.
+        AppBannerManager.setTimeDeltaForTesting(7);
+        new TabLoadObserver(getActivity().getActivityTab())
+                .fullyLoadUrl(mWebAppUrl, PageTransition.TYPED);
+        waitUntilAppBannerInfoBarAppears(WEB_APP_TITLE);
     }
 
     @MediumTest
     @Feature({"AppBanners"})
     public void testBlockedBannerDoesNotAppearAgainForMonths() throws Exception {
         // Visit a site that requests a banner.
-        new TabLoadObserver(getActivity().getActivityTab()).fullyLoadUrl(mNativeAppUrl);
-        waitUntilAppDetailsRetrieved(1);
+        resetEngagementForUrl(mNativeAppUrl, 0);
+        new TabLoadObserver(getActivity().getActivityTab())
+                .fullyLoadUrl(mNativeAppUrl, PageTransition.TYPED);
         waitUntilNoInfoBarsExist();
 
-        // Indicate a day has passed, then revisit the page.
+        // Update engagement, then revisit the page.
+        resetEngagementForUrl(mNativeAppUrl, 10);
         InfoBarContainer container = getActivity().getActivityTab().getInfoBarContainer();
         final InfobarListener listener = new InfobarListener();
         container.setAnimationListener(listener);
-        AppBannerManager.setTimeDeltaForTesting(1);
-        new TabLoadObserver(getActivity().getActivityTab()).fullyLoadUrl(mNativeAppUrl);
-        waitUntilAppDetailsRetrieved(2);
+        new TabLoadObserver(getActivity().getActivityTab())
+                .fullyLoadUrl(mNativeAppUrl, PageTransition.TYPED);
+        waitUntilAppDetailsRetrieved(1);
         waitUntilAppBannerInfoBarAppears(NATIVE_APP_TITLE);
 
         // Explicitly dismiss the banner.
@@ -438,56 +468,97 @@
 
         // Waiting two months shouldn't be long enough.
         AppBannerManager.setTimeDeltaForTesting(61);
-        new TabLoadObserver(getActivity().getActivityTab()).fullyLoadUrl(mNativeAppUrl);
-        waitUntilAppDetailsRetrieved(3);
+        new TabLoadObserver(getActivity().getActivityTab())
+                .fullyLoadUrl(mNativeAppUrl, PageTransition.TYPED);
+        waitUntilAppDetailsRetrieved(2);
         waitUntilNoInfoBarsExist();
 
         AppBannerManager.setTimeDeltaForTesting(62);
-        new TabLoadObserver(getActivity().getActivityTab()).fullyLoadUrl(mNativeAppUrl);
-        waitUntilAppDetailsRetrieved(4);
+        new TabLoadObserver(getActivity().getActivityTab())
+                .fullyLoadUrl(mNativeAppUrl, PageTransition.TYPED);
+        waitUntilAppDetailsRetrieved(3);
         waitUntilNoInfoBarsExist();
 
         // Waiting three months should allow banners to reappear.
         AppBannerManager.setTimeDeltaForTesting(91);
-        new TabLoadObserver(getActivity().getActivityTab()).fullyLoadUrl(mNativeAppUrl);
-        waitUntilAppDetailsRetrieved(5);
-        waitUntilNoInfoBarsExist();
-
-        AppBannerManager.setTimeDeltaForTesting(92);
-        new TabLoadObserver(getActivity().getActivityTab()).fullyLoadUrl(mNativeAppUrl);
-        waitUntilAppDetailsRetrieved(6);
+        new TabLoadObserver(getActivity().getActivityTab())
+                .fullyLoadUrl(mNativeAppUrl, PageTransition.TYPED);
+        waitUntilAppDetailsRetrieved(4);
         waitUntilAppBannerInfoBarAppears(NATIVE_APP_TITLE);
     }
 
     @MediumTest
     @Feature({"AppBanners"})
-    @RetryOnFailure
+    public void testBlockedBannerDoesNotAppearAgainForCustomTime() throws Exception {
+        AppBannerManager.setDaysAfterDismissAndIgnoreForTesting(7, 7);
+
+        // Update engagement, then visit a page which triggers a banner.
+        resetEngagementForUrl(mWebAppUrl, 10);
+        InfoBarContainer container = getActivity().getActivityTab().getInfoBarContainer();
+        final InfobarListener listener = new InfobarListener();
+        container.setAnimationListener(listener);
+        new TabLoadObserver(getActivity().getActivityTab())
+                .fullyLoadUrl(mWebAppUrl, PageTransition.TYPED);
+        waitUntilAppBannerInfoBarAppears(WEB_APP_TITLE);
+
+        // Explicitly dismiss the banner.
+        CriteriaHelper.pollUiThread(new Criteria() {
+            @Override
+            public boolean isSatisfied() {
+                return listener.mDoneAnimating;
+            }
+        });
+        ArrayList<InfoBar> infobars = container.getInfoBarsForTesting();
+        View close = infobars.get(0).getView().findViewById(R.id.infobar_close_button);
+        TouchCommon.singleClickView(close);
+        waitUntilNoInfoBarsExist();
+
+        // Waiting seven days should be long enough.
+        AppBannerManager.setTimeDeltaForTesting(7);
+        new TabLoadObserver(getActivity().getActivityTab())
+                .fullyLoadUrl(mWebAppUrl, PageTransition.TYPED);
+        waitUntilAppBannerInfoBarAppears(WEB_APP_TITLE);
+    }
+
+    @MediumTest
+    @Feature({"AppBanners"})
     public void testBitmapFetchersCanOverlapWithoutCrashing() throws Exception {
         // Visit a site that requests a banner rapidly and repeatedly.
+        resetEngagementForUrl(mNativeAppUrl, 10);
         for (int i = 1; i <= 10; i++) {
-            new TabLoadObserver(getActivity().getActivityTab()).fullyLoadUrl(mNativeAppUrl);
+            new TabLoadObserver(getActivity().getActivityTab())
+                    .fullyLoadUrl(mNativeAppUrl, PageTransition.TYPED);
 
             final Integer iteration = Integer.valueOf(i);
-            CriteriaHelper.pollUiThread(
-                    Criteria.equals(iteration, new Callable<Integer>() {
-                        @Override
-                        public Integer call() {
-                            return mDetailsDelegate.mNumRetrieved;
-                        }
-                    }));
+            CriteriaHelper.pollUiThread(Criteria.equals(iteration, new Callable<Integer>() {
+                @Override
+                public Integer call() {
+                    return mDetailsDelegate.mNumRetrieved;
+                }
+            }));
         }
     }
 
     @SmallTest
     @Feature({"AppBanners"})
-    @RetryOnFailure
     public void testWebAppBannerAppears() throws Exception {
         triggerWebAppBanner(mWebAppUrl, WEB_APP_TITLE, false);
     }
 
     @SmallTest
     @Feature({"AppBanners"})
-    @RetryOnFailure
+    public void testWebAppBannerDoesNotAppearAfterInstall() throws Exception {
+        triggerWebAppBanner(mWebAppUrl, WEB_APP_TITLE, true);
+
+        // The banner should not reshow after the site has been installed.
+        AppBannerManager.setTimeDeltaForTesting(100);
+        new TabLoadObserver(getActivity().getActivityTab())
+                .fullyLoadUrl(mWebAppUrl, PageTransition.TYPED);
+        waitUntilNoInfoBarsExist();
+    }
+
+    @SmallTest
+    @Feature({"AppBanners"})
     public void testBannerFallsBackToShortName() throws Exception {
         triggerWebAppBanner(WebappTestPage.urlOfPageWithServiceWorkerAndManifest(
                                     mTestServer, WEB_APP_SHORT_TITLE_MANIFEST),
@@ -496,7 +567,6 @@
 
     @SmallTest
     @Feature({"AppBanners"})
-    @RetryOnFailure
     public void testWebAppSplashscreenIsDownloaded() throws Exception {
         // Sets the overriden factory to observer splash screen update.
         final TestDataStorageFactory dataStorageFactory = new TestDataStorageFactory();
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp
index d8f0e647..f8a4775 100644
--- a/chrome/app/chromeos_strings.grdp
+++ b/chrome/app/chromeos_strings.grdp
@@ -806,6 +806,9 @@
   <message name="IDS_FILE_BROWSER_METADATA_BOX_EXIF_DEVICE_MODEL" desc="Label for the device model which created the image.">
     Device Model
   </message>
+  <message name="IDS_FILE_BROWSER_METADATA_BOX_EXIF_DEVICE_SETTINGS" desc="Label for the device settings (exif's F number, exposure time, focal length and ISO speed rating) metadata.">
+    Device Settings
+  </message>
   <message name="IDS_FILE_BROWSER_METADATA_BOX_EXIF_GEOGRAPHY" desc="Label for the latitude and the longitude where the image was taken.">
     Geography
   </message>
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index ff9ba4c..4ff6479ef 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -746,6 +746,10 @@
     "ntp_snippets/content_suggestions_service_factory.h",
     "ntp_snippets/download_suggestions_provider.cc",
     "ntp_snippets/download_suggestions_provider.h",
+    "ntp_tiles/chrome_most_visited_sites_factory.cc",
+    "ntp_tiles/chrome_most_visited_sites_factory.h",
+    "ntp_tiles/chrome_popular_sites_factory.cc",
+    "ntp_tiles/chrome_popular_sites_factory.h",
     "page_load_metrics/browser_page_track_decider.cc",
     "page_load_metrics/browser_page_track_decider.h",
     "page_load_metrics/metrics_navigation_throttle.cc",
@@ -3102,8 +3106,6 @@
       "android/ntp/ntp_snippets_bridge.h",
       "android/ntp/ntp_snippets_launcher.cc",
       "android/ntp/ntp_snippets_launcher.h",
-      "android/ntp/popular_sites.cc",
-      "android/ntp/popular_sites.h",
       "android/offline_pages/background_scheduler_bridge.cc",
       "android/offline_pages/background_scheduler_bridge.h",
       "android/offline_pages/downloads/offline_page_download_bridge.cc",
diff --git a/chrome/browser/android/banners/app_banner_manager_android.cc b/chrome/browser/android/banners/app_banner_manager_android.cc
index 11e2df9a..38358bc 100644
--- a/chrome/browser/android/banners/app_banner_manager_android.cc
+++ b/chrome/browser/android/banners/app_banner_manager_android.cc
@@ -307,12 +307,12 @@
 }
 
 // static
-void SetEngagementWeights(JNIEnv* env,
-                          const JavaParamRef<jclass>& clazz,
-                          jdouble direct_engagement,
-                          jdouble indirect_engagement) {
-  AppBannerManager::SetEngagementWeights(direct_engagement,
-                                         indirect_engagement);
+void SetDaysAfterDismissAndIgnoreToTrigger(JNIEnv* env,
+                                           const JavaParamRef<jclass>& clazz,
+                                           jint dismiss_days,
+                                           jint ignore_days) {
+  AppBannerSettingsHelper::SetDaysAfterDismissAndIgnoreToTrigger(dismiss_days,
+                                                                 ignore_days);
 }
 
 // static
@@ -322,4 +322,11 @@
   AppBannerManager::SetTimeDeltaForTesting(days);
 }
 
+// static
+void SetTotalEngagementToTrigger(JNIEnv* env,
+                                 const JavaParamRef<jclass>& clazz,
+                                 jdouble engagement) {
+  AppBannerSettingsHelper::SetTotalEngagementToTrigger(engagement);
+}
+
 }  // namespace banners
diff --git a/chrome/browser/android/data_usage/OWNERS b/chrome/browser/android/data_usage/OWNERS
index ad4b2b21..78d68ca 100644
--- a/chrome/browser/android/data_usage/OWNERS
+++ b/chrome/browser/android/data_usage/OWNERS
@@ -1,3 +1,4 @@
 bengr@chromium.org
+rajendrant@chromium.org
 sclittle@chromium.org
 tbansal@chromium.org
\ No newline at end of file
diff --git a/chrome/browser/android/ntp/most_visited_sites_bridge.cc b/chrome/browser/android/ntp/most_visited_sites_bridge.cc
index cbb5bcb..4f35387 100644
--- a/chrome/browser/android/ntp/most_visited_sites_bridge.cc
+++ b/chrome/browser/android/ntp/most_visited_sites_bridge.cc
@@ -10,34 +10,16 @@
 #include "base/android/jni_array.h"
 #include "base/android/jni_string.h"
 #include "base/android/scoped_java_ref.h"
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/memory/ptr_util.h"
-#include "chrome/browser/android/ntp/popular_sites.h"
 #include "chrome/browser/browser_process.h"
-#include "chrome/browser/favicon/favicon_service_factory.h"
-#include "chrome/browser/history/top_sites_factory.h"
+#include "chrome/browser/ntp_tiles/chrome_most_visited_sites_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_android.h"
-#include "chrome/browser/search/suggestions/image_decoder_impl.h"
-#include "chrome/browser/search/suggestions/suggestions_service_factory.h"
-#include "chrome/browser/search_engines/template_url_service_factory.h"
-#include "chrome/browser/supervised_user/supervised_user_service.h"
-#include "chrome/browser/supervised_user/supervised_user_service_factory.h"
-#include "chrome/browser/supervised_user/supervised_user_url_filter.h"
 #include "chrome/browser/thumbnails/thumbnail_list_source.h"
-#include "components/history/core/browser/top_sites.h"
-#include "components/image_fetcher/image_fetcher_impl.h"
-#include "components/ntp_tiles/icon_cacher.h"
 #include "components/ntp_tiles/metrics.h"
-#include "components/ntp_tiles/popular_sites.h"
+#include "components/ntp_tiles/most_visited_sites.h"
 #include "components/rappor/rappor_service_impl.h"
-#include "components/safe_json/safe_json_parser.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/url_data_source.h"
 #include "jni/MostVisitedSites_jni.h"
 #include "ui/gfx/android/java_bitmap.h"
-#include "url/gurl.h"
 
 using base::android::AttachCurrentThread;
 using base::android::ConvertJavaStringToUTF8;
@@ -47,63 +29,11 @@
 using base::android::ScopedJavaLocalRef;
 using base::android::ToJavaArrayOfStrings;
 using base::android::ToJavaIntArray;
-using content::BrowserThread;
+using ntp_tiles::MostVisitedSites;
+using ntp_tiles::NTPTileSource;
+using ntp_tiles::NTPTilesVector;
 using ntp_tiles::metrics::MostVisitedTileType;
 using ntp_tiles::metrics::TileImpression;
-using ntp_tiles::MostVisitedSites;
-using ntp_tiles::MostVisitedSitesSupervisor;
-using ntp_tiles::NTPTileSource;
-using suggestions::SuggestionsServiceFactory;
-
-MostVisitedSitesBridge::SupervisorBridge::SupervisorBridge(Profile* profile)
-    : profile_(profile),
-      supervisor_observer_(nullptr),
-      register_observer_(this) {
-  register_observer_.Add(SupervisedUserServiceFactory::GetForProfile(profile_));
-}
-
-MostVisitedSitesBridge::SupervisorBridge::~SupervisorBridge() {}
-
-void MostVisitedSitesBridge::SupervisorBridge::SetObserver(
-    Observer* new_observer) {
-  if (new_observer)
-    DCHECK(!supervisor_observer_);
-  else
-    DCHECK(supervisor_observer_);
-
-  supervisor_observer_ = new_observer;
-}
-
-bool MostVisitedSitesBridge::SupervisorBridge::IsBlocked(const GURL& url) {
-  SupervisedUserService* supervised_user_service =
-      SupervisedUserServiceFactory::GetForProfile(profile_);
-  auto* url_filter = supervised_user_service->GetURLFilterForUIThread();
-  return url_filter->GetFilteringBehaviorForURL(url) ==
-         SupervisedUserURLFilter::FilteringBehavior::BLOCK;
-}
-
-std::vector<MostVisitedSitesSupervisor::Whitelist>
-MostVisitedSitesBridge::SupervisorBridge::whitelists() {
-  std::vector<MostVisitedSitesSupervisor::Whitelist> results;
-  SupervisedUserService* supervised_user_service =
-      SupervisedUserServiceFactory::GetForProfile(profile_);
-  for (const auto& whitelist : supervised_user_service->whitelists()) {
-    results.emplace_back(Whitelist{
-        whitelist->title(), whitelist->entry_point(),
-        whitelist->large_icon_path(),
-    });
-  }
-  return results;
-}
-
-bool MostVisitedSitesBridge::SupervisorBridge::IsChildProfile() {
-  return profile_->IsChild();
-}
-
-void MostVisitedSitesBridge::SupervisorBridge::OnURLFilterChanged() {
-  if (supervisor_observer_)
-    supervisor_observer_->OnBlockedSitesChanged();
-}
 
 class MostVisitedSitesBridge::JavaObserver : public MostVisitedSites::Observer {
  public:
@@ -157,19 +87,7 @@
 }
 
 MostVisitedSitesBridge::MostVisitedSitesBridge(Profile* profile)
-    : supervisor_(profile),
-      most_visited_(profile->GetPrefs(),
-                    TopSitesFactory::GetForProfile(profile),
-                    SuggestionsServiceFactory::GetForProfile(profile),
-                    ChromePopularSites::NewForProfile(profile),
-                    base::MakeUnique<ntp_tiles::IconCacher>(
-                        FaviconServiceFactory::GetForProfile(
-                            profile,
-                            ServiceAccessType::IMPLICIT_ACCESS),
-                        base::MakeUnique<image_fetcher::ImageFetcherImpl>(
-                            base::MakeUnique<suggestions::ImageDecoderImpl>(),
-                            profile->GetRequestContext())),
-                    &supervisor_) {
+    : most_visited_(ChromeMostVisitedSitesFactory::NewForProfile(profile)) {
   // Register the thumbnails debugging page.
   // TODO(sfiera): find thumbnails a home. They don't belong here.
   content::URLDataSource::Add(profile, new ThumbnailListSource(profile));
@@ -189,7 +107,7 @@
     const JavaParamRef<jobject>& j_observer,
     jint num_sites) {
   java_observer_.reset(new JavaObserver(env, j_observer));
-  most_visited_.SetMostVisitedURLsObserver(java_observer_.get(), num_sites);
+  most_visited_->SetMostVisitedURLsObserver(java_observer_.get(), num_sites);
 }
 
 void MostVisitedSitesBridge::AddOrRemoveBlacklistedUrl(
@@ -198,7 +116,7 @@
     const JavaParamRef<jstring>& j_url,
     jboolean add_url) {
   GURL url(ConvertJavaStringToUTF8(env, j_url));
-  most_visited_.AddOrRemoveBlacklistedUrl(url, add_url);
+  most_visited_->AddOrRemoveBlacklistedUrl(url, add_url);
 }
 
 void MostVisitedSitesBridge::RecordPageImpression(
diff --git a/chrome/browser/android/ntp/most_visited_sites_bridge.h b/chrome/browser/android/ntp/most_visited_sites_bridge.h
index 18020c9b..a86483d 100644
--- a/chrome/browser/android/ntp/most_visited_sites_bridge.h
+++ b/chrome/browser/android/ntp/most_visited_sites_bridge.h
@@ -6,22 +6,18 @@
 #define CHROME_BROWSER_ANDROID_NTP_MOST_VISITED_SITES_BRIDGE_H_
 
 #include <jni.h>
-#include <stddef.h>
 
 #include <memory>
-#include <string>
-#include <vector>
 
 #include "base/android/scoped_java_ref.h"
 #include "base/macros.h"
-#include "chrome/browser/supervised_user/supervised_user_service.h"
-#include "chrome/browser/supervised_user/supervised_user_service_observer.h"
-#include "components/ntp_tiles/most_visited_sites.h"
-
-using ntp_tiles::NTPTilesVector;
 
 class Profile;
 
+namespace ntp_tiles {
+class MostVisitedSites;
+}  // namespace ntp_tiles
+
 // Provides the list of most visited sites and their thumbnails to Java.
 class MostVisitedSitesBridge {
  public:
@@ -62,29 +58,7 @@
   class JavaObserver;
   std::unique_ptr<JavaObserver> java_observer_;
 
-  class SupervisorBridge : public ntp_tiles::MostVisitedSitesSupervisor,
-                           public SupervisedUserServiceObserver {
-   public:
-    explicit SupervisorBridge(Profile* profile);
-    ~SupervisorBridge() override;
-
-    void SetObserver(Observer* observer) override;
-    bool IsBlocked(const GURL& url) override;
-    std::vector<MostVisitedSitesSupervisor::Whitelist> whitelists() override;
-    bool IsChildProfile() override;
-
-    // SupervisedUserServiceObserver implementation.
-    void OnURLFilterChanged() override;
-
-   private:
-    Profile* const profile_;
-    Observer* supervisor_observer_;
-    ScopedObserver<SupervisedUserService, SupervisedUserServiceObserver>
-        register_observer_;
-  };
-  SupervisorBridge supervisor_;
-
-  ntp_tiles::MostVisitedSites most_visited_;
+  std::unique_ptr<ntp_tiles::MostVisitedSites> most_visited_;
 
   DISALLOW_COPY_AND_ASSIGN(MostVisitedSitesBridge);
 };
diff --git a/chrome/browser/android/ntp/popular_sites.h b/chrome/browser/android/ntp/popular_sites.h
deleted file mode 100644
index 07d3730..0000000
--- a/chrome/browser/android/ntp/popular_sites.h
+++ /dev/null
@@ -1,29 +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.
-
-#ifndef CHROME_BROWSER_ANDROID_NTP_POPULAR_SITES_H_
-#define CHROME_BROWSER_ANDROID_NTP_POPULAR_SITES_H_
-
-#include <memory>
-
-#include "base/files/file_path.h"
-#include "base/macros.h"
-
-class Profile;
-
-namespace ntp_tiles {
-class PopularSites;
-}  // namespace ntp_tiles
-
-// TODO(sfiera): move to chrome_popular_sites.h
-class ChromePopularSites {
- public:
-  static std::unique_ptr<ntp_tiles::PopularSites> NewForProfile(
-      Profile* profile);
-
- private:
-  DISALLOW_IMPLICIT_CONSTRUCTORS(ChromePopularSites);
-};
-
-#endif  // CHROME_BROWSER_ANDROID_NTP_POPULAR_SITES_H_
diff --git a/chrome/browser/banners/app_banner_manager.cc b/chrome/browser/banners/app_banner_manager.cc
index bad0034..d9f4521 100644
--- a/chrome/browser/banners/app_banner_manager.cc
+++ b/chrome/browser/banners/app_banner_manager.cc
@@ -72,10 +72,8 @@
 }
 
 // static
-void AppBannerManager::SetEngagementWeights(double direct_engagement,
-                                            double indirect_engagement) {
-  AppBannerSettingsHelper::SetEngagementWeights(direct_engagement,
-                                                indirect_engagement);
+void AppBannerManager::SetTotalEngagementToTrigger(double engagement) {
+  AppBannerSettingsHelper::SetTotalEngagementToTrigger(engagement);
 }
 
 // static
@@ -363,8 +361,7 @@
     return;
 
   load_finished_ = false;
-  if (AppBannerSettingsHelper::ShouldUseSiteEngagementScore() &&
-      GetSiteEngagementService() == nullptr) {
+  if (GetSiteEngagementService() == nullptr) {
     // Ensure that we are observing the site engagement service on navigation
     // start. This may be the first navigation, or we may have stopped
     // observing if the banner flow was triggered on the previous page.
@@ -376,7 +373,6 @@
 void AppBannerManager::DidFinishNavigation(content::NavigationHandle* handle) {
   if (handle->IsInMainFrame() && handle->HasCommitted() &&
       !handle->IsSamePage()) {
-    last_transition_type_ = handle->GetPageTransition();
     active_media_players_.clear();
     if (is_active_)
       Stop();
@@ -392,10 +388,9 @@
 
   load_finished_ = true;
   validated_url_ = validated_url;
-  // Start the pipeline immediately if we aren't using engagement, or if 0
-  // engagement is required.
-  if (!AppBannerSettingsHelper::ShouldUseSiteEngagementScore() ||
-      banner_request_queued_ ||
+  // Start the pipeline immediately if 0 engagement is required or if we've
+  // queued a banner request.
+  if (banner_request_queued_ ||
       AppBannerSettingsHelper::HasSufficientEngagement(0)) {
     SiteEngagementObserver::Observe(nullptr);
     banner_request_queued_ = false;
@@ -448,9 +443,9 @@
   content::WebContents* contents = web_contents();
   DCHECK(contents);
 
-  AppBannerSettingsHelper::RecordBannerCouldShowEvent(
+  AppBannerSettingsHelper::RecordBannerEvent(
       contents, validated_url_, GetAppIdentifier(),
-      GetCurrentTime(), last_transition_type_);
+      AppBannerSettingsHelper::APP_BANNER_EVENT_COULD_SHOW, GetCurrentTime());
 }
 
 bool AppBannerManager::CheckIfShouldShowBanner() {
diff --git a/chrome/browser/banners/app_banner_manager.h b/chrome/browser/banners/app_banner_manager.h
index 20bff4c..15bb380e 100644
--- a/chrome/browser/banners/app_banner_manager.h
+++ b/chrome/browser/banners/app_banner_manager.h
@@ -58,11 +58,8 @@
   // Fast-forwards the current time for testing.
   static void SetTimeDeltaForTesting(int days);
 
-  // Sets the weights applied to direct and indirect navigations for triggering
-  // the banner. Deprecated and will be removed when app banners fully migrates
-  // to using site engagement as a trigger.
-  static void SetEngagementWeights(double direct_engagement,
-                                   double indirect_engagement);
+  // Sets the total engagement required for triggering the banner in testing.
+  static void SetTotalEngagementToTrigger(double engagement);
 
   // Returns whether or not the URLs match for everything except for the ref.
   static bool URLsAreForTheSamePage(const GURL& first, const GURL& second);
@@ -160,9 +157,8 @@
 
   // Sends a message to the renderer that the page has met the requirements to
   // show a banner. The page can respond to cancel the banner (and possibly
-  // display it later), or otherwise allow it to be shown. This is virtual to
-  // allow tests to mock out the renderer IPC.
-  virtual void SendBannerPromptRequest();
+  // display it later), or otherwise allow it to be shown.
+  void SendBannerPromptRequest();
 
   // content::WebContentsObserver overrides.
   void DidStartNavigation(content::NavigationHandle* handle) override;
@@ -233,9 +229,6 @@
   // requesting that it be shown later.
   void DisplayAppBanner() override;
 
-  // The type of navigation made to the page
-  ui::PageTransition last_transition_type_;
-
   // Fetches the data required to display a banner for the current page.
   InstallableManager* manager_;
 
diff --git a/chrome/browser/banners/app_banner_manager_browsertest.cc b/chrome/browser/banners/app_banner_manager_browsertest.cc
index 7324640..cbf81ea 100644
--- a/chrome/browser/banners/app_banner_manager_browsertest.cc
+++ b/chrome/browser/banners/app_banner_manager_browsertest.cc
@@ -2,58 +2,51 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/banners/app_banner_manager.h"
+#include <vector>
 
 #include "base/command_line.h"
 #include "base/run_loop.h"
-#include "base/single_thread_task_runner.h"
-#include "base/task_runner.h"
 #include "base/test/histogram_tester.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "chrome/browser/banners/app_banner_manager.h"
 #include "chrome/browser/banners/app_banner_metrics.h"
 #include "chrome/browser/banners/app_banner_settings_helper.h"
-#include "chrome/browser/installable/installable_manager.h"
+#include "chrome/browser/engagement/site_engagement_service.h"
+#include "chrome/browser/installable/installable_logging.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
-#include "content/public/common/content_switches.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
 
 namespace banners {
 
-// All calls to RequestAppBanner should terminate in one of Stop() (not showing
-// banner) or ShowBanner(). This browser test uses this and overrides those two
-// methods to capture this information.
+// Browser tests for web app banners.
+// NOTE: this test relies on service workers; failures and flakiness may be due
+// to changes in SW code.
 class AppBannerManagerTest : public AppBannerManager {
  public:
   explicit AppBannerManagerTest(content::WebContents* web_contents)
       : AppBannerManager(web_contents) {}
+
   ~AppBannerManagerTest() override {}
 
   bool will_show() { return will_show_.get() && *will_show_; }
 
   bool is_active() { return AppBannerManager::is_active(); }
 
-  // Set the page transition of each banner request.
-  void set_page_transition_(ui::PageTransition transition) {
-    last_transition_type_ = transition;
-  }
-
-  using AppBannerManager::RequestAppBanner;
-  void RequestAppBanner(const GURL& validated_url,
-                        bool is_debug_mode,
-                        base::Closure quit_closure) {
-    will_show_.reset(nullptr);
-    quit_closure_ = quit_closure;
-    AppBannerManager::RequestAppBanner(validated_url, is_debug_mode);
-  }
-
   bool need_to_log_status() { return need_to_log_status_; }
 
+  void Prepare(base::Closure quit_closure) {
+    will_show_.reset(nullptr);
+    quit_closure_ = quit_closure;
+  }
+
  protected:
+  // All calls to RequestAppBanner should terminate in one of Stop() (not
+  // showing banner) or ShowBanner(). Override those two methods to capture test
+  // status.
   void Stop() override {
     AppBannerManager::Stop();
     ASSERT_FALSE(will_show_.get());
@@ -65,21 +58,13 @@
     // Fake the call to ReportStatus here - this is usually called in
     // platform-specific code which is not exposed here.
     ReportStatus(nullptr, SHOWING_WEB_APP_BANNER);
+    RecordDidShowBanner("AppBanner.WebApp.Shown");
+
     ASSERT_FALSE(will_show_.get());
     will_show_.reset(new bool(true));
     base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, quit_closure_);
   }
 
-  void DidStartNavigation(content::NavigationHandle* handle) override {
-    // Do nothing to ensure we never observe the site engagement service.
-  }
-
-  void DidFinishLoad(content::RenderFrameHost* render_frame_host,
-                     const GURL& validated_url) override {
-    // Do nothing else to ensure the banner pipeline doesn't start.
-    validated_url_ = validated_url;
-  }
-
  private:
   bool IsDebugMode() const override { return false; }
 
@@ -90,8 +75,7 @@
 class AppBannerManagerBrowserTest : public InProcessBrowserTest {
  public:
   void SetUpOnMainThread() override {
-    AppBannerSettingsHelper::SetEngagementWeights(1, 1);
-    AppBannerSettingsHelper::SetTotalEngagementToTrigger(2);
+    AppBannerSettingsHelper::SetTotalEngagementToTrigger(10);
     ASSERT_TRUE(embedded_test_server()->Start());
     InProcessBrowserTest::SetUpOnMainThread();
   }
@@ -103,23 +87,6 @@
   }
 
  protected:
-  void RequestAppBanner(AppBannerManagerTest* manager,
-                        const GURL& url,
-                        base::RunLoop& run_loop,
-                        ui::PageTransition transition,
-                        bool expected_to_show) {
-    manager->set_page_transition_(transition);
-    manager->RequestAppBanner(url, false, run_loop.QuitClosure());
-    run_loop.Run();
-
-    EXPECT_EQ(expected_to_show, manager->will_show());
-    ASSERT_FALSE(manager->is_active());
-
-    // If showing the banner, ensure that the minutes histogram is recorded.
-    histograms_.ExpectTotalCount(banners::kMinutesHistogram,
-                                (manager->will_show() ? 1 : 0));
-  }
-
   // Returns a test server URL to a page controlled by a service worker with
   // |manifest_url| injected as the manifest tag.
   std::string GetURLOfPageWithServiceWorkerAndManifest(
@@ -129,276 +96,155 @@
   }
 
   void RunBannerTest(const std::string& url,
-                     ui::PageTransition transition,
-                     unsigned int unshown_repetitions,
+                     const std::vector<double>& engagement_scores,
                      InstallableStatusCode expected_code_for_histogram,
                      bool expected_to_show) {
-    std::string valid_page(url);
-    GURL test_url = embedded_test_server()->GetURL(valid_page);
+    base::HistogramTester histograms;
+    GURL test_url = embedded_test_server()->GetURL(url);
     content::WebContents* web_contents =
         browser()->tab_strip_model()->GetActiveWebContents();
     std::unique_ptr<AppBannerManagerTest> manager(
         new AppBannerManagerTest(web_contents));
 
-    for (unsigned int i = 1; i <= unshown_repetitions; ++i) {
-      ui_test_utils::NavigateToURL(browser(), test_url);
-      base::RunLoop run_loop;
-      RequestAppBanner(manager.get(), web_contents->GetLastCommittedURL(),
-                       run_loop, transition, false);
-      CheckInstallableStatusCodeHistogram(INSUFFICIENT_ENGAGEMENT, i, i);
-      AppBannerManager::SetTimeDeltaForTesting(i);
+    // Loop through the vector of engagement scores. We only expect the banner
+    // pipeline to trigger on the last one; otherwise, nothing is expected to
+    // happen.
+    int iterations = 0;
+    SiteEngagementService* service =
+        SiteEngagementService::Get(browser()->profile());
+    for (double engagement : engagement_scores) {
+      if (iterations > 0) {
+        ui_test_utils::NavigateToURL(browser(), test_url);
+
+        EXPECT_EQ(false, manager->will_show());
+        EXPECT_FALSE(manager->is_active());
+
+        histograms.ExpectTotalCount(banners::kMinutesHistogram, 0);
+        histograms.ExpectTotalCount(banners::kInstallableStatusCodeHistogram,
+                                     0);
+      }
+      service->ResetScoreForURL(test_url, engagement);
+      ++iterations;
     }
 
-    // On the final loop, check whether the banner triggered or not as expected.
-    ui_test_utils::NavigateToURL(browser(), test_url);
+    // On the final loop, we expect the banner pipeline to trigger - the
+    // navigation should generate the final engagement to show the banner. Spin
+    // the run loop, which should be quit by either Stop() or ShowBanner().
     base::RunLoop run_loop;
-    RequestAppBanner(manager.get(), web_contents->GetLastCommittedURL(),
-                     run_loop, transition, expected_to_show);
+    manager->Prepare(run_loop.QuitClosure());
+    ui_test_utils::NavigateToURL(browser(), test_url);
+    run_loop.Run();
+
+    EXPECT_EQ(expected_to_show, manager->will_show());
+    EXPECT_FALSE(manager->is_active());
+
     // Navigate to ensure the InstallableStatusCodeHistogram is logged.
     ui_test_utils::NavigateToURL(browser(), GURL("about:blank"));
-    CheckInstallableStatusCodeHistogram(expected_code_for_histogram, 1,
-                                        unshown_repetitions + 1);
+
+    // If showing the banner, ensure that the minutes histogram is recorded.
+    histograms.ExpectTotalCount(banners::kMinutesHistogram,
+                                 (manager->will_show() ? 1 : 0));
+    histograms.ExpectUniqueSample(banners::kInstallableStatusCodeHistogram,
+                                   expected_code_for_histogram, 1);
     EXPECT_FALSE(manager->need_to_log_status());
   }
-
-  void CheckInstallableStatusCodeHistogram(InstallableStatusCode expected_code,
-                                           int expected_count,
-                                           int total_count) {
-    histograms_.ExpectBucketCount(banners::kInstallableStatusCodeHistogram,
-                                  expected_code, expected_count);
-    histograms_.ExpectTotalCount(banners::kInstallableStatusCodeHistogram,
-                                 total_count);
-  }
-
- private:
-  base::HistogramTester histograms_;
 };
-IN_PROC_BROWSER_TEST_F(AppBannerManagerBrowserTest, WebAppBannerCreatedDirect) {
-  RunBannerTest("/banners/manifest_test_page.html", ui::PAGE_TRANSITION_TYPED,
-                1, SHOWING_WEB_APP_BANNER, true);
-}
 
-IN_PROC_BROWSER_TEST_F(AppBannerManagerBrowserTest,
-                       WebAppBannerCreatedDirectLargerTotal) {
-  AppBannerSettingsHelper::SetTotalEngagementToTrigger(4);
-  RunBannerTest("/banners/manifest_test_page.html", ui::PAGE_TRANSITION_TYPED,
-                3, SHOWING_WEB_APP_BANNER, true);
-}
-
-IN_PROC_BROWSER_TEST_F(AppBannerManagerBrowserTest,
-                       WebAppBannerCreatedDirectSmallerTotal) {
-  AppBannerSettingsHelper::SetTotalEngagementToTrigger(1);
-  RunBannerTest("/banners/manifest_test_page.html", ui::PAGE_TRANSITION_TYPED,
-                0, SHOWING_WEB_APP_BANNER, true);
-}
-
-IN_PROC_BROWSER_TEST_F(AppBannerManagerBrowserTest,
-                       WebAppBannerCreatedDirectSingle) {
-  AppBannerSettingsHelper::SetEngagementWeights(2, 1);
-  RunBannerTest("/banners/manifest_test_page.html",
-                ui::PAGE_TRANSITION_GENERATED, 0, SHOWING_WEB_APP_BANNER, true);
-}
-
-IN_PROC_BROWSER_TEST_F(AppBannerManagerBrowserTest,
-                       WebAppBannerCreatedDirectMultiple) {
-  AppBannerSettingsHelper::SetEngagementWeights(0.5, 1);
-  RunBannerTest("/banners/manifest_test_page.html",
-                ui::PAGE_TRANSITION_GENERATED, 3, SHOWING_WEB_APP_BANNER, true);
-}
-
-IN_PROC_BROWSER_TEST_F(AppBannerManagerBrowserTest,
-                       WebAppBannerCreatedDirectMultipleLargerTotal) {
-  AppBannerSettingsHelper::SetEngagementWeights(0.5, 1);
-  AppBannerSettingsHelper::SetTotalEngagementToTrigger(3);
-  RunBannerTest("/banners/manifest_test_page.html",
-                ui::PAGE_TRANSITION_GENERATED, 5, SHOWING_WEB_APP_BANNER, true);
-}
-
-IN_PROC_BROWSER_TEST_F(AppBannerManagerBrowserTest,
-                       WebAppBannerCreatedDirectMultipleSmallerTotal) {
-  AppBannerSettingsHelper::SetEngagementWeights(0.5, 1);
-  AppBannerSettingsHelper::SetTotalEngagementToTrigger(1);
-  RunBannerTest("/banners/manifest_test_page.html",
-                ui::PAGE_TRANSITION_GENERATED, 1, SHOWING_WEB_APP_BANNER, true);
-}
-
-IN_PROC_BROWSER_TEST_F(AppBannerManagerBrowserTest,
-                       WebAppBannerCreatedIndirect) {
-  RunBannerTest("/banners/manifest_test_page.html", ui::PAGE_TRANSITION_LINK, 1,
-                SHOWING_WEB_APP_BANNER, true);
-}
-
-// Flaky http://crbug.com/660798
-IN_PROC_BROWSER_TEST_F(AppBannerManagerBrowserTest,
-                       DISABLED_WebAppBannerCreatedIndirectLargerTotal) {
-  AppBannerSettingsHelper::SetTotalEngagementToTrigger(5);
-  RunBannerTest("/banners/manifest_test_page.html", ui::PAGE_TRANSITION_LINK, 4,
+IN_PROC_BROWSER_TEST_F(AppBannerManagerBrowserTest, WebAppBannerCreated) {
+  std::vector<double> engagement_scores{0, 10};
+  RunBannerTest("/banners/manifest_test_page.html", engagement_scores,
                 SHOWING_WEB_APP_BANNER, true);
 }
 
 IN_PROC_BROWSER_TEST_F(AppBannerManagerBrowserTest,
-                       WebAppBannerCreatedIndirectSmallerTotal) {
-  AppBannerSettingsHelper::SetTotalEngagementToTrigger(1);
-  RunBannerTest("/banners/manifest_test_page.html", ui::PAGE_TRANSITION_LINK, 0,
+                       WebAppBannerCreatedImmediately) {
+  std::vector<double> engagement_scores{10};
+  RunBannerTest("/banners/manifest_test_page.html", engagement_scores,
                 SHOWING_WEB_APP_BANNER, true);
 }
 
 IN_PROC_BROWSER_TEST_F(AppBannerManagerBrowserTest,
-                       WebAppBannerCreatedIndirectSingle) {
-  AppBannerSettingsHelper::SetEngagementWeights(1, 3);
-  RunBannerTest("/banners/manifest_test_page.html", ui::PAGE_TRANSITION_RELOAD,
-                0, SHOWING_WEB_APP_BANNER, true);
-}
-
-IN_PROC_BROWSER_TEST_F(AppBannerManagerBrowserTest,
-                       WebAppBannerCreatedIndirectMultiple) {
-  AppBannerSettingsHelper::SetEngagementWeights(1, 0.5);
-  RunBannerTest("/banners/manifest_test_page.html", ui::PAGE_TRANSITION_LINK, 3,
+                       WebAppBannerCreatedAfterSeveralVisits) {
+  std::vector<double> engagement_scores{0, 1, 2, 3, 4, 5, 10};
+  RunBannerTest("/banners/manifest_test_page.html", engagement_scores,
                 SHOWING_WEB_APP_BANNER, true);
 }
 
 IN_PROC_BROWSER_TEST_F(AppBannerManagerBrowserTest,
-                       WebAppBannerCreatedIndirectMultipleLargerTotal) {
-  AppBannerSettingsHelper::SetEngagementWeights(1, 0.5);
-  AppBannerSettingsHelper::SetTotalEngagementToTrigger(4);
-  RunBannerTest("/banners/manifest_test_page.html", ui::PAGE_TRANSITION_LINK, 7,
+                       WebAppBannerNotSeenAfterShowing) {
+  std::vector<double> engagement_scores{0, 10};
+  RunBannerTest("/banners/manifest_test_page.html", engagement_scores,
                 SHOWING_WEB_APP_BANNER, true);
-}
 
-IN_PROC_BROWSER_TEST_F(AppBannerManagerBrowserTest,
-                       WebAppBannerCreatedVarious) {
-  AppBannerSettingsHelper::SetEngagementWeights(0.5, 0.25);
+  AppBannerManager::SetTimeDeltaForTesting(1);
+  RunBannerTest("/banners/manifest_test_page.html", engagement_scores,
+                PREVIOUSLY_IGNORED, false);
 
-  std::string valid_page("/banners/manifest_test_page.html");
-  GURL test_url = embedded_test_server()->GetURL(valid_page);
-  content::WebContents* web_contents =
-      browser()->tab_strip_model()->GetActiveWebContents();
+  AppBannerManager::SetTimeDeltaForTesting(13);
+  RunBannerTest("/banners/manifest_test_page.html", engagement_scores,
+                PREVIOUSLY_IGNORED, false);
 
-  std::unique_ptr<AppBannerManagerTest> manager(
-      new AppBannerManagerTest(web_contents));
+  AppBannerManager::SetTimeDeltaForTesting(14);
+  RunBannerTest("/banners/manifest_test_page.html", engagement_scores,
+                SHOWING_WEB_APP_BANNER, true);
 
-  // Add a direct nav on day 1.
-  {
-    base::RunLoop run_loop;
-    ui_test_utils::NavigateToURL(browser(), test_url);
-    RequestAppBanner(manager.get(), web_contents->GetLastCommittedURL(),
-                     run_loop, ui::PAGE_TRANSITION_TYPED, false);
-    CheckInstallableStatusCodeHistogram(INSUFFICIENT_ENGAGEMENT, 1, 1);
-    EXPECT_FALSE(manager->need_to_log_status());
-  }
+  AppBannerSettingsHelper::SetDaysAfterDismissAndIgnoreToTrigger(90, 2);
 
-  // Add an indirect nav on day 1 which is ignored.
-  {
-    base::RunLoop run_loop;
-    ui_test_utils::NavigateToURL(browser(), test_url);
-    RequestAppBanner(manager.get(), web_contents->GetLastCommittedURL(),
-                     run_loop, ui::PAGE_TRANSITION_LINK, false);
-    CheckInstallableStatusCodeHistogram(INSUFFICIENT_ENGAGEMENT, 2, 2);
-    EXPECT_FALSE(manager->need_to_log_status());
-    AppBannerManager::SetTimeDeltaForTesting(1);
-  }
-
-  // Add an indirect nav on day 2.
-  {
-    base::RunLoop run_loop;
-    ui_test_utils::NavigateToURL(browser(), test_url);
-    RequestAppBanner(manager.get(), web_contents->GetLastCommittedURL(),
-                     run_loop, ui::PAGE_TRANSITION_MANUAL_SUBFRAME, false);
-    CheckInstallableStatusCodeHistogram(INSUFFICIENT_ENGAGEMENT, 3, 3);
-    EXPECT_FALSE(manager->need_to_log_status());
-  }
-
-  // Add a direct nav on day 2 which overrides.
-  {
-    base::RunLoop run_loop;
-    ui_test_utils::NavigateToURL(browser(), test_url);
-    RequestAppBanner(manager.get(), web_contents->GetLastCommittedURL(),
-                     run_loop, ui::PAGE_TRANSITION_GENERATED, false);
-    CheckInstallableStatusCodeHistogram(INSUFFICIENT_ENGAGEMENT, 4, 4);
-    EXPECT_FALSE(manager->need_to_log_status());
-    AppBannerManager::SetTimeDeltaForTesting(2);
-  }
-
-  // Add a direct nav on day 3.
-  {
-    base::RunLoop run_loop;
-    ui_test_utils::NavigateToURL(browser(), test_url);
-    RequestAppBanner(manager.get(), web_contents->GetLastCommittedURL(),
-                     run_loop, ui::PAGE_TRANSITION_GENERATED, false);
-    CheckInstallableStatusCodeHistogram(INSUFFICIENT_ENGAGEMENT, 5, 5);
-    EXPECT_FALSE(manager->need_to_log_status());
-    AppBannerManager::SetTimeDeltaForTesting(3);
-  }
-
-  // Add an indirect nav on day 4.
-  {
-    base::RunLoop run_loop;
-    ui_test_utils::NavigateToURL(browser(), test_url);
-    RequestAppBanner(manager.get(), web_contents->GetLastCommittedURL(),
-                     run_loop, ui::PAGE_TRANSITION_FORM_SUBMIT, false);
-    EXPECT_FALSE(manager->need_to_log_status());
-    CheckInstallableStatusCodeHistogram(INSUFFICIENT_ENGAGEMENT, 6, 6);
-  }
-
-  // Add a direct nav on day 4 which should trigger the banner.
-  {
-    base::RunLoop run_loop;
-    ui_test_utils::NavigateToURL(browser(), test_url);
-    RequestAppBanner(manager.get(), web_contents->GetLastCommittedURL(),
-                     run_loop, ui::PAGE_TRANSITION_TYPED, true);
-    EXPECT_FALSE(manager->need_to_log_status());
-    CheckInstallableStatusCodeHistogram(SHOWING_WEB_APP_BANNER, 1, 7);
-  }
+  AppBannerManager::SetTimeDeltaForTesting(16);
+  RunBannerTest("/banners/manifest_test_page.html", engagement_scores,
+                SHOWING_WEB_APP_BANNER, true);
 }
 
 IN_PROC_BROWSER_TEST_F(AppBannerManagerBrowserTest,
                        WebAppBannerNoTypeInManifest) {
+  std::vector<double> engagement_scores{0, 10};
   RunBannerTest(GetURLOfPageWithServiceWorkerAndManifest(
                     "/banners/manifest_no_type.json"),
-                ui::PAGE_TRANSITION_TYPED, 1, SHOWING_WEB_APP_BANNER, true);
+                engagement_scores, SHOWING_WEB_APP_BANNER, true);
 }
 
 IN_PROC_BROWSER_TEST_F(AppBannerManagerBrowserTest,
                        WebAppBannerNoTypeInManifestCapsExtension) {
+  std::vector<double> engagement_scores{0, 10};
   RunBannerTest(GetURLOfPageWithServiceWorkerAndManifest(
                     "/banners/manifest_no_type_caps.json"),
-                ui::PAGE_TRANSITION_TYPED, 1, SHOWING_WEB_APP_BANNER, true);
+                engagement_scores, SHOWING_WEB_APP_BANNER, true);
 }
 
 IN_PROC_BROWSER_TEST_F(AppBannerManagerBrowserTest, NoManifest) {
-  RunBannerTest("/banners/no_manifest_test_page.html",
-                ui::PAGE_TRANSITION_TYPED, 0, NO_MANIFEST, false);
+  std::vector<double> engagement_scores{10};
+  RunBannerTest("/banners/no_manifest_test_page.html", engagement_scores,
+                NO_MANIFEST, false);
 }
 
 IN_PROC_BROWSER_TEST_F(AppBannerManagerBrowserTest, MissingManifest) {
+  std::vector<double> engagement_scores{10};
   RunBannerTest(GetURLOfPageWithServiceWorkerAndManifest(
                     "/banners/manifest_missing.json"),
-                ui::PAGE_TRANSITION_TYPED, 0, MANIFEST_EMPTY, false);
+                engagement_scores, MANIFEST_EMPTY, false);
 }
 
 IN_PROC_BROWSER_TEST_F(AppBannerManagerBrowserTest, CancelBannerDirect) {
-  RunBannerTest("/banners/cancel_test_page.html", ui::PAGE_TRANSITION_TYPED, 1,
-                RENDERER_CANCELLED, false);
-}
-
-IN_PROC_BROWSER_TEST_F(AppBannerManagerBrowserTest, CancelBannerIndirect) {
-  AppBannerSettingsHelper::SetEngagementWeights(1, 0.5);
-  RunBannerTest("/banners/cancel_test_page.html", ui::PAGE_TRANSITION_LINK, 3,
+  std::vector<double> engagement_scores{10};
+  RunBannerTest("/banners/cancel_test_page.html", engagement_scores,
                 RENDERER_CANCELLED, false);
 }
 
 IN_PROC_BROWSER_TEST_F(AppBannerManagerBrowserTest, PromptBanner) {
-  RunBannerTest("/banners/prompt_test_page.html", ui::PAGE_TRANSITION_TYPED, 1,
+  std::vector<double> engagement_scores{0, 5, 10};
+  RunBannerTest("/banners/prompt_test_page.html", engagement_scores,
                 SHOWING_WEB_APP_BANNER, true);
 }
 
 IN_PROC_BROWSER_TEST_F(AppBannerManagerBrowserTest, PromptBannerInHandler) {
-  RunBannerTest("/banners/prompt_in_handler_test_page.html",
-                ui::PAGE_TRANSITION_TYPED, 1, SHOWING_WEB_APP_BANNER, true);
+  std::vector<double> engagement_scores{0, 2, 5, 10};
+  RunBannerTest("/banners/prompt_in_handler_test_page.html", engagement_scores,
+                SHOWING_WEB_APP_BANNER, true);
 }
 
 IN_PROC_BROWSER_TEST_F(AppBannerManagerBrowserTest, WebAppBannerInIFrame) {
-  RunBannerTest("/banners/iframe_test_page.html", ui::PAGE_TRANSITION_TYPED, 0,
+  std::vector<double> engagement_scores{10};
+  RunBannerTest("/banners/iframe_test_page.html", engagement_scores,
                 NO_MANIFEST, false);
 }
 
diff --git a/chrome/browser/banners/app_banner_settings_helper.cc b/chrome/browser/banners/app_banner_settings_helper.cc
index 75e02fe..f314a0c 100644
--- a/chrome/browser/banners/app_banner_settings_helper.cc
+++ b/chrome/browser/banners/app_banner_settings_helper.cc
@@ -6,15 +6,13 @@
 
 #include <stddef.h>
 
-#include <algorithm>
+#include <memory>
 #include <string>
 #include <utility>
 
 #include "base/command_line.h"
 #include "base/memory/ptr_util.h"
-#include "base/metrics/field_trial.h"
 #include "base/strings/string_number_conversions.h"
-#include "base/strings/string_util.h"
 #include "chrome/browser/banners/app_banner_manager.h"
 #include "chrome/browser/banners/app_banner_metrics.h"
 #include "chrome/browser/browser_process.h"
@@ -28,7 +26,6 @@
 #include "components/rappor/rappor_service_impl.h"
 #include "components/variations/variations_associated_data.h"
 #include "content/public/browser/web_contents.h"
-#include "net/base/escape.h"
 #include "url/gurl.h"
 
 namespace {
@@ -37,21 +34,12 @@
 // site may show a banner for.
 const size_t kMaxAppsPerSite = 3;
 
-// Oldest could show banner event we care about, in days.
-const unsigned int kOldestCouldShowBannerEventInDays = 14;
-
 // Default number of days that dismissing or ignoring the banner will prevent it
 // being seen again for.
 const unsigned int kMinimumBannerBlockedToBannerShown = 90;
 const unsigned int kMinimumDaysBetweenBannerShows = 14;
 
-const unsigned int kNumberOfMinutesInADay = 1440;
-
-// Default scores assigned to direct and indirect navigations respectively.
-const unsigned int kDefaultDirectNavigationEngagement = 1;
-const unsigned int kDefaultIndirectNavigationEngagement = 1;
-
-// Default number of navigations required to trigger the banner.
+// Default site engagement required to trigger the banner.
 const unsigned int kDefaultTotalEngagementToTrigger = 2;
 
 // The number of days in the past that a site should be launched from homescreen
@@ -60,7 +48,8 @@
 // WebappDataStorage.wasLaunchedRecently.
 const unsigned int kRecentLastLaunchInDays = 10;
 
-// Dictionary keys to use for the events.
+// Dictionary keys to use for the events. Must be kept in sync with
+// AppBannerEvent.
 const char* kBannerEventKeys[] = {
     "couldShowBannerEvents",
     "didShowBannerEvent",
@@ -68,32 +57,13 @@
     "didAddToHomescreenEvent",
 };
 
-// Keys to use when storing BannerEvent structs.
-const char kBannerTimeKey[] = "time";
-const char kBannerEngagementKey[] = "engagement";
-
 // Keys to use when querying the variations params.
 const char kBannerParamsKey[] = "AppBannerTriggering";
-const char kBannerParamsDirectKey[] = "direct";
-const char kBannerParamsIndirectKey[] = "indirect";
-const char kBannerParamsTotalKey[] = "total";
-const char kBannerParamsMinutesKey[] = "minutes";
 const char kBannerParamsEngagementTotalKey[] = "site_engagement_total";
 const char kBannerParamsDaysAfterBannerDismissedKey[] = "days_after_dismiss";
 const char kBannerParamsDaysAfterBannerIgnoredKey[] = "days_after_ignore";
-const char kBannerSiteEngagementParamsKey[] = "use_site_engagement";
 const char kBannerParamsLanguageKey[] = "language_option";
 
-// Engagement weight assigned to direct and indirect navigations.
-// By default, a direct navigation is a page visit via ui::PAGE_TRANSITION_TYPED
-// or ui::PAGE_TRANSITION_GENERATED.
-double gDirectNavigationEngagement = kDefaultDirectNavigationEngagement;
-double gIndirectNavigationEnagagement = kDefaultIndirectNavigationEngagement;
-
-// Number of minutes between visits that will trigger a could show banner event.
-// Defaults to the number of minutes in a day.
-unsigned int gMinimumMinutesBetweenVisits = kNumberOfMinutesInADay;
-
 // Total engagement score required before a banner will actually be triggered.
 double gTotalEngagementToTrigger = kDefaultTotalEngagementToTrigger;
 
@@ -131,17 +101,6 @@
   return app_dict;
 }
 
-double GetEventEngagement(ui::PageTransition transition_type) {
-  if (ui::PageTransitionCoreTypeIs(transition_type,
-                                   ui::PAGE_TRANSITION_TYPED) ||
-      ui::PageTransitionCoreTypeIs(transition_type,
-                                   ui::PAGE_TRANSITION_GENERATED)) {
-    return gDirectNavigationEngagement;
-  } else {
-    return gIndirectNavigationEnagagement;
-  }
-}
-
 // Queries variations for the number of days which dismissing and ignoring the
 // banner should prevent a banner from showing.
 void UpdateDaysBetweenShowing() {
@@ -178,50 +137,6 @@
   }
 }
 
-// Queries variations for updates to the default engagement values assigned
-// to direct and indirect navigations.
-void UpdateEngagementWeights() {
-  std::string direct_param = variations::GetVariationParamValue(
-      kBannerParamsKey, kBannerParamsDirectKey);
-  std::string indirect_param = variations::GetVariationParamValue(
-      kBannerParamsKey, kBannerParamsIndirectKey);
-  std::string total_param = variations::GetVariationParamValue(
-      kBannerParamsKey, kBannerParamsTotalKey);
-
-  if (!direct_param.empty() && !indirect_param.empty() &&
-      !total_param.empty()) {
-    double direct_engagement = -1;
-    double indirect_engagement = -1;
-    double total_engagement = -1;
-
-    // Ensure that we get valid doubles from the field trial, and that both
-    // values are greater than or equal to zero and less than or equal to the
-    // total engagement required to trigger the banner.
-    if (base::StringToDouble(direct_param, &direct_engagement) &&
-        base::StringToDouble(indirect_param, &indirect_engagement) &&
-        base::StringToDouble(total_param, &total_engagement) &&
-        direct_engagement >= 0 && indirect_engagement >= 0 &&
-        total_engagement > 0 && direct_engagement <= total_engagement &&
-        indirect_engagement <= total_engagement) {
-      AppBannerSettingsHelper::SetEngagementWeights(direct_engagement,
-                                                    indirect_engagement);
-      AppBannerSettingsHelper::SetTotalEngagementToTrigger(total_engagement);
-    }
-  }
-}
-
-// Queries variation for updates to the default number of minutes between
-// site visits counted for the purposes of displaying a banner.
-void UpdateMinutesBetweenVisits() {
-  std::string param = variations::GetVariationParamValue(
-      kBannerParamsKey, kBannerParamsMinutesKey);
-  if (!param.empty()) {
-    int minimum_minutes = 0;
-    if (base::StringToInt(param, &minimum_minutes))
-      AppBannerSettingsHelper::SetMinimumMinutesBetweenVisits(minimum_minutes);
-  }
-}
-
 }  // namespace
 
 // Key to store instant apps events.
@@ -247,7 +162,8 @@
   banners::TrackInstallEvent(banners::INSTALL_EVENT_WEB_APP_INSTALLED);
 
   AppBannerSettingsHelper::RecordBannerEvent(
-      web_contents, web_contents->GetURL(), package_name_or_start_url,
+      web_contents, web_contents->GetLastCommittedURL(),
+      package_name_or_start_url,
       AppBannerSettingsHelper::APP_BANNER_EVENT_DID_ADD_TO_HOMESCREEN,
       banners::AppBannerManager::GetCurrentTime());
 
@@ -255,7 +171,7 @@
       g_browser_process->rappor_service(),
       (rappor_metric == WEB ? "AppBanner.WebApp.Installed"
                             : "AppBanner.NativeApp.Installed"),
-      web_contents->GetURL());
+      web_contents->GetLastCommittedURL());
 }
 
 void AppBannerSettingsHelper::RecordBannerDismissEvent(
@@ -265,7 +181,8 @@
   banners::TrackDismissEvent(banners::DISMISS_EVENT_CLOSE_BUTTON);
 
   AppBannerSettingsHelper::RecordBannerEvent(
-      web_contents, web_contents->GetURL(), package_name_or_start_url,
+      web_contents, web_contents->GetLastCommittedURL(),
+      package_name_or_start_url,
       AppBannerSettingsHelper::APP_BANNER_EVENT_DID_BLOCK,
       banners::AppBannerManager::GetCurrentTime());
 
@@ -273,7 +190,7 @@
       g_browser_process->rappor_service(),
       (rappor_metric == WEB ? "AppBanner.WebApp.Dismissed"
                             : "AppBanner.NativeApp.Dismissed"),
-      web_contents->GetURL());
+      web_contents->GetLastCommittedURL());
 }
 
 void AppBannerSettingsHelper::RecordBannerEvent(
@@ -282,8 +199,6 @@
     const std::string& package_name_or_start_url,
     AppBannerEvent event,
     base::Time time) {
-  DCHECK(event != APP_BANNER_EVENT_COULD_SHOW);
-
   Profile* profile =
       Profile::FromBrowserContext(web_contents->GetBrowserContext());
   if (profile->IsOffTheRecord() || package_name_or_start_url.empty())
@@ -304,6 +219,13 @@
   // Dates are stored in their raw form (i.e. not local dates) to be resilient
   // to time zone changes.
   std::string event_key(kBannerEventKeys[event]);
+
+  if (event == APP_BANNER_EVENT_COULD_SHOW) {
+    // Do not overwrite a could show event, as this is used for metrics.
+    double internal_date;
+    if (app_dict->GetDouble(event_key, &internal_date))
+      return;
+  }
   app_dict->SetDouble(event_key, time.ToInternalValue());
 
   settings->SetWebsiteSettingDefaultScope(
@@ -319,90 +241,6 @@
     settings->FlushLossyWebsiteSettings();
 }
 
-void AppBannerSettingsHelper::RecordBannerCouldShowEvent(
-    content::WebContents* web_contents,
-    const GURL& origin_url,
-    const std::string& package_name_or_start_url,
-    base::Time time,
-    ui::PageTransition transition_type) {
-  Profile* profile =
-      Profile::FromBrowserContext(web_contents->GetBrowserContext());
-  if (profile->IsOffTheRecord() || package_name_or_start_url.empty())
-    return;
-
-  HostContentSettingsMap* settings =
-      HostContentSettingsMapFactory::GetForProfile(profile);
-  std::unique_ptr<base::DictionaryValue> origin_dict =
-      GetOriginDict(settings, origin_url);
-  if (!origin_dict)
-    return;
-
-  base::DictionaryValue* app_dict =
-      GetAppDict(origin_dict.get(), package_name_or_start_url);
-  if (!app_dict)
-    return;
-
-  std::string event_key(kBannerEventKeys[APP_BANNER_EVENT_COULD_SHOW]);
-  double engagement = GetEventEngagement(transition_type);
-
-  base::ListValue* could_show_list = nullptr;
-  if (!app_dict->GetList(event_key, &could_show_list)) {
-    could_show_list = new base::ListValue();
-    app_dict->Set(event_key, base::WrapUnique(could_show_list));
-  }
-
-  // Trim any items that are older than we should care about. For comparisons
-  // the times are converted to local dates.
-  base::Time date = BucketTimeToResolution(time, gMinimumMinutesBetweenVisits);
-  for (auto it = could_show_list->begin(); it != could_show_list->end();) {
-    if ((*it)->IsType(base::Value::Type::DICTIONARY)) {
-      base::DictionaryValue* internal_value;
-      double internal_date;
-      (*it)->GetAsDictionary(&internal_value);
-
-      if (internal_value->GetDouble(kBannerTimeKey, &internal_date)) {
-        base::Time other_date =
-            BucketTimeToResolution(base::Time::FromInternalValue(internal_date),
-                                   gMinimumMinutesBetweenVisits);
-        if (other_date == date) {
-          double other_engagement = 0;
-          if (internal_value->GetDouble(kBannerEngagementKey,
-                                        &other_engagement) &&
-              other_engagement >= engagement) {
-            // This date has already been added, but with an equal or higher
-            // engagement. Don't add the date again. If the conditional fails,
-            // fall to the end of the loop where the existing entry is deleted.
-            return;
-          }
-        } else {
-          base::TimeDelta delta = date - other_date;
-          if (delta <
-              base::TimeDelta::FromDays(kOldestCouldShowBannerEventInDays)) {
-            ++it;
-            continue;
-          }
-        }
-      }
-    }
-
-    // Either this date is older than we care about, or it isn't in the correct
-    // format, or it is the same as the current date but with a lower
-    // engagement, so remove it.
-    it = could_show_list->Erase(it, nullptr);
-  }
-
-  // Dates are stored in their raw form (i.e. not local dates) to be resilient
-  // to time zone changes.
-  std::unique_ptr<base::DictionaryValue> value(new base::DictionaryValue());
-  value->SetDouble(kBannerTimeKey, time.ToInternalValue());
-  value->SetDouble(kBannerEngagementKey, engagement);
-  could_show_list->Append(std::move(value));
-
-  settings->SetWebsiteSettingDefaultScope(
-      origin_url, GURL(), CONTENT_SETTINGS_TYPE_APP_BANNER, std::string(),
-      std::move(origin_dict));
-}
-
 InstallableStatusCode AppBannerSettingsHelper::ShouldShowBanner(
     content::WebContents* web_contents,
     const GURL& origin_url,
@@ -443,83 +281,14 @@
     return PREVIOUSLY_IGNORED;
   }
 
-  // If we have gotten this far and want to use site engagement, the banner flow
-  // was triggered by the site engagement service informing the banner manager
-  // that sufficient engagement has been accumulated. Hence there is no need to
-  // check the total amount of engagement.
-  // TODO(dominickn): just return true here and remove all of the following code
-  // in this method when app banners have fully migrated to using site
-  // engagement as a trigger condition. See crbug.com/616322.
-  // Do not do engagement checks for instant app banners.
-  if (ShouldUseSiteEngagementScore() ||
-      package_name_or_start_url == kInstantAppsKey) {
-    return NO_ERROR_DETECTED;
-  }
-
-  double total_engagement = 0;
-  std::vector<BannerEvent> could_show_events = GetCouldShowBannerEvents(
-      web_contents, origin_url, package_name_or_start_url);
-
-  for (const auto& event : could_show_events)
-    total_engagement += event.engagement;
-
-  if (!HasSufficientEngagement(total_engagement))
-    return INSUFFICIENT_ENGAGEMENT;
-
   return NO_ERROR_DETECTED;
 }
 
-std::vector<AppBannerSettingsHelper::BannerEvent>
-AppBannerSettingsHelper::GetCouldShowBannerEvents(
-    content::WebContents* web_contents,
-    const GURL& origin_url,
-    const std::string& package_name_or_start_url) {
-  std::vector<BannerEvent> result;
-
-  Profile* profile =
-      Profile::FromBrowserContext(web_contents->GetBrowserContext());
-  HostContentSettingsMap* settings =
-      HostContentSettingsMapFactory::GetForProfile(profile);
-  std::unique_ptr<base::DictionaryValue> origin_dict =
-      GetOriginDict(settings, origin_url);
-
-  if (!origin_dict)
-    return result;
-
-  base::DictionaryValue* app_dict =
-      GetAppDict(origin_dict.get(), package_name_or_start_url);
-  if (!app_dict)
-    return result;
-
-  std::string event_key(kBannerEventKeys[APP_BANNER_EVENT_COULD_SHOW]);
-  base::ListValue* could_show_list = nullptr;
-  if (!app_dict->GetList(event_key, &could_show_list))
-    return result;
-
-  for (const auto& value : *could_show_list) {
-    if (value->IsType(base::Value::Type::DICTIONARY)) {
-      base::DictionaryValue* internal_value;
-      double internal_date = 0;
-      value->GetAsDictionary(&internal_value);
-      double engagement = 0;
-
-      if (internal_value->GetDouble(kBannerTimeKey, &internal_date) &&
-          internal_value->GetDouble(kBannerEngagementKey, &engagement)) {
-        base::Time date = base::Time::FromInternalValue(internal_date);
-        result.push_back({date, engagement});
-      }
-    }
-  }
-
-  return result;
-}
-
 base::Time AppBannerSettingsHelper::GetSingleBannerEvent(
     content::WebContents* web_contents,
     const GURL& origin_url,
     const std::string& package_name_or_start_url,
     AppBannerEvent event) {
-  DCHECK(event != APP_BANNER_EVENT_COULD_SHOW);
   DCHECK(event < APP_BANNER_EVENT_NUM_EVENTS);
 
   Profile* profile =
@@ -556,12 +325,13 @@
     const GURL& origin_url,
     const std::string& package_name_or_start_url,
     base::Time time) {
-  std::vector<BannerEvent> could_show_events = GetCouldShowBannerEvents(
-      web_contents, origin_url, package_name_or_start_url);
+  base::Time could_show_time =
+      GetSingleBannerEvent(web_contents, origin_url, package_name_or_start_url,
+                           APP_BANNER_EVENT_COULD_SHOW);
 
   int minutes = 0;
-  if (could_show_events.size())
-    minutes = (time - could_show_events[0].time).InMinutes();
+  if (!could_show_time.is_null())
+    minutes = (time - could_show_time).InMinutes();
 
   banners::TrackMinutesFromFirstVisitToBannerShown(minutes);
 }
@@ -580,6 +350,8 @@
   // Iterate over everything in the content setting, which should be a set of
   // dictionaries per app path. If we find one that has been added to
   // homescreen recently, return true.
+  base::TimeDelta recent_last_launch_in_days =
+      base::TimeDelta::FromDays(kRecentLastLaunchInDays);
   for (base::DictionaryValue::Iterator it(*origin_dict); !it.IsAtEnd();
        it.Advance()) {
     if (it.value().IsType(base::Value::Type::DICTIONARY)) {
@@ -594,10 +366,8 @@
         continue;
       }
 
-      base::Time added_time = base::Time::FromInternalValue(internal_time);
-
-      if ((now - added_time) <=
-          base::TimeDelta::FromDays(kRecentLastLaunchInDays)) {
+      if ((now - base::Time::FromInternalValue(internal_time)) <=
+          recent_last_launch_in_days) {
         return true;
       }
     }
@@ -613,67 +383,20 @@
   gDaysAfterIgnoredToShow = ignore_days;
 }
 
-void AppBannerSettingsHelper::SetEngagementWeights(double direct_engagement,
-                                                   double indirect_engagement) {
-  gDirectNavigationEngagement = direct_engagement;
-  gIndirectNavigationEnagagement = indirect_engagement;
-}
-
-void AppBannerSettingsHelper::SetMinimumMinutesBetweenVisits(
-    unsigned int minutes) {
-  gMinimumMinutesBetweenVisits = minutes;
-}
-
 void AppBannerSettingsHelper::SetTotalEngagementToTrigger(
     double total_engagement) {
   gTotalEngagementToTrigger = total_engagement;
 }
 
 void AppBannerSettingsHelper::SetDefaultParameters() {
-  SetDaysAfterDismissAndIgnoreToTrigger(kMinimumBannerBlockedToBannerShown,
-                                        kMinimumDaysBetweenBannerShows);
-  SetEngagementWeights(kDefaultDirectNavigationEngagement,
-                       kDefaultIndirectNavigationEngagement);
-  SetMinimumMinutesBetweenVisits(kNumberOfMinutesInADay);
   SetTotalEngagementToTrigger(kDefaultTotalEngagementToTrigger);
 }
 
-// Given a time, returns that time scoped to the nearest minute resolution
-// locally. For example, if the resolution is one hour, this function will
-// return the time to the closest (previous) hour in the local time zone.
-base::Time AppBannerSettingsHelper::BucketTimeToResolution(
-    base::Time time,
-    unsigned int minutes) {
-  // Only support resolutions smaller than or equal to one day. Enforce
-  // that resolutions divide evenly into one day. Otherwise, default to a
-  // day resolution (each time converted to midnight local time).
-  if (minutes == 0 || minutes >= kNumberOfMinutesInADay ||
-      kNumberOfMinutesInADay % minutes != 0) {
-    return time.LocalMidnight();
-  }
-
-  // Extract the number of minutes past midnight in local time. Divide that
-  // number by the resolution size, and return the time converted to local
-  // midnight with the resulting truncated number added.
-  base::Time::Exploded exploded;
-  time.LocalExplode(&exploded);
-  int total_minutes = exploded.hour * 60 + exploded.minute;
-
-  // Use truncating integer division here.
-  return time.LocalMidnight() +
-         base::TimeDelta::FromMinutes((total_minutes / minutes) * minutes);
-}
-
 void AppBannerSettingsHelper::UpdateFromFieldTrial() {
   // If we are using the site engagement score, only extract the total
   // engagement to trigger from the params variations.
   UpdateDaysBetweenShowing();
-  if (ShouldUseSiteEngagementScore()) {
-    UpdateSiteEngagementToTrigger();
-  } else {
-    UpdateEngagementWeights();
-    UpdateMinutesBetweenVisits();
-  }
+  UpdateSiteEngagementToTrigger();
 }
 
 AppBannerSettingsHelper::LanguageOption
@@ -690,17 +413,3 @@
 
   return static_cast<LanguageOption>(language_option);
 }
-
-bool AppBannerSettingsHelper::ShouldUseSiteEngagementScore() {
-  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kEnableSiteEngagementAppBanner)) {
-    return true;
-  }
-
-  // Assume any value which is not "0" or "false" indicates that we should use
-  // site engagement.
-  std::string param = variations::GetVariationParamValue(
-      kBannerParamsKey, kBannerSiteEngagementParamsKey);
-
-  return (!param.empty() && param != "0" && param != "false");
-}
diff --git a/chrome/browser/banners/app_banner_settings_helper.h b/chrome/browser/banners/app_banner_settings_helper.h
index 06ab2f3..6e2b8585 100644
--- a/chrome/browser/banners/app_banner_settings_helper.h
+++ b/chrome/browser/banners/app_banner_settings_helper.h
@@ -7,12 +7,10 @@
 
 #include <set>
 #include <string>
-#include <vector>
 
 #include "base/macros.h"
 #include "base/time/time.h"
 #include "chrome/browser/installable/installable_logging.h"
-#include "ui/base/page_transition_types.h"
 
 namespace content {
 class WebContents;
@@ -52,12 +50,25 @@
     LANGUAGE_OPTION_MAX = LANGUAGE_OPTION_INSTALL,
   };
 
+  // The various types of banner events recorded as timestamps in the app banner
+  // content setting per origin and package_name_or_start_url pair. This enum
+  // corresponds to the kBannerEventsKeys array.
   // TODO(mariakhomenko): Rename events to reflect that they are used in more
   // contexts now.
   enum AppBannerEvent {
+    // Records the first time that a site met the conditions to show a banner.
+    // Used for computing the MinutesFromFirstVisitToBannerShown metric.
     APP_BANNER_EVENT_COULD_SHOW,
+    // Records the latest time a banner was shown to the user. Used to suppress
+    // the banner from being shown too often.
     APP_BANNER_EVENT_DID_SHOW,
+    // Records the latest time a banner was dismissed by the user. Used to
+    // suppress the banenr for some time if the user explicitly didn't want it.
     APP_BANNER_EVENT_DID_BLOCK,
+    // Records the latest time the user adds a site to the homescreen from a
+    // banner, or launched that site from homescreen. Used to ensure banenrs are
+    // not shown for sites which were added, and to determine if sites were
+    // launched recently.
     APP_BANNER_EVENT_DID_ADD_TO_HOMESCREEN,
     APP_BANNER_EVENT_NUM_EVENTS,
   };
@@ -69,13 +80,6 @@
 
   static const char kInstantAppsKey[];
 
-  // BannerEvents record the time that a site was accessed, along with an
-  // engagement weight representing the importance of the access.
-  struct BannerEvent {
-    base::Time time;
-    double engagement;
-  };
-
   // The content setting basically records a simplified subset of history.
   // For privacy reasons this needs to be cleared. The ClearHistoryForURLs
   // function removes any information from the banner content settings for the
@@ -95,22 +99,13 @@
       const std::string& package_name_or_start_url,
       AppBannerRapporMetric rappor_metric);
 
-  // Record a banner event. Should not be used for could show events, as they
-  // require a transition type.
+  // Record a banner event specified by |event|.
   static void RecordBannerEvent(content::WebContents* web_contents,
                                 const GURL& origin_url,
                                 const std::string& package_name_or_start_url,
                                 AppBannerEvent event,
                                 base::Time time);
 
-  // Record a banner could show event, with a specified transition type.
-  static void RecordBannerCouldShowEvent(
-      content::WebContents* web_contents,
-      const GURL& origin_url,
-      const std::string& package_name_or_start_url,
-      base::Time time,
-      ui::PageTransition transition_type);
-
   // Determine if the banner should be shown, given the recorded events for the
   // supplied app. Returns an InstallableStatusCode indicated the reason why the
   // banner shouldn't be shown, or NO_ERROR_DETECTED if it should be shown.
@@ -120,16 +115,8 @@
       const std::string& package_name_or_start_url,
       base::Time time);
 
-  // Gets the could have been shown events that are stored for the given package
-  // or start url. This is only exposed for testing.
-  static std::vector<BannerEvent> GetCouldShowBannerEvents(
-      content::WebContents* web_contents,
-      const GURL& origin_url,
-      const std::string& package_name_or_start_url);
-
-  // Get the recorded event for an event type that only records the last event.
-  // Should not be used with APP_BANNER_EVENT_COULD_SHOW. This is only exposed
-  // for testing.
+  // Get the time that |event| was recorded, or a null time if it has not yet
+  // been recorded. Exposed for testing.
   static base::Time GetSingleBannerEvent(
       content::WebContents* web_contents,
       const GURL& origin_url,
@@ -162,16 +149,6 @@
   static void SetDaysAfterDismissAndIgnoreToTrigger(unsigned int dismiss_days,
                                                     unsigned int ignore_days);
 
-  // Set the engagement weights assigned to direct and indirect navigations.
-  static void SetEngagementWeights(double direct_engagement,
-                                   double indirect_engagement);
-
-  // Set the minimum number of minutes between banner visits that will
-  // trigger a could show banner event. This must be less than the
-  // number of minutes in a day, and evenly divide the number of minutes
-  // in a day.
-  static void SetMinimumMinutesBetweenVisits(unsigned int minutes);
-
   // Set the total engagement weight required to trigger a banner.
   static void SetTotalEngagementToTrigger(double total_engagement);
 
@@ -179,10 +156,6 @@
   // trigger to their default values.
   static void SetDefaultParameters();
 
-  // Bucket a given time to the given resolution in local time.
-  static base::Time BucketTimeToResolution(base::Time time,
-                                           unsigned int minutes);
-
   // Updates all values from field trial.
   static void UpdateFromFieldTrial();
 
@@ -190,10 +163,6 @@
   // app banners and add to homescreen.
   static LanguageOption GetHomescreenLanguageOption();
 
-  // Returns true if the app banner trigger condition should use the site
-  // engagement score instead of the navigation-based heuristic.
-  static bool ShouldUseSiteEngagementScore();
-
  private:
   DISALLOW_IMPLICIT_CONSTRUCTORS(AppBannerSettingsHelper);
 };
diff --git a/chrome/browser/banners/app_banner_settings_helper_unittest.cc b/chrome/browser/banners/app_banner_settings_helper_unittest.cc
index d7abe63f..a4035e9 100644
--- a/chrome/browser/banners/app_banner_settings_helper_unittest.cc
+++ b/chrome/browser/banners/app_banner_settings_helper_unittest.cc
@@ -2,17 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include <vector>
-
-#include "base/command_line.h"
 #include "chrome/browser/banners/app_banner_metrics.h"
 #include "chrome/browser/banners/app_banner_settings_helper.h"
 #include "chrome/browser/engagement/site_engagement_service.h"
 #include "chrome/browser/installable/installable_logging.h"
-#include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
 #include "chrome/test/base/testing_profile.h"
-#include "ui/base/page_transition_types.h"
 
 namespace {
 
@@ -38,16 +33,6 @@
   return out_time;
 }
 
-bool IsWithinDay(base::Time time1, base::Time time2) {
-  return time1 - time2 < base::TimeDelta::FromDays(1) ||
-         time2 - time1 < base::TimeDelta::FromDays(1);
-}
-
-bool IsWithinHour(base::Time time1, base::Time time2) {
-  return time1 - time2 < base::TimeDelta::FromHours(1) ||
-         time2 - time1 < base::TimeDelta::FromHours(1);
-}
-
 class AppBannerSettingsHelperTest : public ChromeRenderViewHostTestHarness {
   void SetUp() override {
     ChromeRenderViewHostTestHarness::SetUp();
@@ -57,338 +42,13 @@
 
 }  // namespace
 
-TEST_F(AppBannerSettingsHelperTest, BucketTimeToResolutionInvalid) {
-  base::Time reference_time = GetReferenceTime();
-
-  // Test null, 1 day, and greater than 1 day cases.
-  EXPECT_EQ(AppBannerSettingsHelper::BucketTimeToResolution(reference_time, 0),
-            reference_time.LocalMidnight());
-  EXPECT_EQ(
-      AppBannerSettingsHelper::BucketTimeToResolution(reference_time, 1440),
-      reference_time.LocalMidnight());
-  EXPECT_EQ(
-      AppBannerSettingsHelper::BucketTimeToResolution(reference_time, 2880),
-      reference_time.LocalMidnight());
-
-  // Test number of minutes in 1 day + 1.
-  EXPECT_EQ(
-      AppBannerSettingsHelper::BucketTimeToResolution(reference_time, 1441),
-      reference_time.LocalMidnight());
-
-  // Test minutes which are not divisible by 1440 (minutes in a day).
-  EXPECT_EQ(AppBannerSettingsHelper::BucketTimeToResolution(reference_time, 7),
-            reference_time.LocalMidnight());
-  EXPECT_EQ(AppBannerSettingsHelper::BucketTimeToResolution(reference_time, 13),
-            reference_time.LocalMidnight());
-  EXPECT_EQ(AppBannerSettingsHelper::BucketTimeToResolution(reference_time, 21),
-            reference_time.LocalMidnight());
-  EXPECT_EQ(AppBannerSettingsHelper::BucketTimeToResolution(reference_time, 35),
-            reference_time.LocalMidnight());
-  EXPECT_EQ(AppBannerSettingsHelper::BucketTimeToResolution(reference_time, 42),
-            reference_time.LocalMidnight());
-  EXPECT_EQ(AppBannerSettingsHelper::BucketTimeToResolution(reference_time, 50),
-            reference_time.LocalMidnight());
-  EXPECT_EQ(AppBannerSettingsHelper::BucketTimeToResolution(reference_time, 59),
-            reference_time.LocalMidnight());
-}
-
-TEST_F(AppBannerSettingsHelperTest, BucketTimeToResolutionValid) {
-  // 11:00
-  base::Time reference_time = GetReferenceTime();
-  // 13:44
-  base::Time same_day_later =
-      reference_time + base::TimeDelta::FromMinutes(164);
-  // 10:18
-  base::Time same_day_earlier =
-      reference_time - base::TimeDelta::FromMinutes(42);
-  base::Time midnight = reference_time.LocalMidnight();
-  base::Time bucketed_hour = midnight + base::TimeDelta::FromHours(11);
-  base::Time bucketed_hour_later = midnight + base::TimeDelta::FromHours(13);
-  base::Time bucketed_hour_earlier = midnight + base::TimeDelta::FromHours(10);
-
-  // Resolution of 1 minute: 11:00, 13:44, 10:18.
-  EXPECT_EQ(AppBannerSettingsHelper::BucketTimeToResolution(reference_time, 1),
-            bucketed_hour);
-  EXPECT_EQ(AppBannerSettingsHelper::BucketTimeToResolution(same_day_later, 1),
-            bucketed_hour_later + base::TimeDelta::FromMinutes(44));
-  EXPECT_EQ(
-      AppBannerSettingsHelper::BucketTimeToResolution(same_day_earlier, 1),
-      bucketed_hour_earlier + base::TimeDelta::FromMinutes(18));
-
-  // Resolution of 3 minutes: 11:00, 13:43, 10:18.
-  EXPECT_EQ(AppBannerSettingsHelper::BucketTimeToResolution(reference_time, 3),
-            bucketed_hour);
-  EXPECT_EQ(AppBannerSettingsHelper::BucketTimeToResolution(same_day_later, 3),
-            bucketed_hour_later + base::TimeDelta::FromMinutes(42));
-  EXPECT_EQ(
-      AppBannerSettingsHelper::BucketTimeToResolution(same_day_earlier, 3),
-      bucketed_hour_earlier + base::TimeDelta::FromMinutes(18));
-
-  // Resolution of 10 minutes: 11:00, 13:40, 10:10.
-  EXPECT_EQ(AppBannerSettingsHelper::BucketTimeToResolution(reference_time, 10),
-            bucketed_hour);
-  EXPECT_EQ(AppBannerSettingsHelper::BucketTimeToResolution(same_day_later, 10),
-            bucketed_hour_later + base::TimeDelta::FromMinutes(40));
-  EXPECT_EQ(
-      AppBannerSettingsHelper::BucketTimeToResolution(same_day_earlier, 10),
-      bucketed_hour_earlier + base::TimeDelta::FromMinutes(10));
-
-  // Resolution of 20 minutes: 11:00, 13:40, 10:00.
-  EXPECT_EQ(AppBannerSettingsHelper::BucketTimeToResolution(reference_time, 20),
-            bucketed_hour);
-  EXPECT_EQ(AppBannerSettingsHelper::BucketTimeToResolution(same_day_later, 20),
-            bucketed_hour_later + base::TimeDelta::FromMinutes(40));
-  EXPECT_EQ(
-      AppBannerSettingsHelper::BucketTimeToResolution(same_day_earlier, 20),
-      bucketed_hour_earlier);
-
-  // Resolution of 60 minutes: 11:00, 13:00, 10:00.
-  EXPECT_EQ(AppBannerSettingsHelper::BucketTimeToResolution(reference_time, 60),
-            bucketed_hour);
-  EXPECT_EQ(AppBannerSettingsHelper::BucketTimeToResolution(same_day_later, 60),
-            bucketed_hour_later);
-  EXPECT_EQ(
-      AppBannerSettingsHelper::BucketTimeToResolution(same_day_earlier, 60),
-      bucketed_hour_earlier);
-
-  // Resolution of 120 minutes: 10:00, 12:00, 10:00.
-  EXPECT_EQ(
-      AppBannerSettingsHelper::BucketTimeToResolution(reference_time, 120),
-      bucketed_hour_earlier);
-  EXPECT_EQ(
-      AppBannerSettingsHelper::BucketTimeToResolution(same_day_later, 120),
-      bucketed_hour_later - base::TimeDelta::FromHours(1));
-  EXPECT_EQ(
-      AppBannerSettingsHelper::BucketTimeToResolution(same_day_earlier, 120),
-      bucketed_hour_earlier);
-
-  // Resolution of 180 minutes: 9:00, 12:00, 9:00.
-  EXPECT_EQ(
-      AppBannerSettingsHelper::BucketTimeToResolution(reference_time, 180),
-      bucketed_hour_earlier - base::TimeDelta::FromHours(1));
-  EXPECT_EQ(
-      AppBannerSettingsHelper::BucketTimeToResolution(same_day_later, 180),
-      bucketed_hour_later - base::TimeDelta::FromHours(1));
-  EXPECT_EQ(
-      AppBannerSettingsHelper::BucketTimeToResolution(same_day_earlier, 180),
-      bucketed_hour_earlier - base::TimeDelta::FromHours(1));
-
-  // Resolution of 240 minutes: 8:00, 12:00, 8:00.
-  EXPECT_EQ(
-      AppBannerSettingsHelper::BucketTimeToResolution(reference_time, 240),
-      midnight + base::TimeDelta::FromHours(8));
-  EXPECT_EQ(
-      AppBannerSettingsHelper::BucketTimeToResolution(same_day_later, 240),
-      midnight + base::TimeDelta::FromHours(12));
-  EXPECT_EQ(
-      AppBannerSettingsHelper::BucketTimeToResolution(same_day_earlier, 240),
-      midnight + base::TimeDelta::FromHours(8));
-
-  // Resolution of 360 minutes: 6:00, 12:00, 6:00
-  EXPECT_EQ(
-      AppBannerSettingsHelper::BucketTimeToResolution(reference_time, 360),
-      midnight + base::TimeDelta::FromHours(6));
-  EXPECT_EQ(
-      AppBannerSettingsHelper::BucketTimeToResolution(same_day_later, 360),
-      midnight + base::TimeDelta::FromHours(12));
-  EXPECT_EQ(
-      AppBannerSettingsHelper::BucketTimeToResolution(same_day_earlier, 360),
-      midnight + base::TimeDelta::FromHours(6));
-
-  // Resolution of 720 minutes: 0:00, 12:00, 0:00
-  EXPECT_EQ(
-      AppBannerSettingsHelper::BucketTimeToResolution(reference_time, 720),
-      midnight);
-  EXPECT_EQ(
-      AppBannerSettingsHelper::BucketTimeToResolution(same_day_later, 720),
-      midnight + base::TimeDelta::FromHours(12));
-  EXPECT_EQ(
-      AppBannerSettingsHelper::BucketTimeToResolution(same_day_earlier, 720),
-      midnight);
-
-  // Resolution of 1440 minutes: 0:00, 0:00, 0:00
-  EXPECT_EQ(
-      AppBannerSettingsHelper::BucketTimeToResolution(reference_time, 1440),
-      midnight);
-  EXPECT_EQ(
-      AppBannerSettingsHelper::BucketTimeToResolution(same_day_later, 1440),
-      midnight);
-  EXPECT_EQ(
-      AppBannerSettingsHelper::BucketTimeToResolution(same_day_earlier, 1440),
-      midnight);
-}
-
-TEST_F(AppBannerSettingsHelperTest, CouldShowEvents) {
-  GURL url(kTestURL);
-  NavigateAndCommit(url);
-
-  // Check that by default, there are no events recorded.
-  std::vector<AppBannerSettingsHelper::BannerEvent> events =
-      AppBannerSettingsHelper::GetCouldShowBannerEvents(web_contents(), url,
-                                                        kTestPackageName);
-  EXPECT_TRUE(events.empty());
-
-  base::Time reference_time = GetReferenceTime();
-  base::Time same_day = reference_time + base::TimeDelta::FromHours(2);
-  base::Time three_days_prior = reference_time - base::TimeDelta::FromDays(3);
-  base::Time previous_fortnight =
-      reference_time - base::TimeDelta::FromDays(14);
-
-  // Test adding the first date.
-  AppBannerSettingsHelper::RecordBannerCouldShowEvent(
-      web_contents(), url, kTestPackageName, previous_fortnight,
-      ui::PAGE_TRANSITION_TYPED);
-
-  // It should be the only date recorded.
-  events = AppBannerSettingsHelper::GetCouldShowBannerEvents(
-      web_contents(), url, kTestPackageName);
-  EXPECT_EQ(1u, events.size());
-  EXPECT_TRUE(IsWithinDay(events[0].time, previous_fortnight));
-  EXPECT_EQ(events[0].engagement, 1);
-
-  // Now add the next date.
-  AppBannerSettingsHelper::RecordBannerCouldShowEvent(
-      web_contents(), url, kTestPackageName, three_days_prior,
-      ui::PAGE_TRANSITION_GENERATED);
-
-  // Now there should be two events.
-  events = AppBannerSettingsHelper::GetCouldShowBannerEvents(
-      web_contents(), url, kTestPackageName);
-  EXPECT_EQ(2u, events.size());
-  EXPECT_TRUE(IsWithinDay(events[0].time, previous_fortnight));
-  EXPECT_TRUE(IsWithinDay(events[1].time, three_days_prior));
-  EXPECT_EQ(events[0].engagement, 1);
-  EXPECT_EQ(events[1].engagement, 1);
-
-  // Now add the reference date.
-  AppBannerSettingsHelper::RecordBannerCouldShowEvent(
-      web_contents(), url, kTestPackageName, reference_time,
-      ui::PAGE_TRANSITION_LINK);
-
-  // Now there should still be two events, but the first date should have been
-  // removed.
-  events = AppBannerSettingsHelper::GetCouldShowBannerEvents(
-      web_contents(), url, kTestPackageName);
-  EXPECT_EQ(2u, events.size());
-  EXPECT_TRUE(IsWithinDay(events[0].time, three_days_prior));
-  EXPECT_TRUE(IsWithinDay(events[1].time, reference_time));
-  EXPECT_EQ(events[0].engagement, 1);
-  EXPECT_EQ(events[1].engagement, 1);
-
-  // Now add the the other date on the reference day.
-  AppBannerSettingsHelper::RecordBannerCouldShowEvent(
-      web_contents(), url, kTestPackageName, same_day,
-      ui::PAGE_TRANSITION_RELOAD);
-
-  // Now there should still be the same two dates.
-  events = AppBannerSettingsHelper::GetCouldShowBannerEvents(
-      web_contents(), url, kTestPackageName);
-  EXPECT_EQ(2u, events.size());
-  EXPECT_TRUE(IsWithinDay(events[0].time, three_days_prior));
-  EXPECT_TRUE(IsWithinDay(events[1].time, reference_time));
-  EXPECT_EQ(events[0].engagement, 1);
-  EXPECT_EQ(events[1].engagement, 1);
-}
-
-TEST_F(AppBannerSettingsHelperTest, CouldShowEventsDifferentResolution) {
-  AppBannerSettingsHelper::SetMinimumMinutesBetweenVisits(20);
-  GURL url(kTestURL);
-  NavigateAndCommit(url);
-
-  // Check that by default, there are no events recorded.
-  std::vector<AppBannerSettingsHelper::BannerEvent> events =
-      AppBannerSettingsHelper::GetCouldShowBannerEvents(web_contents(), url,
-                                                        kTestPackageName);
-  EXPECT_TRUE(events.empty());
-
-  base::Time reference_time = GetReferenceTime();
-  base::Time same_day_ignored_i =
-      reference_time + base::TimeDelta::FromMinutes(10);
-  base::Time same_day_counted_i =
-      reference_time + base::TimeDelta::FromMinutes(20);
-  base::Time same_day_counted_ii =
-      reference_time + base::TimeDelta::FromMinutes(45);
-  base::Time same_day_ignored_ii =
-      reference_time + base::TimeDelta::FromMinutes(59);
-
-  // Add the reference date.
-  AppBannerSettingsHelper::RecordBannerCouldShowEvent(
-      web_contents(), url, kTestPackageName, reference_time,
-      ui::PAGE_TRANSITION_LINK);
-
-  // There should be one event recorded
-  events = AppBannerSettingsHelper::GetCouldShowBannerEvents(
-      web_contents(), url, kTestPackageName);
-  EXPECT_EQ(1u, events.size());
-  EXPECT_TRUE(IsWithinDay(events[0].time, reference_time));
-  EXPECT_EQ(events[0].engagement, 1);
-
-  // Now add the the ignored date on the reference day.
-  AppBannerSettingsHelper::RecordBannerCouldShowEvent(
-      web_contents(), url, kTestPackageName, same_day_ignored_i,
-      ui::PAGE_TRANSITION_RELOAD);
-
-  // Now there should still one event.
-  events = AppBannerSettingsHelper::GetCouldShowBannerEvents(
-      web_contents(), url, kTestPackageName);
-  EXPECT_EQ(1u, events.size());
-  EXPECT_TRUE(IsWithinDay(events[0].time, reference_time));
-  EXPECT_EQ(events[0].engagement, 1);
-
-  // Now add the the first counted date on the reference day.
-  AppBannerSettingsHelper::RecordBannerCouldShowEvent(
-      web_contents(), url, kTestPackageName, same_day_counted_i,
-      ui::PAGE_TRANSITION_TYPED);
-
-  // Now there should be two events.
-  events = AppBannerSettingsHelper::GetCouldShowBannerEvents(
-      web_contents(), url, kTestPackageName);
-  EXPECT_EQ(2u, events.size());
-  EXPECT_TRUE(IsWithinDay(events[0].time, reference_time));
-  EXPECT_TRUE(IsWithinDay(events[1].time, same_day_counted_i));
-  EXPECT_EQ(events[0].engagement, 1);
-  EXPECT_EQ(events[1].engagement, 1);
-
-  // Now add the the second counted date on the reference day.
-  AppBannerSettingsHelper::RecordBannerCouldShowEvent(
-      web_contents(), url, kTestPackageName, same_day_counted_ii,
-      ui::PAGE_TRANSITION_GENERATED);
-
-  // Now there should be three events.
-  events = AppBannerSettingsHelper::GetCouldShowBannerEvents(
-      web_contents(), url, kTestPackageName);
-  EXPECT_EQ(3u, events.size());
-  EXPECT_TRUE(IsWithinDay(events[0].time, reference_time));
-  EXPECT_TRUE(IsWithinDay(events[1].time, same_day_counted_i));
-  EXPECT_TRUE(IsWithinDay(events[2].time, same_day_counted_ii));
-  EXPECT_EQ(events[0].engagement, 1);
-  EXPECT_EQ(events[1].engagement, 1);
-  EXPECT_EQ(events[2].engagement, 1);
-
-  // Now add the the second ignored date on the reference day.
-  AppBannerSettingsHelper::RecordBannerCouldShowEvent(
-      web_contents(), url, kTestPackageName, same_day_ignored_ii,
-      ui::PAGE_TRANSITION_LINK);
-
-  // Now there should still be three events.
-  events = AppBannerSettingsHelper::GetCouldShowBannerEvents(
-      web_contents(), url, kTestPackageName);
-  EXPECT_EQ(3u, events.size());
-  EXPECT_TRUE(IsWithinDay(events[0].time, reference_time));
-  EXPECT_TRUE(IsWithinDay(events[1].time, same_day_counted_i));
-  EXPECT_TRUE(IsWithinDay(events[2].time, same_day_counted_ii));
-  EXPECT_EQ(events[0].engagement, 1);
-  EXPECT_EQ(events[1].engagement, 1);
-  EXPECT_EQ(events[2].engagement, 1);
-}
-
 TEST_F(AppBannerSettingsHelperTest, SingleEvents) {
   GURL url(kTestURL);
   NavigateAndCommit(url);
 
   base::Time reference_time = GetReferenceTime();
   base::Time other_time = reference_time - base::TimeDelta::FromDays(3);
-  for (int event = AppBannerSettingsHelper::APP_BANNER_EVENT_DID_SHOW;
+  for (int event = AppBannerSettingsHelper::APP_BANNER_EVENT_COULD_SHOW;
        event < AppBannerSettingsHelper::APP_BANNER_EVENT_NUM_EVENTS; ++event) {
     // Check that by default, there is no event.
     base::Time event_time = AppBannerSettingsHelper::GetSingleBannerEvent(
@@ -414,222 +74,51 @@
     event_time = AppBannerSettingsHelper::GetSingleBannerEvent(
         web_contents(), url, kTestPackageName,
         AppBannerSettingsHelper::AppBannerEvent(event));
-    EXPECT_EQ(other_time, event_time);
+
+    // COULD_SHOW events are not overwritten, but other events are.
+    if (event == AppBannerSettingsHelper::APP_BANNER_EVENT_COULD_SHOW)
+      EXPECT_EQ(reference_time, event_time);
+    else
+      EXPECT_EQ(other_time, event_time);
   }
 }
 
-TEST_F(AppBannerSettingsHelperTest, CouldShowEventReplacedWithHigherWeight) {
-  // Set direct engagement to be worth 4 and indirect to be worth 2.
-  AppBannerSettingsHelper::SetEngagementWeights(4, 2);
-  GURL url(kTestURL);
-  NavigateAndCommit(url);
-
-  base::Time reference_time = GetReferenceTime();
-  base::Time later_same_day = reference_time + base::TimeDelta::FromHours(2);
-  base::Time later_again_same_day =
-      reference_time + base::TimeDelta::FromHours(6);
-  base::Time next_day = reference_time + base::TimeDelta::FromDays(1);
-  base::Time later_next_day = next_day + base::TimeDelta::FromHours(3);
-
-  // Ensure there are no events recorded by default.
-  std::vector<AppBannerSettingsHelper::BannerEvent> events =
-      AppBannerSettingsHelper::GetCouldShowBannerEvents(web_contents(), url,
-                                                        kTestPackageName);
-  EXPECT_TRUE(events.empty());
-
-  // Record an indirect engagement type.
-  AppBannerSettingsHelper::RecordBannerCouldShowEvent(
-      web_contents(), url, kTestPackageName, reference_time,
-      ui::PAGE_TRANSITION_LINK);
-
-  events = AppBannerSettingsHelper::GetCouldShowBannerEvents(
-      web_contents(), url, kTestPackageName);
-
-  EXPECT_EQ(1u, events.size());
-  EXPECT_TRUE(IsWithinHour(events[0].time, reference_time));
-  EXPECT_EQ(2, events[0].engagement);
-
-  // Record a direct engagement type. This should override the previous value.
-  AppBannerSettingsHelper::RecordBannerCouldShowEvent(
-      web_contents(), url, kTestPackageName, later_same_day,
-      ui::PAGE_TRANSITION_TYPED);
-
-  events = AppBannerSettingsHelper::GetCouldShowBannerEvents(
-      web_contents(), url, kTestPackageName);
-
-  EXPECT_EQ(1u, events.size());
-  EXPECT_TRUE(IsWithinHour(events[0].time, later_same_day));
-  EXPECT_EQ(4, events[0].engagement);
-
-  // Record an indirect engagement type. This should be ignored.
-  AppBannerSettingsHelper::RecordBannerCouldShowEvent(
-      web_contents(), url, kTestPackageName, later_again_same_day,
-      ui::PAGE_TRANSITION_RELOAD);
-
-  events = AppBannerSettingsHelper::GetCouldShowBannerEvents(
-      web_contents(), url, kTestPackageName);
-
-  EXPECT_EQ(1u, events.size());
-  EXPECT_TRUE(IsWithinHour(events[0].time, later_same_day));
-  EXPECT_EQ(4, events[0].engagement);
-
-  // Record an indirect engagement type one day later. This should appear.
-  AppBannerSettingsHelper::RecordBannerCouldShowEvent(
-      web_contents(), url, kTestPackageName, next_day,
-      ui::PAGE_TRANSITION_AUTO_BOOKMARK);
-
-  events = AppBannerSettingsHelper::GetCouldShowBannerEvents(
-      web_contents(), url, kTestPackageName);
-
-  EXPECT_EQ(2u, events.size());
-  EXPECT_TRUE(IsWithinHour(events[0].time, later_same_day));
-  EXPECT_EQ(4, events[0].engagement);
-  EXPECT_TRUE(IsWithinHour(events[1].time, next_day));
-  EXPECT_EQ(2, events[1].engagement);
-
-  // Record a direct engagement type later on the next day. This should override
-  // the previous value.
-  AppBannerSettingsHelper::RecordBannerCouldShowEvent(
-      web_contents(), url, kTestPackageName, later_next_day,
-      ui::PAGE_TRANSITION_GENERATED);
-
-  events = AppBannerSettingsHelper::GetCouldShowBannerEvents(
-      web_contents(), url, kTestPackageName);
-
-  EXPECT_EQ(2u, events.size());
-  EXPECT_TRUE(IsWithinHour(events[0].time, later_same_day));
-  EXPECT_EQ(4, events[0].engagement);
-  EXPECT_TRUE(IsWithinHour(events[1].time, later_next_day));
-  EXPECT_EQ(4, events[1].engagement);
-}
-
-TEST_F(AppBannerSettingsHelperTest, IndirectEngagementWithLowerWeight) {
-  AppBannerSettingsHelper::SetEngagementWeights(2, 0.5);
-  GURL url(kTestURL);
-  NavigateAndCommit(url);
-
-  base::Time reference_time = GetReferenceTime();
-  base::Time second_day = reference_time + base::TimeDelta::FromDays(1);
-  base::Time third_day = reference_time + base::TimeDelta::FromDays(2);
-  base::Time fourth_day = reference_time + base::TimeDelta::FromDays(3);
-
-  // By default the banner should not be shown.
-  EXPECT_EQ(INSUFFICIENT_ENGAGEMENT,
-            AppBannerSettingsHelper::ShouldShowBanner(
-                web_contents(), url, kTestPackageName, reference_time));
-
-  // It should take four indirect visits with a weight of 0.5 to trigger the
-  // banner.
-  AppBannerSettingsHelper::RecordBannerCouldShowEvent(
-      web_contents(), url, kTestPackageName, reference_time,
-      ui::PAGE_TRANSITION_LINK);
-  EXPECT_EQ(INSUFFICIENT_ENGAGEMENT,
-            AppBannerSettingsHelper::ShouldShowBanner(
-                web_contents(), url, kTestPackageName, reference_time));
-
-  AppBannerSettingsHelper::RecordBannerCouldShowEvent(
-      web_contents(), url, kTestPackageName, second_day,
-      ui::PAGE_TRANSITION_LINK);
-  EXPECT_EQ(INSUFFICIENT_ENGAGEMENT,
-            AppBannerSettingsHelper::ShouldShowBanner(
-                web_contents(), url, kTestPackageName, second_day));
-
-  AppBannerSettingsHelper::RecordBannerCouldShowEvent(
-      web_contents(), url, kTestPackageName, third_day,
-      ui::PAGE_TRANSITION_FORM_SUBMIT);
-  EXPECT_EQ(INSUFFICIENT_ENGAGEMENT,
-            AppBannerSettingsHelper::ShouldShowBanner(
-                web_contents(), url, kTestPackageName, third_day));
-
-  // Visit the site again; now it should be shown.
-  AppBannerSettingsHelper::RecordBannerCouldShowEvent(
-      web_contents(), url, kTestPackageName, fourth_day,
-      ui::PAGE_TRANSITION_MANUAL_SUBFRAME);
-  EXPECT_EQ(NO_ERROR_DETECTED,
-            AppBannerSettingsHelper::ShouldShowBanner(
-                web_contents(), url, kTestPackageName, fourth_day));
-}
-
-TEST_F(AppBannerSettingsHelperTest, DirectEngagementWithHigherWeight) {
-  AppBannerSettingsHelper::SetEngagementWeights(2, 0.5);
-  GURL url(kTestURL);
-  NavigateAndCommit(url);
-
-  base::Time reference_time = GetReferenceTime();
-
-  // By default the banner should not be shown.
-  EXPECT_EQ(INSUFFICIENT_ENGAGEMENT,
-            AppBannerSettingsHelper::ShouldShowBanner(
-                web_contents(), url, kTestPackageName, reference_time));
-
-  // It should take one direct visit with a weight of 2 to trigger the banner.
-  AppBannerSettingsHelper::RecordBannerCouldShowEvent(
-      web_contents(), url, kTestPackageName, reference_time,
-      ui::PAGE_TRANSITION_TYPED);
-  EXPECT_EQ(NO_ERROR_DETECTED,
-            AppBannerSettingsHelper::ShouldShowBanner(
-                web_contents(), url, kTestPackageName, reference_time));
-}
-
 TEST_F(AppBannerSettingsHelperTest, ShouldShowFromEngagement) {
   GURL url(kTestURL);
-  NavigateAndCommit(url);
-
-  base::Time reference_time = GetReferenceTime();
-  base::Time one_day_ago = reference_time - base::TimeDelta::FromDays(1);
-  base::Time one_year_ago = reference_time - base::TimeDelta::FromDays(366);
+  SiteEngagementService* service = SiteEngagementService::Get(profile());
 
   // By default the banner should not be shown.
-  EXPECT_EQ(INSUFFICIENT_ENGAGEMENT,
-            AppBannerSettingsHelper::ShouldShowBanner(
-                web_contents(), url, kTestPackageName, reference_time));
+  EXPECT_FALSE(
+      AppBannerSettingsHelper::HasSufficientEngagement(service->GetScore(url)));
 
-  // Visit the site once, it still should not be shown.
-  AppBannerSettingsHelper::RecordBannerCouldShowEvent(
-      web_contents(), url, kTestPackageName, one_year_ago,
-      ui::PAGE_TRANSITION_TYPED);
-  EXPECT_EQ(INSUFFICIENT_ENGAGEMENT,
-            AppBannerSettingsHelper::ShouldShowBanner(
-                web_contents(), url, kTestPackageName, reference_time));
+  // Add 1 engagement, it still should not be shown.
+  service->ResetScoreForURL(url, 1);
+  EXPECT_FALSE(
+      AppBannerSettingsHelper::HasSufficientEngagement(service->GetScore(url)));
 
-  // Visit the site again after a long delay, it still should not be shown.
-  AppBannerSettingsHelper::RecordBannerCouldShowEvent(
-      web_contents(), url, kTestPackageName, one_day_ago,
-      ui::PAGE_TRANSITION_TYPED);
-  EXPECT_EQ(INSUFFICIENT_ENGAGEMENT,
-            AppBannerSettingsHelper::ShouldShowBanner(
-                web_contents(), url, kTestPackageName, reference_time));
-
-  // Visit the site again; now it should be shown.
-  AppBannerSettingsHelper::RecordBannerCouldShowEvent(
-      web_contents(), url, kTestPackageName, reference_time,
-      ui::PAGE_TRANSITION_TYPED);
-  EXPECT_EQ(NO_ERROR_DETECTED,
-            AppBannerSettingsHelper::ShouldShowBanner(
-                web_contents(), url, kTestPackageName, reference_time));
+  // Add 1 more engagement; now it should be shown.
+  service->ResetScoreForURL(url, 2);
+  EXPECT_TRUE(
+      AppBannerSettingsHelper::HasSufficientEngagement(service->GetScore(url)));
 }
 
 TEST_F(AppBannerSettingsHelperTest, ShouldNotShowAfterBlocking) {
   GURL url(kTestURL);
   NavigateAndCommit(url);
+  SiteEngagementService* service = SiteEngagementService::Get(profile());
 
   base::Time reference_time = GetReferenceTime();
-  base::Time one_day_ago = reference_time - base::TimeDelta::FromDays(1);
   base::Time two_months_ago = reference_time - base::TimeDelta::FromDays(60);
   base::Time one_year_ago = reference_time - base::TimeDelta::FromDays(366);
 
   // By default the banner should not be shown.
-  EXPECT_EQ(INSUFFICIENT_ENGAGEMENT,
-            AppBannerSettingsHelper::ShouldShowBanner(
-                web_contents(), url, kTestPackageName, reference_time));
+  EXPECT_FALSE(
+      AppBannerSettingsHelper::HasSufficientEngagement(service->GetScore(url)));
 
-  // Record events such that the banner should show.
-  AppBannerSettingsHelper::RecordBannerCouldShowEvent(
-      web_contents(), url, kTestPackageName, one_day_ago,
-      ui::PAGE_TRANSITION_TYPED);
-  AppBannerSettingsHelper::RecordBannerCouldShowEvent(
-      web_contents(), url, kTestPackageName, reference_time,
-      ui::PAGE_TRANSITION_TYPED);
+  // Add engagement such that the banner should show.
+  service->ResetScoreForURL(url, 4);
+  EXPECT_TRUE(
+      AppBannerSettingsHelper::HasSufficientEngagement(service->GetScore(url)));
   EXPECT_EQ(NO_ERROR_DETECTED,
             AppBannerSettingsHelper::ShouldShowBanner(
                 web_contents(), url, kTestPackageName, reference_time));
@@ -661,24 +150,20 @@
 TEST_F(AppBannerSettingsHelperTest, ShouldNotShowAfterShowing) {
   GURL url(kTestURL);
   NavigateAndCommit(url);
+  SiteEngagementService* service = SiteEngagementService::Get(profile());
 
   base::Time reference_time = GetReferenceTime();
-  base::Time one_day_ago = reference_time - base::TimeDelta::FromDays(1);
   base::Time one_week_ago = reference_time - base::TimeDelta::FromDays(7);
   base::Time one_year_ago = reference_time - base::TimeDelta::FromDays(366);
 
   // By default the banner should not be shown.
-  EXPECT_EQ(INSUFFICIENT_ENGAGEMENT,
-            AppBannerSettingsHelper::ShouldShowBanner(
-                web_contents(), url, kTestPackageName, reference_time));
+  EXPECT_FALSE(
+      AppBannerSettingsHelper::HasSufficientEngagement(service->GetScore(url)));
 
-  // Record events such that the banner should show.
-  AppBannerSettingsHelper::RecordBannerCouldShowEvent(
-      web_contents(), url, kTestPackageName, one_day_ago,
-      ui::PAGE_TRANSITION_TYPED);
-  AppBannerSettingsHelper::RecordBannerCouldShowEvent(
-      web_contents(), url, kTestPackageName, reference_time,
-      ui::PAGE_TRANSITION_TYPED);
+  // Add engagement such that the banner should show.
+  service->ResetScoreForURL(url, 4);
+  EXPECT_TRUE(
+      AppBannerSettingsHelper::HasSufficientEngagement(service->GetScore(url)));
   EXPECT_EQ(NO_ERROR_DETECTED,
             AppBannerSettingsHelper::ShouldShowBanner(
                 web_contents(), url, kTestPackageName, reference_time));
@@ -709,24 +194,19 @@
 
 TEST_F(AppBannerSettingsHelperTest, ShouldNotShowAfterAdding) {
   GURL url(kTestURL);
-  NavigateAndCommit(url);
+  SiteEngagementService* service = SiteEngagementService::Get(profile());
 
   base::Time reference_time = GetReferenceTime();
-  base::Time one_day_ago = reference_time - base::TimeDelta::FromDays(1);
   base::Time one_year_ago = reference_time - base::TimeDelta::FromDays(366);
 
   // By default the banner should not be shown.
-  EXPECT_EQ(INSUFFICIENT_ENGAGEMENT,
-            AppBannerSettingsHelper::ShouldShowBanner(
-                web_contents(), url, kTestPackageName, reference_time));
+  EXPECT_FALSE(
+      AppBannerSettingsHelper::HasSufficientEngagement(service->GetScore(url)));
 
-  // Record events such that the banner should show.
-  AppBannerSettingsHelper::RecordBannerCouldShowEvent(
-      web_contents(), url, kTestPackageName, one_day_ago,
-      ui::PAGE_TRANSITION_TYPED);
-  AppBannerSettingsHelper::RecordBannerCouldShowEvent(
-      web_contents(), url, kTestPackageName, reference_time,
-      ui::PAGE_TRANSITION_TYPED);
+  // Add engagement such that the banner should show.
+  service->ResetScoreForURL(url, 4);
+  EXPECT_TRUE(
+      AppBannerSettingsHelper::HasSufficientEngagement(service->GetScore(url)));
   EXPECT_EQ(NO_ERROR_DETECTED,
             AppBannerSettingsHelper::ShouldShowBanner(
                 web_contents(), url, kTestPackageName, reference_time));
@@ -743,85 +223,61 @@
 
 TEST_F(AppBannerSettingsHelperTest, OperatesOnOrigins) {
   GURL url(kTestURL);
-  NavigateAndCommit(url);
-
-  base::Time reference_time = GetReferenceTime();
-  base::Time one_day_ago = reference_time - base::TimeDelta::FromDays(1);
+  SiteEngagementService* service = SiteEngagementService::Get(profile());
 
   // By default the banner should not be shown.
-  EXPECT_EQ(INSUFFICIENT_ENGAGEMENT,
-            AppBannerSettingsHelper::ShouldShowBanner(
-                web_contents(), url, kTestPackageName, reference_time));
+  EXPECT_FALSE(
+      AppBannerSettingsHelper::HasSufficientEngagement(service->GetScore(url)));
 
-  // Record events such that the banner should show.
-  AppBannerSettingsHelper::RecordBannerCouldShowEvent(
-      web_contents(), url, kTestPackageName, one_day_ago,
-      ui::PAGE_TRANSITION_TYPED);
-  AppBannerSettingsHelper::RecordBannerCouldShowEvent(
-      web_contents(), url, kTestPackageName, reference_time,
-      ui::PAGE_TRANSITION_TYPED);
+  // Add engagement such that the banner should show.
+  service->ResetScoreForURL(url, 4);
+  EXPECT_TRUE(
+      AppBannerSettingsHelper::HasSufficientEngagement(service->GetScore(url)));
 
-  // Navigate to another page on the same origin.
+  // Try another page on the same origin.
   url = GURL(kSameOriginTestURL);
-  NavigateAndCommit(url);
 
   // The banner should show as settings are per-origin.
+  EXPECT_TRUE(
+      AppBannerSettingsHelper::HasSufficientEngagement(service->GetScore(url)));
   EXPECT_EQ(NO_ERROR_DETECTED,
             AppBannerSettingsHelper::ShouldShowBanner(
-                web_contents(), url, kTestPackageName, reference_time));
+                web_contents(), url, kTestPackageName, GetReferenceTime()));
 }
 
 TEST_F(AppBannerSettingsHelperTest, ShouldShowWithHigherTotal) {
-  AppBannerSettingsHelper::SetTotalEngagementToTrigger(5);
+  AppBannerSettingsHelper::SetTotalEngagementToTrigger(10);
   GURL url(kTestURL);
-  NavigateAndCommit(url);
+  SiteEngagementService* service = SiteEngagementService::Get(profile());
 
-  base::Time reference_time = GetReferenceTime();
-  base::Time second_day = reference_time + base::TimeDelta::FromDays(1);
-  base::Time third_day = reference_time + base::TimeDelta::FromDays(2);
-  base::Time fourth_day = reference_time + base::TimeDelta::FromDays(3);
-  base::Time fifth_day = reference_time + base::TimeDelta::FromDays(4);
+  // By default the banner should not be shown.
+  EXPECT_FALSE(
+      AppBannerSettingsHelper::HasSufficientEngagement(service->GetScore(url)));
 
-  EXPECT_EQ(INSUFFICIENT_ENGAGEMENT,
-            AppBannerSettingsHelper::ShouldShowBanner(
-                web_contents(), url, kTestPackageName, reference_time));
+  // Add engagement such that the banner should show.
+  service->ResetScoreForURL(url, 2);
+  EXPECT_FALSE(
+      AppBannerSettingsHelper::HasSufficientEngagement(service->GetScore(url)));
 
-  // It should take five visits to trigger the banner.
-  AppBannerSettingsHelper::RecordBannerCouldShowEvent(
-      web_contents(), url, kTestPackageName, reference_time,
-      ui::PAGE_TRANSITION_LINK);
-  EXPECT_EQ(INSUFFICIENT_ENGAGEMENT,
-            AppBannerSettingsHelper::ShouldShowBanner(
-                web_contents(), url, kTestPackageName, reference_time));
+  service->ResetScoreForURL(url, 4);
+  EXPECT_FALSE(
+      AppBannerSettingsHelper::HasSufficientEngagement(service->GetScore(url)));
 
-  AppBannerSettingsHelper::RecordBannerCouldShowEvent(
-      web_contents(), url, kTestPackageName, second_day,
-      ui::PAGE_TRANSITION_TYPED);
-  EXPECT_EQ(INSUFFICIENT_ENGAGEMENT,
-            AppBannerSettingsHelper::ShouldShowBanner(
-                web_contents(), url, kTestPackageName, reference_time));
+  service->ResetScoreForURL(url, 6);
+  EXPECT_FALSE(
+      AppBannerSettingsHelper::HasSufficientEngagement(service->GetScore(url)));
 
-  AppBannerSettingsHelper::RecordBannerCouldShowEvent(
-      web_contents(), url, kTestPackageName, third_day,
-      ui::PAGE_TRANSITION_GENERATED);
-  EXPECT_EQ(INSUFFICIENT_ENGAGEMENT,
-            AppBannerSettingsHelper::ShouldShowBanner(
-                web_contents(), url, kTestPackageName, reference_time));
+  service->ResetScoreForURL(url, 8);
+  EXPECT_FALSE(
+      AppBannerSettingsHelper::HasSufficientEngagement(service->GetScore(url)));
 
-  AppBannerSettingsHelper::RecordBannerCouldShowEvent(
-      web_contents(), url, kTestPackageName, fourth_day,
-      ui::PAGE_TRANSITION_LINK);
-  EXPECT_EQ(INSUFFICIENT_ENGAGEMENT,
-            AppBannerSettingsHelper::ShouldShowBanner(
-                web_contents(), url, kTestPackageName, reference_time));
+  service->ResetScoreForURL(url, 10);
+  EXPECT_TRUE(
+      AppBannerSettingsHelper::HasSufficientEngagement(service->GetScore(url)));
 
-  // Visit the site again; now it should be shown.
-  AppBannerSettingsHelper::RecordBannerCouldShowEvent(
-      web_contents(), url, kTestPackageName, fifth_day,
-      ui::PAGE_TRANSITION_TYPED);
   EXPECT_EQ(NO_ERROR_DETECTED,
             AppBannerSettingsHelper::ShouldShowBanner(
-                web_contents(), url, kTestPackageName, reference_time));
+                web_contents(), url, kTestPackageName, GetReferenceTime()));
 }
 
 TEST_F(AppBannerSettingsHelperTest, WasLaunchedRecently) {
diff --git a/chrome/browser/chromeos/arc/arc_session_manager.cc b/chrome/browser/chromeos/arc/arc_session_manager.cc
index 28c08494..3d52d7a 100644
--- a/chrome/browser/chromeos/arc/arc_session_manager.cc
+++ b/chrome/browser/chromeos/arc/arc_session_manager.cc
@@ -192,11 +192,10 @@
   return user_manager::UserManager::Get()->IsLoggedInAsArcKioskApp();
 }
 
-void ArcSessionManager::OnBridgeStopped(ArcBridgeService::StopReason reason) {
+void ArcSessionManager::OnSessionStopped(StopReason reason) {
   // TODO(crbug.com/625923): Use |reason| to report more detailed errors.
-  if (arc_sign_in_timer_.IsRunning()) {
+  if (arc_sign_in_timer_.IsRunning())
     OnProvisioningFinished(ProvisioningResult::ARC_STOPPED);
-  }
 
   if (profile_->GetPrefs()->GetBoolean(prefs::kArcDataRemoveRequested)) {
     // This should be always true, but just in case as this is looked at
diff --git a/chrome/browser/chromeos/arc/arc_session_manager.h b/chrome/browser/chromeos/arc/arc_session_manager.h
index 5c6a16e..be8c6131 100644
--- a/chrome/browser/chromeos/arc/arc_session_manager.h
+++ b/chrome/browser/chromeos/arc/arc_session_manager.h
@@ -15,8 +15,8 @@
 #include "base/timer/timer.h"
 #include "chrome/browser/chromeos/arc/arc_support_host.h"
 #include "chrome/browser/chromeos/policy/android_management_client.h"
-#include "components/arc/arc_bridge_service.h"
 #include "components/arc/arc_service.h"
+#include "components/arc/arc_session_observer.h"
 #include "components/prefs/pref_change_registrar.h"
 #include "components/sync_preferences/pref_service_syncable_observer.h"
 #include "components/sync_preferences/synced_pref_observer.h"
@@ -38,13 +38,14 @@
 class ArcAndroidManagementChecker;
 class ArcAuthCodeFetcher;
 class ArcAuthContext;
+class ArcBridgeService;
 class ArcTermsOfServiceNegotiator;
 enum class ProvisioningResult : int;
 
 // This class proxies the request from the client to fetch an auth code from
 // LSO. It lives on the UI thread.
 class ArcSessionManager : public ArcService,
-                          public ArcBridgeService::Observer,
+                          public ArcSessionObserver,
                           public ArcSupportHost::Observer,
                           public sync_preferences::PrefServiceSyncableObserver,
                           public sync_preferences::SyncedPrefObserver {
@@ -153,8 +154,8 @@
   void AddObserver(Observer* observer);
   void RemoveObserver(Observer* observer);
 
-  // ArcBridgeService::Observer:
-  void OnBridgeStopped(ArcBridgeService::StopReason reason) override;
+  // ArcSessionObserver:
+  void OnSessionStopped(StopReason reason) override;
 
   // Called from Arc support platform app when user cancels signing.
   void CancelAuthCode();
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader.cc b/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader.cc
index a43f395..a1302df 100644
--- a/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader.cc
+++ b/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader.cc
@@ -4,10 +4,14 @@
 
 #include "chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader.h"
 
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "base/files/file.h"
+#include "base/threading/thread_restrictions.h"
 #include "chrome/browser/chromeos/arc/fileapi/arc_file_system_instance_util.h"
 #include "content/public/browser/browser_thread.h"
 #include "mojo/edk/embedder/embedder.h"
-#include "net/base/file_stream.h"
 #include "net/base/io_buffer.h"
 #include "net/base/net_errors.h"
 
@@ -15,9 +19,19 @@
 
 namespace {
 
-void OnGetFileSize(const net::Int64CompletionCallback& callback, int64_t size) {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-  callback.Run(size < 0 ? net::ERR_FAILED : size);
+// Calls base::File::ReadAtCurrentPosNoBestEffort with the given buffer.
+int ReadFile(base::File* file,
+             scoped_refptr<net::IOBuffer> buffer,
+             int buffer_length) {
+  return file->ReadAtCurrentPosNoBestEffort(buffer->data(), buffer_length);
+}
+
+// Seeks the file, returns 0 on success, or errno on an error.
+int SeekFile(base::File* file, size_t offset) {
+  base::ThreadRestrictions::AssertIOAllowed();
+  // lseek() instead of |file|'s method for errno.
+  off_t result = lseek(file->GetPlatformFile(), offset, SEEK_SET);
+  return result < 0 ? errno : 0;
 }
 
 }  // namespace
@@ -25,24 +39,28 @@
 ArcContentFileSystemFileStreamReader::ArcContentFileSystemFileStreamReader(
     const GURL& arc_url,
     int64_t offset)
-    : arc_url_(arc_url), offset_(offset), weak_ptr_factory_(this) {}
+    : arc_url_(arc_url), offset_(offset), weak_ptr_factory_(this) {
+  auto* blocking_pool = content::BrowserThread::GetBlockingPool();
+  task_runner_ = blocking_pool->GetSequencedTaskRunnerWithShutdownBehavior(
+      blocking_pool->GetSequenceToken(),
+      base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
+}
 
-ArcContentFileSystemFileStreamReader::~ArcContentFileSystemFileStreamReader() =
-    default;
+ArcContentFileSystemFileStreamReader::~ArcContentFileSystemFileStreamReader() {
+  // Use the task runner to destruct |file_| after the completion of all
+  // in-flight operations.
+  task_runner_->PostTask(
+      FROM_HERE, base::Bind(&base::DeletePointer<base::File>, file_.release()));
+}
 
 int ArcContentFileSystemFileStreamReader::Read(
     net::IOBuffer* buffer,
     int buffer_length,
     const net::CompletionCallback& callback) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-  if (file_stream_)
-    return file_stream_->Read(buffer, buffer_length, callback);
-
-  if (offset_ != 0) {
-    // TODO(hashimoto): Handle offset_ != 0 cases.
-    NOTIMPLEMENTED() << "Non-zero offset is not supported yet: offset_ = "
-                     << offset_;
-    return net::ERR_FAILED;
+  if (file_) {
+    ReadInternal(buffer, buffer_length, callback);
+    return net::ERR_IO_PENDING;
   }
   file_system_instance_util::OpenFileToReadOnIOThread(
       arc_url_,
@@ -56,16 +74,47 @@
     const net::Int64CompletionCallback& callback) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
   file_system_instance_util::GetFileSizeOnIOThread(
-      arc_url_, base::Bind(&OnGetFileSize, callback));
+      arc_url_, base::Bind(&ArcContentFileSystemFileStreamReader::OnGetFileSize,
+                           weak_ptr_factory_.GetWeakPtr(), callback));
   return net::ERR_IO_PENDING;
 }
 
+void ArcContentFileSystemFileStreamReader::ReadInternal(
+    net::IOBuffer* buffer,
+    int buffer_length,
+    const net::CompletionCallback& callback) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+  DCHECK(file_);
+  DCHECK(file_->IsValid());
+  base::PostTaskAndReplyWithResult(
+      task_runner_.get(), FROM_HERE,
+      base::Bind(&ReadFile, file_.get(), make_scoped_refptr(buffer),
+                 buffer_length),
+      base::Bind(&ArcContentFileSystemFileStreamReader::OnRead,
+                 weak_ptr_factory_.GetWeakPtr(), callback));
+}
+
+void ArcContentFileSystemFileStreamReader::OnRead(
+    const net::CompletionCallback& callback,
+    int result) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+  callback.Run(result < 0 ? net::ERR_FAILED : result);
+}
+
+void ArcContentFileSystemFileStreamReader::OnGetFileSize(
+    const net::Int64CompletionCallback& callback,
+    int64_t size) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+  callback.Run(size < 0 ? net::ERR_FAILED : size);
+}
+
 void ArcContentFileSystemFileStreamReader::OnOpenFile(
     scoped_refptr<net::IOBuffer> buf,
     int buffer_length,
     const net::CompletionCallback& callback,
     mojo::ScopedHandle handle) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+  DCHECK(!file_);
 
   mojo::edk::ScopedPlatformHandle platform_handle;
   if (mojo::edk::PassWrappedPlatformHandle(
@@ -74,18 +123,90 @@
     callback.Run(net::ERR_FAILED);
     return;
   }
-  base::File file(platform_handle.release().handle);
-  if (!file.IsValid()) {
+  file_.reset(new base::File(platform_handle.release().handle));
+  if (!file_->IsValid()) {
     LOG(ERROR) << "Invalid file.";
     callback.Run(net::ERR_FAILED);
     return;
   }
-  file_stream_.reset(new net::FileStream(
-      std::move(file), content::BrowserThread::GetBlockingPool()));
-  // Resume Read().
-  int result = Read(buf.get(), buffer_length, callback);
-  if (result != net::ERR_IO_PENDING)
-    callback.Run(result);
+  base::PostTaskAndReplyWithResult(
+      task_runner_.get(), FROM_HERE,
+      base::Bind(&SeekFile, file_.get(), offset_),
+      base::Bind(&ArcContentFileSystemFileStreamReader::OnSeekFile,
+                 weak_ptr_factory_.GetWeakPtr(), buf, buffer_length, callback));
+}
+
+void ArcContentFileSystemFileStreamReader::OnSeekFile(
+    scoped_refptr<net::IOBuffer> buf,
+    int buffer_length,
+    const net::CompletionCallback& callback,
+    int seek_result) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+  DCHECK(file_);
+  DCHECK(file_->IsValid());
+  switch (seek_result) {
+    case 0:
+      // File stream is ready. Resume Read().
+      ReadInternal(buf.get(), buffer_length, callback);
+      break;
+    case ESPIPE: {
+      // Pipe is not seekable. Just consume the contents.
+      const size_t kTemporaryBufferSize = 1024 * 1024;
+      auto temporary_buffer =
+          make_scoped_refptr(new net::IOBufferWithSize(kTemporaryBufferSize));
+      ConsumeFileContents(buf, buffer_length, callback, temporary_buffer,
+                          offset_);
+      break;
+    }
+    default:
+      LOG(ERROR) << "Failed to seek: " << seek_result;
+      callback.Run(net::FileErrorToNetError(
+          base::File::OSErrorToFileError(seek_result)));
+  }
+}
+
+void ArcContentFileSystemFileStreamReader::ConsumeFileContents(
+    scoped_refptr<net::IOBuffer> buf,
+    int buffer_length,
+    const net::CompletionCallback& callback,
+    scoped_refptr<net::IOBufferWithSize> temporary_buffer,
+    int64_t num_bytes_to_consume) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+  DCHECK(file_);
+  DCHECK(file_->IsValid());
+  if (num_bytes_to_consume == 0) {
+    // File stream is ready. Resume Read().
+    ReadInternal(buf.get(), buffer_length, callback);
+    return;
+  }
+  auto num_bytes_to_read = std::min(
+      static_cast<int64_t>(temporary_buffer->size()), num_bytes_to_consume);
+  // TODO(hashimoto): This may block the worker thread forever. crbug.com/673222
+  base::PostTaskAndReplyWithResult(
+      task_runner_.get(), FROM_HERE,
+      base::Bind(&ReadFile, file_.get(), temporary_buffer, num_bytes_to_read),
+      base::Bind(&ArcContentFileSystemFileStreamReader::OnConsumeFileContents,
+                 weak_ptr_factory_.GetWeakPtr(), buf, buffer_length, callback,
+                 temporary_buffer, num_bytes_to_consume));
+}
+
+void ArcContentFileSystemFileStreamReader::OnConsumeFileContents(
+    scoped_refptr<net::IOBuffer> buf,
+    int buffer_length,
+    const net::CompletionCallback& callback,
+    scoped_refptr<net::IOBufferWithSize> temporary_buffer,
+    int64_t num_bytes_to_consume,
+    int read_result) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+  if (read_result < 0) {
+    LOG(ERROR) << "Failed to consume the file stream.";
+    callback.Run(net::ERR_FAILED);
+    return;
+  }
+  DCHECK_GE(num_bytes_to_consume, read_result);
+  num_bytes_to_consume -= read_result;
+  ConsumeFileContents(buf, buffer_length, callback, temporary_buffer,
+                      num_bytes_to_consume);
 }
 
 }  // namespace arc
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader.h b/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader.h
index 2d49c1e..6afb987 100644
--- a/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader.h
+++ b/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader.h
@@ -7,15 +7,21 @@
 
 #include <memory>
 
+#include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
 #include "mojo/public/cpp/system/handle.h"
 #include "net/base/completion_callback.h"
 #include "storage/browser/fileapi/file_stream_reader.h"
 #include "url/gurl.h"
 
+namespace base {
+class File;
+class SequencedTaskRunner;
+}
+
 namespace net {
-class FileStream;
 class IOBuffer;
+class IOBufferWithSize;
 }
 
 namespace arc {
@@ -33,15 +39,53 @@
   int64_t GetLength(const net::Int64CompletionCallback& callback) override;
 
  private:
+  // Actually performs read.
+  void ReadInternal(net::IOBuffer* buffer,
+                    int buffer_length,
+                    const net::CompletionCallback& callback);
+
+  // Called when read completes.
+  void OnRead(const net::CompletionCallback& callback, int result);
+
+  // Called when GetFileSize() completes.
+  void OnGetFileSize(const net::Int64CompletionCallback& callback,
+                     int64_t size);
+
+  // Called when opening file completes.
   void OnOpenFile(scoped_refptr<net::IOBuffer> buf,
                   int buffer_length,
                   const net::CompletionCallback& callback,
                   mojo::ScopedHandle handle);
 
+  // Called when seek completes.
+  void OnSeekFile(scoped_refptr<net::IOBuffer> buf,
+                  int buffer_length,
+                  const net::CompletionCallback& callback,
+                  int seek_result);
+
+  // Reads the contents of the file to reach the offset.
+  void ConsumeFileContents(
+      scoped_refptr<net::IOBuffer> buf,
+      int buffer_length,
+      const net::CompletionCallback& callback,
+      scoped_refptr<net::IOBufferWithSize> temporary_buffer,
+      int64_t num_bytes_to_consume);
+
+  // Called to handle read result for ConsumeFileContents().
+  void OnConsumeFileContents(
+      scoped_refptr<net::IOBuffer> buf,
+      int buffer_length,
+      const net::CompletionCallback& callback,
+      scoped_refptr<net::IOBufferWithSize> temporary_buffer,
+      int64_t num_bytes_to_consume,
+      int read_result);
+
   GURL arc_url_;
   int64_t offset_;
 
-  std::unique_ptr<net::FileStream> file_stream_;
+  scoped_refptr<base::SequencedTaskRunner> task_runner_;
+
+  std::unique_ptr<base::File> file_;
 
   base::WeakPtrFactory<ArcContentFileSystemFileStreamReader> weak_ptr_factory_;
 
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader_unittest.cc b/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader_unittest.cc
index db45af1..41a8862 100644
--- a/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader_unittest.cc
+++ b/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader_unittest.cc
@@ -25,9 +25,33 @@
 
 namespace {
 
-constexpr char kArcUrl[] = "content://org.chromium.foo/bar";
+// URL which returns a file descriptor of a regular file.
+constexpr char kArcUrlFile[] = "content://org.chromium.foo/file";
+
+// URL which returns a file descriptor of a pipe's read end.
+constexpr char kArcUrlPipe[] = "content://org.chromium.foo/pipe";
+
 constexpr char kData[] = "abcdefghijklmnopqrstuvwxyz";
 
+// Reads data from the reader to fill the buffer.
+bool ReadData(ArcContentFileSystemFileStreamReader* reader,
+              net::IOBufferWithSize* buffer) {
+  auto drainable_buffer =
+      make_scoped_refptr(new net::DrainableIOBuffer(buffer, buffer->size()));
+  while (drainable_buffer->BytesRemaining()) {
+    net::TestCompletionCallback callback;
+    int result = callback.GetResult(
+        reader->Read(drainable_buffer.get(), drainable_buffer->BytesRemaining(),
+                     callback.callback()));
+    if (result < 0) {
+      LOG(ERROR) << "Read failed: " << result;
+      return false;
+    }
+    drainable_buffer->DidConsume(result);
+  }
+  return true;
+}
+
 class ArcFileSystemInstanceTestImpl : public FakeFileSystemInstance {
  public:
   explicit ArcFileSystemInstanceTestImpl(const base::FilePath& file_path)
@@ -37,7 +61,7 @@
 
   void GetFileSize(const std::string& url,
                    const GetFileSizeCallback& callback) override {
-    EXPECT_EQ(kArcUrl, url);
+    EXPECT_EQ(kArcUrlFile, url);
     base::File::Info info;
     EXPECT_TRUE(base::GetFileInfo(file_path_, &info));
     base::ThreadTaskRunnerHandle::Get()->PostTask(
@@ -46,13 +70,19 @@
 
   void OpenFileToRead(const std::string& url,
                       const OpenFileToReadCallback& callback) override {
-    EXPECT_EQ(kArcUrl, url);
-
-    base::File file(file_path_, base::File::FLAG_OPEN | base::File::FLAG_READ);
-    EXPECT_TRUE(file.IsValid());
-
+    base::ScopedFD fd;
+    if (url == kArcUrlFile) {
+      fd = OpenRegularFileToRead();
+    } else if (url == kArcUrlPipe) {
+      fd = OpenPipeToRead();
+    } else {
+      LOG(ERROR) << "Unknown URL: " << url;
+      base::ThreadTaskRunnerHandle::Get()->PostTask(
+          FROM_HERE, base::Bind(callback, base::Passed(mojo::ScopedHandle())));
+      return;
+    }
     mojo::edk::ScopedPlatformHandle platform_handle(
-        mojo::edk::PlatformHandle(file.TakePlatformFile()));
+        mojo::edk::PlatformHandle(fd.release()));
     MojoHandle wrapped_handle;
     EXPECT_EQ(MOJO_RESULT_OK, mojo::edk::CreatePlatformHandleWrapper(
                                   std::move(platform_handle), &wrapped_handle));
@@ -64,6 +94,35 @@
   }
 
  private:
+  // Returns a ScopedFD to read |file_path_|.
+  base::ScopedFD OpenRegularFileToRead() {
+    base::File file(file_path_, base::File::FLAG_OPEN | base::File::FLAG_READ);
+    EXPECT_TRUE(file.IsValid());
+    return base::ScopedFD(file.TakePlatformFile());
+  }
+
+  // Returns a pipe's read end with |file_path_|'s contents written.
+  base::ScopedFD OpenPipeToRead() {
+    // Create a new pipe.
+    int fds[2];
+    if (pipe(fds) != 0) {
+      LOG(ERROR) << "pipe() failed.";
+      return base::ScopedFD();
+    }
+    base::ScopedFD fd_read(fds[0]);
+    base::ScopedFD fd_write(fds[1]);
+    // Put the file's contents to the pipe.
+    std::string contents;
+    if (!base::ReadFileToString(file_path_, &contents) ||
+        !base::WriteFileDescriptor(fd_write.get(), contents.data(),
+                                   contents.length())) {
+      LOG(ERROR) << "Failed to write the file contents to the pipe";
+      return base::ScopedFD();
+    }
+    // Return the read end.
+    return fd_read;
+  }
+
   base::FilePath file_path_;
 
   DISALLOW_COPY_AND_ASSIGN(ArcFileSystemInstanceTestImpl);
@@ -101,27 +160,44 @@
 
 }  // namespace
 
-TEST_F(ArcContentFileSystemFileStreamReaderTest, Read) {
-  ArcContentFileSystemFileStreamReader reader(GURL(kArcUrl), 0);
-
-  auto base_buffer =
-      make_scoped_refptr(new net::IOBufferWithSize(arraysize(kData)));
-  auto drainable_buffer = make_scoped_refptr(
-      new net::DrainableIOBuffer(base_buffer.get(), base_buffer->size()));
-  while (drainable_buffer->BytesRemaining()) {
-    net::TestCompletionCallback callback;
-    int result = callback.GetResult(
-        reader.Read(drainable_buffer.get(), drainable_buffer->BytesRemaining(),
-                    callback.callback()));
-    ASSERT_GT(result, 0);
-    drainable_buffer->DidConsume(result);
-  }
+TEST_F(ArcContentFileSystemFileStreamReaderTest, ReadRegularFile) {
+  ArcContentFileSystemFileStreamReader reader(GURL(kArcUrlFile), 0);
+  auto buffer = make_scoped_refptr(new net::IOBufferWithSize(arraysize(kData)));
+  EXPECT_TRUE(ReadData(&reader, buffer.get()));
   EXPECT_EQ(base::StringPiece(kData, arraysize(kData)),
-            base::StringPiece(base_buffer->data(), base_buffer->size()));
+            base::StringPiece(buffer->data(), buffer->size()));
+}
+
+TEST_F(ArcContentFileSystemFileStreamReaderTest, ReadRegularFileWithOffset) {
+  constexpr size_t kOffset = 10;
+  ArcContentFileSystemFileStreamReader reader(GURL(kArcUrlFile), kOffset);
+  auto buffer =
+      make_scoped_refptr(new net::IOBufferWithSize(arraysize(kData) - kOffset));
+  EXPECT_TRUE(ReadData(&reader, buffer.get()));
+  EXPECT_EQ(base::StringPiece(kData + kOffset, arraysize(kData) - kOffset),
+            base::StringPiece(buffer->data(), buffer->size()));
+}
+
+TEST_F(ArcContentFileSystemFileStreamReaderTest, ReadPipe) {
+  ArcContentFileSystemFileStreamReader reader(GURL(kArcUrlPipe), 0);
+  auto buffer = make_scoped_refptr(new net::IOBufferWithSize(arraysize(kData)));
+  EXPECT_TRUE(ReadData(&reader, buffer.get()));
+  EXPECT_EQ(base::StringPiece(kData, arraysize(kData)),
+            base::StringPiece(buffer->data(), buffer->size()));
+}
+
+TEST_F(ArcContentFileSystemFileStreamReaderTest, ReadPipeWithOffset) {
+  constexpr size_t kOffset = 10;
+  ArcContentFileSystemFileStreamReader reader(GURL(kArcUrlPipe), kOffset);
+  auto buffer =
+      make_scoped_refptr(new net::IOBufferWithSize(arraysize(kData) - kOffset));
+  EXPECT_TRUE(ReadData(&reader, buffer.get()));
+  EXPECT_EQ(base::StringPiece(kData + kOffset, arraysize(kData) - kOffset),
+            base::StringPiece(buffer->data(), buffer->size()));
 }
 
 TEST_F(ArcContentFileSystemFileStreamReaderTest, GetLength) {
-  ArcContentFileSystemFileStreamReader reader(GURL(kArcUrl), 0);
+  ArcContentFileSystemFileStreamReader reader(GURL(kArcUrlFile), 0);
 
   net::TestInt64CompletionCallback callback;
   EXPECT_EQ(static_cast<int64_t>(arraysize(kData)),
diff --git a/chrome/browser/chromeos/arc/notification/arc_boot_error_notification.cc b/chrome/browser/chromeos/arc/notification/arc_boot_error_notification.cc
index 59fe999..e8192dc 100644
--- a/chrome/browser/chromeos/arc/notification/arc_boot_error_notification.cc
+++ b/chrome/browser/chromeos/arc/notification/arc_boot_error_notification.cc
@@ -11,6 +11,7 @@
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/chrome_pages.h"
 #include "chrome/grit/generated_resources.h"
+#include "components/arc/arc_bridge_service.h"
 #include "components/user_manager/user_manager.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
@@ -95,11 +96,9 @@
   arc_bridge_service()->RemoveObserver(this);
 }
 
-void ArcBootErrorNotification::OnBridgeStopped(
-    ArcBridgeService::StopReason reason) {
-  if (reason == ArcBridgeService::StopReason::LOW_DISK_SPACE) {
+void ArcBootErrorNotification::OnSessionStopped(StopReason reason) {
+  if (reason == StopReason::LOW_DISK_SPACE)
     ShowLowDiskSpaceErrorNotification();
-  }
 }
 
 }  // namespace arc
diff --git a/chrome/browser/chromeos/arc/notification/arc_boot_error_notification.h b/chrome/browser/chromeos/arc/notification/arc_boot_error_notification.h
index 5d13a8ac..aa6c03dd 100644
--- a/chrome/browser/chromeos/arc/notification/arc_boot_error_notification.h
+++ b/chrome/browser/chromeos/arc/notification/arc_boot_error_notification.h
@@ -6,20 +6,19 @@
 #define CHROME_BROWSER_CHROMEOS_ARC_NOTIFICATION_ARC_BOOT_ERROR_NOTIFICATION_H_
 
 #include "base/macros.h"
-#include "components/arc/arc_bridge_service.h"
 #include "components/arc/arc_service.h"
+#include "components/arc/arc_session_observer.h"
 
 namespace arc {
 
 // Watches for ARC boot errors and show notifications.
-class ArcBootErrorNotification : public ArcService,
-                                 public ArcBridgeService::Observer {
+class ArcBootErrorNotification : public ArcService, public ArcSessionObserver {
  public:
   explicit ArcBootErrorNotification(ArcBridgeService* bridge_service);
   ~ArcBootErrorNotification() override;
 
-  // ArcBridgeService::Observer
-  void OnBridgeStopped(ArcBridgeService::StopReason reason) override;
+  // ArcSessionObserver:
+  void OnSessionStopped(StopReason reason) override;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(ArcBootErrorNotification);
diff --git a/chrome/browser/chromeos/arc/print/arc_print_service.h b/chrome/browser/chromeos/arc/print/arc_print_service.h
index 6354817..656b4dd0 100644
--- a/chrome/browser/chromeos/arc/print/arc_print_service.h
+++ b/chrome/browser/chromeos/arc/print/arc_print_service.h
@@ -22,7 +22,7 @@
   explicit ArcPrintService(ArcBridgeService* bridge_service);
   ~ArcPrintService() override;
 
-  // ArcBridgeService::Observer overrides.
+  // InstanceHolder<mojom::PrintInstance>::Observer:
   void OnInstanceReady() override;
 
   void Print(mojo::ScopedHandle pdf_data) override;
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_strings.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_strings.cc
index c59684df..045c478 100644
--- a/chrome/browser/chromeos/extensions/file_manager/private_api_strings.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/private_api_strings.cc
@@ -498,6 +498,8 @@
   SET_STRING("METADATA_BOX_DURATION", IDS_FILE_BROWSER_METADATA_BOX_DURATION);
   SET_STRING("METADATA_BOX_EXIF_DEVICE_MODEL",
              IDS_FILE_BROWSER_METADATA_BOX_EXIF_DEVICE_MODEL);
+  SET_STRING("METADATA_BOX_EXIF_DEVICE_SETTINGS",
+             IDS_FILE_BROWSER_METADATA_BOX_EXIF_DEVICE_SETTINGS);
   SET_STRING("METADATA_BOX_EXIF_GEOGRAPHY",
              IDS_FILE_BROWSER_METADATA_BOX_EXIF_GEOGRAPHY);
   SET_STRING("METADATA_BOX_FILE_PATH", IDS_FILE_BROWSER_METADATA_BOX_FILE_PATH);
diff --git a/chrome/browser/data_usage/OWNERS b/chrome/browser/data_usage/OWNERS
index 2a0ba6bb..29d852c 100644
--- a/chrome/browser/data_usage/OWNERS
+++ b/chrome/browser/data_usage/OWNERS
@@ -1,3 +1,4 @@
 bengr@chromium.org
+rajendrant@chromium.org
 sclittle@chromium.org
 tbansal@chromium.org
diff --git a/chrome/browser/media/webrtc/webrtc_browsertest_perf.cc b/chrome/browser/media/webrtc/webrtc_browsertest_perf.cc
index 3a37ad32..3d6b580b 100644
--- a/chrome/browser/media/webrtc/webrtc_browsertest_perf.cc
+++ b/chrome/browser/media/webrtc/webrtc_browsertest_perf.cc
@@ -31,9 +31,6 @@
     return;
   }
 
-  EXPECT_TRUE(pc_dict.GetString(Statistic("bytesReceived", ssrc), &value));
-  perf_test::PrintResult(
-      "audio_bytes", modifier, "bytes_recv", value, "bytes", false);
   EXPECT_TRUE(pc_dict.GetString(Statistic("packetsLost", ssrc), &value));
   perf_test::PrintResult(
       "audio_misc", modifier, "packets_lost", value, "frames", false);
@@ -64,9 +61,6 @@
     return;
   }
 
-  EXPECT_TRUE(pc_dict.GetString(Statistic("bytesSent", ssrc), &value));
-  perf_test::PrintResult(
-      "audio_bytes", modifier, "bytes_sent", value, "bytes", false);
   EXPECT_TRUE(pc_dict.GetString(Statistic("googJitterReceived", ssrc), &value));
   perf_test::PrintResult(
       "audio_tx", modifier, "goog_jitter_recv", value, "ms", false);
@@ -97,10 +91,6 @@
   perf_test::PrintResult(
       "video_fps", modifier, "goog_frame_rate_input", value, "fps", false);
 
-  EXPECT_TRUE(pc_dict.GetString(Statistic("bytesSent", ssrc), &value));
-  perf_test::PrintResult(
-      "video_total_bytes", modifier, "bytes_sent", value, "bytes", false);
-
   EXPECT_TRUE(pc_dict.GetString(Statistic("googFirsReceived", ssrc), &value));
   perf_test::PrintResult(
       "video_misc", modifier, "goog_firs_recv", value, "", false);
@@ -148,10 +138,6 @@
   perf_test::PrintResult("video_misc", modifier, "packets_lost", value,
                          "frames", false);
 
-  EXPECT_TRUE(pc_dict.GetString(Statistic("bytesReceived", ssrc), &value));
-  perf_test::PrintResult(
-      "video_total_bytes", modifier, "bytes_recv", value, "bytes", false);
-
   EXPECT_TRUE(
       pc_dict.GetString(Statistic("googFrameWidthReceived", ssrc), &value));
   perf_test::PrintResult("video_resolution", modifier, "goog_frame_width_recv",
diff --git a/chrome/browser/net/spdyproxy/OWNERS b/chrome/browser/net/spdyproxy/OWNERS
index ecec94d5..2783dea 100644
--- a/chrome/browser/net/spdyproxy/OWNERS
+++ b/chrome/browser/net/spdyproxy/OWNERS
@@ -1,6 +1 @@
-bengr@chromium.org
-kundaji@chromium.org
-megjablon@chromium.org
-ryansturm@chromium.org
-sclittle@chromium.org
-tbansal@chromium.org
\ No newline at end of file
+file://components/data_reduction_proxy/OWNERS
diff --git a/chrome/browser/ntp_tiles/OWNERS b/chrome/browser/ntp_tiles/OWNERS
new file mode 100644
index 0000000..af1328d
--- /dev/null
+++ b/chrome/browser/ntp_tiles/OWNERS
@@ -0,0 +1 @@
+file://components/ntp_tiles/OWNERS
diff --git a/chrome/browser/ntp_tiles/chrome_most_visited_sites_factory.cc b/chrome/browser/ntp_tiles/chrome_most_visited_sites_factory.cc
new file mode 100644
index 0000000..88ea6d7a
--- /dev/null
+++ b/chrome/browser/ntp_tiles/chrome_most_visited_sites_factory.cc
@@ -0,0 +1,125 @@
+// Copyright 2013 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/ntp_tiles/chrome_most_visited_sites_factory.h"
+
+#include <utility>
+
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/memory/ptr_util.h"
+#include "chrome/browser/favicon/favicon_service_factory.h"
+#include "chrome/browser/history/top_sites_factory.h"
+#include "chrome/browser/ntp_tiles/chrome_popular_sites_factory.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/search/suggestions/image_decoder_impl.h"
+#include "chrome/browser/search/suggestions/suggestions_service_factory.h"
+#include "chrome/browser/supervised_user/supervised_user_service.h"
+#include "chrome/browser/supervised_user/supervised_user_service_factory.h"
+#include "chrome/browser/supervised_user/supervised_user_service_observer.h"
+#include "chrome/browser/supervised_user/supervised_user_url_filter.h"
+#include "chrome/browser/thumbnails/thumbnail_list_source.h"
+#include "components/history/core/browser/top_sites.h"
+#include "components/image_fetcher/image_fetcher_impl.h"
+#include "components/ntp_tiles/icon_cacher.h"
+#include "components/ntp_tiles/metrics.h"
+#include "components/ntp_tiles/most_visited_sites.h"
+
+using suggestions::SuggestionsServiceFactory;
+
+namespace {
+
+class SupervisorBridge : public ntp_tiles::MostVisitedSitesSupervisor,
+                         public SupervisedUserServiceObserver {
+ public:
+  explicit SupervisorBridge(Profile* profile);
+  ~SupervisorBridge() override;
+
+  void SetObserver(Observer* observer) override;
+  bool IsBlocked(const GURL& url) override;
+  std::vector<MostVisitedSitesSupervisor::Whitelist> whitelists() override;
+  bool IsChildProfile() override;
+
+  // SupervisedUserServiceObserver implementation.
+  void OnURLFilterChanged() override;
+
+ private:
+  Profile* const profile_;
+  Observer* supervisor_observer_;
+  ScopedObserver<SupervisedUserService, SupervisedUserServiceObserver>
+      register_observer_;
+};
+
+SupervisorBridge::SupervisorBridge(Profile* profile)
+    : profile_(profile),
+      supervisor_observer_(nullptr),
+      register_observer_(this) {
+  register_observer_.Add(SupervisedUserServiceFactory::GetForProfile(profile_));
+}
+
+SupervisorBridge::~SupervisorBridge() {}
+
+void SupervisorBridge::SetObserver(Observer* new_observer) {
+  if (new_observer) {
+    DCHECK(!supervisor_observer_);
+  } else {
+    DCHECK(supervisor_observer_);
+  }
+
+  supervisor_observer_ = new_observer;
+}
+
+bool SupervisorBridge::IsBlocked(const GURL& url) {
+  SupervisedUserService* supervised_user_service =
+      SupervisedUserServiceFactory::GetForProfile(profile_);
+  auto* url_filter = supervised_user_service->GetURLFilterForUIThread();
+  return url_filter->GetFilteringBehaviorForURL(url) ==
+         SupervisedUserURLFilter::FilteringBehavior::BLOCK;
+}
+
+std::vector<ntp_tiles::MostVisitedSitesSupervisor::Whitelist>
+SupervisorBridge::whitelists() {
+  std::vector<MostVisitedSitesSupervisor::Whitelist> results;
+  SupervisedUserService* supervised_user_service =
+      SupervisedUserServiceFactory::GetForProfile(profile_);
+  for (const auto& whitelist : supervised_user_service->whitelists()) {
+    results.emplace_back(Whitelist{
+        whitelist->title(), whitelist->entry_point(),
+        whitelist->large_icon_path(),
+    });
+  }
+  return results;
+}
+
+bool SupervisorBridge::IsChildProfile() {
+  return profile_->IsChild();
+}
+
+void SupervisorBridge::OnURLFilterChanged() {
+  if (supervisor_observer_) {
+    supervisor_observer_->OnBlockedSitesChanged();
+  }
+}
+
+}  // namespace
+
+// static
+std::unique_ptr<ntp_tiles::MostVisitedSites>
+ChromeMostVisitedSitesFactory::NewForProfile(Profile* profile) {
+  return base::MakeUnique<ntp_tiles::MostVisitedSites>(
+      profile->GetPrefs(), TopSitesFactory::GetForProfile(profile),
+      SuggestionsServiceFactory::GetForProfile(profile),
+#if defined(OS_ANDROID)
+      ChromePopularSitesFactory::NewForProfile(profile),
+#else
+      nullptr,
+#endif
+      base::MakeUnique<ntp_tiles::IconCacher>(
+          FaviconServiceFactory::GetForProfile(
+              profile, ServiceAccessType::IMPLICIT_ACCESS),
+          base::MakeUnique<image_fetcher::ImageFetcherImpl>(
+              base::MakeUnique<suggestions::ImageDecoderImpl>(),
+              profile->GetRequestContext())),
+      base::MakeUnique<SupervisorBridge>(profile));
+}
diff --git a/chrome/browser/ntp_tiles/chrome_most_visited_sites_factory.h b/chrome/browser/ntp_tiles/chrome_most_visited_sites_factory.h
new file mode 100644
index 0000000..2ceec1b
--- /dev/null
+++ b/chrome/browser/ntp_tiles/chrome_most_visited_sites_factory.h
@@ -0,0 +1,24 @@
+// 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 CHROME_BROWSER_NTP_TILES_CHROME_MOST_VISITED_SITES_FACTORY_H_
+#define CHROME_BROWSER_NTP_TILES_CHROME_MOST_VISITED_SITES_FACTORY_H_
+
+#include <memory>
+
+class Profile;
+
+namespace ntp_tiles {
+class MostVisitedSites;
+}  // namespace ntp_tiles
+
+class ChromeMostVisitedSitesFactory {
+ public:
+  static std::unique_ptr<ntp_tiles::MostVisitedSites> NewForProfile(
+      Profile* profile);
+
+  ChromeMostVisitedSitesFactory() = delete;
+};
+
+#endif  // CHROME_BROWSER_NTP_TILES_CHROME_MOST_VISITED_SITES_FACTORY_H_
diff --git a/chrome/browser/android/ntp/popular_sites.cc b/chrome/browser/ntp_tiles/chrome_popular_sites_factory.cc
similarity index 85%
rename from chrome/browser/android/ntp/popular_sites.cc
rename to chrome/browser/ntp_tiles/chrome_popular_sites_factory.cc
index 3413ce4..0970f35 100644
--- a/chrome/browser/android/ntp/popular_sites.cc
+++ b/chrome/browser/ntp_tiles/chrome_popular_sites_factory.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/android/ntp/popular_sites.h"
+#include "chrome/browser/ntp_tiles/chrome_popular_sites_factory.h"
 
 #include "base/bind.h"
 #include "base/memory/ptr_util.h"
@@ -15,8 +15,8 @@
 #include "components/safe_json/safe_json_parser.h"
 #include "content/public/browser/browser_thread.h"
 
-std::unique_ptr<ntp_tiles::PopularSites> ChromePopularSites::NewForProfile(
-    Profile* profile) {
+std::unique_ptr<ntp_tiles::PopularSites>
+ChromePopularSitesFactory::NewForProfile(Profile* profile) {
   base::FilePath directory;  // remains empty if PathService::Get() fails.
   PathService::Get(chrome::DIR_USER_DATA, &directory);
   return base::MakeUnique<ntp_tiles::PopularSites>(
diff --git a/chrome/browser/ntp_tiles/chrome_popular_sites_factory.h b/chrome/browser/ntp_tiles/chrome_popular_sites_factory.h
new file mode 100644
index 0000000..97c355f
--- /dev/null
+++ b/chrome/browser/ntp_tiles/chrome_popular_sites_factory.h
@@ -0,0 +1,24 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_NTP_TILES_CHROME_POPULAR_SITES_FACTORY_H_
+#define CHROME_BROWSER_NTP_TILES_CHROME_POPULAR_SITES_FACTORY_H_
+
+#include <memory>
+
+class Profile;
+
+namespace ntp_tiles {
+class PopularSites;
+}  // namespace ntp_tiles
+
+class ChromePopularSitesFactory {
+ public:
+  static std::unique_ptr<ntp_tiles::PopularSites> NewForProfile(
+      Profile* profile);
+
+  ChromePopularSitesFactory() = delete;
+};
+
+#endif  // CHROME_BROWSER_NTP_TILES_CHROME_POPULAR_SITES_FACTORY_H_
diff --git a/chrome/browser/resources/options/password_manager.js b/chrome/browser/resources/options/password_manager.js
index 6263595f..8322b5f 100644
--- a/chrome/browser/resources/options/password_manager.js
+++ b/chrome/browser/resources/options/password_manager.js
@@ -171,56 +171,6 @@
     },
 
     /**
-     * Updates eliding of origins. If there is no enough space to show the full
-     * origin, the origin is elided from the left with ellipsis.
-     * @param {!cr.ui.List} list The list to update eliding.
-     */
-    updateOriginsEliding_: function(list) {
-      var entries = list.getElementsByClassName('deletable-item');
-      if (entries.length == 0)
-        return;
-      var entry = entries[0];
-      var computedStyle = window.getComputedStyle(entry.urlDiv);
-      var columnWidth = entry.urlDiv.offsetWidth -
-          parseInt(computedStyle.webkitMarginStart, 10) -
-          parseInt(computedStyle.webkitPaddingStart, 10);
-
-      // We use a canvas context to compute text widths. This canvas is not
-      // part of the DOM and thus avoids layout thrashing when updating the
-      // contained text.
-      var canvas = document.createElement('canvas');
-      var ctx = canvas.getContext('2d');
-      ctx.font = computedStyle.font;
-
-      for (var i = 0; i < entries.length; ++i) {
-        entry = entries[i];
-        // For android://com.example, elide from the right.
-        if (!entry.isClickable)
-          continue;
-        var cellWidth = columnWidth;
-        if (entry.androidUriSuffix)
-          cellWidth -= entry.androidUriSuffix.offsetWidth;
-        var urlLink = entry.urlLink;
-        if (cellWidth <= 0) {
-          console.error('cellWidth <= 0. Skip origins eliding for ' +
-              urlLink.textContent);
-          continue;
-        }
-
-        var textContent = urlLink.textContent;
-        if (ctx.measureText(textContent).width <= cellWidth)
-          continue;
-
-        textContent = '…' + textContent.substring(1);
-        while (ctx.measureText(textContent).width > cellWidth)
-          textContent = '…' + textContent.substring(2);
-
-        // Write the elided origin back to the DOM.
-        urlLink.textContent = textContent;
-      }
-    },
-
-    /**
      * Updates the data model for the saved passwords list with the values from
      * |entries|.
      * @param {!Array} entries The list of saved password data.
@@ -247,9 +197,6 @@
       }
       this.savedPasswordsList_.dataModel = new ArrayDataModel(entries);
       this.updateListVisibility_(this.savedPasswordsList_);
-      // updateOriginsEliding_ should be called after updateListVisibility_,
-      // otherwise updateOrigins... might be not able to read width of elements.
-      this.updateOriginsEliding_(this.savedPasswordsList_);
     },
 
     /**
@@ -260,9 +207,6 @@
     setPasswordExceptionsList_: function(entries) {
       this.passwordExceptionsList_.dataModel = new ArrayDataModel(entries);
       this.updateListVisibility_(this.passwordExceptionsList_);
-      // updateOriginsEliding_ should be called after updateListVisibility_,
-      // otherwise updateOrigins... might be not able to read width of elements.
-      this.updateOriginsEliding_(this.passwordExceptionsList_);
     },
 
     /**
diff --git a/chrome/browser/resources/options/password_manager_list.css b/chrome/browser/resources/options/password_manager_list.css
index 43f7d607..5deae35 100644
--- a/chrome/browser/resources/options/password_manager_list.css
+++ b/chrome/browser/resources/options/password_manager_list.css
@@ -71,3 +71,25 @@
   overflow: hidden;
   text-overflow: ellipsis;
 }
+
+html[dir='ltr'] #saved-passwords-list .url,
+html[dir='ltr'] #password-exceptions-list .url {
+  -webkit-margin-end: 1em;
+  -webkit-margin-start: 0;
+  -webkit-padding-end: 2em;
+  -webkit-padding-start: 1em;
+  direction: rtl;
+  text-align: left;
+}
+
+html[dir='rtl'] #saved-passwords-list .url,
+html[dir='rtl'] #password-exceptions-list .url {
+  -webkit-margin-end: 0;
+  -webkit-margin-start: 1em;
+  -webkit-padding-end: 1em;
+  -webkit-padding-start: 2em;
+  /* Explicitly mention the direction, which, while the same, is independent of
+   * the surrounding text the for URLs. */
+  direction: rtl;
+  text-align: right;
+}
diff --git a/chrome/browser/resources/options/password_manager_list.js b/chrome/browser/resources/options/password_manager_list.js
index 720efb7c..9fd160f 100644
--- a/chrome/browser/resources/options/password_manager_list.js
+++ b/chrome/browser/resources/options/password_manager_list.js
@@ -76,7 +76,6 @@
       urlLink = item.ownerDocument.createElement('a');
       urlLink.href = item.url;
       urlLink.setAttribute('target', '_blank');
-      urlLink.dir = 'ltr';
     } else {
       urlLink = item.ownerDocument.createElement('span');
     }
@@ -97,7 +96,7 @@
     var urlDiv = cr.doc.createElement('div');
     urlDiv.className = 'favicon-cell url';
     urlDiv.setAttribute('title', getTitleForPasswordOrigin(item));
-    urlDiv.style.backgroundImage = cr.icon.getFavicon('origin/' + item.url);
+    urlDiv.style.backgroundImage = cr.icon.getFavicon(item.url);
 
     item.urlLink = createUrlLink(item, urlDiv);
     urlDiv.appendChild(item.urlLink);
diff --git a/chrome/browser/search/instant_service.cc b/chrome/browser/search/instant_service.cc
index c897a96..3d5863d 100644
--- a/chrome/browser/search/instant_service.cc
+++ b/chrome/browser/search/instant_service.cc
@@ -14,6 +14,7 @@
 #include "chrome/browser/favicon/favicon_service_factory.h"
 #include "chrome/browser/favicon/large_icon_service_factory.h"
 #include "chrome/browser/history/top_sites_factory.h"
+#include "chrome/browser/ntp_tiles/chrome_most_visited_sites_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/search/instant_io_context.h"
 #include "chrome/browser/search/instant_service_observer.h"
@@ -100,20 +101,8 @@
                  content::NotificationService::AllSources());
 
   if (base::FeatureList::IsEnabled(kNtpTilesFeature)) {
-    most_visited_sites_ = base::MakeUnique<ntp_tiles::MostVisitedSites>(
-        profile_->GetPrefs(), TopSitesFactory::GetForProfile(profile_),
-        suggestions::SuggestionsServiceFactory::GetForProfile(profile_),
-        /*popular_sites=*/nullptr,
-        base::MakeUnique<ntp_tiles::IconCacher>(
-            FaviconServiceFactory::GetForProfile(
-                profile, ServiceAccessType::IMPLICIT_ACCESS),
-            base::MakeUnique<image_fetcher::ImageFetcherImpl>(
-                base::MakeUnique<suggestions::ImageDecoderImpl>(),
-                profile->GetRequestContext())),
-        /*supervisor=*/nullptr);
-    // TODO(treib): Add supervisor.
-    // TODO(sfiera): Share this with Android in a factory.
-
+    most_visited_sites_ =
+        ChromeMostVisitedSitesFactory::NewForProfile(profile_);
     most_visited_sites_->SetMostVisitedURLsObserver(this, 8);
   } else {
     top_sites_ = TopSitesFactory::GetForProfile(profile_);
diff --git a/chrome/browser/sync/glue/extensions_activity_monitor.cc b/chrome/browser/sync/glue/extensions_activity_monitor.cc
index 60d2284a..bb48f56c 100644
--- a/chrome/browser/sync/glue/extensions_activity_monitor.cc
+++ b/chrome/browser/sync/glue/extensions_activity_monitor.cc
@@ -47,6 +47,9 @@
   DCHECK_EQ(extensions::NOTIFICATION_EXTENSION_BOOKMARKS_API_INVOKED, type);
   const extensions::Extension* extension =
       content::Source<const extensions::Extension>(source).ptr();
+  if (!extension)
+    return;
+
   const extensions::BookmarksFunction* f =
       content::Details<const extensions::BookmarksFunction>(details).ptr();
   switch (f->histogram_value()) {
diff --git a/chrome/browser/ui/webui/ntp_tiles_internals_ui.cc b/chrome/browser/ui/webui/ntp_tiles_internals_ui.cc
index cfaf580..6f705979 100644
--- a/chrome/browser/ui/webui/ntp_tiles_internals_ui.cc
+++ b/chrome/browser/ui/webui/ntp_tiles_internals_ui.cc
@@ -8,6 +8,8 @@
 #include "base/memory/ptr_util.h"
 #include "chrome/browser/favicon/favicon_service_factory.h"
 #include "chrome/browser/history/top_sites_factory.h"
+#include "chrome/browser/ntp_tiles/chrome_most_visited_sites_factory.h"
+#include "chrome/browser/ntp_tiles/chrome_popular_sites_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/search/suggestions/image_decoder_impl.h"
 #include "chrome/browser/search/suggestions/suggestions_service_factory.h"
@@ -26,10 +28,6 @@
 #include "content/public/browser/web_ui_data_source.h"
 #include "content/public/browser/web_ui_message_handler.h"
 
-#if defined(OS_ANDROID)
-#include "chrome/browser/android/ntp/popular_sites.h"
-#endif
-
 namespace {
 
 // The implementation for the chrome://ntp-tiles-internals page.
@@ -69,16 +67,12 @@
   switch (source) {
     case ntp_tiles::NTPTileSource::TOP_SITES:
     case ntp_tiles::NTPTileSource::SUGGESTIONS_SERVICE:
-      return true;
-#if defined(OS_ANDROID)
-    case ntp_tiles::NTPTileSource::POPULAR:
     case ntp_tiles::NTPTileSource::WHITELIST:
       return true;
+    case ntp_tiles::NTPTileSource::POPULAR:
+#if defined(OS_ANDROID)
+      return true;
 #else
-    case ntp_tiles::NTPTileSource::POPULAR:
-      return false;
-    case ntp_tiles::NTPTileSource::WHITELIST:
-      // TODO(sfiera): support WHITELIST.
       return false;
 #endif
   }
@@ -88,25 +82,14 @@
 
 std::unique_ptr<ntp_tiles::MostVisitedSites>
 ChromeNTPTilesInternalsMessageHandlerClient::MakeMostVisitedSites() {
-  // TODO(sfiera): share with Android and Instant in a factory.
-  auto* profile = Profile::FromWebUI(web_ui());
-  return base::MakeUnique<ntp_tiles::MostVisitedSites>(
-      GetPrefs(), TopSitesFactory::GetForProfile(profile),
-      suggestions::SuggestionsServiceFactory::GetForProfile(profile),
-      MakePopularSites(),
-      base::MakeUnique<ntp_tiles::IconCacher>(
-          FaviconServiceFactory::GetForProfile(
-              profile, ServiceAccessType::IMPLICIT_ACCESS),
-          base::MakeUnique<image_fetcher::ImageFetcherImpl>(
-              base::MakeUnique<suggestions::ImageDecoderImpl>(),
-              profile->GetRequestContext())),
-      /*supervisor=*/nullptr);
+  return ChromeMostVisitedSitesFactory::NewForProfile(
+      Profile::FromWebUI(web_ui()));
 }
 
 std::unique_ptr<ntp_tiles::PopularSites>
 ChromeNTPTilesInternalsMessageHandlerClient::MakePopularSites() {
 #if defined(OS_ANDROID)
-  return ChromePopularSites::NewForProfile(Profile::FromWebUI(web_ui()));
+  return ChromePopularSitesFactory::NewForProfile(Profile::FromWebUI(web_ui()));
 #else
   return nullptr;
 #endif
diff --git a/chrome/browser/ui/webui/popular_sites_internals_ui.cc b/chrome/browser/ui/webui/popular_sites_internals_ui.cc
index 4deae00..daf09e3 100644
--- a/chrome/browser/ui/webui/popular_sites_internals_ui.cc
+++ b/chrome/browser/ui/webui/popular_sites_internals_ui.cc
@@ -4,7 +4,7 @@
 
 #include "chrome/browser/ui/webui/popular_sites_internals_ui.h"
 
-#include "chrome/browser/android/ntp/popular_sites.h"
+#include "chrome/browser/ntp_tiles/chrome_popular_sites_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/common/url_constants.h"
 #include "components/grit/components_resources.h"
@@ -56,7 +56,7 @@
 
 std::unique_ptr<ntp_tiles::PopularSites>
 ChromePopularSitesInternalsMessageHandlerBridge::MakePopularSites() {
-  return ChromePopularSites::NewForProfile(Profile::FromWebUI(web_ui()));
+  return ChromePopularSitesFactory::NewForProfile(Profile::FromWebUI(web_ui()));
 }
 
 PrefService* ChromePopularSitesInternalsMessageHandlerBridge::GetPrefs() {
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index cb985991..ad2727b5 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -425,12 +425,6 @@
 // (see SettingsWindowEnabled() below).
 const char kEnableSettingsWindow[]           = "enable-settings-window";
 
-// Enable the Site Engagement App Banner which triggers app install banners
-// using the site engagement service rather than a navigation-based heuristic.
-// Implicitly enables the site engagement service.
-const char kEnableSiteEngagementAppBanner[] =
-    "enable-site-engagement-app-banner";
-
 // Enable the Site Engagement Eviction Policy which evicts temporary storage
 // using the site engagement service. Implicitly enables the site engagement
 // service.
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index efcf7e7..92df33b 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -134,7 +134,6 @@
 extern const char kEnableQuic[];
 extern const char kEnableSaveAsMenuLabelExperiment[];
 extern const char kEnableSettingsWindow[];
-extern const char kEnableSiteEngagementAppBanner[];
 extern const char kEnableSiteEngagementEvictionPolicy[];
 extern const char kEnableSiteSettings[];
 extern const char kEnableSupervisedUserManagedBookmarksFolder[];
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/TabLoadObserver.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/TabLoadObserver.java
index f14c28e..11efcc21 100644
--- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/TabLoadObserver.java
+++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/TabLoadObserver.java
@@ -15,6 +15,7 @@
 import org.chromium.content.browser.test.util.Criteria;
 import org.chromium.content.browser.test.util.CriteriaHelper;
 import org.chromium.content_public.browser.LoadUrlParams;
+import org.chromium.ui.base.PageTransition;
 
 import java.util.Locale;
 
@@ -63,10 +64,20 @@
      * @param url URL to load and wait for.
      */
     public void fullyLoadUrl(final String url) throws Exception {
+        fullyLoadUrl(url, PageTransition.LINK);
+    }
+
+    /**
+     * Loads the given URL and waits for it to complete.
+     *
+     * @param url            URL to load and wait for.
+     * @param transitionType the transition type to use.
+     */
+    public void fullyLoadUrl(final String url, final int transitionType) throws Exception {
         ThreadUtils.runOnUiThread(new Runnable() {
             @Override
             public void run() {
-                mTab.loadUrl(new LoadUrlParams(url));
+                mTab.loadUrl(new LoadUrlParams(url, transitionType));
             }
         });
         assertLoaded();
diff --git a/chrome/test/data/banners/prompt_in_handler_test_page.html b/chrome/test/data/banners/prompt_in_handler_test_page.html
index ae1ed7612..8275f24 100644
--- a/chrome/test/data/banners/prompt_in_handler_test_page.html
+++ b/chrome/test/data/banners/prompt_in_handler_test_page.html
@@ -5,10 +5,7 @@
     <script src="main.js"></script>
     <script>
       window.addEventListener('beforeinstallprompt', function(e) {
-        console.log('Preventing banner from appearing');
         e.preventDefault();
-
-        console.log('Re-prompt banner');
         e.prompt();
       });
     </script>
diff --git a/chrome/test/data/banners/prompt_test_page.html b/chrome/test/data/banners/prompt_test_page.html
index b460e200..095add6 100644
--- a/chrome/test/data/banners/prompt_test_page.html
+++ b/chrome/test/data/banners/prompt_test_page.html
@@ -5,14 +5,11 @@
     <script src="main.js"></script>
     <script>
       function callPrompt(event) {
-        console.log('Re-prompt banner');
         event.prompt();
       }
 
       window.addEventListener('beforeinstallprompt', function(e) {
-        console.log('Preventing banner from appearing');
         e.preventDefault();
-
         setTimeout(callPrompt, 0, e);
       });
 
diff --git a/chrome/test/data/chromeproxy/OWNERS b/chrome/test/data/chromeproxy/OWNERS
index 4e641323..ba99b00 100644
--- a/chrome/test/data/chromeproxy/OWNERS
+++ b/chrome/test/data/chromeproxy/OWNERS
@@ -1,3 +1,2 @@
 bustamante@chromium.org
-kundaji@chromium.org
 bengr@chromium.org
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM
index b75463c4..c687dff 100644
--- a/chromeos/CHROMEOS_LKGM
+++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@
-9079.0.0
\ No newline at end of file
+9083.0.0
\ No newline at end of file
diff --git a/components/arc/BUILD.gn b/components/arc/BUILD.gn
index 155d286..9081811c 100644
--- a/components/arc/BUILD.gn
+++ b/components/arc/BUILD.gn
@@ -104,6 +104,8 @@
     "arc_bridge_service.h",
     "arc_service.cc",
     "arc_service.h",
+    "arc_session_observer.cc",
+    "arc_session_observer.h",
     "instance_holder.h",
   ]
 
diff --git a/components/arc/arc_bridge_service.cc b/components/arc/arc_bridge_service.cc
index b9b5d925..73c96d8 100644
--- a/components/arc/arc_bridge_service.cc
+++ b/components/arc/arc_bridge_service.cc
@@ -23,7 +23,7 @@
 
 ArcBridgeService::ArcBridgeService()
     : state_(State::STOPPED),
-      stop_reason_(StopReason::SHUTDOWN),
+      stop_reason_(ArcSessionObserver::StopReason::SHUTDOWN),
       weak_factory_(this) {}
 
 ArcBridgeService::~ArcBridgeService() {
@@ -55,12 +55,12 @@
   NOTREACHED();
 }
 
-void ArcBridgeService::AddObserver(Observer* observer) {
+void ArcBridgeService::AddObserver(ArcSessionObserver* observer) {
   DCHECK(CalledOnValidThread());
   observer_list_.AddObserver(observer);
 }
 
-void ArcBridgeService::RemoveObserver(Observer* observer) {
+void ArcBridgeService::RemoveObserver(ArcSessionObserver* observer) {
   DCHECK(CalledOnValidThread());
   observer_list_.RemoveObserver(observer);
 }
@@ -72,14 +72,15 @@
   VLOG(2) << "State: " << static_cast<uint32_t>(state_);
   if (state_ == State::READY) {
     for (auto& observer : observer_list())
-      observer.OnBridgeReady();
+      observer.OnSessionReady();
   } else if (state == State::STOPPED) {
     for (auto& observer : observer_list())
-      observer.OnBridgeStopped(stop_reason_);
+      observer.OnSessionStopped(stop_reason_);
   }
 }
 
-void ArcBridgeService::SetStopReason(StopReason stop_reason) {
+void ArcBridgeService::SetStopReason(
+    ArcSessionObserver::StopReason stop_reason) {
   DCHECK(CalledOnValidThread());
   stop_reason_ = stop_reason;
 }
@@ -88,22 +89,4 @@
   return thread_checker_.CalledOnValidThread();
 }
 
-std::ostream& operator<<(
-    std::ostream& os, ArcBridgeService::StopReason reason) {
-  switch (reason) {
-#define CASE_IMPL(val) \
-    case ArcBridgeService::StopReason::val: \
-      return os << #val
-
-    CASE_IMPL(SHUTDOWN);
-    CASE_IMPL(GENERIC_BOOT_FAILURE);
-    CASE_IMPL(LOW_DISK_SPACE);
-    CASE_IMPL(CRASH);
-#undef CASE_IMPL
-  }
-
-  // In case of unexpected value, output the int value.
-  return os << "StopReason(" << static_cast<int>(reason) << ")";
-}
-
 }  // namespace arc
diff --git a/components/arc/arc_bridge_service.h b/components/arc/arc_bridge_service.h
index d05bd75e..6485221 100644
--- a/components/arc/arc_bridge_service.h
+++ b/components/arc/arc_bridge_service.h
@@ -14,6 +14,7 @@
 #include "base/macros.h"
 #include "base/observer_list.h"
 #include "base/values.h"
+#include "components/arc/arc_session_observer.h"
 #include "components/arc/instance_holder.h"
 
 namespace base {
@@ -60,34 +61,6 @@
 // communication channel (the ARC bridge) used to send and receive messages.
 class ArcBridgeService {
  public:
-  // Describes the reason the bridge is stopped.
-  enum class StopReason {
-    // ARC instance has been gracefully shut down.
-    SHUTDOWN,
-
-    // Errors occurred during the ARC instance boot. This includes any failures
-    // before the instance is actually attempted to be started, and also
-    // failures on bootstrapping IPC channels with Android.
-    GENERIC_BOOT_FAILURE,
-
-    // The device is critically low on disk space.
-    LOW_DISK_SPACE,
-
-    // ARC instance has crashed.
-    CRASH,
-  };
-
-  // Notifies life cycle events of ArcBridgeService.
-  class Observer {
-   public:
-    // Called whenever the state of the bridge has changed.
-    virtual void OnBridgeReady() {}
-    virtual void OnBridgeStopped(StopReason reason) {}
-
-   protected:
-    virtual ~Observer() {}
-  };
-
   ArcBridgeService();
   virtual ~ArcBridgeService();
 
@@ -117,8 +90,8 @@
   // Adds or removes observers. This can only be called on the thread that this
   // class was created on. RemoveObserver does nothing if |observer| is not in
   // the list.
-  void AddObserver(Observer* observer);
-  void RemoveObserver(Observer* observer);
+  void AddObserver(ArcSessionObserver* observer);
+  void RemoveObserver(ArcSessionObserver* observer);
 
   InstanceHolder<mojom::AppInstance>* app() { return &app_; }
   InstanceHolder<mojom::AudioInstance>* audio() { return &audio_; }
@@ -239,9 +212,11 @@
   // Sets the reason the bridge is stopped. This function must be always called
   // before SetState(State::STOPPED) to report a correct reason with
   // Observer::OnBridgeStopped().
-  void SetStopReason(StopReason stop_reason);
+  void SetStopReason(ArcSessionObserver::StopReason stop_reason);
 
-  base::ObserverList<Observer>& observer_list() { return observer_list_; }
+  base::ObserverList<ArcSessionObserver>& observer_list() {
+    return observer_list_;
+  }
 
   bool CalledOnValidThread();
 
@@ -254,7 +229,7 @@
   FRIEND_TEST_ALL_PREFIXES(ArcBridgeTest, OnBridgeStopped);
   FRIEND_TEST_ALL_PREFIXES(ArcBridgeTest, Shutdown);
 
-  base::ObserverList<Observer> observer_list_;
+  base::ObserverList<ArcSessionObserver> observer_list_;
 
   base::ThreadChecker thread_checker_;
 
@@ -262,7 +237,7 @@
   ArcBridgeService::State state_;
 
   // The reason the bridge is stopped.
-  StopReason stop_reason_;
+  ArcSessionObserver::StopReason stop_reason_;
 
   // WeakPtrFactory to use callbacks.
   base::WeakPtrFactory<ArcBridgeService> weak_factory_;
@@ -270,10 +245,6 @@
   DISALLOW_COPY_AND_ASSIGN(ArcBridgeService);
 };
 
-// Defines "<<" operator for LOGging purpose.
-std::ostream& operator<<(
-    std::ostream& os, ArcBridgeService::StopReason reason);
-
 }  // namespace arc
 
 #endif  // COMPONENTS_ARC_ARC_BRIDGE_SERVICE_H_
diff --git a/components/arc/arc_bridge_service_impl.cc b/components/arc/arc_bridge_service_impl.cc
index f3efcade..fbc8f0b 100644
--- a/components/arc/arc_bridge_service_impl.cc
+++ b/components/arc/arc_bridge_service_impl.cc
@@ -17,6 +17,7 @@
 #include "chromeos/chromeos_switches.h"
 #include "chromeos/dbus/dbus_method_call_status.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
+#include "components/arc/arc_session.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
 
@@ -119,7 +120,7 @@
   arc_session_->Stop();
 }
 
-void ArcBridgeServiceImpl::OnReady() {
+void ArcBridgeServiceImpl::OnSessionReady() {
   DCHECK(CalledOnValidThread());
   if (state() != State::CONNECTING) {
     VLOG(1) << "StopInstance() called while connecting";
@@ -133,7 +134,7 @@
   SetState(State::READY);
 }
 
-void ArcBridgeServiceImpl::OnStopped(StopReason stop_reason) {
+void ArcBridgeServiceImpl::OnSessionStopped(StopReason stop_reason) {
   DCHECK(CalledOnValidThread());
   VLOG(0) << "ARC stopped: " << stop_reason;
   arc_session_->RemoveObserver(this);
diff --git a/components/arc/arc_bridge_service_impl.h b/components/arc/arc_bridge_service_impl.h
index 5ad9629e2..30e19e4c 100644
--- a/components/arc/arc_bridge_service_impl.h
+++ b/components/arc/arc_bridge_service_impl.h
@@ -15,14 +15,16 @@
 #include "base/memory/ref_counted.h"
 #include "base/task_runner.h"
 #include "components/arc/arc_bridge_service.h"
-#include "components/arc/arc_session.h"
+#include "components/arc/arc_session_observer.h"
 #include "mojo/public/cpp/bindings/binding.h"
 
 namespace arc {
 
+class ArcSession;
+
 // Real IPC based ArcBridgeService that is used in production.
 class ArcBridgeServiceImpl : public ArcBridgeService,
-                             public ArcSession::Observer {
+                             public ArcSessionObserver {
  public:
   // This is the factory interface to inject ArcSession instance
   // for testing purpose.
@@ -62,9 +64,9 @@
   // Stops the running instance.
   void StopInstance();
 
-  // ArcSession::Observer:
-  void OnReady() override;
-  void OnStopped(StopReason reason) override;
+  // ArcSessionObserver:
+  void OnSessionReady() override;
+  void OnSessionStopped(StopReason reason) override;
 
   std::unique_ptr<ArcSession> arc_session_;
 
diff --git a/components/arc/arc_bridge_service_unittest.cc b/components/arc/arc_bridge_service_unittest.cc
index e0ab45d..0b5aec2 100644
--- a/components/arc/arc_bridge_service_unittest.cc
+++ b/components/arc/arc_bridge_service_unittest.cc
@@ -20,23 +20,22 @@
 
 namespace {
 
-class DummyObserver : public ArcBridgeService::Observer {};
+class DummyObserver : public ArcSessionObserver {};
 
 }  // namespace
 
 // TODO(hidehiko): ArcBridgeTest gets complicated and has stale code.
 // Simplify the code.
-class ArcBridgeTest : public testing::Test,
-                      public ArcBridgeService::Observer {
+class ArcBridgeTest : public testing::Test, public ArcSessionObserver {
  public:
   ArcBridgeTest() = default;
 
-  void OnBridgeReady() override {
+  void OnSessionReady() override {
     state_ = ArcBridgeService::State::READY;
     ready_ = true;
   }
 
-  void OnBridgeStopped(ArcBridgeService::StopReason stop_reason) override {
+  void OnSessionStopped(StopReason stop_reason) override {
     // The instance is already destructed in ArcBridgeServiceImpl::OnStopped().
     state_ = ArcBridgeService::State::STOPPED;
     stop_reason_ = stop_reason;
@@ -52,7 +51,7 @@
 
  protected:
   std::unique_ptr<ArcBridgeServiceImpl> service_;
-  ArcBridgeService::StopReason stop_reason_;
+  StopReason stop_reason_;
 
   static std::unique_ptr<ArcSession> CreateSuspendedArcSession() {
     auto arc_session = base::MakeUnique<FakeArcSession>();
@@ -61,7 +60,7 @@
   }
 
   static std::unique_ptr<ArcSession> CreateBootFailureArcSession(
-      ArcBridgeService::StopReason reason) {
+      StopReason reason) {
     auto arc_session = base::MakeUnique<FakeArcSession>();
     arc_session->EnableBootFailureEmulation(reason);
     return std::move(arc_session);
@@ -73,7 +72,7 @@
 
     ready_ = false;
     state_ = ArcBridgeService::State::STOPPED;
-    stop_reason_ = ArcBridgeService::StopReason::SHUTDOWN;
+    stop_reason_ = StopReason::SHUTDOWN;
 
     // We inject FakeArcSession here so we do not need task_runner.
     service_.reset(new ArcBridgeServiceImpl(nullptr));
@@ -131,9 +130,9 @@
 
   service_->SetArcSessionFactoryForTesting(
       base::Bind(ArcBridgeTest::CreateBootFailureArcSession,
-                 ArcBridgeService::StopReason::GENERIC_BOOT_FAILURE));
+                 StopReason::GENERIC_BOOT_FAILURE));
   service_->RequestStart();
-  EXPECT_EQ(ArcBridgeService::StopReason::GENERIC_BOOT_FAILURE, stop_reason_);
+  EXPECT_EQ(StopReason::GENERIC_BOOT_FAILURE, stop_reason_);
   ASSERT_TRUE(service_->stopped());
 }
 
@@ -147,7 +146,7 @@
   // Simulate a connection loss.
   service_->DisableReconnectDelayForTesting();
   ASSERT_TRUE(arc_session());
-  arc_session()->StopWithReason(ArcBridgeService::StopReason::CRASH);
+  arc_session()->StopWithReason(StopReason::CRASH);
   ASSERT_TRUE(service_->ready());
 
   service_->RequestStop();
@@ -164,20 +163,19 @@
 
   // Simulate boot failure.
   ASSERT_TRUE(arc_session());
-  arc_session()->StopWithReason(
-      ArcBridgeService::StopReason::GENERIC_BOOT_FAILURE);
-  EXPECT_EQ(ArcBridgeService::StopReason::GENERIC_BOOT_FAILURE, stop_reason_);
+  arc_session()->StopWithReason(StopReason::GENERIC_BOOT_FAILURE);
+  EXPECT_EQ(StopReason::GENERIC_BOOT_FAILURE, stop_reason_);
   ASSERT_TRUE(service_->ready());
 
   // Simulate crash.
   ASSERT_TRUE(arc_session());
-  arc_session()->StopWithReason(ArcBridgeService::StopReason::CRASH);
-  EXPECT_EQ(ArcBridgeService::StopReason::CRASH, stop_reason_);
+  arc_session()->StopWithReason(StopReason::CRASH);
+  EXPECT_EQ(StopReason::CRASH, stop_reason_);
   ASSERT_TRUE(service_->ready());
 
   // Graceful stop.
   service_->RequestStop();
-  ASSERT_EQ(ArcBridgeService::StopReason::SHUTDOWN, stop_reason_);
+  ASSERT_EQ(StopReason::SHUTDOWN, stop_reason_);
   ASSERT_EQ(ArcBridgeService::State::STOPPED, state());
 }
 
@@ -190,7 +188,7 @@
 
   // Simulate shutdown.
   service_->OnShutdown();
-  ASSERT_EQ(ArcBridgeService::StopReason::SHUTDOWN, stop_reason_);
+  ASSERT_EQ(StopReason::SHUTDOWN, stop_reason_);
   ASSERT_EQ(ArcBridgeService::State::STOPPED, state());
 }
 
diff --git a/components/arc/arc_session.cc b/components/arc/arc_session.cc
index 2de8f50f2..c3dc195 100644
--- a/components/arc/arc_session.cc
+++ b/components/arc/arc_session.cc
@@ -27,6 +27,7 @@
 #include "chromeos/dbus/session_manager_client.h"
 #include "components/arc/arc_bridge_host_impl.h"
 #include "components/arc/arc_features.h"
+#include "components/arc/arc_session_observer.h"
 #include "components/user_manager/user_manager.h"
 #include "mojo/edk/embedder/embedder.h"
 #include "mojo/edk/embedder/named_platform_handle.h"
@@ -124,7 +125,7 @@
   //
   // At any state, Stop() can be called. It does not immediately stop the
   // instance, but will eventually stop it.
-  // The actual stop will be notified via Observer::OnStopped().
+  // The actual stop will be notified via ArcSessionObserver::OnStopped().
   //
   // When Stop() is called, it makes various behavior based on the current
   // phase.
@@ -232,7 +233,7 @@
   void ArcInstanceStopped(bool clean) override;
 
   // Completes the termination procedure.
-  void OnStopped(ArcBridgeService::StopReason reason);
+  void OnStopped(ArcSessionObserver::StopReason reason);
 
   // Checks whether a function runs on the thread where the instance is
   // created.
@@ -343,13 +344,13 @@
 
   if (stop_requested_) {
     VLOG(1) << "Stop() called while connecting";
-    OnStopped(ArcBridgeService::StopReason::SHUTDOWN);
+    OnStopped(ArcSessionObserver::StopReason::SHUTDOWN);
     return;
   }
 
   if (!socket_fd.is_valid()) {
     LOG(ERROR) << "ARC: Error creating socket";
-    OnStopped(ArcBridgeService::StopReason::GENERIC_BOOT_FAILURE);
+    OnStopped(ArcSessionObserver::StopReason::GENERIC_BOOT_FAILURE);
     return;
   }
 
@@ -390,15 +391,15 @@
       StopArcInstance();
       return;
     }
-    OnStopped(ArcBridgeService::StopReason::SHUTDOWN);
+    OnStopped(ArcSessionObserver::StopReason::SHUTDOWN);
     return;
   }
 
   if (result != StartArcInstanceResult::SUCCESS) {
     LOG(ERROR) << "Failed to start ARC instance";
     OnStopped(result == StartArcInstanceResult::LOW_FREE_DISK_SPACE
-                  ? ArcBridgeService::StopReason::LOW_DISK_SPACE
-                  : ArcBridgeService::StopReason::GENERIC_BOOT_FAILURE);
+                  ? ArcSessionObserver::StopReason::LOW_DISK_SPACE
+                  : ArcSessionObserver::StopReason::GENERIC_BOOT_FAILURE);
     return;
   }
 
@@ -409,7 +410,7 @@
   // Stop().
   base::ScopedFD cancel_fd;
   if (!CreatePipe(&cancel_fd, &accept_cancel_pipe_)) {
-    OnStopped(ArcBridgeService::StopReason::GENERIC_BOOT_FAILURE);
+    OnStopped(ArcSessionObserver::StopReason::GENERIC_BOOT_FAILURE);
     return;
   }
 
@@ -499,7 +500,7 @@
   VLOG(2) << "Mojo is connected. ARC is running.";
   state_ = State::RUNNING;
   for (auto& observer : observer_list_)
-    observer.OnReady();
+    observer.OnSessionReady();
 }
 
 void ArcSessionImpl::Stop() {
@@ -515,7 +516,7 @@
   arc_bridge_host_.reset();
   switch (state_) {
     case State::NOT_STARTED:
-      OnStopped(ArcBridgeService::StopReason::SHUTDOWN);
+      OnStopped(ArcSessionObserver::StopReason::SHUTDOWN);
       return;
 
     case State::CREATING_SOCKET:
@@ -572,24 +573,24 @@
   // unlock the BlockingPool thread.
   accept_cancel_pipe_.reset();
 
-  ArcBridgeService::StopReason reason;
+  ArcSessionObserver::StopReason reason;
   if (stop_requested_) {
     // If the ARC instance is stopped after its explicit request,
     // return SHUTDOWN.
-    reason = ArcBridgeService::StopReason::SHUTDOWN;
+    reason = ArcSessionObserver::StopReason::SHUTDOWN;
   } else if (clean) {
     // If the ARC instance is stopped, but it is not explicitly requested,
     // then this is triggered by some failure during the starting procedure.
     // Return GENERIC_BOOT_FAILURE for the case.
-    reason = ArcBridgeService::StopReason::GENERIC_BOOT_FAILURE;
+    reason = ArcSessionObserver::StopReason::GENERIC_BOOT_FAILURE;
   } else {
     // Otherwise, this is caused by CRASH occured inside of the ARC instance.
-    reason = ArcBridgeService::StopReason::CRASH;
+    reason = ArcSessionObserver::StopReason::CRASH;
   }
   OnStopped(reason);
 }
 
-void ArcSessionImpl::OnStopped(ArcBridgeService::StopReason reason) {
+void ArcSessionImpl::OnStopped(ArcSessionObserver::StopReason reason) {
   DCHECK(thread_checker_.CalledOnValidThread());
   // OnStopped() should be called once per instance.
   DCHECK_NE(state_, State::STOPPED);
@@ -597,7 +598,7 @@
   arc_bridge_host_.reset();
   state_ = State::STOPPED;
   for (auto& observer : observer_list_)
-    observer.OnStopped(reason);
+    observer.OnSessionStopped(reason);
 }
 
 void ArcSessionImpl::OnShutdown() {
@@ -622,7 +623,7 @@
   // Directly set to the STOPPED stateby OnStopped(). Note that calling
   // StopArcInstance() may not work well. At least, because the UI thread is
   // already stopped here, ArcInstanceStopped() callback cannot be invoked.
-  OnStopped(ArcBridgeService::StopReason::SHUTDOWN);
+  OnStopped(ArcSessionObserver::StopReason::SHUTDOWN);
 }
 
 }  // namespace
@@ -630,11 +631,11 @@
 ArcSession::ArcSession() = default;
 ArcSession::~ArcSession() = default;
 
-void ArcSession::AddObserver(Observer* observer) {
+void ArcSession::AddObserver(ArcSessionObserver* observer) {
   observer_list_.AddObserver(observer);
 }
 
-void ArcSession::RemoveObserver(Observer* observer) {
+void ArcSession::RemoveObserver(ArcSessionObserver* observer) {
   observer_list_.RemoveObserver(observer);
 }
 
diff --git a/components/arc/arc_session.h b/components/arc/arc_session.h
index e39b43d..25aeede5 100644
--- a/components/arc/arc_session.h
+++ b/components/arc/arc_session.h
@@ -17,6 +17,8 @@
 
 namespace arc {
 
+class ArcSessionObserver;
+
 // Starts the ARC instance and bootstraps the bridge connection.
 // Clients should implement the Delegate to be notified upon communications
 // being available.
@@ -26,22 +28,6 @@
 // conflict.
 class ArcSession {
  public:
-  class Observer {
-   public:
-    Observer() = default;
-    virtual ~Observer() = default;
-
-    // Called when the connection with ARC instance has been established.
-    virtual void OnReady() = 0;
-
-    // Called when ARC instance is stopped. This is called exactly once
-    // per instance which is Start()ed.
-    virtual void OnStopped(ArcBridgeService::StopReason reason) = 0;
-
-   private:
-    DISALLOW_COPY_AND_ASSIGN(Observer);
-  };
-
   // Creates a default instance of ArcSession.
   static std::unique_ptr<ArcSession> Create(
       ArcBridgeService* arc_bridge_service,
@@ -61,13 +47,13 @@
   // loop is already stopped, and the instance will soon be deleted.
   virtual void OnShutdown() = 0;
 
-  void AddObserver(Observer* observer);
-  void RemoveObserver(Observer* observer);
+  void AddObserver(ArcSessionObserver* observer);
+  void RemoveObserver(ArcSessionObserver* observer);
 
  protected:
   ArcSession();
 
-  base::ObserverList<Observer> observer_list_;
+  base::ObserverList<ArcSessionObserver> observer_list_;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(ArcSession);
diff --git a/components/arc/arc_session_observer.cc b/components/arc/arc_session_observer.cc
new file mode 100644
index 0000000..eca089c
--- /dev/null
+++ b/components/arc/arc_session_observer.cc
@@ -0,0 +1,27 @@
+// 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 "components/arc/arc_session_observer.h"
+
+namespace arc {
+
+std::ostream& operator<<(std::ostream& os,
+                         ArcSessionObserver::StopReason reason) {
+  switch (reason) {
+#define CASE_IMPL(val)                      \
+  case ArcSessionObserver::StopReason::val: \
+    return os << #val
+
+    CASE_IMPL(SHUTDOWN);
+    CASE_IMPL(GENERIC_BOOT_FAILURE);
+    CASE_IMPL(LOW_DISK_SPACE);
+    CASE_IMPL(CRASH);
+#undef CASE_IMPL
+  }
+
+  // In case of unexpected value, output the int value.
+  return os << "StopReason(" << static_cast<int>(reason) << ")";
+}
+
+}  // namespace arc
diff --git a/components/arc/arc_session_observer.h b/components/arc/arc_session_observer.h
new file mode 100644
index 0000000..2751e35
--- /dev/null
+++ b/components/arc/arc_session_observer.h
@@ -0,0 +1,48 @@
+// 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 COMPONENTS_ARC_ARC_SESSION_OBSERVER_H_
+#define COMPONENTS_ARC_ARC_SESSION_OBSERVER_H_
+
+#include <ostream>
+
+namespace arc {
+
+// Interface to observe the ARC instance running state.
+class ArcSessionObserver {
+ public:
+  // Describes the reason the ARC instance is stopped.
+  enum class StopReason {
+    // ARC instance has been gracefully shut down.
+    SHUTDOWN,
+
+    // Errors occurred during the ARC instance boot. This includes any failures
+    // before the instance is actually attempted to be started, and also
+    // failures on bootstrapping IPC channels with Android.
+    GENERIC_BOOT_FAILURE,
+
+    // The device is critically low on disk space.
+    LOW_DISK_SPACE,
+
+    // ARC instance has crashed.
+    CRASH,
+  };
+
+  virtual ~ArcSessionObserver() = default;
+
+  // Called when the connection with ARC instance has been established.
+  virtual void OnSessionReady() {}
+
+  // Called when ARC instance is stopped. This is called exactly once
+  // per instance which is Start()ed.
+  virtual void OnSessionStopped(StopReason reason) {}
+};
+
+// Defines "<<" operator for LOGging purpose.
+std::ostream& operator<<(std::ostream& os,
+                         ArcSessionObserver::StopReason reason);
+
+}  // namespace arc
+
+#endif  // COMPONENTS_ARC_ARC_SESSION_OBSERVER_H_
diff --git a/components/arc/common/intent_helper.typemap b/components/arc/common/intent_helper.typemap
new file mode 100644
index 0000000..5b1a17ce
--- /dev/null
+++ b/components/arc/common/intent_helper.typemap
@@ -0,0 +1,16 @@
+# 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.
+
+mojom = "//components/arc/common/intent_helper.mojom"
+public_headers = [ "//components/arc/intent_helper/intent_filter.h" ]
+traits_headers =
+    [ "//components/arc/intent_helper/intent_filter_struct_traits.h" ]
+sources = [
+  "//components/arc/intent_helper/intent_filter_struct_traits.cc",
+]
+type_mappings = [
+  "arc.mojom.IntentFilter=::arc::IntentFilter[move_only]",
+  "arc.mojom.AuthorityEntry=::arc::IntentFilter::AuthorityEntry[move_only]",
+  "arc.mojom.PatternMatcher=::arc::IntentFilter::PatternMatcher[move_only]",
+]
diff --git a/components/arc/common/typemaps.gni b/components/arc/common/typemaps.gni
index 4359362f..618f002b 100644
--- a/components/arc/common/typemaps.gni
+++ b/components/arc/common/typemaps.gni
@@ -6,4 +6,5 @@
   "//components/arc/common/app.typemap",
   "//components/arc/common/bitmap.typemap",
   "//components/arc/common/bluetooth.typemap",
+  "//components/arc/common/intent_helper.typemap",
 ]
diff --git a/components/arc/intent_helper/OWNERS b/components/arc/intent_helper/OWNERS
new file mode 100644
index 0000000..bb65116
--- /dev/null
+++ b/components/arc/intent_helper/OWNERS
@@ -0,0 +1,2 @@
+per-file *_struct_traits*.*=set noparent
+per-file *_struct_traits*.*=file://ipc/SECURITY_OWNERS
diff --git a/components/arc/intent_helper/arc_intent_helper_bridge.cc b/components/arc/intent_helper/arc_intent_helper_bridge.cc
index 53b0b414..1e309ad 100644
--- a/components/arc/intent_helper/arc_intent_helper_bridge.cc
+++ b/components/arc/intent_helper/arc_intent_helper_bridge.cc
@@ -173,7 +173,7 @@
 }
 
 void ArcIntentHelperBridge::OnIntentFiltersUpdated(
-    std::vector<mojom::IntentFilterPtr> filters) {
+    std::vector<IntentFilter> filters) {
   DCHECK(thread_checker_.CalledOnValidThread());
   activity_resolver_->UpdateIntentFilters(std::move(filters));
 
diff --git a/components/arc/intent_helper/arc_intent_helper_bridge.h b/components/arc/intent_helper/arc_intent_helper_bridge.h
index 1955228..64eb023 100644
--- a/components/arc/intent_helper/arc_intent_helper_bridge.h
+++ b/components/arc/intent_helper/arc_intent_helper_bridge.h
@@ -30,6 +30,7 @@
 
 class ActivityIconLoader;
 class ArcBridgeService;
+class IntentFilter;
 class LocalActivityResolver;
 
 // Receives intents from ARC.
@@ -64,7 +65,7 @@
   // mojom::IntentHelperHost
   void OnIconInvalidated(const std::string& package_name) override;
   void OnIntentFiltersUpdated(
-      std::vector<mojom::IntentFilterPtr> intent_filters) override;
+      std::vector<IntentFilter> intent_filters) override;
   void OnOpenDownloads() override;
   void OnOpenUrl(const std::string& url) override;
   void OpenWallpaperPicker() override;
diff --git a/components/arc/intent_helper/arc_intent_helper_bridge_unittest.cc b/components/arc/intent_helper/arc_intent_helper_bridge_unittest.cc
index 0861082..1015842 100644
--- a/components/arc/intent_helper/arc_intent_helper_bridge_unittest.cc
+++ b/components/arc/intent_helper/arc_intent_helper_bridge_unittest.cc
@@ -155,13 +155,13 @@
   auto observer = base::MakeUnique<FakeObserver>();
   instance_->AddObserver(observer.get());
   EXPECT_FALSE(observer->IsUpdated());
-  instance_->OnIntentFiltersUpdated(std::vector<mojom::IntentFilterPtr>());
+  instance_->OnIntentFiltersUpdated(std::vector<IntentFilter>());
   EXPECT_TRUE(observer->IsUpdated());
 
   // Observer should not be called after it's removed.
   observer->Reset();
   instance_->RemoveObserver(observer.get());
-  instance_->OnIntentFiltersUpdated(std::vector<mojom::IntentFilterPtr>());
+  instance_->OnIntentFiltersUpdated(std::vector<IntentFilter>());
   EXPECT_FALSE(observer->IsUpdated());
 }
 
diff --git a/components/arc/intent_helper/intent_filter.cc b/components/arc/intent_helper/intent_filter.cc
index de104ae..85f30b4f 100644
--- a/components/arc/intent_helper/intent_filter.cc
+++ b/components/arc/intent_helper/intent_filter.cc
@@ -6,31 +6,27 @@
 
 #include "base/compiler_specific.h"
 #include "base/strings/string_util.h"
+#include "components/arc/common/intent_helper.mojom.h"
 #include "url/gurl.h"
 
 namespace arc {
 
-IntentFilter::IntentFilter(const mojom::IntentFilterPtr& mojo_intent_filter) {
-  // TODO(yusukes): Use mojo typemaps to simplify the constructor.
-  if (mojo_intent_filter->data_authorities.has_value()) {
-    for (const mojom::AuthorityEntryPtr& authorityptr :
-         *mojo_intent_filter->data_authorities) {
-      authorities_.emplace_back(authorityptr);
-    }
-  }
+IntentFilter::IntentFilter() = default;
+IntentFilter::IntentFilter(IntentFilter&& other) = default;
+
+IntentFilter::IntentFilter(
+    std::vector<IntentFilter::AuthorityEntry> authorities,
+    std::vector<IntentFilter::PatternMatcher> paths)
+    : authorities_(std::move(authorities)) {
   // In order to register a path we need to have at least one authority.
-  if (!authorities_.empty() && mojo_intent_filter->data_paths.has_value()) {
-    for (const mojom::PatternMatcherPtr& pattern :
-         *mojo_intent_filter->data_paths) {
-      paths_.emplace_back(pattern);
-    }
-  }
+  if (!authorities_.empty())
+    paths_ = std::move(paths);
 }
 
-IntentFilter::IntentFilter(const IntentFilter& other) = default;
-
 IntentFilter::~IntentFilter() = default;
 
+IntentFilter& IntentFilter::operator=(IntentFilter&& other) = default;
+
 // Logically, this maps to IntentFilter#match, but this code only deals with
 // view intents for http/https URLs and so it really only implements the
 // #matchData part of the match code.
@@ -73,9 +69,15 @@
   return false;
 }
 
+IntentFilter::AuthorityEntry::AuthorityEntry() = default;
 IntentFilter::AuthorityEntry::AuthorityEntry(
-    const mojom::AuthorityEntryPtr& entry)
-    : host_(entry->host), port_(entry->port) {
+    IntentFilter::AuthorityEntry&& other) = default;
+
+IntentFilter::AuthorityEntry& IntentFilter::AuthorityEntry::operator=(
+    IntentFilter::AuthorityEntry&& other) = default;
+
+IntentFilter::AuthorityEntry::AuthorityEntry(const std::string& host, int port)
+    : host_(host), port_(port) {
   // Wildcards are only allowed at the front of the host string.
   wild_ = !host_.empty() && host_[0] == '*';
   if (wild_) {
@@ -118,9 +120,16 @@
   }
 }
 
+IntentFilter::PatternMatcher::PatternMatcher() = default;
 IntentFilter::PatternMatcher::PatternMatcher(
-    const mojom::PatternMatcherPtr& pattern)
-    : pattern_(pattern->pattern), match_type_(pattern->type) {}
+    IntentFilter::PatternMatcher&& other) = default;
+
+IntentFilter::PatternMatcher::PatternMatcher(const std::string& pattern,
+                                             mojom::PatternType match_type)
+    : pattern_(pattern), match_type_(match_type) {}
+
+IntentFilter::PatternMatcher& IntentFilter::PatternMatcher::operator=(
+    IntentFilter::PatternMatcher&& other) = default;
 
 // Transcribed from android's PatternMatcher#matchPattern.
 bool IntentFilter::PatternMatcher::Match(const std::string& str) const {
diff --git a/components/arc/intent_helper/intent_filter.h b/components/arc/intent_helper/intent_filter.h
index eb07523..e6c447f58 100644
--- a/components/arc/intent_helper/intent_filter.h
+++ b/components/arc/intent_helper/intent_filter.h
@@ -8,55 +8,90 @@
 #include <string>
 #include <vector>
 
-#include "components/arc/common/intent_helper.mojom.h"
+#include "base/macros.h"
 
 class GURL;
 
 namespace arc {
 
+namespace mojom {
+enum class PatternType;
+}  // namespace mojom
+
 // A chrome-side implementation of Android's IntentFilter class.  This is used
 // to approximate the intent filtering and determine whether a given URL is
 // likely to be handled by any android-side apps, prior to making expensive IPC
 // calls.
 class IntentFilter {
  public:
-  explicit IntentFilter(const mojom::IntentFilterPtr& mojo_intent_filter);
-  IntentFilter(const IntentFilter& other);
-  ~IntentFilter();
-
-  bool Match(const GURL& url) const;
-
- private:
   // A helper class for handling matching of the host part of the URL.
   class AuthorityEntry {
    public:
-    explicit AuthorityEntry(const mojom::AuthorityEntryPtr& entry);
+    AuthorityEntry();
+    AuthorityEntry(AuthorityEntry&& other);
+    AuthorityEntry(const std::string& host, int port);
+
+    AuthorityEntry& operator=(AuthorityEntry&& other);
+
     bool Match(const GURL& url) const;
 
+    const std::string& host() const { return host_; }
+    int port() const { return port_; }
+
    private:
     std::string host_;
     bool wild_;
     int port_;
+
+    DISALLOW_COPY_AND_ASSIGN(AuthorityEntry);
   };
 
   // A helper class for handling matching of various patterns in the URL.
   class PatternMatcher {
    public:
-    explicit PatternMatcher(const mojom::PatternMatcherPtr& pattern);
+    PatternMatcher();
+    PatternMatcher(PatternMatcher&& other);
+    PatternMatcher(const std::string& pattern, mojom::PatternType match_type);
+
+    PatternMatcher& operator=(PatternMatcher&& other);
+
     bool Match(const std::string& match) const;
 
+    const std::string& pattern() const { return pattern_; }
+    mojom::PatternType match_type() const { return match_type_; }
+
    private:
     bool MatchGlob(const std::string& match) const;
 
     std::string pattern_;
     mojom::PatternType match_type_;
+
+    DISALLOW_COPY_AND_ASSIGN(PatternMatcher);
   };
 
+  IntentFilter();
+  IntentFilter(IntentFilter&& other);
+  IntentFilter(std::vector<AuthorityEntry> authorities,
+               std::vector<PatternMatcher> paths);
+  ~IntentFilter();
+
+  IntentFilter& operator=(IntentFilter&& other);
+
+  bool Match(const GURL& url) const;
+
+  const std::vector<AuthorityEntry>& authorities() const {
+    return authorities_;
+  }
+  const std::vector<PatternMatcher>& paths() const { return paths_; }
+
+ private:
   bool MatchDataAuthority(const GURL& url) const;
   bool HasDataPath(const GURL& url) const;
 
   std::vector<AuthorityEntry> authorities_;
   std::vector<PatternMatcher> paths_;
+
+  DISALLOW_COPY_AND_ASSIGN(IntentFilter);
 };
 
 }  // namespace arc
diff --git a/components/arc/intent_helper/intent_filter_struct_traits.cc b/components/arc/intent_helper/intent_filter_struct_traits.cc
new file mode 100644
index 0000000..2ef34534
--- /dev/null
+++ b/components/arc/intent_helper/intent_filter_struct_traits.cc
@@ -0,0 +1,55 @@
+// 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 "components/arc/intent_helper/intent_filter_struct_traits.h"
+
+#include "base/strings/string_util.h"
+
+namespace mojo {
+
+bool StructTraits<arc::mojom::IntentFilterDataView, arc::IntentFilter>::
+    Read(arc::mojom::IntentFilterDataView data,
+         arc::IntentFilter* out) {
+  std::vector<arc::IntentFilter::AuthorityEntry> authorities;
+  if (!data.ReadDataAuthorities(&authorities))
+    return false;
+
+  std::vector<arc::IntentFilter::PatternMatcher> paths;
+  if (!data.ReadDataPaths(&paths))
+    return false;
+
+  *out = arc::IntentFilter(std::move(authorities), std::move(paths));
+  return true;
+}
+
+bool StructTraits<arc::mojom::AuthorityEntryDataView,
+                    arc::IntentFilter::AuthorityEntry>::
+    Read(arc::mojom::AuthorityEntryDataView data,
+         arc::IntentFilter::AuthorityEntry* out) {
+  std::string host;
+  bool result = data.ReadHost(&host);
+  if (!result)
+    return false;
+
+  *out = arc::IntentFilter::AuthorityEntry(std::move(host), data.port());
+  return true;
+}
+
+bool StructTraits<arc::mojom::PatternMatcherDataView,
+                    arc::IntentFilter::PatternMatcher>::
+  Read(arc::mojom::PatternMatcherDataView data,
+                   arc::IntentFilter::PatternMatcher* out) {
+  std::string pattern;
+  if (!data.ReadPattern(&pattern))
+    return false;
+
+  arc::mojom::PatternType type;
+  if (!data.ReadType(&type))
+    return false;
+
+  *out = arc::IntentFilter::PatternMatcher(std::move(pattern), type);
+  return true;
+}
+
+}  // namespace mojo
diff --git a/components/arc/intent_helper/intent_filter_struct_traits.h b/components/arc/intent_helper/intent_filter_struct_traits.h
new file mode 100644
index 0000000..ca9ba9c
--- /dev/null
+++ b/components/arc/intent_helper/intent_filter_struct_traits.h
@@ -0,0 +1,79 @@
+// 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 COMPONENT_ARC_INTENT_FILTER_INTENT_FILTER_STRUCT_TRAITS_H_
+#define COMPONENT_ARC_INTENT_FILTER_INTENT_FILTER_STRUCT_TRAITS_H_
+
+#include "components/arc/common/intent_helper.mojom.h"
+#include "components/arc/intent_helper/intent_filter.h"
+
+namespace mojo {
+
+template <>
+struct StructTraits<arc::mojom::IntentFilterDataView, arc::IntentFilter> {
+  static const mojo::CArray<std::string> actions(const arc::IntentFilter& r) {
+    // Returns an empty array.
+    return mojo::CArray<std::string>();
+  }
+  static const mojo::CArray<std::string> categories(
+      const arc::IntentFilter& r) {
+    // Returns an empty array.
+    return mojo::CArray<std::string>();
+  }
+  static const mojo::CArray<std::string> data_schemes(
+      const arc::IntentFilter& r) {
+    // Returns an empty array.
+    return mojo::CArray<std::string>();
+  }
+  static const std::vector<arc::IntentFilter::AuthorityEntry>& data_authorities(
+      const arc::IntentFilter& r) {
+    return r.authorities();
+  }
+  static const std::vector<arc::IntentFilter::PatternMatcher>& data_paths(
+      const arc::IntentFilter& r) {
+    return r.paths();
+  }
+  static const mojo::CArray<arc::IntentFilter::PatternMatcher>
+  deprecated_data_scheme_specific_parts(const arc::IntentFilter& r) {
+    // Returns an empty array.
+    return mojo::CArray<arc::IntentFilter::PatternMatcher>();
+  }
+
+  static bool Read(arc::mojom::IntentFilterDataView data,
+                   arc::IntentFilter* out);
+};
+
+template <>
+struct StructTraits<arc::mojom::AuthorityEntryDataView,
+                    arc::IntentFilter::AuthorityEntry> {
+  static const std::string& host(const arc::IntentFilter::AuthorityEntry& r) {
+    return r.host();
+  }
+  static int32_t port(const arc::IntentFilter::AuthorityEntry& r) {
+    return r.port();
+  }
+
+  static bool Read(arc::mojom::AuthorityEntryDataView data,
+                   arc::IntentFilter::AuthorityEntry* out);
+};
+
+template <>
+struct StructTraits<arc::mojom::PatternMatcherDataView,
+                    arc::IntentFilter::PatternMatcher> {
+  static const std::string& pattern(
+      const arc::IntentFilter::PatternMatcher& r) {
+    return r.pattern();
+  }
+  static arc::mojom::PatternType type(
+      const arc::IntentFilter::PatternMatcher& r) {
+    return r.match_type();
+  }
+
+  static bool Read(arc::mojom::PatternMatcherDataView data,
+                   arc::IntentFilter::PatternMatcher* out);
+};
+
+}  // namespace mojo
+
+#endif  // COMPONENT_ARC_INTENT_FILTER_INTENT_FILTER_STRUCT_TRAITS_H_
diff --git a/components/arc/intent_helper/intent_filter_unittest.cc b/components/arc/intent_helper/intent_filter_unittest.cc
index 1e0113f..1205c2e 100644
--- a/components/arc/intent_helper/intent_filter_unittest.cc
+++ b/components/arc/intent_helper/intent_filter_unittest.cc
@@ -20,41 +20,32 @@
 
 class IntentFilterBuilder {
  public:
-  IntentFilterBuilder():
-      filter_spec_(mojom::IntentFilter::New()) {
-  }
+  IntentFilterBuilder() = default;
 
   IntentFilterBuilder& authority(const std::string& host) {
     return authority(host, -1);
   }
 
   IntentFilterBuilder& authority(const std::string& host, int port) {
-    mojom::AuthorityEntryPtr ae = mojom::AuthorityEntry::New();
-    ae->host = host;
-    ae->port = port;
-    if (!filter_spec_->data_authorities.has_value())
-      filter_spec_->data_authorities = std::vector<mojom::AuthorityEntryPtr>();
-    filter_spec_->data_authorities->push_back(std::move(ae));
+    authorities_.emplace_back(host, port);
     return *this;
   }
 
   IntentFilterBuilder& path(const std::string& path,
                             const mojom::PatternType& type) {
-    mojom::PatternMatcherPtr p = mojom::PatternMatcher::New();
-    p->pattern = path;
-    p->type = type;
-    if (!filter_spec_->data_paths.has_value())
-      filter_spec_->data_paths = std::vector<mojom::PatternMatcherPtr>();
-    filter_spec_->data_paths->push_back(std::move(p));
+    paths_.emplace_back(path, type);
     return *this;
   }
 
-  operator IntentFilter() const {
-    return std::move(IntentFilter(filter_spec_));
+  operator IntentFilter() {
+    return IntentFilter(std::move(authorities_), std::move(paths_));
   }
 
  private:
-  mojom::IntentFilterPtr filter_spec_;
+  std::vector<IntentFilter::AuthorityEntry> authorities_;
+  std::vector<IntentFilter::PatternMatcher> paths_;
+
+  DISALLOW_COPY_AND_ASSIGN(IntentFilterBuilder);
 };
 
 }  // namespace
diff --git a/components/arc/intent_helper/local_activity_resolver.cc b/components/arc/intent_helper/local_activity_resolver.cc
index b9939d42..8ea0c55 100644
--- a/components/arc/intent_helper/local_activity_resolver.cc
+++ b/components/arc/intent_helper/local_activity_resolver.cc
@@ -28,10 +28,8 @@
 }
 
 void LocalActivityResolver::UpdateIntentFilters(
-    std::vector<mojom::IntentFilterPtr> mojo_intent_filters) {
-  intent_filters_.clear();
-  for (mojom::IntentFilterPtr& mojo_filter : mojo_intent_filters)
-    intent_filters_.emplace_back(mojo_filter);
+    std::vector<IntentFilter> intent_filters) {
+  intent_filters_ = std::move(intent_filters);
 }
 
 }  // namespace arc
diff --git a/components/arc/intent_helper/local_activity_resolver.h b/components/arc/intent_helper/local_activity_resolver.h
index ff37156..353d31c 100644
--- a/components/arc/intent_helper/local_activity_resolver.h
+++ b/components/arc/intent_helper/local_activity_resolver.h
@@ -29,7 +29,7 @@
   bool ShouldChromeHandleUrl(const GURL& url);
 
   // Called when the list of intent filters on ARC side is updated.
-  void UpdateIntentFilters(std::vector<mojom::IntentFilterPtr> intent_filters);
+  void UpdateIntentFilters(std::vector<IntentFilter> intent_filters);
 
  private:
   friend class base::RefCounted<LocalActivityResolver>;
diff --git a/components/arc/intent_helper/local_activity_resolver_unittest.cc b/components/arc/intent_helper/local_activity_resolver_unittest.cc
index fff6076..09bf445 100644
--- a/components/arc/intent_helper/local_activity_resolver_unittest.cc
+++ b/components/arc/intent_helper/local_activity_resolver_unittest.cc
@@ -15,14 +15,12 @@
 
 namespace {
 
-mojom::IntentFilterPtr GetIntentFilter(const std::string& host) {
-  mojom::IntentFilterPtr filter = mojom::IntentFilter::New();
-  mojom::AuthorityEntryPtr authority_entry = mojom::AuthorityEntry::New();
-  authority_entry->host = host;
-  authority_entry->port = -1;
-  filter->data_authorities = std::vector<mojom::AuthorityEntryPtr>();
-  filter->data_authorities->push_back(std::move(authority_entry));
-  return filter;
+IntentFilter GetIntentFilter(const std::string& host) {
+  std::vector<IntentFilter::AuthorityEntry> authorities;
+  authorities.emplace_back(host, -1);
+
+  return IntentFilter(std::move(authorities),
+                      std::vector<IntentFilter::PatternMatcher>());
 }
 
 }  // namespace
@@ -41,8 +39,8 @@
 TEST(LocalActivityResolverTest, TestSingleFilter) {
   scoped_refptr<LocalActivityResolver> resolver(new LocalActivityResolver());
 
-  std::vector<mojom::IntentFilterPtr> array;
-  array.push_back(GetIntentFilter("www.google.com"));
+  std::vector<IntentFilter> array;
+  array.emplace_back(GetIntentFilter("www.google.com"));
   resolver->UpdateIntentFilters(std::move(array));
 
   EXPECT_FALSE(resolver->ShouldChromeHandleUrl(GURL("http://www.google.com")));
@@ -56,10 +54,10 @@
 TEST(LocalActivityResolverTest, TestMultipleFilters) {
   scoped_refptr<LocalActivityResolver> resolver(new LocalActivityResolver());
 
-  std::vector<mojom::IntentFilterPtr> array;
-  array.push_back(GetIntentFilter("www.google.com"));
-  array.push_back(GetIntentFilter("www.google.co.uk"));
-  array.push_back(GetIntentFilter("dev.chromium.org"));
+  std::vector<IntentFilter> array;
+  array.emplace_back(GetIntentFilter("www.google.com"));
+  array.emplace_back(GetIntentFilter("www.google.co.uk"));
+  array.emplace_back(GetIntentFilter("dev.chromium.org"));
   resolver->UpdateIntentFilters(std::move(array));
 
   EXPECT_FALSE(resolver->ShouldChromeHandleUrl(GURL("http://www.google.com")));
@@ -80,8 +78,8 @@
 TEST(LocalActivityResolverTest, TestNonHttp) {
   scoped_refptr<LocalActivityResolver> resolver(new LocalActivityResolver());
 
-  std::vector<mojom::IntentFilterPtr> array;
-  array.push_back(GetIntentFilter("www.google.com"));
+  std::vector<IntentFilter> array;
+  array.emplace_back(GetIntentFilter("www.google.com"));
   resolver->UpdateIntentFilters(std::move(array));
 
   EXPECT_TRUE(resolver->ShouldChromeHandleUrl(GURL("chrome://www.google.com")));
@@ -93,15 +91,15 @@
 TEST(LocalActivityResolverTest, TestMultipleUpdate) {
   scoped_refptr<LocalActivityResolver> resolver(new LocalActivityResolver());
 
-  std::vector<mojom::IntentFilterPtr> array;
-  array.push_back(GetIntentFilter("www.google.com"));
-  array.push_back(GetIntentFilter("dev.chromium.org"));
+  std::vector<IntentFilter> array;
+  array.emplace_back(GetIntentFilter("www.google.com"));
+  array.emplace_back(GetIntentFilter("dev.chromium.org"));
   resolver->UpdateIntentFilters(std::move(array));
 
-  std::vector<mojom::IntentFilterPtr> array2;
-  array2.push_back(GetIntentFilter("www.google.co.uk"));
-  array2.push_back(GetIntentFilter("dev.chromium.org"));
-  array2.push_back(GetIntentFilter("www.android.com"));
+  std::vector<IntentFilter> array2;
+  array2.emplace_back(GetIntentFilter("www.google.co.uk"));
+  array2.emplace_back(GetIntentFilter("dev.chromium.org"));
+  array2.emplace_back(GetIntentFilter("www.android.com"));
   resolver->UpdateIntentFilters(std::move(array2));
 
   EXPECT_TRUE(resolver->ShouldChromeHandleUrl(GURL("http://www.google.com")));
diff --git a/components/arc/test/fake_arc_session.cc b/components/arc/test/fake_arc_session.cc
index 5ebc1e0..493fe870 100644
--- a/components/arc/test/fake_arc_session.cc
+++ b/components/arc/test/fake_arc_session.cc
@@ -18,28 +18,28 @@
 void FakeArcSession::Start() {
   if (boot_failure_emulation_enabled_) {
     for (auto& observer : observer_list_)
-      observer.OnStopped(boot_failure_reason_);
+      observer.OnSessionStopped(boot_failure_reason_);
   } else if (!boot_suspended_) {
     for (auto& observer : observer_list_)
-      observer.OnReady();
+      observer.OnSessionReady();
   }
 }
 
 void FakeArcSession::Stop() {
-  StopWithReason(ArcBridgeService::StopReason::SHUTDOWN);
+  StopWithReason(ArcSessionObserver::StopReason::SHUTDOWN);
 }
 
 void FakeArcSession::OnShutdown() {
-  StopWithReason(ArcBridgeService::StopReason::SHUTDOWN);
+  StopWithReason(ArcSessionObserver::StopReason::SHUTDOWN);
 }
 
-void FakeArcSession::StopWithReason(ArcBridgeService::StopReason reason) {
+void FakeArcSession::StopWithReason(ArcSessionObserver::StopReason reason) {
   for (auto& observer : observer_list_)
-    observer.OnStopped(reason);
+    observer.OnSessionStopped(reason);
 }
 
 void FakeArcSession::EnableBootFailureEmulation(
-    ArcBridgeService::StopReason reason) {
+    ArcSessionObserver::StopReason reason) {
   DCHECK(!boot_failure_emulation_enabled_);
   DCHECK(!boot_suspended_);
 
diff --git a/components/arc/test/fake_arc_session.h b/components/arc/test/fake_arc_session.h
index fb56229c..9ddd3e2 100644
--- a/components/arc/test/fake_arc_session.h
+++ b/components/arc/test/fake_arc_session.h
@@ -9,6 +9,7 @@
 
 #include "base/macros.h"
 #include "components/arc/arc_session.h"
+#include "components/arc/arc_session_observer.h"
 
 namespace arc {
 
@@ -24,13 +25,13 @@
   void OnShutdown() override;
 
   // To emulate unexpected stop, such as crash.
-  void StopWithReason(ArcBridgeService::StopReason reason);
+  void StopWithReason(ArcSessionObserver::StopReason reason);
 
   // The following control Start() behavior for testing various situations.
 
   // Enables/disables boot failure emulation, in which OnStopped(reason) will
   // be called when Start() is called.
-  void EnableBootFailureEmulation(ArcBridgeService::StopReason reason);
+  void EnableBootFailureEmulation(ArcSessionObserver::StopReason reason);
 
   // Emulate Start() is suspended at some phase, before OnReady() is invoked.
   void SuspendBoot();
@@ -41,7 +42,7 @@
 
  private:
   bool boot_failure_emulation_enabled_ = false;
-  ArcBridgeService::StopReason boot_failure_reason_;
+  ArcSessionObserver::StopReason boot_failure_reason_;
 
   bool boot_suspended_ = false;
 
diff --git a/components/data_reduction_proxy/OWNERS b/components/data_reduction_proxy/OWNERS
index 2868ce9f..340aa35a 100644
--- a/components/data_reduction_proxy/OWNERS
+++ b/components/data_reduction_proxy/OWNERS
@@ -1,7 +1,7 @@
 bengr@chromium.org
 bolian@chromium.org
-kundaji@chromium.org
 megjablon@chromium.org
+rajendrant@chromium.org
 ryansturm@chromium.org
 sclittle@chromium.org
 tbansal@chromium.org
diff --git a/components/data_usage/OWNERS b/components/data_usage/OWNERS
index ad4b2b21..78d68ca 100644
--- a/components/data_usage/OWNERS
+++ b/components/data_usage/OWNERS
@@ -1,3 +1,4 @@
 bengr@chromium.org
+rajendrant@chromium.org
 sclittle@chromium.org
 tbansal@chromium.org
\ No newline at end of file
diff --git a/components/ntp_tiles/most_visited_sites.cc b/components/ntp_tiles/most_visited_sites.cc
index 397b9e4..0e73f9f9 100644
--- a/components/ntp_tiles/most_visited_sites.cc
+++ b/components/ntp_tiles/most_visited_sites.cc
@@ -46,18 +46,19 @@
 
 }  // namespace
 
-MostVisitedSites::MostVisitedSites(PrefService* prefs,
-                                   scoped_refptr<history::TopSites> top_sites,
-                                   SuggestionsService* suggestions,
-                                   std::unique_ptr<PopularSites> popular_sites,
-                                   std::unique_ptr<IconCacher> icon_cacher,
-                                   MostVisitedSitesSupervisor* supervisor)
+MostVisitedSites::MostVisitedSites(
+    PrefService* prefs,
+    scoped_refptr<history::TopSites> top_sites,
+    SuggestionsService* suggestions,
+    std::unique_ptr<PopularSites> popular_sites,
+    std::unique_ptr<IconCacher> icon_cacher,
+    std::unique_ptr<MostVisitedSitesSupervisor> supervisor)
     : prefs_(prefs),
       top_sites_(top_sites),
       suggestions_service_(suggestions),
       popular_sites_(std::move(popular_sites)),
       icon_cacher_(std::move(icon_cacher)),
-      supervisor_(supervisor),
+      supervisor_(std::move(supervisor)),
       observer_(nullptr),
       num_sites_(0),
       top_sites_observer_(this),
diff --git a/components/ntp_tiles/most_visited_sites.h b/components/ntp_tiles/most_visited_sites.h
index d097b1bc..1b1f9f5 100644
--- a/components/ntp_tiles/most_visited_sites.h
+++ b/components/ntp_tiles/most_visited_sites.h
@@ -53,6 +53,8 @@
     ~Observer() {}
   };
 
+  virtual ~MostVisitedSitesSupervisor() {}
+
   // Pass non-null to set observer, or null to remove observer.
   // If setting observer, there must not yet be an observer set.
   // If removing observer, there must already be one to remove.
@@ -67,9 +69,6 @@
 
   // If true, be conservative about suggesting sites from outside sources.
   virtual bool IsChildProfile() = 0;
-
- protected:
-  virtual ~MostVisitedSitesSupervisor() {}
 };
 
 // Tracks the list of most visited sites and their thumbnails.
@@ -98,7 +97,7 @@
                    suggestions::SuggestionsService* suggestions,
                    std::unique_ptr<PopularSites> popular_sites,
                    std::unique_ptr<IconCacher> icon_cacher,
-                   MostVisitedSitesSupervisor* supervisor);
+                   std::unique_ptr<MostVisitedSitesSupervisor> supervisor);
 
   ~MostVisitedSites() override;
 
@@ -177,7 +176,7 @@
   suggestions::SuggestionsService* suggestions_service_;
   std::unique_ptr<PopularSites> const popular_sites_;
   std::unique_ptr<IconCacher> const icon_cacher_;
-  MostVisitedSitesSupervisor* supervisor_;
+  std::unique_ptr<MostVisitedSitesSupervisor> supervisor_;
 
   Observer* observer_;
 
diff --git a/components/resources/OWNERS b/components/resources/OWNERS
index 0b7fe56..9156ca7f 100644
--- a/components/resources/OWNERS
+++ b/components/resources/OWNERS
@@ -6,8 +6,8 @@
 per-file crash_*=scottmg@chromium.org
 per-file crash_*=thestig@chromium.org
 per-file data_reduction_proxy*=bengr@chromium.org
-per-file data_reduction_proxy*=kundaji@chromium.org
 per-file data_reduction_proxy*=megjablon@chromium.org
+per-file data_reduction_proxy*=rajendrant@chromium.org
 per-file data_reduction_proxy*=ryansturm@chromium.org
 per-file data_reduction_proxy*=sclittle@chromium.org
 per-file data_reduction_proxy*=tbansal@chromium.org
diff --git a/components/test/data/data_reduction_proxy/OWNERS b/components/test/data/data_reduction_proxy/OWNERS
index f74fd0ab..2783dea 100644
--- a/components/test/data/data_reduction_proxy/OWNERS
+++ b/components/test/data/data_reduction_proxy/OWNERS
@@ -1,8 +1 @@
-bengr@chromium.org
-bolian@chromium.org
-kundaji@chromium.org
-marq@chromium.org
-megjablon@chromium.org
-ryansturm@chromium.org
-sclittle@chromium.org
-tbansal@chromium.org
\ No newline at end of file
+file://components/data_reduction_proxy/OWNERS
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index f7cf2ee..d3294588a 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -184,6 +184,8 @@
     "$target_gen_dir/devtools/protocol/schema.h",
     "$target_gen_dir/devtools/protocol/security.cc",
     "$target_gen_dir/devtools/protocol/security.h",
+    "$target_gen_dir/devtools/protocol/storage.cc",
+    "$target_gen_dir/devtools/protocol/storage.h",
     "$target_gen_dir/devtools/protocol/system_info.cc",
     "$target_gen_dir/devtools/protocol/system_info.h",
     "$target_gen_dir/devtools/protocol/tethering.cc",
diff --git a/content/browser/devtools/BUILD.gn b/content/browser/devtools/BUILD.gn
index 5c0d063..5ef4994 100644
--- a/content/browser/devtools/BUILD.gn
+++ b/content/browser/devtools/BUILD.gn
@@ -76,6 +76,8 @@
     "protocol/schema.h",
     "protocol/security.cc",
     "protocol/security.h",
+    "protocol/storage.cc",
+    "protocol/storage.h",
     "protocol/system_info.cc",
     "protocol/system_info.h",
     "protocol/tethering.cc",
diff --git a/content/browser/devtools/protocol/devtools_protocol_handler_generator.py b/content/browser/devtools/protocol/devtools_protocol_handler_generator.py
index 00f9c00b6..823d2185c 100755
--- a/content/browser/devtools/protocol/devtools_protocol_handler_generator.py
+++ b/content/browser/devtools/protocol/devtools_protocol_handler_generator.py
@@ -643,7 +643,7 @@
 includes = []
 fields_init = []
 
-browser_domains_list = ["Target", "ServiceWorker", "Input", "Storage"]
+browser_domains_list = ["Target", "ServiceWorker", "Input"]
 browser_commands_list = []
 async_commands_list = [
     "Input.synthesizePinchGesture",
diff --git a/content/browser/devtools/protocol/storage_handler.cc b/content/browser/devtools/protocol/storage_handler.cc
index 94415de7..9c3a06ce 100644
--- a/content/browser/devtools/protocol/storage_handler.cc
+++ b/content/browser/devtools/protocol/storage_handler.cc
@@ -9,14 +9,12 @@
 #include <vector>
 
 #include "base/strings/string_split.h"
-#include "content/browser/devtools/protocol/devtools_protocol_dispatcher.h"
-#include "content/public/browser/render_frame_host.h"
+#include "content/browser/frame_host/render_frame_host_impl.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/storage_partition.h"
 
 namespace content {
-namespace devtools {
-namespace storage {
+namespace protocol {
 
 namespace {
 static const char kAppCache[] = "appcache";
@@ -31,23 +29,29 @@
 static const char kAll[] = "all";
 }
 
-typedef DevToolsProtocolClient::Response Response;
-
 StorageHandler::StorageHandler()
     : host_(nullptr) {
 }
 
 StorageHandler::~StorageHandler() = default;
 
-void StorageHandler::SetRenderFrameHost(RenderFrameHost* host) {
+void StorageHandler::Wire(UberDispatcher* dispatcher) {
+  Storage::Dispatcher::wire(dispatcher, this);
+}
+
+void StorageHandler::SetRenderFrameHost(RenderFrameHostImpl* host) {
   host_ = host;
 }
 
+Response StorageHandler::Disable() {
+  return Response::OK();
+}
+
 Response StorageHandler::ClearDataForOrigin(
     const std::string& origin,
     const std::string& storage_types) {
   if (!host_)
-    return Response::InternalError("Not connected to host");
+    return Response::InternalError();
 
   StoragePartition* partition = host_->GetProcess()->GetStoragePartition();
   std::vector<std::string> types = base::SplitString(
@@ -87,6 +91,5 @@
   return Response::OK();
 }
 
-}  // namespace storage
-}  // namespace devtools
+}  // namespace protocol
 }  // namespace content
diff --git a/content/browser/devtools/protocol/storage_handler.h b/content/browser/devtools/protocol/storage_handler.h
index d6f7c65..f203a12 100644
--- a/content/browser/devtools/protocol/storage_handler.h
+++ b/content/browser/devtools/protocol/storage_handler.h
@@ -6,37 +6,34 @@
 #define CONTENT_BROWSER_DEVTOOLS_PROTOCOL_STORAGE_HANDLER_H_
 
 #include "base/macros.h"
-#include "content/browser/devtools/devtools_protocol_handler.h"
-#include "content/browser/devtools/protocol/devtools_protocol_dispatcher.h"
+#include "content/browser/devtools/protocol/storage.h"
 
 namespace content {
 
-class RenderFrameHost;
+class RenderFrameHostImpl;
 
-namespace devtools {
-namespace storage {
+namespace protocol {
 
-class StorageHandler {
+class StorageHandler : public Storage::Backend {
  public:
-  typedef DevToolsProtocolClient::Response Response;
-
   StorageHandler();
-  ~StorageHandler();
+  ~StorageHandler() override;
 
-  void SetRenderFrameHost(RenderFrameHost* host);
+  void Wire(UberDispatcher*);
+  void SetRenderFrameHost(RenderFrameHostImpl* host);
+  Response Disable() override;
 
   Response ClearDataForOrigin(
       const std::string& origin,
-      const std::string& storage_types);
+      const std::string& storage_types) override;
 
  private:
-  RenderFrameHost* host_;
+  RenderFrameHostImpl* host_;
 
   DISALLOW_COPY_AND_ASSIGN(StorageHandler);
 };
 
-}  // namespace storage
-}  // namespace devtools
+}  // namespace protocol
 }  // namespace content
 
 #endif  // CONTENT_BROWSER_DEVTOOLS_PROTOCOL_STORAGE_HANDLER_H_
diff --git a/content/browser/devtools/protocol_config.json b/content/browser/devtools/protocol_config.json
index cb1899f7..c64ec06c 100644
--- a/content/browser/devtools/protocol_config.json
+++ b/content/browser/devtools/protocol_config.json
@@ -52,6 +52,9 @@
                 "domain": "Security"
             },
             {
+                "domain": "Storage"
+            },
+            {
                 "domain": "SystemInfo",
                 "async": ["getInfo"]
             },
diff --git a/content/browser/devtools/render_frame_devtools_agent_host.cc b/content/browser/devtools/render_frame_devtools_agent_host.cc
index c7693a5..b217d8e 100644
--- a/content/browser/devtools/render_frame_devtools_agent_host.cc
+++ b/content/browser/devtools/render_frame_devtools_agent_host.cc
@@ -397,7 +397,6 @@
       input_handler_(new devtools::input::InputHandler()),
       service_worker_handler_(
           new devtools::service_worker::ServiceWorkerHandler()),
-      storage_handler_(new devtools::storage::StorageHandler()),
       target_handler_(new devtools::target::TargetHandler()),
       frame_trace_recorder_(nullptr),
       protocol_handler_(new DevToolsProtocolHandler(this)),
@@ -408,7 +407,6 @@
   DevToolsProtocolDispatcher* dispatcher = protocol_handler_->dispatcher();
   dispatcher->SetInputHandler(input_handler_.get());
   dispatcher->SetServiceWorkerHandler(service_worker_handler_.get());
-  dispatcher->SetStorageHandler(storage_handler_.get());
   dispatcher->SetTargetHandler(target_handler_.get());
 
   SetPending(host);
@@ -511,6 +509,9 @@
     security_handler_->SetRenderFrameHost(handlers_frame_host_);
   }
 
+  storage_handler_.reset(new protocol::StorageHandler());
+  storage_handler_->Wire(session()->dispatcher());
+
   tracing_handler_.reset(new protocol::TracingHandler(
       protocol::TracingHandler::Renderer,
       frame_tree_node_->frame_tree_node_id(),
@@ -547,6 +548,8 @@
     security_handler_->Disable();
     security_handler_.reset();
   }
+  storage_handler_->Disable();
+  storage_handler_.reset();
   tracing_handler_->Disable();
   tracing_handler_.reset();
 
diff --git a/content/browser/devtools/render_frame_devtools_agent_host.h b/content/browser/devtools/render_frame_devtools_agent_host.h
index b17972cd..2b464da 100644
--- a/content/browser/devtools/render_frame_devtools_agent_host.h
+++ b/content/browser/devtools/render_frame_devtools_agent_host.h
@@ -42,7 +42,6 @@
 namespace devtools {
 namespace input { class InputHandler; }
 namespace service_worker { class ServiceWorkerHandler; }
-namespace storage { class StorageHandler; }
 namespace target { class TargetHandler; }
 }
 
@@ -55,6 +54,7 @@
 class PageHandler;
 class SchemaHandler;
 class SecurityHandler;
+class StorageHandler;
 class TracingHandler;
 }  // namespace protocol
 
@@ -193,8 +193,7 @@
   std::unique_ptr<protocol::SecurityHandler> security_handler_;
   std::unique_ptr<devtools::service_worker::ServiceWorkerHandler>
       service_worker_handler_;
-  std::unique_ptr<devtools::storage::StorageHandler>
-      storage_handler_;
+  std::unique_ptr<protocol::StorageHandler> storage_handler_;
   std::unique_ptr<devtools::target::TargetHandler> target_handler_;
   std::unique_ptr<protocol::TracingHandler> tracing_handler_;
   std::unique_ptr<protocol::EmulationHandler> emulation_handler_;
diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc
index f5be8d59..967758ea 100644
--- a/content/browser/renderer_host/render_view_host_impl.cc
+++ b/content/browser/renderer_host/render_view_host_impl.cc
@@ -74,7 +74,6 @@
 #include "content/public/common/content_features.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/common/context_menu_params.h"
-#include "content/public/common/drop_data.h"
 #include "content/public/common/file_chooser_file_info.h"
 #include "content/public/common/file_chooser_params.h"
 #include "content/public/common/result_codes.h"
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
index 33282e6..a33e65d7 100644
--- a/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -2509,6 +2509,7 @@
         GURL(storage::GetIsolatedFileSystemRootURIString(
                  file_system_url.origin(), filesystem_id, std::string())
                  .append(register_name));
+    file_system_file.filesystem_id = filesystem_id;
   }
 }
 
diff --git a/content/browser/web_contents/web_contents_view_aura.cc b/content/browser/web_contents/web_contents_view_aura.cc
index 709ea5d..ebcaf95 100644
--- a/content/browser/web_contents/web_contents_view_aura.cc
+++ b/content/browser/web_contents/web_contents_view_aura.cc
@@ -245,6 +245,7 @@
   for (size_t i = 0; i < file_system_files.size(); ++i) {
     pickle->WriteString(file_system_files[i].url.spec());
     pickle->WriteInt64(file_system_files[i].size);
+    pickle->WriteString(file_system_files[i].filesystem_id);
   }
 }
 
@@ -262,8 +263,11 @@
   for (uint32_t i = 0; i < num_files; ++i) {
     std::string url_string;
     int64_t size = 0;
-    if (!iter.ReadString(&url_string) || !iter.ReadInt64(&size))
+    std::string filesystem_id;
+    if (!iter.ReadString(&url_string) || !iter.ReadInt64(&size) ||
+        !iter.ReadString(&filesystem_id)) {
       return false;
+    }
 
     GURL url(url_string);
     if (!url.is_valid())
@@ -271,6 +275,7 @@
 
     (*file_system_files)[i].url = url;
     (*file_system_files)[i].size = size;
+    (*file_system_files)[i].filesystem_id = filesystem_id;
   }
   return true;
 }
diff --git a/content/common/drag_traits.h b/content/common/drag_traits.h
index 9278815..5f9d151 100644
--- a/content/common/drag_traits.h
+++ b/content/common/drag_traits.h
@@ -42,6 +42,7 @@
 IPC_STRUCT_TRAITS_BEGIN(content::DropData::FileSystemFileInfo)
   IPC_STRUCT_TRAITS_MEMBER(url)
   IPC_STRUCT_TRAITS_MEMBER(size)
+  IPC_STRUCT_TRAITS_MEMBER(filesystem_id)
 IPC_STRUCT_TRAITS_END()
 
 IPC_STRUCT_TRAITS_BEGIN(content::DropData::Metadata)
diff --git a/content/public/common/drop_data.h b/content/public/common/drop_data.h
index f131b81..a5439b6 100644
--- a/content/public/common/drop_data.h
+++ b/content/public/common/drop_data.h
@@ -31,6 +31,7 @@
 
     GURL url;
     int64_t size;
+    std::string filesystem_id;
   };
 
   enum class Kind {
diff --git a/content/renderer/drop_data_builder.cc b/content/renderer/drop_data_builder.cc
index e10d8d79..3dc64de 100644
--- a/content/renderer/drop_data_builder.cc
+++ b/content/renderer/drop_data_builder.cc
@@ -69,6 +69,7 @@
         DropData::FileSystemFileInfo info;
         info.url = item.fileSystemURL;
         info.size = item.fileSystemFileSize;
+        info.filesystem_id = item.fileSystemId.ascii();
         result.file_system_files.push_back(info);
         break;
       }
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc
index e47f7f6..f25fa82 100644
--- a/content/renderer/render_widget.cc
+++ b/content/renderer/render_widget.cc
@@ -294,6 +294,7 @@
     item.storageType = WebDragData::Item::StorageTypeFileSystemFile;
     item.fileSystemURL = it->url;
     item.fileSystemFileSize = it->size;
+    item.fileSystemId = blink::WebString::fromASCII(it->filesystem_id);
     item_list.push_back(item);
   }
 
diff --git a/docs/memory-infra/README.md b/docs/memory-infra/README.md
index aa759749..5066a650 100644
--- a/docs/memory-infra/README.md
+++ b/docs/memory-infra/README.md
@@ -105,7 +105,7 @@
 [discardable]:base/memory/discardable_memory.h
 [cc-memory]:  probe-cc.md
 [gpu-memory]: probe-gpu.md
-[partalloc]:  /third_party/WebKit/Source/wtf/allocator/PartitionAlloc.md
+[partalloc]:  /base/allocator/partition_allocator/PartitionAlloc.md
 
 ## Related Pages
 
diff --git a/media/base/audio_timestamp_helper.cc b/media/base/audio_timestamp_helper.cc
index 8694ae32..0d62c12 100644
--- a/media/base/audio_timestamp_helper.cc
+++ b/media/base/audio_timestamp_helper.cc
@@ -20,7 +20,7 @@
 // static
 int64_t AudioTimestampHelper::TimeToFrames(base::TimeDelta time,
                                            int samples_per_second) {
-  return time.InSecondsF() * samples_per_second;
+  return std::round(time.InSecondsF() * samples_per_second);
 }
 
 AudioTimestampHelper::AudioTimestampHelper(int samples_per_second)
diff --git a/media/base/audio_timestamp_helper_unittest.cc b/media/base/audio_timestamp_helper_unittest.cc
index 83bf57f1..0ae2ad5 100644
--- a/media/base/audio_timestamp_helper_unittest.cc
+++ b/media/base/audio_timestamp_helper_unittest.cc
@@ -80,9 +80,11 @@
   // Zero.
   EXPECT_EQ(0, AudioTimestampHelper::TimeToFrames(
                    base::TimeDelta::FromMicroseconds(0), k48kHz));
-  // Any duration less than 21 microseconds will return zero frames at 48 kHz
-  // because each frame is 20.833 microseconds.
+  // Duration of each frame is 20.833 microseconds. The result is rounded to
+  // integral.
   EXPECT_EQ(0, AudioTimestampHelper::TimeToFrames(
+                   base::TimeDelta::FromMicroseconds(10), k48kHz));
+  EXPECT_EQ(1, AudioTimestampHelper::TimeToFrames(
                    base::TimeDelta::FromMicroseconds(20), k48kHz));
   EXPECT_EQ(1, AudioTimestampHelper::TimeToFrames(
                    base::TimeDelta::FromMicroseconds(21), k48kHz));
diff --git a/third_party/WebKit/Source/core/BUILD.gn b/third_party/WebKit/Source/core/BUILD.gn
index 3537f1a6..9157c76 100644
--- a/third_party/WebKit/Source/core/BUILD.gn
+++ b/third_party/WebKit/Source/core/BUILD.gn
@@ -1105,17 +1105,15 @@
     "fetch/ClientHintsPreferencesTest.cpp",
     "fetch/CrossOriginAccessControlTest.cpp",
     "fetch/FetchUtilsTest.cpp",
-    "fetch/ImageResourceTest.cpp",
     "fetch/MemoryCacheCorrectnessTest.cpp",
     "fetch/MemoryCacheCorrectnessTestHelper.cpp",
     "fetch/MemoryCacheCorrectnessTestHelper.h",
     "fetch/MemoryCacheTest.cpp",
     "fetch/MockFetchContext.h",
-    "fetch/MockImageResourceClient.cpp",
-    "fetch/MockImageResourceClient.h",
+    "fetch/MockResource.cpp",
+    "fetch/MockResource.h",
     "fetch/MockResourceClient.cpp",
     "fetch/MockResourceClient.h",
-    "fetch/MultipartImageResourceParserTest.cpp",
     "fetch/RawResourceTest.cpp",
     "fetch/ResourceFetcherTest.cpp",
     "fetch/ResourceLoaderOptionsTest.cpp",
diff --git a/third_party/WebKit/Source/core/clipboard/DataObject.cpp b/third_party/WebKit/Source/core/clipboard/DataObject.cpp
index 5b1bbe5..ea267e8 100644
--- a/third_party/WebKit/Source/core/clipboard/DataObject.cpp
+++ b/third_party/WebKit/Source/core/clipboard/DataObject.cpp
@@ -106,7 +106,17 @@
     return nullptr;
 
   DataObjectItem* item = DataObjectItem::createFromFile(file);
-  m_itemList.push_back(item);
+  internalAddFileItem(item);
+  return item;
+}
+
+DataObjectItem* DataObject::add(File* file, const String& fileSystemId) {
+  if (!file)
+    return nullptr;
+
+  DataObjectItem* item =
+      DataObjectItem::createFromFileWithFileSystemId(file, fileSystemId);
+  internalAddFileItem(item);
   return item;
 }
 
@@ -206,9 +216,10 @@
 }
 
 void DataObject::addFilename(const String& filename,
-                             const String& displayName) {
-  internalAddFileItem(DataObjectItem::createFromFile(
-      File::createForUserProvidedFile(filename, displayName)));
+                             const String& displayName,
+                             const String& fileSystemId) {
+  internalAddFileItem(DataObjectItem::createFromFileWithFileSystemId(
+      File::createForUserProvidedFile(filename, displayName), fileSystemId));
 }
 
 void DataObject::addSharedBuffer(const String& name,
@@ -252,6 +263,7 @@
 
 DataObject* DataObject::create(WebDragData data) {
   DataObject* dataObject = create();
+  bool hasFileSystem = false;
 
   WebVector<WebDragData::Item> items = data.items();
   for (unsigned i = 0; i < items.size(); ++i) {
@@ -267,7 +279,9 @@
           dataObject->setData(item.stringType, item.stringData);
         break;
       case WebDragData::Item::StorageTypeFilename:
-        dataObject->addFilename(item.filenameData, item.displayNameData);
+        hasFileSystem = true;
+        dataObject->addFilename(item.filenameData, item.displayNameData,
+                                data.filesystemId());
         break;
       case WebDragData::Item::StorageTypeBinaryData:
         // This should never happen when dragging in.
@@ -275,17 +289,23 @@
       case WebDragData::Item::StorageTypeFileSystemFile: {
         // FIXME: The file system URL may refer a user visible file, see
         // http://crbug.com/429077
+        hasFileSystem = true;
         FileMetadata fileMetadata;
         fileMetadata.length = item.fileSystemFileSize;
-        dataObject->add(File::createForFileSystemFile(
-            item.fileSystemURL, fileMetadata, File::IsNotUserVisible));
+
+        dataObject->add(
+            File::createForFileSystemFile(item.fileSystemURL, fileMetadata,
+                                          File::IsNotUserVisible),
+            item.fileSystemId);
       } break;
     }
   }
 
-  if (!data.filesystemId().isNull())
-    DraggedIsolatedFileSystem::prepareForDataObject(dataObject,
-                                                    data.filesystemId());
+  dataObject->setFilesystemId(data.filesystemId());
+
+  if (hasFileSystem)
+    DraggedIsolatedFileSystem::prepareForDataObject(dataObject);
+
   return dataObject;
 }
 
@@ -318,6 +338,7 @@
             item.storageType = WebDragData::Item::StorageTypeFileSystemFile;
             item.fileSystemURL = file->fileSystemURL();
             item.fileSystemFileSize = file->size();
+            item.fileSystemId = originalItem->fileSystemId();
           } else {
             // FIXME: support dragging constructed Files across renderers, see
             // http://crbug.com/394955
diff --git a/third_party/WebKit/Source/core/clipboard/DataObject.h b/third_party/WebKit/Source/core/clipboard/DataObject.h
index de2a186..9cd3e3d3 100644
--- a/third_party/WebKit/Source/core/clipboard/DataObject.h
+++ b/third_party/WebKit/Source/core/clipboard/DataObject.h
@@ -72,6 +72,7 @@
   // Returns null if an item already exists with the provided type.
   DataObjectItem* add(const String& data, const String& type);
   DataObjectItem* add(File*);
+  DataObjectItem* add(File*, const String& fileSystemId);
 
   // WebCore helpers.
   void clearData(const String& type);
@@ -88,7 +89,9 @@
   // Used for dragging in files from the desktop.
   bool containsFilenames() const;
   Vector<String> filenames() const;
-  void addFilename(const String& filename, const String& displayName);
+  void addFilename(const String& filename,
+                   const String& displayName,
+                   const String& fileSystemId);
 
   // Used for dragging in filesystem from the desktop.
   void setFilesystemId(const String& fileSystemId) {
diff --git a/third_party/WebKit/Source/core/clipboard/DataObjectItem.cpp b/third_party/WebKit/Source/core/clipboard/DataObjectItem.cpp
index ca13837..314dc57 100644
--- a/third_party/WebKit/Source/core/clipboard/DataObjectItem.cpp
+++ b/third_party/WebKit/Source/core/clipboard/DataObjectItem.cpp
@@ -51,6 +51,15 @@
   return item;
 }
 
+DataObjectItem* DataObjectItem::createFromFileWithFileSystemId(
+    File* file,
+    const String& fileSystemId) {
+  DataObjectItem* item = new DataObjectItem(FileKind, file->type());
+  item->m_file = file;
+  item->m_fileSystemId = fileSystemId;
+  return item;
+}
+
 DataObjectItem* DataObjectItem::createFromURL(const String& url,
                                               const String& title) {
   DataObjectItem* item = new DataObjectItem(StringKind, mimeTypeTextURIList);
@@ -161,6 +170,14 @@
   return m_kind == FileKind && m_file;
 }
 
+bool DataObjectItem::hasFileSystemId() const {
+  return m_kind == FileKind && !m_fileSystemId.isEmpty();
+}
+
+String DataObjectItem::fileSystemId() const {
+  return m_fileSystemId;
+}
+
 DEFINE_TRACE(DataObjectItem) {
   visitor->trace(m_file);
 }
diff --git a/third_party/WebKit/Source/core/clipboard/DataObjectItem.h b/third_party/WebKit/Source/core/clipboard/DataObjectItem.h
index 419fc126..123eb78 100644
--- a/third_party/WebKit/Source/core/clipboard/DataObjectItem.h
+++ b/third_party/WebKit/Source/core/clipboard/DataObjectItem.h
@@ -50,6 +50,11 @@
   static DataObjectItem* createFromString(const String& type,
                                           const String& data);
   static DataObjectItem* createFromFile(File*);
+  // File with non-empty filesystem ID can be converted into FileEntry by using
+  // webkitGetAsEntry.
+  static DataObjectItem* createFromFileWithFileSystemId(
+      File*,
+      const String& fileSystemId);
   static DataObjectItem* createFromURL(const String& url, const String& title);
   static DataObjectItem* createFromHTML(const String& html,
                                         const KURL& baseURL);
@@ -70,6 +75,9 @@
   KURL baseURL() const { return m_baseURL; }
   bool isFilename() const;
 
+  bool hasFileSystemId() const;
+  String fileSystemId() const;
+
   DECLARE_TRACE();
 
  private:
@@ -93,6 +101,7 @@
   KURL m_baseURL;
 
   uint64_t m_sequenceNumber;  // Only valid when m_source == PasteboardSource
+  String m_fileSystemId;      // Only valid when m_file is backed by FileEntry.
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/clipboard/DataObjectTest.cpp b/third_party/WebKit/Source/core/clipboard/DataObjectTest.cpp
index 659dfe8..ef63afc1e 100644
--- a/third_party/WebKit/Source/core/clipboard/DataObjectTest.cpp
+++ b/third_party/WebKit/Source/core/clipboard/DataObjectTest.cpp
@@ -22,7 +22,7 @@
   String filePath = testing::blinkRootDir();
   filePath.append("/Source/core/clipboard/DataObjectTest.cpp");
 
-  m_dataObject->addFilename(filePath, String());
+  m_dataObject->addFilename(filePath, String(), String());
   EXPECT_EQ(1U, m_dataObject->length());
 
   DataObjectItem* item = m_dataObject->item(0);
@@ -40,7 +40,7 @@
   String filePath = testing::blinkRootDir();
   filePath.append("/Source/core/clipboard/DataObjectTest.cpp");
 
-  m_dataObject->addFilename(filePath, "name.cpp");
+  m_dataObject->addFilename(filePath, "name.cpp", String());
   EXPECT_EQ(1U, m_dataObject->length());
 
   DataObjectItem* item = m_dataObject->item(0);
@@ -55,4 +55,35 @@
   EXPECT_EQ("name.cpp", file->name());
 }
 
+TEST_F(DataObjectTest, fileSystemId) {
+  String filePath = testing::blinkRootDir();
+  filePath.append("/Source/core/clipboard/DataObjectTest.cpp");
+  KURL url;
+
+  m_dataObject->addFilename(filePath, String(), String());
+  m_dataObject->addFilename(filePath, String(), "fileSystemIdForFilename");
+  m_dataObject->add(
+      File::createForFileSystemFile(url, FileMetadata(), File::IsUserVisible),
+      "fileSystemIdForFileSystemFile");
+
+  ASSERT_EQ(3U, m_dataObject->length());
+
+  {
+    DataObjectItem* item = m_dataObject->item(0);
+    EXPECT_FALSE(item->hasFileSystemId());
+  }
+
+  {
+    DataObjectItem* item = m_dataObject->item(1);
+    EXPECT_TRUE(item->hasFileSystemId());
+    EXPECT_EQ("fileSystemIdForFilename", item->fileSystemId());
+  }
+
+  {
+    DataObjectItem* item = m_dataObject->item(2);
+    EXPECT_TRUE(item->hasFileSystemId());
+    EXPECT_EQ("fileSystemIdForFileSystemFile", item->fileSystemId());
+  }
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/clipboard/DataTransfer.cpp b/third_party/WebKit/Source/core/clipboard/DataTransfer.cpp
index 953afd5..4a4f2ff9 100644
--- a/third_party/WebKit/Source/core/clipboard/DataTransfer.cpp
+++ b/third_party/WebKit/Source/core/clipboard/DataTransfer.cpp
@@ -32,13 +32,13 @@
 #include "core/editing/EphemeralRange.h"
 #include "core/editing/FrameSelection.h"
 #include "core/editing/serializers/Serialization.h"
-#include "core/fetch/ImageResourceContent.h"
 #include "core/fileapi/FileList.h"
 #include "core/frame/LocalFrame.h"
 #include "core/html/HTMLImageElement.h"
 #include "core/html/TextControlElement.h"
 #include "core/layout/LayoutImage.h"
 #include "core/layout/LayoutObject.h"
+#include "core/loader/resource/ImageResourceContent.h"
 #include "platform/DragImage.h"
 #include "platform/clipboard/ClipboardMimeTypes.h"
 #include "platform/clipboard/ClipboardUtilities.h"
diff --git a/third_party/WebKit/Source/core/clipboard/DataTransfer.h b/third_party/WebKit/Source/core/clipboard/DataTransfer.h
index 13d54a2..658dffd 100644
--- a/third_party/WebKit/Source/core/clipboard/DataTransfer.h
+++ b/third_party/WebKit/Source/core/clipboard/DataTransfer.h
@@ -27,7 +27,7 @@
 #include "bindings/core/v8/ScriptWrappable.h"
 #include "core/CoreExport.h"
 #include "core/clipboard/DataTransferAccessPolicy.h"
-#include "core/fetch/ImageResourceContent.h"
+#include "core/loader/resource/ImageResourceContent.h"
 #include "core/page/DragActions.h"
 #include "platform/geometry/IntPoint.h"
 #include "platform/heap/Handle.h"
diff --git a/third_party/WebKit/Source/core/clipboard/DraggedIsolatedFileSystem.cpp b/third_party/WebKit/Source/core/clipboard/DraggedIsolatedFileSystem.cpp
index 0719936..88901aa 100644
--- a/third_party/WebKit/Source/core/clipboard/DraggedIsolatedFileSystem.cpp
+++ b/third_party/WebKit/Source/core/clipboard/DraggedIsolatedFileSystem.cpp
@@ -15,11 +15,9 @@
   s_prepareCallback = callback;
 }
 
-void DraggedIsolatedFileSystem::prepareForDataObject(
-    DataObject* dataObject,
-    const String& filesystemId) {
+void DraggedIsolatedFileSystem::prepareForDataObject(DataObject* dataObject) {
   ASSERT(s_prepareCallback);
-  (*s_prepareCallback)(dataObject, filesystemId);
+  (*s_prepareCallback)(dataObject);
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/clipboard/DraggedIsolatedFileSystem.h b/third_party/WebKit/Source/core/clipboard/DraggedIsolatedFileSystem.h
index 449f6ff..82389a6 100644
--- a/third_party/WebKit/Source/core/clipboard/DraggedIsolatedFileSystem.h
+++ b/third_party/WebKit/Source/core/clipboard/DraggedIsolatedFileSystem.h
@@ -20,10 +20,10 @@
   DraggedIsolatedFileSystem() {}
   virtual ~DraggedIsolatedFileSystem() {}
 
-  using FileSystemIdPreparationCallback = void (*)(DataObject*, const String&);
+  using FileSystemIdPreparationCallback = void (*)(DataObject*);
   static void init(FileSystemIdPreparationCallback);
 
-  static void prepareForDataObject(DataObject*, const String& filesystemId);
+  static void prepareForDataObject(DataObject*);
 
  private:
   static FileSystemIdPreparationCallback s_prepareCallback;
diff --git a/third_party/WebKit/Source/core/css/CSSCrossfadeValue.h b/third_party/WebKit/Source/core/css/CSSCrossfadeValue.h
index ac154b2..4ecdce7 100644
--- a/third_party/WebKit/Source/core/css/CSSCrossfadeValue.h
+++ b/third_party/WebKit/Source/core/css/CSSCrossfadeValue.h
@@ -29,8 +29,8 @@
 #include "core/CoreExport.h"
 #include "core/css/CSSImageGeneratorValue.h"
 #include "core/css/CSSPrimitiveValue.h"
-#include "core/fetch/ImageResourceContent.h"
-#include "core/fetch/ImageResourceObserver.h"
+#include "core/loader/resource/ImageResourceContent.h"
+#include "core/loader/resource/ImageResourceObserver.h"
 #include "platform/graphics/Image.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/css/CSSImageSetValue.cpp b/third_party/WebKit/Source/core/css/CSSImageSetValue.cpp
index 136c933..eedc255 100644
--- a/third_party/WebKit/Source/core/css/CSSImageSetValue.cpp
+++ b/third_party/WebKit/Source/core/css/CSSImageSetValue.cpp
@@ -30,10 +30,10 @@
 #include "core/dom/Document.h"
 #include "core/fetch/FetchInitiatorTypeNames.h"
 #include "core/fetch/FetchRequest.h"
-#include "core/fetch/ImageResourceContent.h"
 #include "core/fetch/ResourceFetcher.h"
 #include "core/fetch/ResourceLoaderOptions.h"
 #include "core/frame/Settings.h"
+#include "core/loader/resource/ImageResourceContent.h"
 #include "core/style/StyleFetchedImageSet.h"
 #include "core/style/StyleInvalidImage.h"
 #include "platform/weborigin/KURL.h"
diff --git a/third_party/WebKit/Source/core/css/CSSImageValue.cpp b/third_party/WebKit/Source/core/css/CSSImageValue.cpp
index 727f81c9..e2f9a5e 100644
--- a/third_party/WebKit/Source/core/css/CSSImageValue.cpp
+++ b/third_party/WebKit/Source/core/css/CSSImageValue.cpp
@@ -24,9 +24,9 @@
 #include "core/dom/Document.h"
 #include "core/fetch/FetchInitiatorTypeNames.h"
 #include "core/fetch/FetchRequest.h"
-#include "core/fetch/ImageResourceContent.h"
 #include "core/fetch/ResourceFetcher.h"
 #include "core/frame/Settings.h"
+#include "core/loader/resource/ImageResourceContent.h"
 #include "core/style/StyleFetchedImage.h"
 #include "core/style/StyleInvalidImage.h"
 #include "platform/CrossOriginAttributeValue.h"
diff --git a/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h b/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h
index 84f09b5..7f34a978 100644
--- a/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h
+++ b/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h
@@ -1896,25 +1896,25 @@
 inline CSSIdentifierValue::CSSIdentifierValue(EOverflow e)
     : CSSValue(IdentifierClass) {
   switch (e) {
-    case OverflowVisible:
+    case EOverflow::Visible:
       m_valueID = CSSValueVisible;
       break;
-    case OverflowHidden:
+    case EOverflow::Hidden:
       m_valueID = CSSValueHidden;
       break;
-    case OverflowScroll:
+    case EOverflow::Scroll:
       m_valueID = CSSValueScroll;
       break;
-    case OverflowAuto:
+    case EOverflow::Auto:
       m_valueID = CSSValueAuto;
       break;
-    case OverflowOverlay:
+    case EOverflow::Overlay:
       m_valueID = CSSValueOverlay;
       break;
-    case OverflowPagedX:
+    case EOverflow::PagedX:
       m_valueID = CSSValueWebkitPagedX;
       break;
-    case OverflowPagedY:
+    case EOverflow::PagedY:
       m_valueID = CSSValueWebkitPagedY;
       break;
   }
@@ -1924,25 +1924,25 @@
 inline EOverflow CSSIdentifierValue::convertTo() const {
   switch (m_valueID) {
     case CSSValueVisible:
-      return OverflowVisible;
+      return EOverflow::Visible;
     case CSSValueHidden:
-      return OverflowHidden;
+      return EOverflow::Hidden;
     case CSSValueScroll:
-      return OverflowScroll;
+      return EOverflow::Scroll;
     case CSSValueAuto:
-      return OverflowAuto;
+      return EOverflow::Auto;
     case CSSValueOverlay:
-      return OverflowOverlay;
+      return EOverflow::Overlay;
     case CSSValueWebkitPagedX:
-      return OverflowPagedX;
+      return EOverflow::PagedX;
     case CSSValueWebkitPagedY:
-      return OverflowPagedY;
+      return EOverflow::PagedY;
     default:
       break;
   }
 
   ASSERT_NOT_REACHED();
-  return OverflowVisible;
+  return EOverflow::Visible;
 }
 
 template <>
diff --git a/third_party/WebKit/Source/core/css/CSSProperties.in b/third_party/WebKit/Source/core/css/CSSProperties.in
index 8c80b934..26ed284 100644
--- a/third_party/WebKit/Source/core/css/CSSProperties.in
+++ b/third_party/WebKit/Source/core/css/CSSProperties.in
@@ -324,7 +324,7 @@
 paint-order inherited, svg, converter=convertPaintOrder
 perspective interpolable, converter=convertPerspective
 perspective-origin interpolable, converter=convertPosition
-pointer-events inherited, independent
+pointer-events inherited, independent, keyword_only, keywords=[none|auto|stroke|fill|painted|visible|visibleStroke|visibleFill|visiblePainted|bounding-box|all], initial_keyword=auto
 position custom_inherit
 quotes inherited, converter=convertQuotes
 resize custom_value
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSStyleImageValue.h b/third_party/WebKit/Source/core/css/cssom/CSSStyleImageValue.h
index a380f4f..a561eb2 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSStyleImageValue.h
+++ b/third_party/WebKit/Source/core/css/cssom/CSSStyleImageValue.h
@@ -10,9 +10,9 @@
 #include "core/css/CSSImageValue.h"
 #include "core/css/cssom/CSSResourceValue.h"
 #include "core/css/cssom/CSSStyleValue.h"
-#include "core/fetch/ImageResourceContent.h"
 #include "core/html/canvas/CanvasImageSource.h"
 #include "core/imagebitmap/ImageBitmapSource.h"
+#include "core/loader/resource/ImageResourceContent.h"
 #include "core/style/StyleImage.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/css/resolver/StyleAdjuster.cpp b/third_party/WebKit/Source/core/css/resolver/StyleAdjuster.cpp
index 5ba97158..55275ee 100644
--- a/third_party/WebKit/Source/core/css/resolver/StyleAdjuster.cpp
+++ b/third_party/WebKit/Source/core/css/resolver/StyleAdjuster.cpp
@@ -230,8 +230,8 @@
   if (isHTMLFrameElementBase(element)) {
     // Frames cannot overflow (they are always the size we ask them to be).
     // Some compositing code paths may try to draw scrollbars anyhow.
-    style.setOverflowX(OverflowVisible);
-    style.setOverflowY(OverflowVisible);
+    style.setOverflowX(EOverflow::Visible);
+    style.setOverflowY(EOverflow::Visible);
     return;
   }
 
@@ -250,18 +250,18 @@
 
   if (isHTMLMarqueeElement(element)) {
     // For now, <marquee> requires an overflow clip to work properly.
-    style.setOverflowX(OverflowHidden);
-    style.setOverflowY(OverflowHidden);
+    style.setOverflowX(EOverflow::Hidden);
+    style.setOverflowY(EOverflow::Hidden);
     return;
   }
 
   if (isHTMLTextAreaElement(element)) {
     // Textarea considers overflow visible as auto.
-    style.setOverflowX(style.overflowX() == OverflowVisible
-                           ? OverflowAuto
+    style.setOverflowX(style.overflowX() == EOverflow::Visible
+                           ? EOverflow::Auto
                            : style.overflowX());
-    style.setOverflowY(style.overflowY() == OverflowVisible
-                           ? OverflowAuto
+    style.setOverflowY(style.overflowY() == EOverflow::Visible
+                           ? EOverflow::Auto
                            : style.overflowY());
     return;
   }
@@ -274,8 +274,8 @@
 }
 
 static void adjustOverflow(ComputedStyle& style) {
-  ASSERT(style.overflowX() != OverflowVisible ||
-         style.overflowY() != OverflowVisible);
+  DCHECK(style.overflowX() != EOverflow::Visible ||
+         style.overflowY() != EOverflow::Visible);
 
   if (style.display() == EDisplay::Table ||
       style.display() == EDisplay::InlineTable) {
@@ -284,34 +284,34 @@
     // a table is not a block container box the rules for resolving conflicting
     // x and y values in CSS Overflow Module Level 3 do not apply. Arguably
     // overflow-x and overflow-y aren't allowed on tables but all UAs allow it.
-    if (style.overflowX() != OverflowHidden)
-      style.setOverflowX(OverflowVisible);
-    if (style.overflowY() != OverflowHidden)
-      style.setOverflowY(OverflowVisible);
+    if (style.overflowX() != EOverflow::Hidden)
+      style.setOverflowX(EOverflow::Visible);
+    if (style.overflowY() != EOverflow::Hidden)
+      style.setOverflowY(EOverflow::Visible);
     // If we are left with conflicting overflow values for the x and y axes on a
     // table then resolve both to OverflowVisible. This is interoperable
     // behaviour but is not specced anywhere.
-    if (style.overflowX() == OverflowVisible)
-      style.setOverflowY(OverflowVisible);
-    else if (style.overflowY() == OverflowVisible)
-      style.setOverflowX(OverflowVisible);
-  } else if (style.overflowX() == OverflowVisible &&
-             style.overflowY() != OverflowVisible) {
+    if (style.overflowX() == EOverflow::Visible)
+      style.setOverflowY(EOverflow::Visible);
+    else if (style.overflowY() == EOverflow::Visible)
+      style.setOverflowX(EOverflow::Visible);
+  } else if (style.overflowX() == EOverflow::Visible &&
+             style.overflowY() != EOverflow::Visible) {
     // If either overflow value is not visible, change to auto.
     // FIXME: Once we implement pagination controls, overflow-x should default
     // to hidden if overflow-y is set to -webkit-paged-x or -webkit-page-y. For
     // now, we'll let it default to auto so we can at least scroll through the
     // pages.
-    style.setOverflowX(OverflowAuto);
-  } else if (style.overflowY() == OverflowVisible &&
-             style.overflowX() != OverflowVisible) {
-    style.setOverflowY(OverflowAuto);
+    style.setOverflowX(EOverflow::Auto);
+  } else if (style.overflowY() == EOverflow::Visible &&
+             style.overflowX() != EOverflow::Visible) {
+    style.setOverflowY(EOverflow::Auto);
   }
 
   // Menulists should have visible overflow
   if (style.appearance() == MenulistPart) {
-    style.setOverflowX(OverflowVisible);
-    style.setOverflowY(OverflowVisible);
+    style.setOverflowX(EOverflow::Visible);
+    style.setOverflowY(EOverflow::Visible);
   }
 }
 
@@ -433,8 +433,8 @@
     style.setIsStackingContext(true);
   }
 
-  if (style.overflowX() != OverflowVisible ||
-      style.overflowY() != OverflowVisible)
+  if (style.overflowX() != EOverflow::Visible ||
+      style.overflowY() != EOverflow::Visible)
     adjustOverflow(style);
 
   if (doesNotInheritTextDecoration(style, element))
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp
index 13592b8..ed0d0860 100644
--- a/third_party/WebKit/Source/core/dom/Document.cpp
+++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -1806,8 +1806,8 @@
   }
 
   EOverflowAnchor overflowAnchor = EOverflowAnchor::Auto;
-  EOverflow overflowX = OverflowAuto;
-  EOverflow overflowY = OverflowAuto;
+  EOverflow overflowX = EOverflow::Auto;
+  EOverflow overflowY = EOverflow::Auto;
   float columnGap = 0;
   if (overflowStyle) {
     overflowAnchor = overflowStyle->overflowAnchor();
@@ -1815,10 +1815,10 @@
     overflowY = overflowStyle->overflowY();
     // Visible overflow on the viewport is meaningless, and the spec says to
     // treat it as 'auto':
-    if (overflowX == OverflowVisible)
-      overflowX = OverflowAuto;
-    if (overflowY == OverflowVisible)
-      overflowY = OverflowAuto;
+    if (overflowX == EOverflow::Visible)
+      overflowX = EOverflow::Auto;
+    if (overflowY == EOverflow::Visible)
+      overflowY = EOverflow::Auto;
     if (overflowAnchor == EOverflowAnchor::Visible)
       overflowAnchor = EOverflowAnchor::Auto;
     // Column-gap is (ab)used by the current paged overflow implementation (in
diff --git a/third_party/WebKit/Source/core/editing/Editor.cpp b/third_party/WebKit/Source/core/editing/Editor.cpp
index 8aea7a9..47433a7 100644
--- a/third_party/WebKit/Source/core/editing/Editor.cpp
+++ b/third_party/WebKit/Source/core/editing/Editor.cpp
@@ -62,7 +62,6 @@
 #include "core/events/KeyboardEvent.h"
 #include "core/events/ScopedEventQueue.h"
 #include "core/events/TextEvent.h"
-#include "core/fetch/ImageResourceContent.h"
 #include "core/fetch/ResourceFetcher.h"
 #include "core/frame/FrameView.h"
 #include "core/frame/LocalFrame.h"
@@ -80,6 +79,7 @@
 #include "core/layout/HitTestResult.h"
 #include "core/layout/LayoutImage.h"
 #include "core/loader/EmptyClients.h"
+#include "core/loader/resource/ImageResourceContent.h"
 #include "core/page/DragData.h"
 #include "core/page/EditorClient.h"
 #include "core/page/FocusController.h"
diff --git a/third_party/WebKit/Source/core/editing/commands/EditorCommand.cpp b/third_party/WebKit/Source/core/editing/commands/EditorCommand.cpp
index da67f2e..015917c 100644
--- a/third_party/WebKit/Source/core/editing/commands/EditorCommand.cpp
+++ b/third_party/WebKit/Source/core/editing/commands/EditorCommand.cpp
@@ -477,8 +477,8 @@
   const ComputedStyle* style = layoutBox.style();
   if (!style)
     return 0;
-  if (!(style->overflowY() == OverflowScroll ||
-        style->overflowY() == OverflowAuto ||
+  if (!(style->overflowY() == EOverflow::Scroll ||
+        style->overflowY() == EOverflow::Auto ||
         hasEditableStyle(*focusedElement)))
     return 0;
   int height = std::min<int>(layoutBox.clientHeight().toInt(),
diff --git a/third_party/WebKit/Source/core/fetch/BUILD.gn b/third_party/WebKit/Source/core/fetch/BUILD.gn
index b0aa502..7bc81db 100644
--- a/third_party/WebKit/Source/core/fetch/BUILD.gn
+++ b/third_party/WebKit/Source/core/fetch/BUILD.gn
@@ -21,17 +21,10 @@
     "FetchRequest.h",
     "FetchUtils.cpp",
     "FetchUtils.h",
-    "ImageResource.cpp",
-    "ImageResource.h",
-    "ImageResourceContent.cpp",
-    "ImageResourceContent.h",
-    "ImageResourceInfo.h",
     "IntegrityMetadata.cpp",
     "IntegrityMetadata.h",
     "MemoryCache.cpp",
     "MemoryCache.h",
-    "MultipartImageResourceParser.cpp",
-    "MultipartImageResourceParser.h",
     "RawResource.cpp",
     "RawResource.h",
     "Resource.cpp",
diff --git a/third_party/WebKit/Source/core/fetch/DEPS b/third_party/WebKit/Source/core/fetch/DEPS
index f2a592e7..a3fb599e 100644
--- a/third_party/WebKit/Source/core/fetch/DEPS
+++ b/third_party/WebKit/Source/core/fetch/DEPS
@@ -2,9 +2,4 @@
     "-core",
     "+core/CoreExport.h",
     "+core/fetch",
-
-    # core/fetch/ shouldn't depend on anything else in core/,
-    # but has not been fully isolated yet.
-    # Do not add to this list.
-    "!core/svg/graphics/SVGImage.h",
 ]
diff --git a/third_party/WebKit/Source/core/fetch/MemoryCacheCorrectnessTest.cpp b/third_party/WebKit/Source/core/fetch/MemoryCacheCorrectnessTest.cpp
index 69f71fc..5da4703 100644
--- a/third_party/WebKit/Source/core/fetch/MemoryCacheCorrectnessTest.cpp
+++ b/third_party/WebKit/Source/core/fetch/MemoryCacheCorrectnessTest.cpp
@@ -31,8 +31,8 @@
 #include "core/fetch/MemoryCache.h"
 
 #include "core/fetch/FetchRequest.h"
-#include "core/fetch/ImageResource.h"
 #include "core/fetch/MemoryCacheCorrectnessTestHelper.h"
+#include "core/fetch/MockResource.h"
 #include "core/fetch/RawResource.h"
 #include "core/fetch/Resource.h"
 #include "platform/network/ResourceRequest.h"
@@ -42,21 +42,23 @@
 
 class MemoryCacheCorrectnessTest : public MemoryCacheCorrectnessTestHelper {
  protected:
-  Resource* fetchImage() {
+  Resource* fetchMockResource() {
     FetchRequest fetchRequest(
         ResourceRequest(KURL(ParsedURLString, kResourceURL)),
         FetchInitiatorInfo());
-    return ImageResource::fetch(fetchRequest, fetcher());
+    return MockResource::fetch(fetchRequest, fetcher());
   }
 
  private:
   Resource* createResource(const ResourceRequest& request,
                            Resource::Type type) override {
+    // TODO(toyoshim): Consider to use MockResource for all tests instead of
+    // RawResource.
     switch (type) {
       case Resource::Raw:
         return RawResource::create(request, type);
-      case Resource::Image:
-        return ImageResource::create(request);
+      case Resource::Mock:
+        return MockResource::create(request);
       default:
         EXPECT_TRUE(false) << "'Unreachable' code was reached";
         break;
@@ -148,48 +150,48 @@
   EXPECT_NE(expired200, fetched);
 }
 
-// If the image hasn't been loaded in this "document" before, then it shouldn't
-// have list of available images logic.
-TEST_F(MemoryCacheCorrectnessTest, NewImageExpiredFromExpires) {
+// If the resource hasn't been loaded in this "document" before, then it
+// shouldn't have list of available resources logic.
+TEST_F(MemoryCacheCorrectnessTest, NewMockResourceExpiredFromExpires) {
   ResourceResponse expired200Response;
   expired200Response.setHTTPStatusCode(200);
   expired200Response.setHTTPHeaderField("Date", kOriginalRequestDateAsString);
   expired200Response.setHTTPHeaderField("Expires", kOneDayAfterOriginalRequest);
 
   Resource* expired200 =
-      resourceFromResourceResponse(expired200Response, Resource::Image);
+      resourceFromResourceResponse(expired200Response, Resource::Mock);
 
   // Advance the clock within the expiredness period of this resource before we
   // make a request.
   advanceClock(24. * 60. * 60. + 15.);
 
-  Resource* fetched = fetchImage();
+  Resource* fetched = fetchMockResource();
   EXPECT_NE(expired200, fetched);
 }
 
-// If the image has been loaded in this "document" before, then it should have
-// list of available images logic, and so normal cache testing should be
+// If the resource has been loaded in this "document" before, then it should
+// have list of available resources logic, and so normal cache testing should be
 // bypassed.
-TEST_F(MemoryCacheCorrectnessTest, ReuseImageExpiredFromExpires) {
+TEST_F(MemoryCacheCorrectnessTest, ReuseMockResourceExpiredFromExpires) {
   ResourceResponse expired200Response;
   expired200Response.setHTTPStatusCode(200);
   expired200Response.setHTTPHeaderField("Date", kOriginalRequestDateAsString);
   expired200Response.setHTTPHeaderField("Expires", kOneDayAfterOriginalRequest);
 
   Resource* expired200 =
-      resourceFromResourceResponse(expired200Response, Resource::Image);
+      resourceFromResourceResponse(expired200Response, Resource::Mock);
 
   // Advance the clock within the freshness period, and make a request to add
-  // this image to the document resources.
+  // this resource to the document resources.
   advanceClock(15.);
-  Resource* firstFetched = fetchImage();
+  Resource* firstFetched = fetchMockResource();
   EXPECT_EQ(expired200, firstFetched);
 
   // Advance the clock within the expiredness period of this resource before we
   // make a request.
   advanceClock(24. * 60. * 60. + 15.);
 
-  Resource* fetched = fetchImage();
+  Resource* fetched = fetchMockResource();
   EXPECT_EQ(expired200, fetched);
 }
 
diff --git a/third_party/WebKit/Source/core/fetch/MemoryCacheCorrectnessTestHelper.cpp b/third_party/WebKit/Source/core/fetch/MemoryCacheCorrectnessTestHelper.cpp
index 8003353..bf0d022 100644
--- a/third_party/WebKit/Source/core/fetch/MemoryCacheCorrectnessTestHelper.cpp
+++ b/third_party/WebKit/Source/core/fetch/MemoryCacheCorrectnessTestHelper.cpp
@@ -40,11 +40,6 @@
   Resource* resource = createResource(ResourceRequest(response.url()), type);
   resource->setResponse(response);
   resource->finish();
-  // Because we didn't give any real data, an image will have set its status
-  // to DecodeError. Override it so the resource is cacaheable for testing
-  // purposes.
-  if (type == Resource::Image)
-    resource->setStatus(Resource::Cached);
   memoryCache()->add(resource);
 
   return resource;
diff --git a/third_party/WebKit/Source/core/fetch/MockResource.cpp b/third_party/WebKit/Source/core/fetch/MockResource.cpp
new file mode 100644
index 0000000..57796d0
--- /dev/null
+++ b/third_party/WebKit/Source/core/fetch/MockResource.cpp
@@ -0,0 +1,46 @@
+// 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 "core/fetch/MockResource.h"
+
+#include "core/fetch/FetchRequest.h"
+#include "core/fetch/ResourceFetcher.h"
+#include "core/fetch/ResourceLoaderOptions.h"
+
+namespace blink {
+
+namespace {
+
+class MockResourceFactory final : public ResourceFactory {
+ public:
+  MockResourceFactory() : ResourceFactory(Resource::Mock) {}
+
+  Resource* create(const ResourceRequest& request,
+                   const ResourceLoaderOptions& options,
+                   const String&) const override {
+    return new MockResource(request, options);
+  }
+};
+
+}  // namespace
+
+// static
+MockResource* MockResource::fetch(FetchRequest& request,
+                                  ResourceFetcher* fetcher) {
+  request.mutableResourceRequest().setRequestContext(
+      WebURLRequest::RequestContextSubresource);
+  Resource* resource = fetcher->requestResource(request, MockResourceFactory());
+  return static_cast<MockResource*>(resource);
+}
+
+// static
+MockResource* MockResource::create(const ResourceRequest& request) {
+  return new MockResource(request, ResourceLoaderOptions());
+}
+
+MockResource::MockResource(const ResourceRequest& request,
+                           const ResourceLoaderOptions& options)
+    : Resource(request, Resource::Mock, options) {}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/core/fetch/MockResource.h b/third_party/WebKit/Source/core/fetch/MockResource.h
new file mode 100644
index 0000000..b9e227d
--- /dev/null
+++ b/third_party/WebKit/Source/core/fetch/MockResource.h
@@ -0,0 +1,30 @@
+// 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 MockResource_h
+#define MockResource_h
+
+#include "core/fetch/Resource.h"
+#include "platform/heap/Handle.h"
+
+namespace blink {
+
+class FetchRequest;
+class ResourceFetcher;
+struct ResourceLoaderOptions;
+
+// Mocked Resource sub-class for testing. MockResource class can pretend a type
+// of Resource sub-class in a simple way. You should not expect anything
+// complicated to emulate actual sub-resources, but you may be able to use this
+// class to verify classes that consume Resource sub-classes in a simple way.
+class MockResource final : public Resource {
+ public:
+  static MockResource* fetch(FetchRequest&, ResourceFetcher*);
+  static MockResource* create(const ResourceRequest&);
+  MockResource(const ResourceRequest&, const ResourceLoaderOptions&);
+};
+
+}  // namespace blink
+
+#endif
diff --git a/third_party/WebKit/Source/core/fetch/Resource.cpp b/third_party/WebKit/Source/core/fetch/Resource.cpp
index 623946b..44b796f 100644
--- a/third_party/WebKit/Source/core/fetch/Resource.cpp
+++ b/third_party/WebKit/Source/core/fetch/Resource.cpp
@@ -1080,6 +1080,8 @@
       return "Media";
     case Resource::Manifest:
       return "Manifest";
+    case Resource::Mock:
+      return "Mock";
   }
   NOTREACHED();
   return initatorTypeNameToString(initiatorInfo.name);
@@ -1105,6 +1107,7 @@
     case Resource::TextTrack:
     case Resource::Media:
     case Resource::Manifest:
+    case Resource::Mock:
       return false;
   }
   NOTREACHED();
diff --git a/third_party/WebKit/Source/core/fetch/Resource.h b/third_party/WebKit/Source/core/fetch/Resource.h
index da5a776..22156e87 100644
--- a/third_party/WebKit/Source/core/fetch/Resource.h
+++ b/third_party/WebKit/Source/core/fetch/Resource.h
@@ -81,9 +81,10 @@
     TextTrack,
     ImportResource,
     Media,  // Audio or video file requested by a HTML5 media element
-    Manifest
+    Manifest,
+    Mock  // Only for testing
   };
-  static const int kLastResourceType = Manifest + 1;
+  static const int kLastResourceType = Mock + 1;
 
   using Status = ResourceStatus;
 
diff --git a/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp b/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp
index d62822a2..5163256 100644
--- a/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp
+++ b/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp
@@ -88,6 +88,7 @@
     DEFINE_SINGLE_RESOURCE_HISTOGRAM(prefix, MainResource)   \
     DEFINE_SINGLE_RESOURCE_HISTOGRAM(prefix, Manifest)       \
     DEFINE_SINGLE_RESOURCE_HISTOGRAM(prefix, Media)          \
+    DEFINE_SINGLE_RESOURCE_HISTOGRAM(prefix, Mock)           \
     DEFINE_SINGLE_RESOURCE_HISTOGRAM(prefix, Raw)            \
     DEFINE_SINGLE_RESOURCE_HISTOGRAM(prefix, Script)         \
     DEFINE_SINGLE_RESOURCE_HISTOGRAM(prefix, SVGDocument)    \
@@ -132,6 +133,7 @@
       // Also visible resources/images (set explicitly in loadPriority)
       return ResourceLoadPriorityHigh;
     case Resource::Manifest:
+    case Resource::Mock:
       // Also late-body scripts discovered by the preload scanner (set
       // explicitly in loadPriority)
       return ResourceLoadPriorityMedium;
@@ -237,6 +239,8 @@
       return WebURLRequest::RequestContextVideo;
     case Resource::Manifest:
       return WebURLRequest::RequestContextManifest;
+    case Resource::Mock:
+      return WebURLRequest::RequestContextSubresource;
   }
   NOTREACHED();
   return WebURLRequest::RequestContextSubresource;
@@ -1372,6 +1376,9 @@
         raws++;
         rawMisses += missCount;
         break;
+      case Resource::Mock:
+        // Do not count Resource::Mock because this type is only for testing.
+        break;
       default:
         NOTREACHED();
     }
diff --git a/third_party/WebKit/Source/core/fetch/ResourceFetcherTest.cpp b/third_party/WebKit/Source/core/fetch/ResourceFetcherTest.cpp
index a0ecc90..595f3b9 100644
--- a/third_party/WebKit/Source/core/fetch/ResourceFetcherTest.cpp
+++ b/third_party/WebKit/Source/core/fetch/ResourceFetcherTest.cpp
@@ -33,9 +33,9 @@
 #include "core/fetch/FetchInitiatorInfo.h"
 #include "core/fetch/FetchInitiatorTypeNames.h"
 #include "core/fetch/FetchRequest.h"
-#include "core/fetch/ImageResource.h"
 #include "core/fetch/MemoryCache.h"
 #include "core/fetch/MockFetchContext.h"
+#include "core/fetch/MockResource.h"
 #include "core/fetch/MockResourceClient.h"
 #include "core/fetch/RawResource.h"
 #include "core/fetch/ResourceLoader.h"
@@ -62,8 +62,9 @@
 namespace blink {
 
 namespace {
-const char testImageFilename[] = "white-1x1.png";
-const int testImageSize = 103;  // size of web/tests/data/white-1x1.png
+constexpr char kTestResourceFilename[] = "white-1x1.png";
+constexpr char kTestResourceMimeType[] = "image/png";
+constexpr int kTestResourceSize = 103;  // size of web/tests/data/white-1x1.png
 }
 
 class ResourceFetcherTest : public ::testing::Test {};
@@ -98,18 +99,18 @@
   response.setHTTPStatusCode(200);
   response.setHTTPHeaderField(HTTPNames::Cache_Control, "max-age=3600");
   URLTestHelpers::registerMockedURLLoadWithCustomResponse(
-      url, testImageFilename, WebString::fromUTF8(""),
+      url, kTestResourceFilename, WebString::fromUTF8(""),
       WrappedResourceResponse(response));
 
   FetchRequest fetchRequest = FetchRequest(url, FetchInitiatorInfo());
-  Resource* resource = ImageResource::fetch(fetchRequest, fetcher);
+  Resource* resource = MockResource::fetch(fetchRequest, fetcher);
   ASSERT_TRUE(resource);
   Platform::current()->getURLLoaderMockFactory()->serveAsynchronousRequests();
   Platform::current()->getURLLoaderMockFactory()->unregisterURL(url);
   EXPECT_TRUE(resource->isLoaded());
   EXPECT_TRUE(memoryCache()->contains(resource));
 
-  Resource* newResource = ImageResource::fetch(fetchRequest, fetcher);
+  Resource* newResource = MockResource::fetch(fetchRequest, fetcher);
   EXPECT_EQ(resource, newResource);
   memoryCache()->remove(resource);
 }
@@ -212,7 +213,7 @@
   memoryCache()->remove(newResource);
 }
 
-TEST_F(ResourceFetcherTest, VaryImage) {
+TEST_F(ResourceFetcherTest, VaryResource) {
   ResourceFetcher* fetcher = ResourceFetcher::create(
       MockFetchContext::create(MockFetchContext::kShouldLoadNewResource));
 
@@ -223,17 +224,17 @@
   response.setHTTPHeaderField(HTTPNames::Cache_Control, "max-age=3600");
   response.setHTTPHeaderField(HTTPNames::Vary, "*");
   URLTestHelpers::registerMockedURLLoadWithCustomResponse(
-      url, testImageFilename, WebString::fromUTF8(""),
+      url, kTestResourceFilename, WebString::fromUTF8(""),
       WrappedResourceResponse(response));
 
   FetchRequest fetchRequestOriginal = FetchRequest(url, FetchInitiatorInfo());
-  Resource* resource = ImageResource::fetch(fetchRequestOriginal, fetcher);
+  Resource* resource = MockResource::fetch(fetchRequestOriginal, fetcher);
   ASSERT_TRUE(resource);
   Platform::current()->getURLLoaderMockFactory()->serveAsynchronousRequests();
   ASSERT_TRUE(resource->hasVaryHeader());
 
   FetchRequest fetchRequest = FetchRequest(url, FetchInitiatorInfo());
-  Resource* newResource = ImageResource::fetch(fetchRequest, fetcher);
+  Resource* newResource = MockResource::fetch(fetchRequest, fetcher);
   EXPECT_EQ(resource, newResource);
 
   memoryCache()->remove(newResource);
@@ -256,7 +257,7 @@
     context->setCachePolicy(CachePolicyRevalidate);
     ResourceFetcher* fetcher2 = ResourceFetcher::create(context);
     FetchRequest fetchRequest2(m_resource->url(), FetchInitiatorInfo());
-    Resource* resource2 = ImageResource::fetch(fetchRequest2, fetcher2);
+    Resource* resource2 = MockResource::fetch(fetchRequest2, fetcher2);
     EXPECT_EQ(m_resource, resource2);
     m_notifyFinishedCalled = true;
   }
@@ -282,14 +283,14 @@
   response.setHTTPHeaderField(HTTPNames::Cache_Control, "max-age=3600");
   response.setHTTPHeaderField(HTTPNames::ETag, "1234567890");
   URLTestHelpers::registerMockedURLLoadWithCustomResponse(
-      url, testImageFilename, WebString::fromUTF8(""),
+      url, kTestResourceFilename, WebString::fromUTF8(""),
       WrappedResourceResponse(response));
   ResourceFetcher* fetcher1 = ResourceFetcher::create(
       MockFetchContext::create(MockFetchContext::kShouldLoadNewResource));
   ResourceRequest request1(url);
   request1.setHTTPHeaderField(HTTPNames::Cache_Control, "no-cache");
   FetchRequest fetchRequest1 = FetchRequest(request1, FetchInitiatorInfo());
-  Resource* resource1 = ImageResource::fetch(fetchRequest1, fetcher1);
+  Resource* resource1 = MockResource::fetch(fetchRequest1, fetcher1);
   Persistent<RequestSameResourceOnComplete> client =
       new RequestSameResourceOnComplete(resource1);
   resource1->addClient(client);
@@ -364,7 +365,8 @@
 // network response, leading to an invalid state transition in ResourceLoader.
 TEST_F(ResourceFetcherTest, ResponseOnCancel) {
   KURL url(ParsedURLString, "http://127.0.0.1:8000/foo.png");
-  URLTestHelpers::registerMockedURLLoad(url, testImageFilename, "image/png");
+  URLTestHelpers::registerMockedURLLoad(url, kTestResourceFilename,
+                                        kTestResourceMimeType);
 
   ResourceFetcher* fetcher = ResourceFetcher::create(
       MockFetchContext::create(MockFetchContext::kShouldLoadNewResource));
@@ -403,7 +405,7 @@
 
   void registerFinalResource(const WebString& url) {
     KURL finalURL(ParsedURLString, url);
-    URLTestHelpers::registerMockedURLLoad(finalURL, testImageFilename);
+    URLTestHelpers::registerMockedURLLoad(finalURL, kTestResourceFilename);
   }
 
   void request(const WebString& url) {
@@ -438,7 +440,7 @@
   requester.registerFinalResource(finalURL);
   requester.request(redirectURL);
 
-  EXPECT_EQ(kRedirectResponseOverheadBytes + testImageSize,
+  EXPECT_EQ(kRedirectResponseOverheadBytes + kTestResourceSize,
             requester.context()->getTransferSize());
 }
 
@@ -450,7 +452,7 @@
   requester.registerFinalResource(finalURL);
   requester.request(redirectURL);
 
-  EXPECT_EQ(testImageSize, requester.context()->getTransferSize());
+  EXPECT_EQ(kTestResourceSize, requester.context()->getTransferSize());
 }
 
 TEST_F(ResourceFetcherTest, ComplexCrossOriginRedirect) {
@@ -465,12 +467,13 @@
   requester.registerFinalResource(finalURL);
   requester.request(redirectURL1);
 
-  EXPECT_EQ(testImageSize, requester.context()->getTransferSize());
+  EXPECT_EQ(kTestResourceSize, requester.context()->getTransferSize());
 }
 
 TEST_F(ResourceFetcherTest, SynchronousRequest) {
   KURL url(ParsedURLString, "http://127.0.0.1:8000/foo.png");
-  URLTestHelpers::registerMockedURLLoad(url, testImageFilename, "image/png");
+  URLTestHelpers::registerMockedURLLoad(url, kTestResourceFilename,
+                                        kTestResourceMimeType);
 
   ResourceFetcher* fetcher = ResourceFetcher::create(
       MockFetchContext::create(MockFetchContext::kShouldLoadNewResource));
@@ -487,21 +490,22 @@
   memoryCache()->remove(resource);
 }
 
-TEST_F(ResourceFetcherTest, PreloadImageTwice) {
+TEST_F(ResourceFetcherTest, PreloadResourceTwice) {
   ResourceFetcher* fetcher = ResourceFetcher::create(
       MockFetchContext::create(MockFetchContext::kShouldLoadNewResource));
 
   KURL url(ParsedURLString, "http://127.0.0.1:8000/foo.png");
-  URLTestHelpers::registerMockedURLLoad(url, testImageFilename, "image/png");
+  URLTestHelpers::registerMockedURLLoad(url, kTestResourceFilename,
+                                        kTestResourceMimeType);
 
   FetchRequest fetchRequestOriginal = FetchRequest(url, FetchInitiatorInfo());
-  Resource* resource = ImageResource::fetch(fetchRequestOriginal, fetcher);
+  Resource* resource = MockResource::fetch(fetchRequestOriginal, fetcher);
   ASSERT_TRUE(resource);
   Platform::current()->getURLLoaderMockFactory()->serveAsynchronousRequests();
   fetcher->preloadStarted(resource);
 
   FetchRequest fetchRequest = FetchRequest(url, FetchInitiatorInfo());
-  Resource* newResource = ImageResource::fetch(fetchRequest, fetcher);
+  Resource* newResource = MockResource::fetch(fetchRequest, fetcher);
   EXPECT_EQ(resource, newResource);
   fetcher->preloadStarted(resource);
 
@@ -511,34 +515,35 @@
   EXPECT_FALSE(resource->isPreloaded());
 }
 
-TEST_F(ResourceFetcherTest, LinkPreloadImageAndUse) {
+TEST_F(ResourceFetcherTest, LinkPreloadResourceAndUse) {
   ResourceFetcher* fetcher = ResourceFetcher::create(
       MockFetchContext::create(MockFetchContext::kShouldLoadNewResource));
 
   KURL url(ParsedURLString, "http://127.0.0.1:8000/foo.png");
-  URLTestHelpers::registerMockedURLLoad(url, testImageFilename, "image/png");
+  URLTestHelpers::registerMockedURLLoad(url, kTestResourceFilename,
+                                        kTestResourceMimeType);
 
   // Link preload preload scanner
   FetchRequest fetchRequestOriginal = FetchRequest(url, FetchInitiatorInfo());
   fetchRequestOriginal.setLinkPreload(true);
-  Resource* resource = ImageResource::fetch(fetchRequestOriginal, fetcher);
+  Resource* resource = MockResource::fetch(fetchRequestOriginal, fetcher);
   ASSERT_TRUE(resource);
   EXPECT_TRUE(resource->isLinkPreload());
   Platform::current()->getURLLoaderMockFactory()->serveAsynchronousRequests();
   fetcher->preloadStarted(resource);
 
-  // Image preload scanner
+  // Resource created by preload scanner
   FetchRequest fetchRequestPreloadScanner =
       FetchRequest(url, FetchInitiatorInfo());
-  Resource* imgPreloadScannerResource =
-      ImageResource::fetch(fetchRequestPreloadScanner, fetcher);
-  EXPECT_EQ(resource, imgPreloadScannerResource);
+  Resource* preloadScannerResource =
+      MockResource::fetch(fetchRequestPreloadScanner, fetcher);
+  EXPECT_EQ(resource, preloadScannerResource);
   EXPECT_FALSE(resource->isLinkPreload());
   fetcher->preloadStarted(resource);
 
-  // Image created by parser
+  // Resource created by parser
   FetchRequest fetchRequest = FetchRequest(url, FetchInitiatorInfo());
-  Resource* newResource = ImageResource::fetch(fetchRequest, fetcher);
+  Resource* newResource = MockResource::fetch(fetchRequest, fetcher);
   Persistent<MockResourceClient> client = new MockResourceClient(newResource);
   EXPECT_EQ(resource, newResource);
   EXPECT_FALSE(resource->isLinkPreload());
@@ -550,18 +555,19 @@
   EXPECT_FALSE(resource->isPreloaded());
 }
 
-TEST_F(ResourceFetcherTest, LinkPreloadImageMultipleFetchersAndUse) {
+TEST_F(ResourceFetcherTest, LinkPreloadResourceMultipleFetchersAndUse) {
   ResourceFetcher* fetcher = ResourceFetcher::create(
       MockFetchContext::create(MockFetchContext::kShouldLoadNewResource));
   ResourceFetcher* fetcher2 = ResourceFetcher::create(
       MockFetchContext::create(MockFetchContext::kShouldLoadNewResource));
 
   KURL url(ParsedURLString, "http://127.0.0.1:8000/foo.png");
-  URLTestHelpers::registerMockedURLLoad(url, testImageFilename, "image/png");
+  URLTestHelpers::registerMockedURLLoad(url, kTestResourceFilename,
+                                        kTestResourceMimeType);
 
   FetchRequest fetchRequestOriginal = FetchRequest(url, FetchInitiatorInfo());
   fetchRequestOriginal.setLinkPreload(true);
-  Resource* resource = ImageResource::fetch(fetchRequestOriginal, fetcher);
+  Resource* resource = MockResource::fetch(fetchRequestOriginal, fetcher);
   ASSERT_TRUE(resource);
   EXPECT_TRUE(resource->isLinkPreload());
   Platform::current()->getURLLoaderMockFactory()->serveAsynchronousRequests();
@@ -569,7 +575,7 @@
 
   FetchRequest fetchRequestSecond = FetchRequest(url, FetchInitiatorInfo());
   fetchRequestSecond.setLinkPreload(true);
-  Resource* secondResource = ImageResource::fetch(fetchRequestSecond, fetcher2);
+  Resource* secondResource = MockResource::fetch(fetchRequestSecond, fetcher2);
   ASSERT_TRUE(secondResource);
   EXPECT_TRUE(secondResource->isLinkPreload());
   Platform::current()->getURLLoaderMockFactory()->serveAsynchronousRequests();
@@ -580,42 +586,43 @@
       FetchRequest(url, FetchInitiatorInfo());
   fetchRequestLinkPreloadScanner.setLinkPreload(true);
   Resource* linkPreloadScannerResource =
-      ImageResource::fetch(fetchRequestLinkPreloadScanner, fetcher);
+      MockResource::fetch(fetchRequestLinkPreloadScanner, fetcher);
   EXPECT_EQ(resource, linkPreloadScannerResource);
   EXPECT_TRUE(resource->isLinkPreload());
   fetcher->preloadStarted(resource);
 
-  // Image preload scanner
+  // Resource created by preload scanner
   FetchRequest fetchRequestPreloadScanner =
       FetchRequest(url, FetchInitiatorInfo());
-  Resource* imgPreloadScannerResource =
-      ImageResource::fetch(fetchRequestPreloadScanner, fetcher);
-  EXPECT_EQ(resource, imgPreloadScannerResource);
+  Resource* preloadScannerResource =
+      MockResource::fetch(fetchRequestPreloadScanner, fetcher);
+  EXPECT_EQ(resource, preloadScannerResource);
   EXPECT_FALSE(resource->isLinkPreload());
   fetcher->preloadStarted(resource);
 
-  // Image preload scanner on the second fetcher
+  // Resource created by preload scanner on the second fetcher
   FetchRequest fetchRequestPreloadScanner2 =
       FetchRequest(url, FetchInitiatorInfo());
-  Resource* imgPreloadScannerResource2 =
-      ImageResource::fetch(fetchRequestPreloadScanner2, fetcher2);
-  EXPECT_EQ(resource, imgPreloadScannerResource2);
+  Resource* preloadScannerResource2 =
+      MockResource::fetch(fetchRequestPreloadScanner2, fetcher2);
+  EXPECT_EQ(resource, preloadScannerResource2);
   EXPECT_FALSE(resource->isLinkPreload());
   fetcher2->preloadStarted(resource);
 
-  // Image created by parser
+  // Resource created by parser
   FetchRequest fetchRequest = FetchRequest(url, FetchInitiatorInfo());
-  Resource* newResource = ImageResource::fetch(fetchRequest, fetcher);
+  Resource* newResource = MockResource::fetch(fetchRequest, fetcher);
   Persistent<MockResourceClient> client = new MockResourceClient(newResource);
   EXPECT_EQ(resource, newResource);
   EXPECT_FALSE(resource->isLinkPreload());
 
-  // Image created by parser on the second fetcher
+  // Resource created by parser on the second fetcher
   FetchRequest fetchRequest2 = FetchRequest(url, FetchInitiatorInfo());
-  Resource* newResource2 = ImageResource::fetch(fetchRequest, fetcher2);
+  Resource* newResource2 = MockResource::fetch(fetchRequest, fetcher2);
   Persistent<MockResourceClient> client2 = new MockResourceClient(newResource2);
   EXPECT_EQ(resource, newResource2);
   EXPECT_FALSE(resource->isLinkPreload());
+
   // DCL reached on first fetcher
   EXPECT_TRUE(resource->isPreloaded());
   fetcher->clearPreloads(ResourceFetcher::ClearSpeculativeMarkupPreloads);
@@ -655,25 +662,26 @@
   EXPECT_NE(resource, newResource);
 }
 
-TEST_F(ResourceFetcherTest, LinkPreloadImageMultipleFetchersAndMove) {
+TEST_F(ResourceFetcherTest, LinkPreloadResourceMultipleFetchersAndMove) {
   ResourceFetcher* fetcher = ResourceFetcher::create(
       MockFetchContext::create(MockFetchContext::kShouldLoadNewResource));
   ResourceFetcher* fetcher2 = ResourceFetcher::create(
       MockFetchContext::create(MockFetchContext::kShouldLoadNewResource));
 
   KURL url(ParsedURLString, "http://127.0.0.1:8000/foo.png");
-  URLTestHelpers::registerMockedURLLoad(url, testImageFilename, "image/png");
+  URLTestHelpers::registerMockedURLLoad(url, kTestResourceFilename,
+                                        kTestResourceMimeType);
 
   FetchRequest fetchRequestOriginal = FetchRequest(url, FetchInitiatorInfo());
   fetchRequestOriginal.setLinkPreload(true);
-  Resource* resource = ImageResource::fetch(fetchRequestOriginal, fetcher);
+  Resource* resource = MockResource::fetch(fetchRequestOriginal, fetcher);
   ASSERT_TRUE(resource);
   EXPECT_TRUE(resource->isLinkPreload());
   fetcher->preloadStarted(resource);
 
-  // Image created by parser on the second fetcher
+  // Resource created by parser on the second fetcher
   FetchRequest fetchRequest2 = FetchRequest(url, FetchInitiatorInfo());
-  Resource* newResource2 = ImageResource::fetch(fetchRequest2, fetcher2);
+  Resource* newResource2 = MockResource::fetch(fetchRequest2, fetcher2);
   Persistent<MockResourceClient> client2 = new MockResourceClient(newResource2);
   EXPECT_EQ(resource, newResource2);
   EXPECT_FALSE(fetcher2->isFetching());
diff --git a/third_party/WebKit/Source/core/frame/FrameSerializer.cpp b/third_party/WebKit/Source/core/frame/FrameSerializer.cpp
index d3e0963..3837422d3a 100644
--- a/third_party/WebKit/Source/core/frame/FrameSerializer.cpp
+++ b/third_party/WebKit/Source/core/frame/FrameSerializer.cpp
@@ -47,7 +47,6 @@
 #include "core/dom/Element.h"
 #include "core/dom/Text.h"
 #include "core/editing/serializers/MarkupAccumulator.h"
-#include "core/fetch/ImageResourceContent.h"
 #include "core/frame/LocalFrame.h"
 #include "core/html/HTMLFrameElementBase.h"
 #include "core/html/HTMLImageElement.h"
@@ -57,6 +56,7 @@
 #include "core/html/HTMLStyleElement.h"
 #include "core/html/ImageDocument.h"
 #include "core/loader/resource/FontResource.h"
+#include "core/loader/resource/ImageResourceContent.h"
 #include "core/style/StyleFetchedImage.h"
 #include "core/style/StyleImage.h"
 #include "platform/Histogram.h"
diff --git a/third_party/WebKit/Source/core/frame/FrameView.cpp b/third_party/WebKit/Source/core/frame/FrameView.cpp
index 7ba537d..b16e02c 100644
--- a/third_party/WebKit/Source/core/frame/FrameView.cpp
+++ b/third_party/WebKit/Source/core/frame/FrameView.cpp
@@ -702,15 +702,15 @@
   EOverflow overflowY = style->overflowY();
 
   if (!shouldIgnoreOverflowHidden()) {
-    if (overflowX == OverflowHidden)
+    if (overflowX == EOverflow::Hidden)
       hMode = ScrollbarAlwaysOff;
-    if (overflowY == OverflowHidden)
+    if (overflowY == EOverflow::Hidden)
       vMode = ScrollbarAlwaysOff;
   }
 
-  if (overflowX == OverflowScroll)
+  if (overflowX == EOverflow::Scroll)
     hMode = ScrollbarAlwaysOn;
-  if (overflowY == OverflowScroll)
+  if (overflowY == EOverflow::Scroll)
     vMode = ScrollbarAlwaysOn;
 }
 
@@ -3653,9 +3653,9 @@
   // anything to override that setting, http://crbug.com/426447
   LayoutObject* viewport = viewportLayoutObject();
   if (viewport && !shouldIgnoreOverflowHidden()) {
-    if (viewport->style()->overflowX() == OverflowHidden)
+    if (viewport->style()->overflowX() == EOverflow::Hidden)
       horizontalMode = ScrollbarAlwaysOff;
-    if (viewport->style()->overflowY() == OverflowHidden)
+    if (viewport->style()->overflowY() == EOverflow::Hidden)
       verticalMode = ScrollbarAlwaysOff;
   }
 
diff --git a/third_party/WebKit/Source/core/frame/ImageBitmapTest.cpp b/third_party/WebKit/Source/core/frame/ImageBitmapTest.cpp
index c9666be3..c9a206a 100644
--- a/third_party/WebKit/Source/core/frame/ImageBitmapTest.cpp
+++ b/third_party/WebKit/Source/core/frame/ImageBitmapTest.cpp
@@ -32,11 +32,11 @@
 
 #include "SkPixelRef.h"  // FIXME: qualify this skia header file.
 #include "core/dom/Document.h"
-#include "core/fetch/ImageResourceContent.h"
 #include "core/fetch/MemoryCache.h"
 #include "core/html/HTMLCanvasElement.h"
 #include "core/html/HTMLImageElement.h"
 #include "core/html/HTMLVideoElement.h"
+#include "core/loader/resource/ImageResourceContent.h"
 #include "platform/graphics/StaticBitmapImage.h"
 #include "platform/graphics/skia/SkiaUtils.h"
 #include "platform/heap/Handle.h"
diff --git a/third_party/WebKit/Source/core/html/HTMLFormControlElement.cpp b/third_party/WebKit/Source/core/html/HTMLFormControlElement.cpp
index 627158c..9e5926a 100644
--- a/third_party/WebKit/Source/core/html/HTMLFormControlElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLFormControlElement.cpp
@@ -452,7 +452,7 @@
 
 void HTMLFormControlElement::updateVisibleValidationMessage() {
   Page* page = document().page();
-  if (!page)
+  if (!page || !page->isPageVisible())
     return;
   String message;
   if (layoutObject() && willValidate())
diff --git a/third_party/WebKit/Source/core/html/HTMLImageElement.cpp b/third_party/WebKit/Source/core/html/HTMLImageElement.cpp
index 2bfb37d..dd9301bfb 100644
--- a/third_party/WebKit/Source/core/html/HTMLImageElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLImageElement.cpp
@@ -33,7 +33,6 @@
 #include "core/dom/Attribute.h"
 #include "core/dom/NodeTraversal.h"
 #include "core/dom/shadow/ShadowRoot.h"
-#include "core/fetch/ImageResourceContent.h"
 #include "core/frame/Deprecation.h"
 #include "core/frame/ImageBitmap.h"
 #include "core/frame/LocalDOMWindow.h"
@@ -51,6 +50,7 @@
 #include "core/layout/LayoutBlockFlow.h"
 #include "core/layout/LayoutImage.h"
 #include "core/layout/api/LayoutImageItem.h"
+#include "core/loader/resource/ImageResourceContent.h"
 #include "core/page/Page.h"
 #include "core/style/ContentData.h"
 #include "core/svg/graphics/SVGImageForContainer.h"
diff --git a/third_party/WebKit/Source/core/html/HTMLImageLoader.cpp b/third_party/WebKit/Source/core/html/HTMLImageLoader.cpp
index 4db49d3..9535f01b 100644
--- a/third_party/WebKit/Source/core/html/HTMLImageLoader.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLImageLoader.cpp
@@ -24,12 +24,12 @@
 #include "core/HTMLNames.h"
 #include "core/dom/Element.h"
 #include "core/events/Event.h"
-#include "core/fetch/ImageResourceContent.h"
 #include "core/fetch/ResourceLoadingLog.h"
 #include "core/html/HTMLImageElement.h"
 #include "core/html/HTMLInputElement.h"
 #include "core/html/HTMLObjectElement.h"
 #include "core/html/parser/HTMLParserIdioms.h"
+#include "core/loader/resource/ImageResourceContent.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp b/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp
index 2bfe488..725463a 100644
--- a/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp
@@ -42,6 +42,7 @@
 #include "core/dom/MutationCallback.h"
 #include "core/dom/MutationObserver.h"
 #include "core/dom/MutationObserverInit.h"
+#include "core/dom/MutationRecord.h"
 #include "core/dom/NodeComputedStyle.h"
 #include "core/dom/NodeListsNodeData.h"
 #include "core/dom/NodeTraversal.h"
@@ -981,11 +982,15 @@
                                      SelectOptionFlags flags) {
   TRACE_EVENT0("blink", "HTMLSelectElement::selectOption");
 
+  bool shouldUpdatePopup = false;
+
   // selectedOption() is O(N).
   if (isAutofilled() && selectedOption() != element)
     setAutofilled(false);
 
   if (element) {
+    if (!element->selected())
+      shouldUpdatePopup = true;
     element->setSelectedState(true);
     if (flags & MakeOptionDirty)
       element->setDirty(true);
@@ -993,7 +998,7 @@
 
   // deselectItemsWithoutValidation() is O(N).
   if (flags & DeselectOtherOptions)
-    deselectItemsWithoutValidation(element);
+    shouldUpdatePopup |= deselectItemsWithoutValidation(element);
 
   // We should update active selection after finishing OPTION state change
   // because setActiveSelectionAnchorIndex() stores OPTION's selection state.
@@ -1019,7 +1024,7 @@
   if (LayoutObject* layoutObject = this->layoutObject())
     layoutObject->updateFromElement();
   // PopupMenu::updateFromElement() posts an O(N) task.
-  if (popupIsVisible())
+  if (popupIsVisible() && shouldUpdatePopup)
     m_popup->updateFromElement(PopupMenu::BySelectionChange);
 
   scrollToSelection();
@@ -1072,17 +1077,23 @@
                                                      sourceCapabilities);
 }
 
-void HTMLSelectElement::deselectItemsWithoutValidation(
+// Returns true if selection state of any OPTIONs is changed.
+bool HTMLSelectElement::deselectItemsWithoutValidation(
     HTMLOptionElement* excludeElement) {
   if (!isMultiple() && usesMenuList() && m_lastOnChangeOption &&
       m_lastOnChangeOption != excludeElement) {
     m_lastOnChangeOption->setSelectedState(false);
-    return;
+    return true;
   }
+  bool didUpdateSelection = false;
   for (const auto& option : optionList()) {
-    if (option != excludeElement)
+    if (option != excludeElement) {
+      if (option->selected())
+        didUpdateSelection = true;
       option->setSelectedState(false);
+    }
   }
+  return didUpdateSelection;
 }
 
 FormControlState HTMLSelectElement::saveFormControlState() const {
@@ -1967,13 +1978,24 @@
   void dispose() { m_observer->disconnect(); }
 
  private:
-  void call(const HeapVector<Member<MutationRecord>>&,
+  void call(const HeapVector<Member<MutationRecord>>& records,
             MutationObserver*) override {
     // We disconnect the MutationObserver when a popuup is closed.  However
     // MutationObserver can call back after disconnection.
     if (!m_select->popupIsVisible())
       return;
-    m_select->didMutateSubtree();
+    for (const auto& record : records) {
+      if (record->type() == "attributes") {
+        const Element& element = *toElement(record->target());
+        if (record->oldValue() == element.getAttribute(record->attributeName()))
+          continue;
+      } else if (record->type() == "characterData") {
+        if (record->oldValue() == record->target()->nodeValue())
+          continue;
+      }
+      m_select->didMutateSubtree();
+      return;
+    }
   }
 
   ExecutionContext* getExecutionContext() const override {
@@ -1995,9 +2017,11 @@
   filter.append(String("selected"));
   filter.append(String("value"));
   MutationObserverInit init;
+  init.setAttributeOldValue(true);
   init.setAttributes(true);
   init.setAttributeFilter(filter);
   init.setCharacterData(true);
+  init.setCharacterDataOldValue(true);
   init.setChildList(true);
   init.setSubtree(true);
   m_observer->observe(&select, init, ASSERT_NO_EXCEPTION);
diff --git a/third_party/WebKit/Source/core/html/HTMLSelectElement.h b/third_party/WebKit/Source/core/html/HTMLSelectElement.h
index 7e12b735..7915295 100644
--- a/third_party/WebKit/Source/core/html/HTMLSelectElement.h
+++ b/third_party/WebKit/Source/core/html/HTMLSelectElement.h
@@ -235,7 +235,7 @@
   };
   typedef unsigned SelectOptionFlags;
   void selectOption(HTMLOptionElement*, SelectOptionFlags);
-  void deselectItemsWithoutValidation(
+  bool deselectItemsWithoutValidation(
       HTMLOptionElement* elementToExclude = nullptr);
   void parseMultipleAttribute(const AtomicString&);
   HTMLOptionElement* lastSelectedOption() const;
diff --git a/third_party/WebKit/Source/core/html/ImageDocument.cpp b/third_party/WebKit/Source/core/html/ImageDocument.cpp
index 072b068..15d9f103 100644
--- a/third_party/WebKit/Source/core/html/ImageDocument.cpp
+++ b/third_party/WebKit/Source/core/html/ImageDocument.cpp
@@ -29,7 +29,6 @@
 #include "core/dom/RawDataDocumentParser.h"
 #include "core/events/EventListener.h"
 #include "core/events/MouseEvent.h"
-#include "core/fetch/ImageResource.h"
 #include "core/frame/FrameHost.h"
 #include "core/frame/FrameView.h"
 #include "core/frame/LocalDOMWindow.h"
@@ -48,6 +47,7 @@
 #include "core/loader/DocumentLoader.h"
 #include "core/loader/FrameLoader.h"
 #include "core/loader/FrameLoaderClient.h"
+#include "core/loader/resource/ImageResource.h"
 #include "platform/HostWindow.h"
 #include "wtf/text/StringBuilder.h"
 #include <limits>
diff --git a/third_party/WebKit/Source/core/html/canvas/CanvasImageSource.h b/third_party/WebKit/Source/core/html/canvas/CanvasImageSource.h
index 680aa0b..cab87e0 100644
--- a/third_party/WebKit/Source/core/html/canvas/CanvasImageSource.h
+++ b/third_party/WebKit/Source/core/html/canvas/CanvasImageSource.h
@@ -28,11 +28,13 @@
 #define CanvasImageSource_h
 
 #include "core/CoreExport.h"
+#include "platform/geometry/FloatSize.h"
 #include "platform/graphics/GraphicsTypes.h"
 #include "wtf/PassRefPtr.h"
 
 namespace blink {
 
+class FloatRect;
 class Image;
 class SecurityOrigin;
 
diff --git a/third_party/WebKit/Source/core/input/EventHandler.cpp b/third_party/WebKit/Source/core/input/EventHandler.cpp
index 132a5ffc..4f3ef35 100644
--- a/third_party/WebKit/Source/core/input/EventHandler.cpp
+++ b/third_party/WebKit/Source/core/input/EventHandler.cpp
@@ -51,7 +51,6 @@
 #include "core/events/TextEvent.h"
 #include "core/events/TouchEvent.h"
 #include "core/events/WheelEvent.h"
-#include "core/fetch/ImageResourceContent.h"
 #include "core/frame/Deprecation.h"
 #include "core/frame/EventHandlerRegistry.h"
 #include "core/frame/FrameHost.h"
@@ -75,6 +74,7 @@
 #include "core/loader/DocumentLoader.h"
 #include "core/loader/FrameLoader.h"
 #include "core/loader/FrameLoaderClient.h"
+#include "core/loader/resource/ImageResourceContent.h"
 #include "core/page/AutoscrollController.h"
 #include "core/page/ChromeClient.h"
 #include "core/page/DragState.h"
diff --git a/third_party/WebKit/Source/core/layout/LayoutBox.cpp b/third_party/WebKit/Source/core/layout/LayoutBox.cpp
index 899f61f..dd615e7 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBox.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBox.cpp
@@ -930,14 +930,14 @@
 }
 
 int LayoutBox::verticalScrollbarWidth() const {
-  if (!hasOverflowClip() || style()->overflowY() == OverflowOverlay)
+  if (!hasOverflowClip() || style()->overflowY() == EOverflow::Overlay)
     return 0;
 
   return getScrollableArea()->verticalScrollbarWidth();
 }
 
 int LayoutBox::horizontalScrollbarHeight() const {
-  if (!hasOverflowClip() || style()->overflowX() == OverflowOverlay)
+  if (!hasOverflowClip() || style()->overflowX() == EOverflow::Overlay)
     return 0;
 
   return getScrollableArea()->horizontalScrollbarHeight();
@@ -3196,8 +3196,8 @@
         // cases, but it is preferable to the alternative (sizing intrinsically
         // and making the row end up too big).
         LayoutTableCell* cell = toLayoutTableCell(cb);
-        if (style()->overflowY() != OverflowVisible &&
-            style()->overflowY() != OverflowHidden &&
+        if (style()->overflowY() != EOverflow::Visible &&
+            style()->overflowY() != EOverflow::Hidden &&
             (!cell->style()->logicalHeight().isAuto() ||
              !cell->table()->style()->logicalHeight().isAuto()))
           return LayoutUnit();
diff --git a/third_party/WebKit/Source/core/layout/LayoutBox.h b/third_party/WebKit/Source/core/layout/LayoutBox.h
index ca58d047..d4a1ae1 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBox.h
+++ b/third_party/WebKit/Source/core/layout/LayoutBox.h
@@ -1002,13 +1002,13 @@
   virtual void stopAutoscroll() {}
 
   DISABLE_CFI_PERF bool hasAutoVerticalScrollbar() const {
-    return hasOverflowClip() && (style()->overflowY() == OverflowAuto ||
-                                 style()->overflowY() == OverflowPagedY ||
-                                 style()->overflowY() == OverflowOverlay);
+    return hasOverflowClip() && (style()->overflowY() == EOverflow::Auto ||
+                                 style()->overflowY() == EOverflow::PagedY ||
+                                 style()->overflowY() == EOverflow::Overlay);
   }
   DISABLE_CFI_PERF bool hasAutoHorizontalScrollbar() const {
-    return hasOverflowClip() && (style()->overflowX() == OverflowAuto ||
-                                 style()->overflowX() == OverflowOverlay);
+    return hasOverflowClip() && (style()->overflowX() == EOverflow::Auto ||
+                                 style()->overflowX() == EOverflow::Overlay);
   }
   DISABLE_CFI_PERF bool scrollsOverflow() const {
     return scrollsOverflowX() || scrollsOverflowY();
@@ -1026,11 +1026,11 @@
            pixelSnappedScrollHeight() != pixelSnappedClientHeight();
   }
   virtual bool scrollsOverflowX() const {
-    return hasOverflowClip() && (style()->overflowX() == OverflowScroll ||
+    return hasOverflowClip() && (style()->overflowX() == EOverflow::Scroll ||
                                  hasAutoHorizontalScrollbar());
   }
   virtual bool scrollsOverflowY() const {
-    return hasOverflowClip() && (style()->overflowY() == OverflowScroll ||
+    return hasOverflowClip() && (style()->overflowY() == EOverflow::Scroll ||
                                  hasAutoVerticalScrollbar());
   }
 
diff --git a/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp b/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp
index fc80cc4..648ff5a0 100644
--- a/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp
@@ -1216,7 +1216,7 @@
     // percentage min size, but we have an indefinite size in that axis.
     minExtent = std::max(LayoutUnit(), minExtent);
   } else if (min.isAuto() && !child.styleRef().containsSize() &&
-             mainAxisOverflowForChild(child) == OverflowVisible &&
+             mainAxisOverflowForChild(child) == EOverflow::Visible &&
              !(isColumnFlow() && child.isFlexibleBox())) {
     // TODO(cbiesinger): For now, we do not handle min-height: auto for nested
     // column flexboxes. We need to implement
diff --git a/third_party/WebKit/Source/core/layout/LayoutGrid.cpp b/third_party/WebKit/Source/core/layout/LayoutGrid.cpp
index c9298c6..0c851ee 100644
--- a/third_party/WebKit/Source/core/layout/LayoutGrid.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutGrid.cpp
@@ -1330,8 +1330,9 @@
   const Length& childMinSize = isRowAxis ? child.styleRef().logicalMinWidth()
                                          : child.styleRef().logicalMinHeight();
   bool overflowIsVisible =
-      isRowAxis ? child.styleRef().overflowInlineDirection() == OverflowVisible
-                : child.styleRef().overflowBlockDirection() == OverflowVisible;
+      isRowAxis
+          ? child.styleRef().overflowInlineDirection() == EOverflow::Visible
+          : child.styleRef().overflowBlockDirection() == EOverflow::Visible;
   if (!childSize.isAuto() || (childMinSize.isAuto() && overflowIsVisible))
     return minContentForChild(child, direction, sizingData);
 
diff --git a/third_party/WebKit/Source/core/layout/LayoutImage.cpp b/third_party/WebKit/Source/core/layout/LayoutImage.cpp
index e2a9ce30..4863e53 100644
--- a/third_party/WebKit/Source/core/layout/LayoutImage.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutImage.cpp
@@ -29,7 +29,6 @@
 #include "core/layout/LayoutImage.h"
 
 #include "core/HTMLNames.h"
-#include "core/fetch/ImageResourceContent.h"
 #include "core/frame/FrameView.h"
 #include "core/frame/LocalFrame.h"
 #include "core/frame/UseCounter.h"
@@ -37,6 +36,7 @@
 #include "core/html/HTMLImageElement.h"
 #include "core/layout/HitTestResult.h"
 #include "core/layout/LayoutView.h"
+#include "core/loader/resource/ImageResourceContent.h"
 #include "core/paint/ImagePainter.h"
 #include "core/svg/graphics/SVGImage.h"
 
diff --git a/third_party/WebKit/Source/core/layout/LayoutImageResource.h b/third_party/WebKit/Source/core/layout/LayoutImageResource.h
index 2e6e102..d7271e3 100644
--- a/third_party/WebKit/Source/core/layout/LayoutImageResource.h
+++ b/third_party/WebKit/Source/core/layout/LayoutImageResource.h
@@ -27,7 +27,7 @@
 #ifndef LayoutImageResource_h
 #define LayoutImageResource_h
 
-#include "core/fetch/ImageResourceContent.h"
+#include "core/loader/resource/ImageResourceContent.h"
 #include "core/style/StyleImage.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/layout/LayoutObject.cpp b/third_party/WebKit/Source/core/layout/LayoutObject.cpp
index 700adf8..759b828 100644
--- a/third_party/WebKit/Source/core/layout/LayoutObject.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutObject.cpp
@@ -144,7 +144,7 @@
 
 void LayoutObject::operator delete(void* ptr) {
   ASSERT(isMainThread());
-  partitionFree(ptr);
+  WTF::partitionFree(ptr);
 }
 
 LayoutObject* LayoutObject::createObject(Element* element,
diff --git a/third_party/WebKit/Source/core/layout/LayoutObject.h b/third_party/WebKit/Source/core/layout/LayoutObject.h
index db0b83e5..5757694 100644
--- a/third_party/WebKit/Source/core/layout/LayoutObject.h
+++ b/third_party/WebKit/Source/core/layout/LayoutObject.h
@@ -31,7 +31,6 @@
 #include "core/dom/Document.h"
 #include "core/dom/DocumentLifecycle.h"
 #include "core/editing/PositionWithAffinity.h"
-#include "core/fetch/ImageResourceObserver.h"
 #include "core/layout/LayoutObjectChildList.h"
 #include "core/layout/MapCoordinatesFlags.h"
 #include "core/layout/PaintInvalidationState.h"
@@ -40,6 +39,7 @@
 #include "core/layout/api/HitTestAction.h"
 #include "core/layout/api/SelectionState.h"
 #include "core/layout/compositing/CompositingState.h"
+#include "core/loader/resource/ImageResourceObserver.h"
 #include "core/paint/LayerHitTestRects.h"
 #include "core/paint/PaintPhase.h"
 #include "core/style/ComputedStyle.h"
diff --git a/third_party/WebKit/Source/core/layout/LayoutTableSection.cpp b/third_party/WebKit/Source/core/layout/LayoutTableSection.cpp
index bf09516..8dcca0a8 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTableSection.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTableSection.cpp
@@ -1114,8 +1114,9 @@
   return cellDescendant->isAtomicInlineLevel() ||
          (cellDescendant->isBox() &&
           toLayoutBox(cellDescendant)->style()->overflowY() !=
-              OverflowVisible &&
-          toLayoutBox(cellDescendant)->style()->overflowY() != OverflowHidden);
+              EOverflow::Visible &&
+          toLayoutBox(cellDescendant)->style()->overflowY() !=
+              EOverflow::Hidden);
 }
 
 void LayoutTableSection::layoutRows() {
diff --git a/third_party/WebKit/Source/core/layout/LayoutTextControl.cpp b/third_party/WebKit/Source/core/layout/LayoutTextControl.cpp
index 86e67524..af49330 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTextControl.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTextControl.cpp
@@ -127,8 +127,8 @@
 
     // We are able to have a horizontal scrollbar if the overflow style is
     // scroll, or if its auto and there's no word wrap.
-    if (style()->overflowInlineDirection() == OverflowScroll ||
-        (style()->overflowInlineDirection() == OverflowAuto &&
+    if (style()->overflowInlineDirection() == EOverflow::Scroll ||
+        (style()->overflowInlineDirection() == EOverflow::Auto &&
          innerEditor->layoutObject()->style()->overflowWrap() ==
              NormalOverflowWrap))
       logicalHeight += scrollbarThickness();
diff --git a/third_party/WebKit/Source/core/layout/LayoutTextControlSingleLine.cpp b/third_party/WebKit/Source/core/layout/LayoutTextControlSingleLine.cpp
index b8a277b..9912a1d 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTextControlSingleLine.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTextControlSingleLine.cpp
@@ -332,9 +332,9 @@
   if (inputElement()->shouldRevealPassword())
     textBlockStyle->setTextSecurity(TSNONE);
 
-  textBlockStyle->setOverflowX(OverflowScroll);
+  textBlockStyle->setOverflowX(EOverflow::Scroll);
   // overflow-y:visible doesn't work because overflow-x:scroll makes a layer.
-  textBlockStyle->setOverflowY(OverflowScroll);
+  textBlockStyle->setOverflowY(EOverflow::Scroll);
   RefPtr<ComputedStyle> noScrollbarStyle = ComputedStyle::create();
   noScrollbarStyle->setStyleType(PseudoIdScrollbar);
   noScrollbarStyle->setDisplay(EDisplay::None);
diff --git a/third_party/WebKit/Source/core/layout/LayoutThemeDefault.cpp b/third_party/WebKit/Source/core/layout/LayoutThemeDefault.cpp
index a23b70c..e0d778f3 100644
--- a/third_party/WebKit/Source/core/layout/LayoutThemeDefault.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutThemeDefault.cpp
@@ -339,7 +339,7 @@
 int LayoutThemeDefault::scrollbarThicknessInDIP() {
   int width = Platform::current()
                   ->themeEngine()
-                  ->getSize(WebThemeEngine::PartScrollbarDownArrow)
+                  ->getSize(WebThemeEngine::PartScrollbarUpArrow)
                   .width;
   return width > 0 ? width : 15;
 }
diff --git a/third_party/WebKit/Source/core/layout/TextAutosizer.cpp b/third_party/WebKit/Source/core/layout/TextAutosizer.cpp
index 61cc389..3de5d5f1 100644
--- a/third_party/WebKit/Source/core/layout/TextAutosizer.cpp
+++ b/third_party/WebKit/Source/core/layout/TextAutosizer.cpp
@@ -236,7 +236,7 @@
   // the content is already overflowing before autosizing kicks in.
   for (; block; block = block->containingBlock()) {
     const ComputedStyle& style = block->styleRef();
-    if (style.overflowY() >= OverflowScroll)
+    if (style.overflowY() >= EOverflow::Scroll)
       return false;
     if (style.height().isSpecified() || style.maxHeight().isSpecified() ||
         block->isOutOfFlowPositioned()) {
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
index aa034ad..1bac1794 100644
--- a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
+++ b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
@@ -27,7 +27,6 @@
 
 #include "core/HTMLNames.h"
 #include "core/dom/DOMNodeIds.h"
-#include "core/fetch/ImageResourceContent.h"
 #include "core/frame/FrameHost.h"
 #include "core/frame/FrameView.h"
 #include "core/frame/RemoteFrame.h"
@@ -48,6 +47,7 @@
 #include "core/layout/api/LayoutAPIShim.h"
 #include "core/layout/api/LayoutPartItem.h"
 #include "core/layout/compositing/PaintLayerCompositor.h"
+#include "core/loader/resource/ImageResourceContent.h"
 #include "core/page/ChromeClient.h"
 #include "core/page/Page.h"
 #include "core/page/scrolling/ScrollingCoordinator.h"
diff --git a/third_party/WebKit/Source/core/layout/line/InlineBox.cpp b/third_party/WebKit/Source/core/layout/line/InlineBox.cpp
index 83ac76f..738cc4bb 100644
--- a/third_party/WebKit/Source/core/layout/line/InlineBox.cpp
+++ b/third_party/WebKit/Source/core/layout/line/InlineBox.cpp
@@ -85,7 +85,7 @@
 }
 
 void InlineBox::operator delete(void* ptr) {
-  partitionFree(ptr);
+  WTF::partitionFree(ptr);
 }
 
 const char* InlineBox::boxName() const {
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.cc b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.cc
index d52d225..52dde27 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.cc
@@ -73,9 +73,9 @@
       .SetAvailableSize(size)
       .SetPercentageResolutionSize(size)
       .SetIsInlineDirectionTriggersScrollbar(
-          box.styleRef().overflowInlineDirection() == OverflowAuto)
+          box.styleRef().overflowInlineDirection() == EOverflow::Auto)
       .SetIsBlockDirectionTriggersScrollbar(
-          box.styleRef().overflowBlockDirection() == OverflowAuto)
+          box.styleRef().overflowBlockDirection() == EOverflow::Auto)
       .SetIsFixedSizeInline(fixed_inline)
       .SetIsFixedSizeBlock(fixed_block)
       .SetIsNewFormattingContext(is_new_fc)
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGRoot.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGRoot.cpp
index 3fbc2df6..e2f1548 100644
--- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGRoot.cpp
+++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGRoot.cpp
@@ -215,9 +215,9 @@
   // clipped. When the svg is stand-alone (isDocumentElement() == true) the
   // viewport clipping should always be applied, noting that the window
   // scrollbars should be hidden if overflow=hidden.
-  return style()->overflowX() == OverflowHidden ||
-         style()->overflowX() == OverflowAuto ||
-         style()->overflowX() == OverflowScroll || this->isDocumentElement();
+  return style()->overflowX() == EOverflow::Hidden ||
+         style()->overflowX() == EOverflow::Auto ||
+         style()->overflowX() == EOverflow::Scroll || this->isDocumentElement();
 }
 
 LayoutRect LayoutSVGRoot::visualOverflowRect() const {
diff --git a/third_party/WebKit/Source/core/layout/svg/SVGLayoutSupport.cpp b/third_party/WebKit/Source/core/layout/svg/SVGLayoutSupport.cpp
index 7dbdbe85..9e096fb4 100644
--- a/third_party/WebKit/Source/core/layout/svg/SVGLayoutSupport.cpp
+++ b/third_party/WebKit/Source/core/layout/svg/SVGLayoutSupport.cpp
@@ -374,8 +374,8 @@
   // itself to the initial viewport size.
   ASSERT(!object->isDocumentElement());
 
-  return object->style()->overflowX() == OverflowHidden ||
-         object->style()->overflowX() == OverflowScroll;
+  return object->style()->overflowX() == EOverflow::Hidden ||
+         object->style()->overflowX() == EOverflow::Scroll;
 }
 
 void SVGLayoutSupport::adjustVisualRectWithResources(
diff --git a/third_party/WebKit/Source/core/loader/BUILD.gn b/third_party/WebKit/Source/core/loader/BUILD.gn
index e543f34..68d6b81 100644
--- a/third_party/WebKit/Source/core/loader/BUILD.gn
+++ b/third_party/WebKit/Source/core/loader/BUILD.gn
@@ -66,10 +66,18 @@
     "resource/DocumentResource.h",
     "resource/FontResource.cpp",
     "resource/FontResource.h",
+    "resource/ImageResource.cpp",
+    "resource/ImageResource.h",
+    "resource/ImageResourceContent.cpp",
+    "resource/ImageResourceContent.h",
+    "resource/ImageResourceInfo.h",
+    "resource/ImageResourceObserver.h",
     "resource/LinkFetchResource.cpp",
     "resource/LinkFetchResource.h",
     "resource/LinkPreloadResourceClients.cpp",
     "resource/LinkPreloadResourceClients.h",
+    "resource/MultipartImageResourceParser.cpp",
+    "resource/MultipartImageResourceParser.h",
     "resource/ScriptResource.cpp",
     "resource/ScriptResource.h",
     "resource/StyleSheetResource.h",
diff --git a/third_party/WebKit/Source/core/loader/DocumentLoader.cpp b/third_party/WebKit/Source/core/loader/DocumentLoader.cpp
index 359afdc..414d297 100644
--- a/third_party/WebKit/Source/core/loader/DocumentLoader.cpp
+++ b/third_party/WebKit/Source/core/loader/DocumentLoader.cpp
@@ -35,7 +35,6 @@
 #include "core/events/Event.h"
 #include "core/fetch/FetchInitiatorTypeNames.h"
 #include "core/fetch/FetchRequest.h"
-#include "core/fetch/ImageResource.h"
 #include "core/fetch/MemoryCache.h"
 #include "core/fetch/ResourceFetcher.h"
 #include "core/frame/Deprecation.h"
@@ -58,6 +57,7 @@
 #include "core/loader/appcache/ApplicationCacheHost.h"
 #include "core/loader/resource/CSSStyleSheetResource.h"
 #include "core/loader/resource/FontResource.h"
+#include "core/loader/resource/ImageResource.h"
 #include "core/loader/resource/ScriptResource.h"
 #include "core/page/FrameTree.h"
 #include "core/page/Page.h"
diff --git a/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp b/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
index baf159b..4682c6d 100644
--- a/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
+++ b/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
@@ -663,6 +663,7 @@
     case Resource::ImportResource:
     case Resource::Media:
     case Resource::Manifest:
+    case Resource::Mock:
       // By default these types of resources can be loaded from any origin.
       // FIXME: Are we sure about Resource::Font?
       if (originRestriction == FetchRequest::RestrictToSameOrigin &&
diff --git a/third_party/WebKit/Source/core/loader/ImageLoader.h b/third_party/WebKit/Source/core/loader/ImageLoader.h
index 5db73d0..2672727 100644
--- a/third_party/WebKit/Source/core/loader/ImageLoader.h
+++ b/third_party/WebKit/Source/core/loader/ImageLoader.h
@@ -24,9 +24,9 @@
 #define ImageLoader_h
 
 #include "core/CoreExport.h"
-#include "core/fetch/ImageResource.h"
-#include "core/fetch/ImageResourceContent.h"
-#include "core/fetch/ImageResourceObserver.h"
+#include "core/loader/resource/ImageResource.h"
+#include "core/loader/resource/ImageResourceContent.h"
+#include "core/loader/resource/ImageResourceObserver.h"
 #include "platform/heap/Handle.h"
 #include "wtf/HashSet.h"
 #include "wtf/WeakPtr.h"
diff --git a/third_party/WebKit/Source/core/loader/resource/CSSStyleSheetResourceTest.cpp b/third_party/WebKit/Source/core/loader/resource/CSSStyleSheetResourceTest.cpp
index cfd86a6..4e1178b 100644
--- a/third_party/WebKit/Source/core/loader/resource/CSSStyleSheetResourceTest.cpp
+++ b/third_party/WebKit/Source/core/loader/resource/CSSStyleSheetResourceTest.cpp
@@ -19,9 +19,9 @@
 #include "core/fetch/FetchContext.h"
 #include "core/fetch/FetchInitiatorTypeNames.h"
 #include "core/fetch/FetchRequest.h"
-#include "core/fetch/ImageResource.h"
 #include "core/fetch/MemoryCache.h"
 #include "core/fetch/ResourceFetcher.h"
+#include "core/loader/resource/ImageResource.h"
 #include "core/testing/DummyPageHolder.h"
 #include "platform/heap/Handle.h"
 #include "platform/heap/Heap.h"
diff --git a/third_party/WebKit/Source/core/fetch/ImageResource.cpp b/third_party/WebKit/Source/core/loader/resource/ImageResource.cpp
similarity index 98%
rename from third_party/WebKit/Source/core/fetch/ImageResource.cpp
rename to third_party/WebKit/Source/core/loader/resource/ImageResource.cpp
index 7c09e13..a13e82a 100644
--- a/third_party/WebKit/Source/core/fetch/ImageResource.cpp
+++ b/third_party/WebKit/Source/core/loader/resource/ImageResource.cpp
@@ -21,15 +21,15 @@
     Boston, MA 02110-1301, USA.
 */
 
-#include "core/fetch/ImageResource.h"
+#include "core/loader/resource/ImageResource.h"
 
-#include "core/fetch/ImageResourceContent.h"
-#include "core/fetch/ImageResourceInfo.h"
 #include "core/fetch/MemoryCache.h"
 #include "core/fetch/ResourceClient.h"
 #include "core/fetch/ResourceFetcher.h"
 #include "core/fetch/ResourceLoader.h"
 #include "core/fetch/ResourceLoadingLog.h"
+#include "core/loader/resource/ImageResourceContent.h"
+#include "core/loader/resource/ImageResourceInfo.h"
 #include "platform/Histogram.h"
 #include "platform/RuntimeEnabledFeatures.h"
 #include "platform/SharedBuffer.h"
diff --git a/third_party/WebKit/Source/core/fetch/ImageResource.h b/third_party/WebKit/Source/core/loader/resource/ImageResource.h
similarity index 97%
rename from third_party/WebKit/Source/core/fetch/ImageResource.h
rename to third_party/WebKit/Source/core/loader/resource/ImageResource.h
index 29360cb..3872761a 100644
--- a/third_party/WebKit/Source/core/fetch/ImageResource.h
+++ b/third_party/WebKit/Source/core/loader/resource/ImageResource.h
@@ -24,9 +24,9 @@
 #define ImageResource_h
 
 #include "core/CoreExport.h"
-#include "core/fetch/ImageResourceInfo.h"
-#include "core/fetch/MultipartImageResourceParser.h"
 #include "core/fetch/Resource.h"
+#include "core/loader/resource/ImageResourceInfo.h"
+#include "core/loader/resource/MultipartImageResourceParser.h"
 #include "platform/Timer.h"
 #include "platform/heap/Handle.h"
 #include <memory>
diff --git a/third_party/WebKit/Source/core/fetch/ImageResourceContent.cpp b/third_party/WebKit/Source/core/loader/resource/ImageResourceContent.cpp
similarity index 97%
rename from third_party/WebKit/Source/core/fetch/ImageResourceContent.cpp
rename to third_party/WebKit/Source/core/loader/resource/ImageResourceContent.cpp
index 4387c12..15707f7 100644
--- a/third_party/WebKit/Source/core/fetch/ImageResourceContent.cpp
+++ b/third_party/WebKit/Source/core/loader/resource/ImageResourceContent.cpp
@@ -2,11 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "core/fetch/ImageResourceContent.h"
+#include "core/loader/resource/ImageResourceContent.h"
 
-#include "core/fetch/ImageResource.h"
-#include "core/fetch/ImageResourceInfo.h"
-#include "core/fetch/ImageResourceObserver.h"
+#include "core/loader/resource/ImageResource.h"
+#include "core/loader/resource/ImageResourceInfo.h"
+#include "core/loader/resource/ImageResourceObserver.h"
 #include "core/svg/graphics/SVGImage.h"
 #include "platform/Histogram.h"
 #include "platform/RuntimeEnabledFeatures.h"
@@ -367,13 +367,15 @@
   if (!image || image != m_image)
     return false;
 
-  for (const auto& it : m_finishedObservers)
+  for (const auto& it : m_finishedObservers) {
     if (it.key->willRenderImage())
       return false;
+  }
 
-  for (const auto& it : m_observers)
+  for (const auto& it : m_observers) {
     if (it.key->willRenderImage())
       return false;
+  }
 
   return true;
 }
diff --git a/third_party/WebKit/Source/core/fetch/ImageResourceContent.h b/third_party/WebKit/Source/core/loader/resource/ImageResourceContent.h
similarity index 100%
rename from third_party/WebKit/Source/core/fetch/ImageResourceContent.h
rename to third_party/WebKit/Source/core/loader/resource/ImageResourceContent.h
diff --git a/third_party/WebKit/Source/core/fetch/ImageResourceInfo.h b/third_party/WebKit/Source/core/loader/resource/ImageResourceInfo.h
similarity index 100%
rename from third_party/WebKit/Source/core/fetch/ImageResourceInfo.h
rename to third_party/WebKit/Source/core/loader/resource/ImageResourceInfo.h
diff --git a/third_party/WebKit/Source/core/fetch/ImageResourceObserver.h b/third_party/WebKit/Source/core/loader/resource/ImageResourceObserver.h
similarity index 100%
rename from third_party/WebKit/Source/core/fetch/ImageResourceObserver.h
rename to third_party/WebKit/Source/core/loader/resource/ImageResourceObserver.h
diff --git a/third_party/WebKit/Source/core/fetch/ImageResourceTest.cpp b/third_party/WebKit/Source/core/loader/resource/ImageResourceTest.cpp
similarity index 98%
rename from third_party/WebKit/Source/core/fetch/ImageResourceTest.cpp
rename to third_party/WebKit/Source/core/loader/resource/ImageResourceTest.cpp
index 8801c001..2213c24 100644
--- a/third_party/WebKit/Source/core/fetch/ImageResourceTest.cpp
+++ b/third_party/WebKit/Source/core/loader/resource/ImageResourceTest.cpp
@@ -28,16 +28,16 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include "core/fetch/ImageResource.h"
+#include "core/loader/resource/ImageResource.h"
 
 #include "core/fetch/FetchInitiatorInfo.h"
 #include "core/fetch/FetchRequest.h"
 #include "core/fetch/MemoryCache.h"
-#include "core/fetch/MockImageResourceClient.h"
 #include "core/fetch/MockResourceClient.h"
 #include "core/fetch/ResourceFetcher.h"
 #include "core/fetch/ResourceLoader.h"
 #include "core/fetch/UniqueIdentifier.h"
+#include "core/loader/resource/MockImageResourceClient.h"
 #include "platform/SharedBuffer.h"
 #include "platform/exported/WrappedResourceResponse.h"
 #include "platform/graphics/BitmapImage.h"
@@ -876,9 +876,8 @@
   Persistent<MockImageResourceClient> client =
       new MockImageResourceClient(image);
 
-  image->loader()->didReceiveResponse(
-      WrappedResourceResponse(ResourceResponse(
-          testURL, "image/jpeg", sizeof(kJpegImage), nullAtom, String())));
+  image->loader()->didReceiveResponse(WrappedResourceResponse(ResourceResponse(
+      testURL, "image/jpeg", sizeof(kJpegImage), nullAtom, String())));
   image->loader()->didReceiveData(reinterpret_cast<const char*>(kJpegImage),
                                   sizeof(kJpegImage));
   image->loader()->didFinishLoading(0.0, sizeof(kJpegImage),
@@ -1017,9 +1016,8 @@
 
   const char kBadData[] = "notanimageresponse";
 
-  image->loader()->didReceiveResponse(
-      WrappedResourceResponse(ResourceResponse(
-          testURL, "image/jpeg", sizeof(kBadData), nullAtom, String())));
+  image->loader()->didReceiveResponse(WrappedResourceResponse(ResourceResponse(
+      testURL, "image/jpeg", sizeof(kBadData), nullAtom, String())));
   image->loader()->didReceiveData(kBadData, sizeof(kBadData));
 
   // The dimensions could not be extracted, so the full original image should be
@@ -1032,9 +1030,8 @@
   EXPECT_FALSE(client->notifyFinishedCalled());
   EXPECT_EQ(0, client->imageNotifyFinishedCount());
 
-  image->loader()->didReceiveResponse(
-      WrappedResourceResponse(ResourceResponse(
-          testURL, "image/jpeg", sizeof(kJpegImage), nullAtom, String())));
+  image->loader()->didReceiveResponse(WrappedResourceResponse(ResourceResponse(
+      testURL, "image/jpeg", sizeof(kJpegImage), nullAtom, String())));
   image->loader()->didReceiveData(reinterpret_cast<const char*>(kJpegImage),
                                   sizeof(kJpegImage));
   image->loader()->didFinishLoading(0.0, sizeof(kJpegImage),
diff --git a/third_party/WebKit/Source/core/loader/resource/LinkPreloadResourceClients.h b/third_party/WebKit/Source/core/loader/resource/LinkPreloadResourceClients.h
index af4ee2cc..241d185 100644
--- a/third_party/WebKit/Source/core/loader/resource/LinkPreloadResourceClients.h
+++ b/third_party/WebKit/Source/core/loader/resource/LinkPreloadResourceClients.h
@@ -5,11 +5,11 @@
 #ifndef LinkPreloadResourceClients_h
 #define LinkPreloadResourceClients_h
 
-#include "core/fetch/ImageResource.h"
 #include "core/fetch/RawResource.h"
 #include "core/fetch/ResourceOwner.h"
 #include "core/loader/resource/CSSStyleSheetResource.h"
 #include "core/loader/resource/FontResource.h"
+#include "core/loader/resource/ImageResource.h"
 #include "core/loader/resource/ScriptResource.h"
 #include "core/loader/resource/StyleSheetResourceClient.h"
 
diff --git a/third_party/WebKit/Source/core/fetch/MockImageResourceClient.cpp b/third_party/WebKit/Source/core/loader/resource/MockImageResourceClient.cpp
similarity index 90%
rename from third_party/WebKit/Source/core/fetch/MockImageResourceClient.cpp
rename to third_party/WebKit/Source/core/loader/resource/MockImageResourceClient.cpp
index 9705278..56e0c2e 100644
--- a/third_party/WebKit/Source/core/fetch/MockImageResourceClient.cpp
+++ b/third_party/WebKit/Source/core/loader/resource/MockImageResourceClient.cpp
@@ -2,10 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "core/fetch/MockImageResourceClient.h"
+#include "core/loader/resource/MockImageResourceClient.h"
 
-#include "core/fetch/ImageResource.h"
-#include "core/fetch/ImageResourceContent.h"
+#include "core/loader/resource/ImageResource.h"
+#include "core/loader/resource/ImageResourceContent.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/fetch/MockImageResourceClient.h b/third_party/WebKit/Source/core/loader/resource/MockImageResourceClient.h
similarity index 89%
rename from third_party/WebKit/Source/core/fetch/MockImageResourceClient.h
rename to third_party/WebKit/Source/core/loader/resource/MockImageResourceClient.h
index ecbfb8a..9a16d55d 100644
--- a/third_party/WebKit/Source/core/fetch/MockImageResourceClient.h
+++ b/third_party/WebKit/Source/core/loader/resource/MockImageResourceClient.h
@@ -5,10 +5,10 @@
 #ifndef MockImageResourceClient_h
 #define MockImageResourceClient_h
 
-#include "core/fetch/ImageResource.h"
-#include "core/fetch/ImageResourceContent.h"
-#include "core/fetch/ImageResourceObserver.h"
 #include "core/fetch/MockResourceClient.h"
+#include "core/loader/resource/ImageResource.h"
+#include "core/loader/resource/ImageResourceContent.h"
+#include "core/loader/resource/ImageResourceObserver.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/core/fetch/MultipartImageResourceParser.cpp b/third_party/WebKit/Source/core/loader/resource/MultipartImageResourceParser.cpp
similarity index 98%
rename from third_party/WebKit/Source/core/fetch/MultipartImageResourceParser.cpp
rename to third_party/WebKit/Source/core/loader/resource/MultipartImageResourceParser.cpp
index 319b2d3..4f68402 100644
--- a/third_party/WebKit/Source/core/fetch/MultipartImageResourceParser.cpp
+++ b/third_party/WebKit/Source/core/loader/resource/MultipartImageResourceParser.cpp
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "core/fetch/MultipartImageResourceParser.h"
+#include "core/loader/resource/MultipartImageResourceParser.h"
 
 #include "platform/network/HTTPParsers.h"
 #include "wtf/NotFound.h"
diff --git a/third_party/WebKit/Source/core/fetch/MultipartImageResourceParser.h b/third_party/WebKit/Source/core/loader/resource/MultipartImageResourceParser.h
similarity index 100%
rename from third_party/WebKit/Source/core/fetch/MultipartImageResourceParser.h
rename to third_party/WebKit/Source/core/loader/resource/MultipartImageResourceParser.h
diff --git a/third_party/WebKit/Source/core/fetch/MultipartImageResourceParserTest.cpp b/third_party/WebKit/Source/core/loader/resource/MultipartImageResourceParserTest.cpp
similarity index 99%
rename from third_party/WebKit/Source/core/fetch/MultipartImageResourceParserTest.cpp
rename to third_party/WebKit/Source/core/loader/resource/MultipartImageResourceParserTest.cpp
index 0601cfa..f596ac3 100644
--- a/third_party/WebKit/Source/core/fetch/MultipartImageResourceParserTest.cpp
+++ b/third_party/WebKit/Source/core/loader/resource/MultipartImageResourceParserTest.cpp
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "core/fetch/MultipartImageResourceParser.h"
+#include "core/loader/resource/MultipartImageResourceParser.h"
 
 #include "platform/network/ResourceResponse.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/third_party/WebKit/Source/core/page/DragController.cpp b/third_party/WebKit/Source/core/page/DragController.cpp
index 6ec0a62..da3319e 100644
--- a/third_party/WebKit/Source/core/page/DragController.cpp
+++ b/third_party/WebKit/Source/core/page/DragController.cpp
@@ -46,7 +46,6 @@
 #include "core/editing/commands/DragAndDropCommand.h"
 #include "core/editing/serializers/Serialization.h"
 #include "core/events/TextEvent.h"
-#include "core/fetch/ImageResourceContent.h"
 #include "core/fetch/ResourceFetcher.h"
 #include "core/frame/FrameHost.h"
 #include "core/frame/FrameView.h"
@@ -64,6 +63,7 @@
 #include "core/layout/api/LayoutViewItem.h"
 #include "core/loader/FrameLoadRequest.h"
 #include "core/loader/FrameLoader.h"
+#include "core/loader/resource/ImageResourceContent.h"
 #include "core/page/ChromeClient.h"
 #include "core/page/DragData.h"
 #include "core/page/DragSession.h"
diff --git a/third_party/WebKit/Source/core/page/SpatialNavigation.cpp b/third_party/WebKit/Source/core/page/SpatialNavigation.cpp
index ac1288b9..bfc71f87 100644
--- a/third_party/WebKit/Source/core/page/SpatialNavigation.cpp
+++ b/third_party/WebKit/Source/core/page/SpatialNavigation.cpp
@@ -330,21 +330,21 @@
   switch (type) {
     case WebFocusTypeLeft:
       return (container->layoutObject()->style()->overflowX() !=
-                  OverflowHidden &&
+                  EOverflow::Hidden &&
               container->layoutBox()->scrollLeft() > 0);
     case WebFocusTypeUp:
       return (container->layoutObject()->style()->overflowY() !=
-                  OverflowHidden &&
+                  EOverflow::Hidden &&
               container->layoutBox()->scrollTop() > 0);
     case WebFocusTypeRight:
       return (container->layoutObject()->style()->overflowX() !=
-                  OverflowHidden &&
+                  EOverflow::Hidden &&
               container->layoutBox()->scrollLeft() +
                       container->layoutBox()->clientWidth() <
                   container->layoutBox()->scrollWidth());
     case WebFocusTypeDown:
       return (container->layoutObject()->style()->overflowY() !=
-                  OverflowHidden &&
+                  EOverflow::Hidden &&
               container->layoutBox()->scrollTop() +
                       container->layoutBox()->clientHeight() <
                   container->layoutBox()->scrollHeight());
@@ -626,9 +626,11 @@
     LayoutRect parentRect = nodeRectInAbsoluteCoordinates(&parentNode);
     if (!candidateRect.intersects(parentRect)) {
       if (((type == WebFocusTypeLeft || type == WebFocusTypeRight) &&
-           parentNode.layoutObject()->style()->overflowX() == OverflowHidden) ||
+           parentNode.layoutObject()->style()->overflowX() ==
+               EOverflow::Hidden) ||
           ((type == WebFocusTypeUp || type == WebFocusTypeDown) &&
-           parentNode.layoutObject()->style()->overflowY() == OverflowHidden))
+           parentNode.layoutObject()->style()->overflowY() ==
+               EOverflow::Hidden))
         return false;
     }
     if (parentNode == candidate.enclosingScrollableBox)
diff --git a/third_party/WebKit/Source/core/paint/PaintLayer.cpp b/third_party/WebKit/Source/core/paint/PaintLayer.cpp
index 98742cb..63f32af 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayer.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayer.cpp
@@ -1251,7 +1251,7 @@
 }
 
 void PaintLayer::operator delete(void* ptr) {
-  partitionFree(ptr);
+  WTF::partitionFree(ptr);
 }
 
 void PaintLayer::addChild(PaintLayer* child, PaintLayer* beforeChild) {
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
index e50d441..42bae0b7 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
@@ -606,8 +606,9 @@
   EOverflow overflowStyle = (orientation == HorizontalScrollbar)
                                 ? box().style()->overflowX()
                                 : box().style()->overflowY();
-  return (overflowStyle == OverflowScroll || overflowStyle == OverflowAuto ||
-          overflowStyle == OverflowOverlay);
+  return (overflowStyle == EOverflow::Scroll ||
+          overflowStyle == EOverflow::Auto ||
+          overflowStyle == EOverflow::Overlay);
 }
 
 bool PaintLayerScrollableArea::shouldPlaceVerticalScrollbarOnLeft() const {
@@ -734,9 +735,9 @@
 
     // Our proprietary overflow: overlay value doesn't trigger a layout.
     if ((horizontalScrollbarShouldChange &&
-         box().style()->overflowX() != OverflowOverlay) ||
+         box().style()->overflowX() != EOverflow::Overlay) ||
         (verticalScrollbarShouldChange &&
-         box().style()->overflowY() != OverflowOverlay)) {
+         box().style()->overflowY() != EOverflow::Overlay)) {
       if ((verticalScrollbarShouldChange && box().isHorizontalWritingMode()) ||
           (horizontalScrollbarShouldChange &&
            !box().isHorizontalWritingMode())) {
@@ -955,14 +956,14 @@
   // With overflow: scroll, scrollbars are always visible but may be disabled.
   // When switching to another value, we need to re-enable them (see bug 11985).
   if (hasHorizontalScrollbar() && oldStyle &&
-      oldStyle->overflowX() == OverflowScroll &&
-      box().style()->overflowX() != OverflowScroll) {
+      oldStyle->overflowX() == EOverflow::Scroll &&
+      box().style()->overflowX() != EOverflow::Scroll) {
     horizontalScrollbar()->setEnabled(true);
   }
 
   if (hasVerticalScrollbar() && oldStyle &&
-      oldStyle->overflowY() == OverflowScroll &&
-      box().style()->overflowY() != OverflowScroll) {
+      oldStyle->overflowY() == EOverflow::Scroll &&
+      box().style()->overflowY() != EOverflow::Scroll) {
     verticalScrollbar()->setEnabled(true);
   }
 
diff --git a/third_party/WebKit/Source/core/style/ComputedStyle.cpp b/third_party/WebKit/Source/core/style/ComputedStyle.cpp
index 6947b90..4a7e199 100644
--- a/third_party/WebKit/Source/core/style/ComputedStyle.cpp
+++ b/third_party/WebKit/Source/core/style/ComputedStyle.cpp
@@ -235,8 +235,6 @@
 void ComputedStyle::propagateIndependentInheritedProperties(
     const ComputedStyle& parentStyle) {
   ComputedStyleBase::propagateIndependentInheritedProperties(parentStyle);
-  if (m_nonInheritedData.m_isPointerEventsInherited)
-    setPointerEvents(parentStyle.pointerEvents());
 }
 
 StyleSelfAlignmentData resolvedSelfAlignment(
@@ -418,11 +416,6 @@
   // m_nonInheritedData.m_affectedByDrag
   // m_nonInheritedData.m_isLink
 
-  // Any properties that are inherited on a style are also inherited on elements
-  // that share this style.
-  m_nonInheritedData.m_isPointerEventsInherited =
-      other.m_nonInheritedData.m_isPointerEventsInherited;
-
   if (m_svgStyle != other.m_svgStyle)
     m_svgStyle.access()->copyNonInheritedFromCached(other.m_svgStyle.get());
   DCHECK_EQ(zoom(), initialZoom());
@@ -501,14 +494,13 @@
 
 bool ComputedStyle::independentInheritedEqual(
     const ComputedStyle& other) const {
-  return ComputedStyleBase::independentInheritedEqual(other) &&
-         m_inheritedData.compareEqualIndependent(other.m_inheritedData);
+  return ComputedStyleBase::independentInheritedEqual(other);
 }
 
 bool ComputedStyle::nonIndependentInheritedEqual(
     const ComputedStyle& other) const {
   return ComputedStyleBase::nonIndependentInheritedEqual(other) &&
-         m_inheritedData.compareEqualNonIndependent(other.m_inheritedData) &&
+         m_inheritedData == other.m_inheritedData &&
          m_styleInheritedData == other.m_styleInheritedData &&
          m_svgStyle->inheritedEqual(*other.m_svgStyle) &&
          m_rareInheritedData == other.m_rareInheritedData;
diff --git a/third_party/WebKit/Source/core/style/ComputedStyle.h b/third_party/WebKit/Source/core/style/ComputedStyle.h
index 514f63b..fcbdce1 100644
--- a/third_party/WebKit/Source/core/style/ComputedStyle.h
+++ b/third_party/WebKit/Source/core/style/ComputedStyle.h
@@ -198,24 +198,6 @@
   // inherit
   struct InheritedData {
     bool operator==(const InheritedData& other) const {
-      return compareEqualIndependent(other) &&
-             compareEqualNonIndependent(other);
-    }
-
-    bool operator!=(const InheritedData& other) const {
-      return !(*this == other);
-    }
-
-    inline bool compareEqualIndependent(const InheritedData& other) const {
-      // These must match the properties tagged 'independent' in
-      // CSSProperties.in.
-      // TODO(napper): Remove this once all independent properties are
-      // generated and replace with a private function used only in
-      // stylePropagationDiff().
-      return (m_pointerEvents == other.m_pointerEvents);
-    }
-
-    inline bool compareEqualNonIndependent(const InheritedData& other) const {
       return (m_listStyleType == other.m_listStyleType) &&
              (m_textAlign == other.m_textAlign) &&
              (m_hasSimpleUnderline == other.m_hasSimpleUnderline) &&
@@ -227,6 +209,10 @@
              (m_writingMode == other.m_writingMode);
     }
 
+    bool operator!=(const InheritedData& other) const {
+      return !(*this == other);
+    }
+
     unsigned m_listStyleType : 7;      // EListStyleType
     unsigned m_textAlign : 4;          // ETextAlign
     unsigned m_hasSimpleUnderline : 1;  // True if 'underline solid' is the only
@@ -238,7 +224,6 @@
     // non CSS2 inherited
     unsigned m_rtlOrdering : 1;       // EOrder
     unsigned m_printColorAdjust : 1;  // PrintColorAdjust
-    unsigned m_pointerEvents : 4;  // EPointerEvents
     unsigned m_insideLink : 2;     // EInsideLink
 
     // CSS Text Layout Module Level 3: Vertical writing support
@@ -324,25 +309,6 @@
 
     mutable unsigned m_hasRemUnits : 1;
 
-    // For each independent inherited property, store a 1 if the stored
-    // value was inherited from its parent, or 0 if it is explicitly set on
-    // this element.
-    // Eventually, all properties will have a bit in here to store whether
-    // they were inherited from their parent or not.
-    // Although two ComputedStyles are equal if their nonInheritedData is
-    // equal regardless of the isInherited flags, this struct is stored next
-    // to the existing flags to take advantage of packing as much as possible.
-    // TODO(sashab): Move these flags closer to inheritedData so that it's
-    // clear which inherited properties have a flag stored and which don't.
-    // Keep this list of fields in sync with:
-    // - setBitDefaults()
-    // - The ComputedStyle setter, which must take an extra boolean parameter
-    //   and set this - propagateIndependentInheritedProperties() in
-    //   ComputedStyle.cpp
-    // - The compareEqual() methods in the corresponding class
-    // InheritedFlags
-    unsigned m_isPointerEventsInherited : 1;
-
     // If you add more style bits here, you will also need to update
     // ComputedStyle::copyNonInheritedFromCached() 68 bits
   } m_nonInheritedData;
@@ -360,8 +326,6 @@
     m_inheritedData.m_rtlOrdering = static_cast<unsigned>(initialRTLOrdering());
     m_inheritedData.m_printColorAdjust =
         static_cast<unsigned>(initialPrintColorAdjust());
-    m_inheritedData.m_pointerEvents =
-        static_cast<unsigned>(initialPointerEvents());
     m_inheritedData.m_insideLink = NotInsideLink;
     m_inheritedData.m_writingMode = initialWritingMode();
 
@@ -370,8 +334,8 @@
             static_cast<unsigned>(initialDisplay());
     m_nonInheritedData.m_overflowAnchor =
         static_cast<unsigned>(initialOverflowAnchor());
-    m_nonInheritedData.m_overflowX = initialOverflowX();
-    m_nonInheritedData.m_overflowY = initialOverflowY();
+    m_nonInheritedData.m_overflowX = static_cast<unsigned>(initialOverflowX());
+    m_nonInheritedData.m_overflowY = static_cast<unsigned>(initialOverflowY());
     m_nonInheritedData.m_verticalAlign = initialVerticalAlign();
     m_nonInheritedData.m_clear = initialClear();
     m_nonInheritedData.m_position = initialPosition();
@@ -393,9 +357,6 @@
     m_nonInheritedData.m_affectedByDrag = false;
     m_nonInheritedData.m_isLink = false;
     m_nonInheritedData.m_hasRemUnits = false;
-
-    // All independently inherited properties default to being inherited.
-    m_nonInheritedData.m_isPointerEventsInherited = true;
   }
 
  private:
@@ -1551,18 +1512,22 @@
   }
 
   // overflow-x
-  static EOverflow initialOverflowX() { return OverflowVisible; }
+  static EOverflow initialOverflowX() { return EOverflow::Visible; }
   EOverflow overflowX() const {
     return static_cast<EOverflow>(m_nonInheritedData.m_overflowX);
   }
-  void setOverflowX(EOverflow v) { m_nonInheritedData.m_overflowX = v; }
+  void setOverflowX(EOverflow v) {
+    m_nonInheritedData.m_overflowX = static_cast<unsigned>(v);
+  }
 
   // overflow-y
-  static EOverflow initialOverflowY() { return OverflowVisible; }
+  static EOverflow initialOverflowY() { return EOverflow::Visible; }
   EOverflow overflowY() const {
     return static_cast<EOverflow>(m_nonInheritedData.m_overflowY);
   }
-  void setOverflowY(EOverflow v) { m_nonInheritedData.m_overflowY = v; }
+  void setOverflowY(EOverflow v) {
+    m_nonInheritedData.m_overflowY = static_cast<unsigned>(v);
+  }
 
   // Padding properties.
   static Length initialPadding() { return Length(Fixed); }
@@ -2130,18 +2095,6 @@
     SET_VAR(m_rareInheritedData, overflowWrap, b);
   }
 
-  // pointer-events
-  static EPointerEvents initialPointerEvents() { return EPointerEvents::Auto; }
-  EPointerEvents pointerEvents() const {
-    return static_cast<EPointerEvents>(m_inheritedData.m_pointerEvents);
-  }
-  void setPointerEvents(EPointerEvents p) {
-    m_inheritedData.m_pointerEvents = static_cast<unsigned>(p);
-  }
-  void setPointerEventsIsInherited(bool isInherited) {
-    m_nonInheritedData.m_isPointerEventsInherited = isInherited;
-  }
-
   // quotes
   static QuotesData* initialQuotes() { return 0; }
   QuotesData* quotes() const { return m_rareInheritedData->quotes.get(); }
@@ -3520,11 +3473,11 @@
   // It's sufficient to just check one direction, since it's illegal to have
   // visible on only one overflow value.
   bool isOverflowVisible() const {
-    DCHECK(overflowX() != OverflowVisible || overflowX() == overflowY());
-    return overflowX() == OverflowVisible;
+    DCHECK(overflowX() != EOverflow::Visible || overflowX() == overflowY());
+    return overflowX() == EOverflow::Visible;
   }
   bool isOverflowPaged() const {
-    return overflowY() == OverflowPagedX || overflowY() == OverflowPagedY;
+    return overflowY() == EOverflow::PagedX || overflowY() == EOverflow::PagedY;
   }
 
   // Visibility utility functions.
@@ -3724,7 +3677,7 @@
     // columns may be laid out along the inline axis, just like for regular
     // multicol. Otherwise, we need to lay out along the block axis.
     if (isOverflowPaged())
-      return (overflowY() == OverflowPagedX) == isHorizontalWritingMode();
+      return (overflowY() == EOverflow::PagedX) == isHorizontalWritingMode();
     return false;
   }
 
diff --git a/third_party/WebKit/Source/core/style/ComputedStyleConstants.h b/third_party/WebKit/Source/core/style/ComputedStyleConstants.h
index 45d0e6b5..913e83f 100644
--- a/third_party/WebKit/Source/core/style/ComputedStyleConstants.h
+++ b/third_party/WebKit/Source/core/style/ComputedStyleConstants.h
@@ -148,14 +148,14 @@
 
 enum class EOverflowAnchor : unsigned { Visible, None, Auto };
 
-enum EOverflow {
-  OverflowVisible,
-  OverflowHidden,
-  OverflowScroll,
-  OverflowAuto,
-  OverflowOverlay,
-  OverflowPagedX,
-  OverflowPagedY
+enum class EOverflow : unsigned {
+  Visible,
+  Hidden,
+  Scroll,
+  Auto,
+  Overlay,
+  PagedX,
+  PagedY
 };
 
 enum EVerticalAlign {
@@ -482,20 +482,6 @@
 
 enum EInsideLink { NotInsideLink, InsideUnvisitedLink, InsideVisitedLink };
 
-enum class EPointerEvents : unsigned {
-  None,
-  Auto,
-  Stroke,
-  Fill,
-  Painted,
-  Visible,
-  VisibleStroke,
-  VisibleFill,
-  VisiblePainted,
-  BoundingBox,
-  All
-};
-
 enum ETransformStyle3D { TransformStyle3DFlat, TransformStyle3DPreserve3D };
 
 enum OffsetRotationType { OffsetRotationAuto, OffsetRotationFixed };
diff --git a/third_party/WebKit/Source/core/style/ComputedStyleTest.cpp b/third_party/WebKit/Source/core/style/ComputedStyleTest.cpp
index fe24b63..b727b9b 100644
--- a/third_party/WebKit/Source/core/style/ComputedStyleTest.cpp
+++ b/third_party/WebKit/Source/core/style/ComputedStyleTest.cpp
@@ -71,8 +71,8 @@
 TEST(ComputedStyleTest, Preserve3dForceStackingContext) {
   RefPtr<ComputedStyle> style = ComputedStyle::create();
   style->setTransformStyle3D(TransformStyle3DPreserve3D);
-  style->setOverflowX(OverflowHidden);
-  style->setOverflowY(OverflowHidden);
+  style->setOverflowX(EOverflow::Hidden);
+  style->setOverflowY(EOverflow::Hidden);
   style->updateIsStackingContext(false, false);
   EXPECT_EQ(TransformStyle3DFlat, style->usedTransformStyle3D());
   EXPECT_TRUE(style->isStackingContext());
diff --git a/third_party/WebKit/Source/core/style/ShapeValue.h b/third_party/WebKit/Source/core/style/ShapeValue.h
index 86f785263..9dc281e 100644
--- a/third_party/WebKit/Source/core/style/ShapeValue.h
+++ b/third_party/WebKit/Source/core/style/ShapeValue.h
@@ -30,10 +30,10 @@
 #ifndef ShapeValue_h
 #define ShapeValue_h
 
-#include "core/fetch/ImageResourceContent.h"
+#include "core/loader/resource/ImageResourceContent.h"
 #include "core/style/BasicShapes.h"
-#include "core/style/DataEquivalency.h"
 #include "core/style/ComputedStyleConstants.h"
+#include "core/style/DataEquivalency.h"
 #include "core/style/StyleImage.h"
 #include "wtf/PassRefPtr.h"
 
diff --git a/third_party/WebKit/Source/core/style/StyleFetchedImage.cpp b/third_party/WebKit/Source/core/style/StyleFetchedImage.cpp
index 76fd5e6..794c961 100644
--- a/third_party/WebKit/Source/core/style/StyleFetchedImage.cpp
+++ b/third_party/WebKit/Source/core/style/StyleFetchedImage.cpp
@@ -24,8 +24,8 @@
 #include "core/style/StyleFetchedImage.h"
 
 #include "core/css/CSSImageValue.h"
-#include "core/fetch/ImageResourceContent.h"
 #include "core/layout/LayoutObject.h"
+#include "core/loader/resource/ImageResourceContent.h"
 #include "core/svg/graphics/SVGImage.h"
 #include "core/svg/graphics/SVGImageForContainer.h"
 
diff --git a/third_party/WebKit/Source/core/style/StyleFetchedImage.h b/third_party/WebKit/Source/core/style/StyleFetchedImage.h
index 07bb8bb..598a749 100644
--- a/third_party/WebKit/Source/core/style/StyleFetchedImage.h
+++ b/third_party/WebKit/Source/core/style/StyleFetchedImage.h
@@ -24,7 +24,7 @@
 #ifndef StyleFetchedImage_h
 #define StyleFetchedImage_h
 
-#include "core/fetch/ImageResourceObserver.h"
+#include "core/loader/resource/ImageResourceObserver.h"
 #include "core/style/StyleImage.h"
 #include "platform/weborigin/KURL.h"
 
diff --git a/third_party/WebKit/Source/core/style/StyleFetchedImageSet.cpp b/third_party/WebKit/Source/core/style/StyleFetchedImageSet.cpp
index 65305b8..49592e82 100644
--- a/third_party/WebKit/Source/core/style/StyleFetchedImageSet.cpp
+++ b/third_party/WebKit/Source/core/style/StyleFetchedImageSet.cpp
@@ -26,8 +26,8 @@
 #include "core/style/StyleFetchedImageSet.h"
 
 #include "core/css/CSSImageSetValue.h"
-#include "core/fetch/ImageResourceContent.h"
 #include "core/layout/LayoutObject.h"
+#include "core/loader/resource/ImageResourceContent.h"
 #include "core/svg/graphics/SVGImageForContainer.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/style/StyleFetchedImageSet.h b/third_party/WebKit/Source/core/style/StyleFetchedImageSet.h
index 6d04c60..6d85211 100644
--- a/third_party/WebKit/Source/core/style/StyleFetchedImageSet.h
+++ b/third_party/WebKit/Source/core/style/StyleFetchedImageSet.h
@@ -26,7 +26,7 @@
 #ifndef StyleFetchedImageSet_h
 #define StyleFetchedImageSet_h
 
-#include "core/fetch/ImageResourceObserver.h"
+#include "core/loader/resource/ImageResourceObserver.h"
 #include "core/style/StyleImage.h"
 #include "platform/geometry/LayoutSize.h"
 #include "platform/weborigin/KURL.h"
diff --git a/third_party/WebKit/Source/core/svg/SVGFEImageElement.h b/third_party/WebKit/Source/core/svg/SVGFEImageElement.h
index ba01823d..111df6a 100644
--- a/third_party/WebKit/Source/core/svg/SVGFEImageElement.h
+++ b/third_party/WebKit/Source/core/svg/SVGFEImageElement.h
@@ -22,8 +22,8 @@
 #define SVGFEImageElement_h
 
 #include "core/SVGNames.h"
-#include "core/fetch/ImageResourceContent.h"
-#include "core/fetch/ImageResourceObserver.h"
+#include "core/loader/resource/ImageResourceContent.h"
+#include "core/loader/resource/ImageResourceObserver.h"
 #include "core/svg/SVGAnimatedPreserveAspectRatio.h"
 #include "core/svg/SVGFilterPrimitiveStandardAttributes.h"
 #include "core/svg/SVGURIReference.h"
diff --git a/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp b/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp
index c80b14d..a3321a0 100644
--- a/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp
+++ b/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp
@@ -33,11 +33,11 @@
 #include "core/frame/FrameView.h"
 #include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
-#include "core/style/ComputedStyle.h"
 #include "core/layout/svg/LayoutSVGRoot.h"
 #include "core/loader/FrameLoadRequest.h"
 #include "core/paint/FloatClipRecorder.h"
 #include "core/paint/TransformRecorder.h"
+#include "core/style/ComputedStyle.h"
 #include "core/svg/SVGDocumentExtensions.h"
 #include "core/svg/SVGFEImageElement.h"
 #include "core/svg/SVGImageElement.h"
diff --git a/third_party/WebKit/Source/modules/filesystem/DataTransferItemFileSystem.cpp b/third_party/WebKit/Source/modules/filesystem/DataTransferItemFileSystem.cpp
index 12aba0f..46b4fec 100644
--- a/third_party/WebKit/Source/modules/filesystem/DataTransferItemFileSystem.cpp
+++ b/third_party/WebKit/Source/modules/filesystem/DataTransferItemFileSystem.cpp
@@ -62,7 +62,8 @@
 
   DOMFileSystem* domFileSystem =
       DraggedIsolatedFileSystemImpl::getDOMFileSystem(
-          item.getDataTransfer()->dataObject(), executionContext);
+          item.getDataTransfer()->dataObject(), executionContext,
+          *item.getDataObjectItem());
   if (!domFileSystem) {
     // IsolatedFileSystem may not be enabled.
     return 0;
diff --git a/third_party/WebKit/Source/modules/filesystem/DraggedIsolatedFileSystemImpl.cpp b/third_party/WebKit/Source/modules/filesystem/DraggedIsolatedFileSystemImpl.cpp
index 89d68ff..2eca96c 100644
--- a/third_party/WebKit/Source/modules/filesystem/DraggedIsolatedFileSystemImpl.cpp
+++ b/third_party/WebKit/Source/modules/filesystem/DraggedIsolatedFileSystemImpl.cpp
@@ -39,15 +39,21 @@
 
 DOMFileSystem* DraggedIsolatedFileSystemImpl::getDOMFileSystem(
     DataObject* host,
-    ExecutionContext* executionContext) {
+    ExecutionContext* executionContext,
+    const DataObjectItem& item) {
+  if (!item.hasFileSystemId())
+    return nullptr;
+  const String fileSystemId = item.fileSystemId();
   DraggedIsolatedFileSystemImpl* draggedIsolatedFileSystem = from(host);
   if (!draggedIsolatedFileSystem)
-    return 0;
-  if (!draggedIsolatedFileSystem->m_filesystem)
-    draggedIsolatedFileSystem->m_filesystem =
-        DOMFileSystem::createIsolatedFileSystem(executionContext,
-                                                host->filesystemId());
-  return draggedIsolatedFileSystem->m_filesystem.get();
+    return nullptr;
+  auto it = draggedIsolatedFileSystem->m_filesystems.find(fileSystemId);
+  if (it != draggedIsolatedFileSystem->m_filesystems.end())
+    return it->value;
+  return draggedIsolatedFileSystem->m_filesystems
+      .add(fileSystemId, DOMFileSystem::createIsolatedFileSystem(
+                             executionContext, fileSystemId))
+      .storedValue->value;
 }
 
 // static
@@ -62,21 +68,15 @@
       Supplement<DataObject>::from(dataObject, supplementName()));
 }
 
-DraggedIsolatedFileSystemImpl::DraggedIsolatedFileSystemImpl(
-    DataObject& host,
-    const String& filesystemId) {
-  host.setFilesystemId(filesystemId);
-}
-
 DEFINE_TRACE(DraggedIsolatedFileSystemImpl) {
-  visitor->trace(m_filesystem);
+  visitor->trace(m_filesystems);
   Supplement<DataObject>::trace(visitor);
 }
 
 void DraggedIsolatedFileSystemImpl::prepareForDataObject(
-    DataObject* dataObject,
-    const String& filesystemId) {
-  DraggedIsolatedFileSystemImpl* fileSystem = create(*dataObject, filesystemId);
+    DataObject* dataObject) {
+  DraggedIsolatedFileSystemImpl* fileSystem =
+      new DraggedIsolatedFileSystemImpl();
   DraggedIsolatedFileSystemImpl::provideTo(
       *dataObject, DraggedIsolatedFileSystemImpl::supplementName(), fileSystem);
 }
diff --git a/third_party/WebKit/Source/modules/filesystem/DraggedIsolatedFileSystemImpl.h b/third_party/WebKit/Source/modules/filesystem/DraggedIsolatedFileSystemImpl.h
index 33afbac..b05ae500 100644
--- a/third_party/WebKit/Source/modules/filesystem/DraggedIsolatedFileSystemImpl.h
+++ b/third_party/WebKit/Source/modules/filesystem/DraggedIsolatedFileSystemImpl.h
@@ -34,6 +34,7 @@
 #include "core/clipboard/DataObject.h"
 #include "core/clipboard/DraggedIsolatedFileSystem.h"
 #include "platform/heap/Handle.h"
+#include "platform/heap/HeapAllocator.h"
 #include "wtf/Forward.h"
 #include "wtf/text/WTFString.h"
 
@@ -48,24 +49,21 @@
   USING_GARBAGE_COLLECTED_MIXIN(DraggedIsolatedFileSystemImpl);
 
  public:
-  static DraggedIsolatedFileSystemImpl* create(DataObject& host,
-                                               const String& filesystemId) {
-    return new DraggedIsolatedFileSystemImpl(host, filesystemId);
-  }
-
-  static DOMFileSystem* getDOMFileSystem(DataObject* host, ExecutionContext*);
+  static DOMFileSystem* getDOMFileSystem(DataObject* host,
+                                         ExecutionContext*,
+                                         const DataObjectItem&);
 
   static const char* supplementName();
   static DraggedIsolatedFileSystemImpl* from(DataObject*);
 
   DECLARE_TRACE();
 
-  static void prepareForDataObject(DataObject*, const String& filesystemId);
+  static void prepareForDataObject(DataObject*);
 
  private:
-  DraggedIsolatedFileSystemImpl(DataObject& host, const String& filesystemId);
+  DraggedIsolatedFileSystemImpl() = default;
 
-  Member<DOMFileSystem> m_filesystem;
+  HeapHashMap<String, Member<DOMFileSystem>> m_filesystems;
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/serviceworkers/NavigatorServiceWorker.cpp b/third_party/WebKit/Source/modules/serviceworkers/NavigatorServiceWorker.cpp
index cd8b179c..73160f0 100644
--- a/third_party/WebKit/Source/modules/serviceworkers/NavigatorServiceWorker.cpp
+++ b/third_party/WebKit/Source/modules/serviceworkers/NavigatorServiceWorker.cpp
@@ -12,9 +12,7 @@
 
 namespace blink {
 
-NavigatorServiceWorker::NavigatorServiceWorker(Navigator& navigator)
-    : ContextLifecycleObserver(navigator.frame() ? navigator.frame()->document()
-                                                 : nullptr) {}
+NavigatorServiceWorker::NavigatorServiceWorker(Navigator& navigator) {}
 
 NavigatorServiceWorker* NavigatorServiceWorker::from(Document& document) {
   if (!document.frame() || !document.frame()->domWindow())
@@ -105,21 +103,23 @@
     return nullptr;
   }
   if (!m_serviceWorker && frame) {
+    // We need to create a new ServiceWorkerContainer when the frame
+    // navigates to a new document. In practice, this happens only when the
+    // frame navigates from the initial empty page to a new same-origin page.
     DCHECK(frame->domWindow());
     m_serviceWorker = ServiceWorkerContainer::create(
-        frame->domWindow()->getExecutionContext());
+        frame->domWindow()->getExecutionContext(), this);
   }
   return m_serviceWorker.get();
 }
 
-void NavigatorServiceWorker::contextDestroyed() {
+void NavigatorServiceWorker::clearServiceWorker() {
   m_serviceWorker = nullptr;
 }
 
 DEFINE_TRACE(NavigatorServiceWorker) {
   visitor->trace(m_serviceWorker);
   Supplement<Navigator>::trace(visitor);
-  ContextLifecycleObserver::trace(visitor);
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/serviceworkers/NavigatorServiceWorker.h b/third_party/WebKit/Source/modules/serviceworkers/NavigatorServiceWorker.h
index c9abaf27..4bb8eb5 100644
--- a/third_party/WebKit/Source/modules/serviceworkers/NavigatorServiceWorker.h
+++ b/third_party/WebKit/Source/modules/serviceworkers/NavigatorServiceWorker.h
@@ -5,7 +5,6 @@
 #ifndef NavigatorServiceWorker_h
 #define NavigatorServiceWorker_h
 
-#include "core/dom/ContextLifecycleObserver.h"
 #include "core/frame/Navigator.h"
 #include "modules/ModulesExport.h"
 #include "platform/Supplementable.h"
@@ -20,8 +19,7 @@
 
 class MODULES_EXPORT NavigatorServiceWorker final
     : public GarbageCollected<NavigatorServiceWorker>,
-      public Supplement<Navigator>,
-      public ContextLifecycleObserver {
+      public Supplement<Navigator> {
   USING_GARBAGE_COLLECTED_MIXIN(NavigatorServiceWorker);
 
  public:
@@ -34,6 +32,7 @@
   static ServiceWorkerContainer* serviceWorker(ExecutionContext*,
                                                Navigator&,
                                                String& errorMessage);
+  void clearServiceWorker();
 
   DECLARE_VIRTUAL_TRACE();
 
@@ -44,9 +43,6 @@
 
   static const char* supplementName();
 
-  // ContextLifecycleObserver override.
-  void contextDestroyed() override;
-
   Member<ServiceWorkerContainer> m_serviceWorker;
 };
 
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerContainer.cpp b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerContainer.cpp
index ca34c93..711d7d7 100644
--- a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerContainer.cpp
+++ b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerContainer.cpp
@@ -45,6 +45,7 @@
 #include "core/frame/UseCounter.h"
 #include "core/frame/csp/ContentSecurityPolicy.h"
 #include "modules/EventTargetModules.h"
+#include "modules/serviceworkers/NavigatorServiceWorker.h"
 #include "modules/serviceworkers/ServiceWorker.h"
 #include "modules/serviceworkers/ServiceWorkerContainerClient.h"
 #include "modules/serviceworkers/ServiceWorkerError.h"
@@ -123,8 +124,9 @@
 };
 
 ServiceWorkerContainer* ServiceWorkerContainer::create(
-    ExecutionContext* executionContext) {
-  return new ServiceWorkerContainer(executionContext);
+    ExecutionContext* executionContext,
+    NavigatorServiceWorker* navigator) {
+  return new ServiceWorkerContainer(executionContext, navigator);
 }
 
 ServiceWorkerContainer::~ServiceWorkerContainer() {
@@ -136,11 +138,14 @@
     m_provider->setClient(0);
     m_provider = nullptr;
   }
+  if (m_navigator)
+    m_navigator->clearServiceWorker();
 }
 
 DEFINE_TRACE(ServiceWorkerContainer) {
   visitor->trace(m_controller);
   visitor->trace(m_ready);
+  visitor->trace(m_navigator);
   EventTargetWithInlineData::trace(visitor);
   ContextLifecycleObserver::trace(visitor);
 }
@@ -459,8 +464,11 @@
 }
 
 ServiceWorkerContainer::ServiceWorkerContainer(
-    ExecutionContext* executionContext)
-    : ContextLifecycleObserver(executionContext), m_provider(0) {
+    ExecutionContext* executionContext,
+    NavigatorServiceWorker* navigator)
+    : ContextLifecycleObserver(executionContext),
+      m_provider(0),
+      m_navigator(navigator) {
   if (!executionContext)
     return;
 
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerContainer.h b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerContainer.h
index 08a93c0..0c3fc313 100644
--- a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerContainer.h
+++ b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerContainer.h
@@ -49,6 +49,7 @@
 namespace blink {
 
 class ExecutionContext;
+class NavigatorServiceWorker;
 class WebServiceWorker;
 class WebServiceWorkerProvider;
 
@@ -63,7 +64,8 @@
   using RegistrationCallbacks =
       WebServiceWorkerProvider::WebServiceWorkerRegistrationCallbacks;
 
-  static ServiceWorkerContainer* create(ExecutionContext*);
+  static ServiceWorkerContainer* create(ExecutionContext*,
+                                        NavigatorServiceWorker*);
   ~ServiceWorkerContainer();
 
   DECLARE_VIRTUAL_TRACE();
@@ -102,7 +104,7 @@
   DEFINE_ATTRIBUTE_EVENT_LISTENER(message);
 
  private:
-  explicit ServiceWorkerContainer(ExecutionContext*);
+  ServiceWorkerContainer(ExecutionContext*, NavigatorServiceWorker*);
 
   class GetRegistrationForReadyCallback;
   typedef ScriptPromiseProperty<Member<ServiceWorkerContainer>,
@@ -114,6 +116,7 @@
   WebServiceWorkerProvider* m_provider;
   Member<ServiceWorker> m_controller;
   Member<ReadyProperty> m_ready;
+  Member<NavigatorServiceWorker> m_navigator;
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerContainerTest.cpp b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerContainerTest.cpp
index 42f19da0..3ada7d2 100644
--- a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerContainerTest.cpp
+++ b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerContainerTest.cpp
@@ -177,7 +177,7 @@
     provide(WTF::makeUnique<NotReachedWebServiceWorkerProvider>());
 
     ServiceWorkerContainer* container =
-        ServiceWorkerContainer::create(getExecutionContext());
+        ServiceWorkerContainer::create(getExecutionContext(), nullptr);
     ScriptState::Scope scriptScope(getScriptState());
     RegistrationOptions options;
     options.setScope(scope);
@@ -191,7 +191,7 @@
     provide(WTF::makeUnique<NotReachedWebServiceWorkerProvider>());
 
     ServiceWorkerContainer* container =
-        ServiceWorkerContainer::create(getExecutionContext());
+        ServiceWorkerContainer::create(getExecutionContext(), nullptr);
     ScriptState::Scope scriptScope(getScriptState());
     ScriptPromise promise =
         container->getRegistration(getScriptState(), documentURL);
@@ -332,7 +332,7 @@
   provide(stubProvider.provider());
 
   ServiceWorkerContainer* container =
-      ServiceWorkerContainer::create(getExecutionContext());
+      ServiceWorkerContainer::create(getExecutionContext(), nullptr);
 
   // register
   {
@@ -358,7 +358,7 @@
   provide(stubProvider.provider());
 
   ServiceWorkerContainer* container =
-      ServiceWorkerContainer::create(getExecutionContext());
+      ServiceWorkerContainer::create(getExecutionContext(), nullptr);
 
   {
     ScriptState::Scope scriptScope(getScriptState());
diff --git a/third_party/WebKit/Source/modules/shapedetection/ShapeDetector.cpp b/third_party/WebKit/Source/modules/shapedetection/ShapeDetector.cpp
index a846f2b..a574933 100644
--- a/third_party/WebKit/Source/modules/shapedetection/ShapeDetector.cpp
+++ b/third_party/WebKit/Source/modules/shapedetection/ShapeDetector.cpp
@@ -7,12 +7,12 @@
 #include "core/dom/DOMException.h"
 #include "core/dom/DOMRect.h"
 #include "core/dom/Document.h"
-#include "core/fetch/ImageResourceContent.h"
 #include "core/frame/ImageBitmap.h"
 #include "core/frame/LocalFrame.h"
 #include "core/html/HTMLImageElement.h"
 #include "core/html/HTMLVideoElement.h"
 #include "core/html/canvas/CanvasImageSource.h"
+#include "core/loader/resource/ImageResourceContent.h"
 #include "platform/graphics/Image.h"
 #include "third_party/skia/include/core/SkImage.h"
 #include "third_party/skia/include/core/SkImageInfo.h"
diff --git a/third_party/WebKit/Source/platform/PartitionAllocMemoryDumpProvider.cpp b/third_party/WebKit/Source/platform/PartitionAllocMemoryDumpProvider.cpp
index fc7a7769..384b529 100644
--- a/third_party/WebKit/Source/platform/PartitionAllocMemoryDumpProvider.cpp
+++ b/third_party/WebKit/Source/platform/PartitionAllocMemoryDumpProvider.cpp
@@ -38,7 +38,7 @@
 // This class is used to invert the dependency of PartitionAlloc on the
 // PartitionAllocMemoryDumpProvider. This implements an interface that will
 // be called with memory statistics for each bucket in the allocator.
-class PartitionStatsDumperImpl final : public PartitionStatsDumper {
+class PartitionStatsDumperImpl final : public WTF::PartitionStatsDumper {
   DISALLOW_NEW();
   WTF_MAKE_NONCOPYABLE(PartitionStatsDumperImpl);
 
@@ -50,9 +50,10 @@
 
   // PartitionStatsDumper implementation.
   void partitionDumpTotals(const char* partitionName,
-                           const PartitionMemoryStats*) override;
-  void partitionsDumpBucketStats(const char* partitionName,
-                                 const PartitionBucketMemoryStats*) override;
+                           const WTF::PartitionMemoryStats*) override;
+  void partitionsDumpBucketStats(
+      const char* partitionName,
+      const WTF::PartitionBucketMemoryStats*) override;
 
   size_t totalActiveBytes() const { return m_totalActiveBytes; }
 
@@ -64,7 +65,7 @@
 
 void PartitionStatsDumperImpl::partitionDumpTotals(
     const char* partitionName,
-    const PartitionMemoryStats* memoryStats) {
+    const WTF::PartitionMemoryStats* memoryStats) {
   m_totalActiveBytes += memoryStats->totalActiveBytes;
   std::string dumpName = getPartitionDumpName(partitionName);
   base::trace_event::MemoryAllocatorDump* allocatorDump =
@@ -84,7 +85,7 @@
 
 void PartitionStatsDumperImpl::partitionsDumpBucketStats(
     const char* partitionName,
-    const PartitionBucketMemoryStats* memoryStats) {
+    const WTF::PartitionBucketMemoryStats* memoryStats) {
   ASSERT(memoryStats->isValid);
   std::string dumpName = getPartitionDumpName(partitionName);
   if (memoryStats->isDirectMap)
@@ -185,11 +186,11 @@
       if (!m_allocationRegister)
         m_allocationRegister.reset(new base::trace_event::AllocationRegister());
     }
-    PartitionAllocHooks::setAllocationHook(reportAllocation);
-    PartitionAllocHooks::setFreeHook(reportFree);
+    WTF::PartitionAllocHooks::setAllocationHook(reportAllocation);
+    WTF::PartitionAllocHooks::setFreeHook(reportFree);
   } else {
-    PartitionAllocHooks::setAllocationHook(nullptr);
-    PartitionAllocHooks::setFreeHook(nullptr);
+    WTF::PartitionAllocHooks::setAllocationHook(nullptr);
+    WTF::PartitionAllocHooks::setFreeHook(nullptr);
   }
   m_isHeapProfilingEnabled = enabled;
 }
diff --git a/third_party/WebKit/Source/platform/graphics/ContiguousContainer.cpp b/third_party/WebKit/Source/platform/graphics/ContiguousContainer.cpp
index ea7c5a2..f9d51b5 100644
--- a/third_party/WebKit/Source/platform/graphics/ContiguousContainer.cpp
+++ b/third_party/WebKit/Source/platform/graphics/ContiguousContainer.cpp
@@ -7,7 +7,6 @@
 #include "wtf/Allocator.h"
 #include "wtf/ContainerAnnotations.h"
 #include "wtf/PtrUtil.h"
-#include "wtf/allocator/PartitionAlloc.h"
 #include "wtf/allocator/Partitions.h"
 #include <algorithm>
 #include <memory>
diff --git a/third_party/WebKit/Source/platform/heap/CallbackStack.cpp b/third_party/WebKit/Source/platform/heap/CallbackStack.cpp
index e61dae9..b9742b22 100644
--- a/third_party/WebKit/Source/platform/heap/CallbackStack.cpp
+++ b/third_party/WebKit/Source/platform/heap/CallbackStack.cpp
@@ -4,7 +4,6 @@
 
 #include "platform/heap/CallbackStack.h"
 #include "wtf/PtrUtil.h"
-#include "wtf/allocator/PageAllocator.h"
 #include "wtf/allocator/Partitions.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/platform/heap/HeapPage.cpp b/third_party/WebKit/Source/platform/heap/HeapPage.cpp
index 4ccb2ebc..c1940b3 100644
--- a/third_party/WebKit/Source/platform/heap/HeapPage.cpp
+++ b/third_party/WebKit/Source/platform/heap/HeapPage.cpp
@@ -50,7 +50,6 @@
 #include "wtf/ContainerAnnotations.h"
 #include "wtf/CurrentTime.h"
 #include "wtf/LeakAnnotations.h"
-#include "wtf/allocator/PageAllocator.h"
 #include "wtf/allocator/Partitions.h"
 
 #ifdef ANNOTATE_CONTIGUOUS_CONTAINER
diff --git a/third_party/WebKit/Source/platform/heap/HeapPage.h b/third_party/WebKit/Source/platform/heap/HeapPage.h
index 3a43031..69d369d 100644
--- a/third_party/WebKit/Source/platform/heap/HeapPage.h
+++ b/third_party/WebKit/Source/platform/heap/HeapPage.h
@@ -42,7 +42,7 @@
 #include "wtf/Assertions.h"
 #include "wtf/ContainerAnnotations.h"
 #include "wtf/Forward.h"
-#include "wtf/allocator/PageAllocator.h"
+#include "wtf/allocator/Partitions.h"
 #include <stdint.h>
 
 namespace blink {
@@ -65,7 +65,7 @@
 // (whose size is 128 KB). So we don't use guard pages in NaCl.
 const size_t blinkGuardPageSize = 0;
 #else
-const size_t blinkGuardPageSize = WTF::kSystemPageSize;
+const size_t blinkGuardPageSize = base::kSystemPageSize;
 #endif
 
 // Double precision floats are more efficient when 8 byte aligned, so we 8 byte
diff --git a/third_party/WebKit/Source/platform/heap/PageMemory.cpp b/third_party/WebKit/Source/platform/heap/PageMemory.cpp
index 6e4f5df..d99f9bb 100644
--- a/third_party/WebKit/Source/platform/heap/PageMemory.cpp
+++ b/third_party/WebKit/Source/platform/heap/PageMemory.cpp
@@ -8,7 +8,6 @@
 #include "wtf/AddressSanitizer.h"
 #include "wtf/Assertions.h"
 #include "wtf/Atomics.h"
-#include "wtf/allocator/PageAllocator.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/heap/PageMemory.h b/third_party/WebKit/Source/platform/heap/PageMemory.h
index 457ba45..6e1e87a 100644
--- a/third_party/WebKit/Source/platform/heap/PageMemory.h
+++ b/third_party/WebKit/Source/platform/heap/PageMemory.h
@@ -9,7 +9,7 @@
 #include "wtf/Allocator.h"
 #include "wtf/Assertions.h"
 #include "wtf/Compiler.h"
-#include "wtf/allocator/PageAllocator.h"
+#include "wtf/allocator/Partitions.h"
 
 #if OS(POSIX)
 #include <sys/mman.h>
diff --git a/third_party/WebKit/Source/platform/heap/Persistent.h b/third_party/WebKit/Source/platform/heap/Persistent.h
index 08a293e3..794753c9 100644
--- a/third_party/WebKit/Source/platform/heap/Persistent.h
+++ b/third_party/WebKit/Source/platform/heap/Persistent.h
@@ -560,7 +560,7 @@
   // PartitionAllocator to ensure persistent heap collections are always
   // allocated off-heap. This allows persistent collections to be used in
   // DEFINE_STATIC_LOCAL et. al.
-  WTF_USE_ALLOCATOR(PersistentHeapCollectionBase, WTF::PartitionAllocator);
+  USE_ALLOCATOR(PersistentHeapCollectionBase, WTF::PartitionAllocator);
   IS_PERSISTENT_REFERENCE_TYPE();
 
  public:
diff --git a/third_party/WebKit/Source/wtf/Allocator.h b/third_party/WebKit/Source/wtf/Allocator.h
index c87ccaa..5aacf77 100644
--- a/third_party/WebKit/Source/wtf/Allocator.h
+++ b/third_party/WebKit/Source/wtf/Allocator.h
@@ -118,13 +118,21 @@
                                                                       \
   void operator delete[](void* p) { ::WTF::Partitions::fastFree(p); } \
   void* operator new(size_t, NotNullTag, void* location) {            \
-    ASSERT(location);                                                 \
+    DCHECK(location);                                                 \
     return location;                                                  \
   }                                                                   \
                                                                       \
  private:                                                             \
   typedef int __thisIsHereToForceASemicolonAfterThisMacro
 
+// In official builds, do not include type info string literals to avoid
+// bloating the binary.
+#if defined(OFFICIAL_BUILD)
+#define WTF_HEAP_PROFILER_TYPE_NAME(T) nullptr
+#else
+#define WTF_HEAP_PROFILER_TYPE_NAME(T) ::WTF::getStringWithTypeName<T>()
+#endif
+
 // Both of these macros enable fast malloc and provide type info to the heap
 // profiler. The regular macro does not provide type info in official builds,
 // to avoid bloating the binary with type name strings. The |WITH_TYPE_NAME|
diff --git a/third_party/WebKit/Source/wtf/Assertions.h b/third_party/WebKit/Source/wtf/Assertions.h
index 637d095..db71532 100644
--- a/third_party/WebKit/Source/wtf/Assertions.h
+++ b/third_party/WebKit/Source/wtf/Assertions.h
@@ -33,6 +33,7 @@
 // For non-debug builds, everything is disabled by default, except for the
 // RELEASE_ASSERT family of macros.
 
+#include "base/allocator/oom.h"
 #include "base/gtest_prod_util.h"
 #include "base/logging.h"
 #include "wtf/Compiler.h"
diff --git a/third_party/WebKit/Source/wtf/BUILD.gn b/third_party/WebKit/Source/wtf/BUILD.gn
index 11fccb12..15ca2408 100644
--- a/third_party/WebKit/Source/wtf/BUILD.gn
+++ b/third_party/WebKit/Source/wtf/BUILD.gn
@@ -134,12 +134,6 @@
     "WTFThreadData.cpp",
     "WTFThreadData.h",
     "WeakPtr.h",
-    "allocator/AddressSpaceRandomization.cpp",
-    "allocator/AddressSpaceRandomization.h",
-    "allocator/PageAllocator.cpp",
-    "allocator/PageAllocator.h",
-    "allocator/PartitionAlloc.cpp",
-    "allocator/PartitionAlloc.h",
     "allocator/PartitionAllocator.cpp",
     "allocator/PartitionAllocator.h",
     "allocator/Partitions.cpp",
@@ -324,7 +318,6 @@
     "TreeNodeTest.cpp",
     "TypeTraitsTest.cpp",
     "VectorTest.cpp",
-    "allocator/PartitionAllocTest.cpp",
     "dtoa_test.cpp",
     "testing/RunAllTests.cpp",
     "text/AtomicStringTest.cpp",
diff --git a/third_party/WebKit/Source/wtf/BitVector.cpp b/third_party/WebKit/Source/wtf/BitVector.cpp
index f8bff347..e850966 100644
--- a/third_party/WebKit/Source/wtf/BitVector.cpp
+++ b/third_party/WebKit/Source/wtf/BitVector.cpp
@@ -27,7 +27,6 @@
 
 #include "wtf/LeakAnnotations.h"
 #include "wtf/PrintStream.h"
-#include "wtf/allocator/PartitionAlloc.h"
 #include "wtf/allocator/Partitions.h"
 #include <algorithm>
 #include <string.h>
diff --git a/third_party/WebKit/Source/wtf/Compiler.h b/third_party/WebKit/Source/wtf/Compiler.h
index 5d227171..1b81bb9 100644
--- a/third_party/WebKit/Source/wtf/Compiler.h
+++ b/third_party/WebKit/Source/wtf/Compiler.h
@@ -65,8 +65,6 @@
 
 // TODO(palmer): Remove this and update callers to use NOINLINE from Chromium
 // base. https://bugs.chromium.org/p/chromium/issues/detail?id=632441
-//
-// For compatibility with callers in Blink:
 #define NEVER_INLINE NOINLINE
 
 /* OBJC_CLASS */
diff --git a/third_party/WebKit/Source/wtf/DEPS b/third_party/WebKit/Source/wtf/DEPS
index 8691db4..8f13a90 100644
--- a/third_party/WebKit/Source/wtf/DEPS
+++ b/third_party/WebKit/Source/wtf/DEPS
@@ -1,6 +1,8 @@
 include_rules = [
     # To whitelist base/ stuff Blink is allowed to include, we list up all
     # directories and files instead of writing 'base/'.
+    "+base/allocator/oom.h",
+    "+base/allocator/partition_allocator",
     "+base/auto_reset.h",
     "+base/bind.h",
     "+base/bits.h",
diff --git a/third_party/WebKit/Source/wtf/Deque.h b/third_party/WebKit/Source/wtf/Deque.h
index 45b475a..e52520c 100644
--- a/third_party/WebKit/Source/wtf/Deque.h
+++ b/third_party/WebKit/Source/wtf/Deque.h
@@ -51,7 +51,7 @@
 class Deque : public ConditionalDestructor<Deque<T, INLINE_CAPACITY, Allocator>,
                                            (INLINE_CAPACITY == 0) &&
                                                Allocator::isGarbageCollected> {
-  WTF_USE_ALLOCATOR(Deque, Allocator);
+  USE_ALLOCATOR(Deque, Allocator);
 
  public:
   typedef DequeIterator<T, inlineCapacity, Allocator> iterator;
diff --git a/third_party/WebKit/Source/wtf/HashCountedSet.h b/third_party/WebKit/Source/wtf/HashCountedSet.h
index 6e0db4e..272fb9bc0 100644
--- a/third_party/WebKit/Source/wtf/HashCountedSet.h
+++ b/third_party/WebKit/Source/wtf/HashCountedSet.h
@@ -24,6 +24,7 @@
 #include "wtf/Assertions.h"
 #include "wtf/HashMap.h"
 #include "wtf/Vector.h"
+#include "wtf/allocator/PartitionAllocator.h"
 
 namespace WTF {
 
@@ -35,7 +36,7 @@
           typename Traits = HashTraits<Value>,
           typename Allocator = PartitionAllocator>
 class HashCountedSet {
-  WTF_USE_ALLOCATOR(HashCountedSet, Allocator);
+  USE_ALLOCATOR(HashCountedSet, Allocator);
   WTF_MAKE_NONCOPYABLE(HashCountedSet);
 
  private:
diff --git a/third_party/WebKit/Source/wtf/HashMap.h b/third_party/WebKit/Source/wtf/HashMap.h
index b503ec6..3ac16620a 100644
--- a/third_party/WebKit/Source/wtf/HashMap.h
+++ b/third_party/WebKit/Source/wtf/HashMap.h
@@ -47,7 +47,7 @@
           typename MappedTraitsArg = HashTraits<MappedArg>,
           typename Allocator = PartitionAllocator>
 class HashMap {
-  WTF_USE_ALLOCATOR(HashMap, Allocator);
+  USE_ALLOCATOR(HashMap, Allocator);
 
  private:
   typedef KeyTraitsArg KeyTraits;
diff --git a/third_party/WebKit/Source/wtf/HashSet.h b/third_party/WebKit/Source/wtf/HashSet.h
index 268ec6a3..310116a 100644
--- a/third_party/WebKit/Source/wtf/HashSet.h
+++ b/third_party/WebKit/Source/wtf/HashSet.h
@@ -37,7 +37,7 @@
           typename TraitsArg = HashTraits<ValueArg>,
           typename Allocator = PartitionAllocator>
 class HashSet {
-  WTF_USE_ALLOCATOR(HashSet, Allocator);
+  USE_ALLOCATOR(HashSet, Allocator);
 
  private:
   typedef HashArg HashFunctions;
diff --git a/third_party/WebKit/Source/wtf/LinkedHashSet.h b/third_party/WebKit/Source/wtf/LinkedHashSet.h
index 019ef73..1fadd930 100644
--- a/third_party/WebKit/Source/wtf/LinkedHashSet.h
+++ b/third_party/WebKit/Source/wtf/LinkedHashSet.h
@@ -157,7 +157,7 @@
           typename TraitsArg = HashTraits<ValueArg>,
           typename Allocator = PartitionAllocator>
 class LinkedHashSet {
-  WTF_USE_ALLOCATOR(LinkedHashSet, Allocator);
+  USE_ALLOCATOR(LinkedHashSet, Allocator);
 
  private:
   typedef ValueArg Value;
diff --git a/third_party/WebKit/Source/wtf/ListHashSet.h b/third_party/WebKit/Source/wtf/ListHashSet.h
index 8522861..1c98df1 100644
--- a/third_party/WebKit/Source/wtf/ListHashSet.h
+++ b/third_party/WebKit/Source/wtf/ListHashSet.h
@@ -77,7 +77,7 @@
           ListHashSet<ValueArg, inlineCapacity, HashArg, AllocatorArg>,
           AllocatorArg::isGarbageCollected> {
   typedef AllocatorArg Allocator;
-  WTF_USE_ALLOCATOR(ListHashSet, Allocator);
+  USE_ALLOCATOR(ListHashSet, Allocator);
 
   typedef ListHashSetNode<ValueArg, Allocator> Node;
   typedef HashTraits<Node*> NodeTraits;
diff --git a/third_party/WebKit/Source/wtf/RefPtr.h b/third_party/WebKit/Source/wtf/RefPtr.h
index b5d2ce3b..c6b28fa7 100644
--- a/third_party/WebKit/Source/wtf/RefPtr.h
+++ b/third_party/WebKit/Source/wtf/RefPtr.h
@@ -25,6 +25,7 @@
 #include "wtf/Allocator.h"
 #include "wtf/HashTableDeletedValueType.h"
 #include "wtf/PassRefPtr.h"
+#include "wtf/allocator/PartitionAllocator.h"
 #include <algorithm>
 #include <utility>
 
diff --git a/third_party/WebKit/Source/wtf/ThreadSpecific.h b/third_party/WebKit/Source/wtf/ThreadSpecific.h
index 386e6cb..e6218ac 100644
--- a/third_party/WebKit/Source/wtf/ThreadSpecific.h
+++ b/third_party/WebKit/Source/wtf/ThreadSpecific.h
@@ -47,6 +47,7 @@
 #include "wtf/StdLibExtras.h"
 #include "wtf/WTF.h"
 #include "wtf/WTFExport.h"
+#include "wtf/allocator/PartitionAllocator.h"
 #include "wtf/allocator/Partitions.h"
 
 #if OS(POSIX)
diff --git a/third_party/WebKit/Source/wtf/Vector.h b/third_party/WebKit/Source/wtf/Vector.h
index 6410cd2..61e67fee 100644
--- a/third_party/WebKit/Source/wtf/Vector.h
+++ b/third_party/WebKit/Source/wtf/Vector.h
@@ -801,7 +801,7 @@
       public ConditionalDestructor<Vector<T, INLINE_CAPACITY, Allocator>,
                                    (INLINE_CAPACITY == 0) &&
                                        Allocator::isGarbageCollected> {
-  WTF_USE_ALLOCATOR(Vector, Allocator);
+  USE_ALLOCATOR(Vector, Allocator);
   using Base = VectorBuffer<T, INLINE_CAPACITY, Allocator>;
   using TypeOperations = VectorTypeOperations<T>;
   using OffsetRange = typename Base::OffsetRange;
diff --git a/third_party/WebKit/Source/wtf/allocator/AddressSpaceRandomization.h b/third_party/WebKit/Source/wtf/allocator/AddressSpaceRandomization.h
deleted file mode 100644
index 9d3ddd1..0000000
--- a/third_party/WebKit/Source/wtf/allocator/AddressSpaceRandomization.h
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef WTF_AddressSpaceRandomization_h
-#define WTF_AddressSpaceRandomization_h
-
-#include "wtf/WTFExport.h"
-
-namespace WTF {
-
-// Calculates a random preferred mapping address. In calculating an
-// address, we balance good ASLR against not fragmenting the address
-// space too badly.
-WTF_EXPORT void* getRandomPageBase();
-}
-
-#endif
diff --git a/third_party/WebKit/Source/wtf/allocator/PageAllocator.h b/third_party/WebKit/Source/wtf/allocator/PageAllocator.h
deleted file mode 100644
index 0942db55..0000000
--- a/third_party/WebKit/Source/wtf/allocator/PageAllocator.h
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * 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.
- *     * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
- * OWNER OR 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 WTF_PageAllocator_h
-#define WTF_PageAllocator_h
-
-#include "wtf/Assertions.h"
-#include "wtf/CPU.h"
-#include "wtf/Compiler.h"
-#include "wtf/WTFExport.h"
-#include <cstddef>
-#include <stdint.h>
-
-namespace WTF {
-
-#if OS(WIN)
-static const size_t kPageAllocationGranularityShift = 16;  // 64KB
-#else
-static const size_t kPageAllocationGranularityShift = 12;  // 4KB
-#endif
-static const size_t kPageAllocationGranularity =
-    1 << kPageAllocationGranularityShift;
-static const size_t kPageAllocationGranularityOffsetMask =
-    kPageAllocationGranularity - 1;
-static const size_t kPageAllocationGranularityBaseMask =
-    ~kPageAllocationGranularityOffsetMask;
-
-// All Blink-supported systems have 4096 sized system pages and can handle
-// permissions and commit / decommit at this granularity.
-static const size_t kSystemPageSize = 4096;
-static const size_t kSystemPageOffsetMask = kSystemPageSize - 1;
-static const size_t kSystemPageBaseMask = ~kSystemPageOffsetMask;
-
-enum PageAccessibilityConfiguration {
-  PageAccessible,
-  PageInaccessible,
-};
-
-// Allocate one or more pages.
-// The requested address is just a hint; the actual address returned may
-// differ. The returned address will be aligned at least to align bytes.
-// len is in bytes, and must be a multiple of kPageAllocationGranularity.
-// align is in bytes, and must be a power-of-two multiple of
-// kPageAllocationGranularity.
-// If addr is null, then a suitable and randomized address will be chosen
-// automatically.
-// PageAccessibilityConfiguration controls the permission of the
-// allocated pages.
-// This call will return null if the allocation cannot be satisfied.
-WTF_EXPORT void* allocPages(void* addr,
-                            size_t len,
-                            size_t align,
-                            PageAccessibilityConfiguration);
-
-// Free one or more pages.
-// addr and len must match a previous call to allocPages().
-WTF_EXPORT void freePages(void* addr, size_t len);
-
-// Mark one or more system pages as being inaccessible.
-// Subsequently accessing any address in the range will fault, and the
-// addresses will not be re-used by future allocations.
-// len must be a multiple of kSystemPageSize bytes.
-WTF_EXPORT void setSystemPagesInaccessible(void* addr, size_t len);
-
-// Mark one or more system pages as being accessible.
-// The pages will be readable and writeable.
-// len must be a multiple of kSystemPageSize bytes.
-// The result bool value indicates whether the permission
-// change succeeded or not. You must check the result
-// (in most cases you need to RELEASE_ASSERT that it is
-// true).
-WTF_EXPORT WARN_UNUSED_RESULT bool setSystemPagesAccessible(void* addr,
-                                                            size_t len);
-
-// Decommit one or more system pages. Decommitted means that the physical memory
-// is released to the system, but the virtual address space remains reserved.
-// System pages are re-committed by calling recommitSystemPages(). Touching
-// a decommitted page _may_ fault.
-// Clients should not make any assumptions about the contents of decommitted
-// system pages, before or after they write to the page. The only guarantee
-// provided is that the contents of the system page will be deterministic again
-// after recommitting and writing to it. In particlar note that system pages are
-// not guaranteed to be zero-filled upon re-commit. len must be a multiple of
-// kSystemPageSize bytes.
-WTF_EXPORT void decommitSystemPages(void* addr, size_t len);
-
-// Recommit one or more system pages. Decommitted system pages must be
-// recommitted before they are read are written again.
-// Note that this operation may be a no-op on some platforms.
-// len must be a multiple of kSystemPageSize bytes.
-WTF_EXPORT void recommitSystemPages(void* addr, size_t len);
-
-// Discard one or more system pages. Discarding is a hint to the system that
-// the page is no longer required. The hint may:
-// - Do nothing.
-// - Discard the page immediately, freeing up physical pages.
-// - Discard the page at some time in the future in response to memory pressure.
-// Only committed pages should be discarded. Discarding a page does not
-// decommit it, and it is valid to discard an already-discarded page.
-// A read or write to a discarded page will not fault.
-// Reading from a discarded page may return the original page content, or a
-// page full of zeroes.
-// Writing to a discarded page is the only guaranteed way to tell the system
-// that the page is required again. Once written to, the content of the page is
-// guaranteed stable once more. After being written to, the page content may be
-// based on the original page content, or a page of zeroes.
-// len must be a multiple of kSystemPageSize bytes.
-WTF_EXPORT void discardSystemPages(void* addr, size_t len);
-
-WTF_EXPORT ALWAYS_INLINE uintptr_t roundUpToSystemPage(uintptr_t address) {
-  return (address + kSystemPageOffsetMask) & kSystemPageBaseMask;
-}
-
-WTF_EXPORT ALWAYS_INLINE uintptr_t roundDownToSystemPage(uintptr_t address) {
-  return address & kSystemPageBaseMask;
-}
-
-// Only allowed inside WTF for investigating WTF::initializeWithoutV8 crashes.
-// Guess, the function fails because of mmap (or VirtualAlloc) failure.
-// The following function returns errno (or GetLastError code) when mmap
-// (or VirtualAlloc) fails.
-uint32_t getAllocPageErrorCode();
-
-}  // namespace WTF
-
-#endif  // WTF_PageAllocator_h
diff --git a/third_party/WebKit/Source/wtf/allocator/PartitionAllocator.cpp b/third_party/WebKit/Source/wtf/allocator/PartitionAllocator.cpp
index 6b27848d..a845964 100644
--- a/third_party/WebKit/Source/wtf/allocator/PartitionAllocator.cpp
+++ b/third_party/WebKit/Source/wtf/allocator/PartitionAllocator.cpp
@@ -1,36 +1,10 @@
-/*
- * Copyright (C) 2014 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * 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.
- *     * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
- * OWNER OR 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.
- */
+// Copyright (c) 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
 
 #include "wtf/allocator/PartitionAllocator.h"
 
-#include "wtf/allocator/PartitionAlloc.h"
+#include "base/allocator/partition_allocator/partition_alloc.h"
 #include "wtf/allocator/Partitions.h"
 
 namespace WTF {
diff --git a/third_party/WebKit/Source/wtf/allocator/PartitionAllocator.h b/third_party/WebKit/Source/wtf/allocator/PartitionAllocator.h
index 8a66590..a897c6b8 100644
--- a/third_party/WebKit/Source/wtf/allocator/PartitionAllocator.h
+++ b/third_party/WebKit/Source/wtf/allocator/PartitionAllocator.h
@@ -1,32 +1,6 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * 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.
- *     * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
- * OWNER OR 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.
- */
+// Copyright (c) 2013 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 WTF_PartitionAllocator_h
 #define WTF_PartitionAllocator_h
@@ -35,11 +9,11 @@
 // traced, garbage collected heap. It uses FastMalloc for collections,
 // but uses the partition allocator for the backing store of the collections.
 
-#include "wtf/Allocator.h"
+#include "base/allocator/partition_allocator/partition_alloc.h"
+#include "third_party/WebKit/Source/wtf/Allocator.h"
 #include "wtf/Assertions.h"
-#include "wtf/allocator/PartitionAlloc.h"
-#include "wtf/allocator/Partitions.h"
-
+#include "wtf/TypeTraits.h"
+#include "wtf/WTFExport.h"
 #include <string.h>
 
 namespace WTF {
@@ -55,8 +29,8 @@
 
   template <typename T>
   static size_t quantizedSize(size_t count) {
-    RELEASE_ASSERT(count <= kGenericMaxDirectMapped / sizeof(T));
-    return partitionAllocActualSize(Partitions::bufferPartition(),
+    RELEASE_ASSERT(count <= base::kGenericMaxDirectMapped / sizeof(T));
+    return partitionAllocActualSize(WTF::Partitions::bufferPartition(),
                                     count * sizeof(T));
   }
   template <typename T>
@@ -108,11 +82,12 @@
 
   template <typename Return, typename Metadata>
   static Return malloc(size_t size, const char* typeName) {
-    return reinterpret_cast<Return>(Partitions::fastMalloc(size, typeName));
+    return reinterpret_cast<Return>(
+        WTF::Partitions::fastMalloc(size, typeName));
   }
 
   static inline bool expandHashTableBacking(void*, size_t) { return false; }
-  static void free(void* address) { Partitions::fastFree(address); }
+  static void free(void* address) { WTF::Partitions::fastFree(address); }
   template <typename T>
   static void* newArray(size_t bytes) {
     return malloc<void*, void>(bytes, WTF_HEAP_PROFILER_TYPE_NAME(T));
@@ -141,7 +116,7 @@
 
 }  // namespace WTF
 
-#define WTF_USE_ALLOCATOR(ClassName, Allocator)                   \
+#define USE_ALLOCATOR(ClassName, Allocator)                       \
  public:                                                          \
   void* operator new(size_t size) {                               \
     return Allocator::template malloc<void*, ClassName>(          \
@@ -161,6 +136,4 @@
  private:                                                         \
   typedef int __thisIsHereToForceASemicolonAfterThisMacro
 
-using WTF::PartitionAllocator;
-
 #endif  // WTF_PartitionAllocator_h
diff --git a/third_party/WebKit/Source/wtf/allocator/Partitions.cpp b/third_party/WebKit/Source/wtf/allocator/Partitions.cpp
index 5b31dcfb..56d0a8f4 100644
--- a/third_party/WebKit/Source/wtf/allocator/Partitions.cpp
+++ b/third_party/WebKit/Source/wtf/allocator/Partitions.cpp
@@ -30,6 +30,7 @@
 
 #include "wtf/allocator/Partitions.h"
 
+#include "base/allocator/partition_allocator/page_allocator.h"
 #include "base/debug/alias.h"
 #include "wtf/allocator/PartitionAllocator.h"
 
@@ -38,21 +39,21 @@
 const char* const Partitions::kAllocatedObjectPoolName =
     "partition_alloc/allocated_objects";
 
-SpinLock Partitions::s_initializationLock;
+base::subtle::SpinLock Partitions::s_initializationLock;
 bool Partitions::s_initialized = false;
 
-PartitionAllocatorGeneric Partitions::m_fastMallocAllocator;
-PartitionAllocatorGeneric Partitions::m_bufferAllocator;
-SizeSpecificPartitionAllocator<1024> Partitions::m_layoutAllocator;
+base::PartitionAllocatorGeneric Partitions::m_fastMallocAllocator;
+base::PartitionAllocatorGeneric Partitions::m_bufferAllocator;
+base::SizeSpecificPartitionAllocator<1024> Partitions::m_layoutAllocator;
 Partitions::ReportPartitionAllocSizeFunction Partitions::m_reportSizeFunction =
     nullptr;
 
 void Partitions::initialize(
     ReportPartitionAllocSizeFunction reportSizeFunction) {
-  SpinLock::Guard guard(s_initializationLock);
+  base::subtle::SpinLock::Guard guard(s_initializationLock);
 
   if (!s_initialized) {
-    partitionAllocGlobalInit(&Partitions::handleOutOfMemory);
+    base::partitionAllocGlobalInit(&Partitions::handleOutOfMemory);
     m_fastMallocAllocator.init();
     m_bufferAllocator.init();
     m_layoutAllocator.init();
@@ -62,7 +63,7 @@
 }
 
 void Partitions::shutdown() {
-  SpinLock::Guard guard(s_initializationLock);
+  base::subtle::SpinLock::Guard guard(s_initializationLock);
 
   // We could ASSERT here for a memory leak within the partition, but it leads
   // to very hard to diagnose ASSERTs, so it's best to leave leak checking for
@@ -80,10 +81,11 @@
     return;
 
   partitionPurgeMemoryGeneric(bufferPartition(),
-                              PartitionPurgeDecommitEmptyPages);
+                              base::PartitionPurgeDecommitEmptyPages);
   partitionPurgeMemoryGeneric(fastMallocPartition(),
-                              PartitionPurgeDecommitEmptyPages);
-  partitionPurgeMemory(layoutPartition(), PartitionPurgeDecommitEmptyPages);
+                              base::PartitionPurgeDecommitEmptyPages);
+  partitionPurgeMemory(layoutPartition(),
+                       base::PartitionPurgeDecommitEmptyPages);
 }
 
 void Partitions::reportMemoryUsageHistogram() {
@@ -102,8 +104,9 @@
   }
 }
 
-void Partitions::dumpMemoryStats(bool isLightDump,
-                                 PartitionStatsDumper* partitionStatsDumper) {
+void Partitions::dumpMemoryStats(
+    bool isLightDump,
+    base::PartitionStatsDumper* partitionStatsDumper) {
   // Object model and rendering partitions are not thread safe and can be
   // accessed only on the main thread.
   ASSERT(isMainThread());
diff --git a/third_party/WebKit/Source/wtf/allocator/Partitions.h b/third_party/WebKit/Source/wtf/allocator/Partitions.h
index 8fd74a3..3e4ea22 100644
--- a/third_party/WebKit/Source/wtf/allocator/Partitions.h
+++ b/third_party/WebKit/Source/wtf/allocator/Partitions.h
@@ -31,9 +31,11 @@
 #ifndef Partitions_h
 #define Partitions_h
 
+#include "base/allocator/partition_allocator/partition_alloc.h"
+#include "base/synchronization/spin_lock.h"
+#include "wtf/Assertions.h"
 #include "wtf/WTF.h"
 #include "wtf/WTFExport.h"
-#include "wtf/allocator/PartitionAlloc.h"
 #include <string.h>
 
 namespace WTF {
@@ -48,21 +50,21 @@
 
   static void initialize(ReportPartitionAllocSizeFunction);
   static void shutdown();
-  ALWAYS_INLINE static PartitionRootGeneric* bufferPartition() {
+  ALWAYS_INLINE static base::PartitionRootGeneric* bufferPartition() {
     ASSERT(s_initialized);
     return m_bufferAllocator.root();
   }
 
-  ALWAYS_INLINE static PartitionRootGeneric* fastMallocPartition() {
+  ALWAYS_INLINE static base::PartitionRootGeneric* fastMallocPartition() {
     ASSERT(s_initialized);
     return m_fastMallocAllocator.root();
   }
 
-  ALWAYS_INLINE static PartitionRoot* nodePartition() {
+  ALWAYS_INLINE static base::PartitionRoot* nodePartition() {
     ASSERT_NOT_REACHED();
     return nullptr;
   }
-  ALWAYS_INLINE static PartitionRoot* layoutPartition() {
+  ALWAYS_INLINE static base::PartitionRoot* layoutPartition() {
     ASSERT(s_initialized);
     return m_layoutAllocator.root();
   }
@@ -85,7 +87,7 @@
 
   static void reportMemoryUsageHistogram();
 
-  static void dumpMemoryStats(bool isLightDump, PartitionStatsDumper*);
+  static void dumpMemoryStats(bool isLightDump, base::PartitionStatsDumper*);
 
   ALWAYS_INLINE static void* bufferMalloc(size_t n, const char* typeName) {
     return partitionAllocGeneric(bufferPartition(), n, typeName);
@@ -121,7 +123,7 @@
   static void handleOutOfMemory();
 
  private:
-  static SpinLock s_initializationLock;
+  static base::subtle::SpinLock s_initializationLock;
   static bool s_initialized;
 
   // We have the following four partitions.
@@ -136,12 +138,37 @@
   //     scripts. Vectors, HashTables, ArrayBufferContents and Strings are
   //     allocated in the buffer partition.
   //   - Fast malloc partition: A partition to allocate all other objects.
-  static PartitionAllocatorGeneric m_fastMallocAllocator;
-  static PartitionAllocatorGeneric m_bufferAllocator;
-  static SizeSpecificPartitionAllocator<1024> m_layoutAllocator;
+  static base::PartitionAllocatorGeneric m_fastMallocAllocator;
+  static base::PartitionAllocatorGeneric m_bufferAllocator;
+  static base::SizeSpecificPartitionAllocator<1024> m_layoutAllocator;
   static ReportPartitionAllocSizeFunction m_reportSizeFunction;
 };
 
+using base::kGenericMaxDirectMapped;
+using base::kPageAllocationGranularity;
+using base::kPageAllocationGranularityBaseMask;
+using base::kPageAllocationGranularityOffsetMask;
+using base::kSystemPageSize;
+
+using base::allocPages;
+using base::decommitSystemPages;
+using base::discardSystemPages;
+using base::partitionFree;
+using base::freePages;
+using base::getAllocPageErrorCode;
+using base::recommitSystemPages;
+using base::roundDownToSystemPage;
+using base::roundUpToSystemPage;
+using base::setSystemPagesAccessible;
+using base::setSystemPagesInaccessible;
+
+using base::PageAccessible;
+using base::PageInaccessible;
+using base::PartitionStatsDumper;
+using base::PartitionMemoryStats;
+using base::PartitionBucketMemoryStats;
+using base::PartitionAllocHooks;
+
 }  // namespace WTF
 
 #endif  // Partitions_h
diff --git a/third_party/WebKit/Source/wtf/text/CString.cpp b/third_party/WebKit/Source/wtf/text/CString.cpp
index 4bab024..7a703c1 100644
--- a/third_party/WebKit/Source/wtf/text/CString.cpp
+++ b/third_party/WebKit/Source/wtf/text/CString.cpp
@@ -27,7 +27,6 @@
 #include "wtf/text/CString.h"
 
 #include "wtf/ASCIICType.h"
-#include "wtf/allocator/PartitionAlloc.h"
 #include "wtf/allocator/Partitions.h"
 #include <string.h>
 
diff --git a/third_party/WebKit/Source/wtf/text/CString.h b/third_party/WebKit/Source/wtf/text/CString.h
index dc75400..c8db1ad7 100644
--- a/third_party/WebKit/Source/wtf/text/CString.h
+++ b/third_party/WebKit/Source/wtf/text/CString.h
@@ -31,6 +31,7 @@
 #include "wtf/RefCounted.h"
 #include "wtf/RefPtr.h"
 #include "wtf/WTFExport.h"
+#include "wtf/allocator/PartitionAllocator.h"
 #include <string.h>
 
 namespace WTF {
diff --git a/third_party/WebKit/Source/wtf/text/StringImpl.cpp b/third_party/WebKit/Source/wtf/text/StringImpl.cpp
index c861abfd..5a5f533c 100644
--- a/third_party/WebKit/Source/wtf/text/StringImpl.cpp
+++ b/third_party/WebKit/Source/wtf/text/StringImpl.cpp
@@ -29,7 +29,6 @@
 #include "wtf/LeakAnnotations.h"
 #include "wtf/PtrUtil.h"
 #include "wtf/StdLibExtras.h"
-#include "wtf/allocator/PartitionAlloc.h"
 #include "wtf/allocator/Partitions.h"
 #include "wtf/text/AtomicString.h"
 #include "wtf/text/AtomicStringTable.h"
diff --git a/third_party/WebKit/Source/wtf/typed_arrays/ArrayBufferContents.cpp b/third_party/WebKit/Source/wtf/typed_arrays/ArrayBufferContents.cpp
index bf5b0b4..b78078e80 100644
--- a/third_party/WebKit/Source/wtf/typed_arrays/ArrayBufferContents.cpp
+++ b/third_party/WebKit/Source/wtf/typed_arrays/ArrayBufferContents.cpp
@@ -26,8 +26,8 @@
 
 #include "wtf/typed_arrays/ArrayBufferContents.h"
 
+#include "base/allocator/partition_allocator/partition_alloc.h"
 #include "wtf/Assertions.h"
-#include "wtf/allocator/PartitionAlloc.h"
 #include "wtf/allocator/Partitions.h"
 #include <string.h>
 
@@ -127,7 +127,7 @@
 void ArrayBufferContents::allocateMemoryOrNull(size_t size,
                                                InitializationPolicy policy,
                                                void*& data) {
-  allocateMemoryWithFlags(size, policy, PartitionAllocReturnNull, data);
+  allocateMemoryWithFlags(size, policy, base::PartitionAllocReturnNull, data);
 }
 
 void ArrayBufferContents::freeMemory(void* data, size_t size) {
diff --git a/third_party/WebKit/public/platform/WebDragData.h b/third_party/WebKit/public/platform/WebDragData.h
index 623918f8..4eb774e0 100644
--- a/third_party/WebKit/public/platform/WebDragData.h
+++ b/third_party/WebKit/public/platform/WebDragData.h
@@ -80,6 +80,7 @@
     // Only valid when storageType == StorageTypeFileSystemFile.
     WebURL fileSystemURL;
     long long fileSystemFileSize;
+    WebString fileSystemId;
 
     // Only valid when stringType == "text/html".
     WebURL baseURL;
diff --git a/tools/chrome_proxy/OWNERS b/tools/chrome_proxy/OWNERS
index 2476bfb..217a164 100644
--- a/tools/chrome_proxy/OWNERS
+++ b/tools/chrome_proxy/OWNERS
@@ -1,9 +1,3 @@
-bengr@chromium.org
-bolian@chromium.org
+file://components/data_reduction_proxy/OWNERS
+
 bustamante@chromium.org
-kundaji@chromium.org
-marq@chromium.org
-megjablon@chromium.org
-ryansturm@chromium.org
-sclittle@chromium.org
-tbansal@chromium.org
diff --git a/ui/file_manager/file_manager/foreground/elements/files_metadata_box.html b/ui/file_manager/file_manager/foreground/elements/files_metadata_box.html
index b4080e9..a76fe82 100644
--- a/ui/file_manager/file_manager/foreground/elements/files_metadata_box.html
+++ b/ui/file_manager/file_manager/foreground/elements/files_metadata_box.html
@@ -59,6 +59,7 @@
         <files-metadata-entry i18n-values="key:METADATA_BOX_GENRE" value="[[mediaGenre]]"></files-metadata-entry>
         <files-metadata-entry i18n-values="key:METADATA_BOX_TRACK" value="[[mediaTrack]]"></files-metadata-entry>
         <files-metadata-entry i18n-values="key:METADATA_BOX_EXIF_DEVICE_MODEL" value="[[deviceModel_(ifd)]]"></files-metadata-entry>
+        <files-metadata-entry i18n-values="key:METADATA_BOX_EXIF_DEVICE_SETTINGS" value="[[deviceSettings_(ifd)]]"></files-metadata-entry>
         <files-metadata-entry i18n-values="key:METADATA_BOX_EXIF_GEOGRAPHY" value="[[geography_(ifd)]]"></files-metadata-entry>
       </div>
     </div>
diff --git a/ui/file_manager/file_manager/foreground/elements/files_metadata_box.js b/ui/file_manager/file_manager/foreground/elements/files_metadata_box.js
index 834def1..e045432 100644
--- a/ui/file_manager/file_manager/foreground/elements/files_metadata_box.js
+++ b/ui/file_manager/file_manager/foreground/elements/files_metadata_box.js
@@ -166,6 +166,18 @@
   },
 
   /**
+   * @param {Array<String>} r array of two strings representing the numerator
+   *     and the denominator.
+   * @return {number}
+   * @private
+   */
+  parseRational_: function(r) {
+    var num = parseInt(r[0], 10);
+    var den = parseInt(r[1], 10);
+    return num / den;
+  },
+
+  /**
    * Returns geolocation as a string in the form of 'latitude, longitude',
    * where the values have 3 decimal precision. Negative latitude indicates
    * south latitude and negative longitude indicates west longitude.
@@ -179,22 +191,54 @@
     if (!gps || !gps[1] || !gps[2] || !gps[3] || !gps[4])
       return '';
 
-    var parseRationale = function(r) {
-      var num = parseInt(r[0], 10);
-      var den = parseInt(r[1], 10);
-      return num / den;
-    };
-
-    var computeCorrdinate = function(value) {
-      return parseRationale(value[0]) + parseRationale(value[1]) / 60 +
-          parseRationale(value[2]) / 3600;
-    };
+    var computeCoordinate = function(value) {
+      return this.parseRational_(value[0]) +
+          this.parseRational_(value[1]) / 60 +
+          this.parseRational_(value[2]) / 3600;
+    }.bind(this);
 
     var latitude =
-        computeCorrdinate(gps[2].value) * (gps[1].value === 'N\0' ? 1 : -1);
+        computeCoordinate(gps[2].value) * (gps[1].value === 'N\0' ? 1 : -1);
     var longitude =
-        computeCorrdinate(gps[4].value) * (gps[3].value === 'E\0' ? 1 : -1);
+        computeCoordinate(gps[4].value) * (gps[3].value === 'E\0' ? 1 : -1);
 
     return Number(latitude).toFixed(3) + ', ' + Number(longitude).toFixed(3);
   },
+
+  /**
+   * Returns device settings as a string in the form of
+   * 'FNumber exposureTime focalLength isoSpeedRating'.
+   * Example: 'f/2 1/120 4.67mm ISO108'.
+   * @param {?Object} ifd
+   * @return {string}
+   *
+   * @private
+   */
+  deviceSettings_: function(ifd) {
+    var exif = ifd && ifd.exif;
+    if (!exif)
+      return '';
+
+    var f = exif[33437] ? this.parseRational_(exif[33437].value) : 0;
+    var fNumber = '';
+    if (f) {
+      fNumber = 'f/' + (Number.isInteger(f) ? f : Number(f).toFixed(1));
+    }
+    var exposureTime =
+        exif[33434] ? exif[33434].value[0] + '/' + exif[33434].value[1] : '';
+    var focalLength = exif[37386] ?
+        Number(this.parseRational_(exif[37386].value)).toFixed(2) + 'mm' :
+        '';
+    var iso = exif[34855] ? 'ISO' + exif[34855].value : '';
+
+    var values = [fNumber, exposureTime, focalLength, iso];
+
+    var result = '';
+    for (var i = 0; i < values.length; i++) {
+      if (values[i]) {
+        result += (result ? ' ' : '') + values[i];
+      }
+    }
+    return result;
+  },
 });