diff --git a/BUILD.gn b/BUILD.gn
index ffb9200e..0208c10 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -111,6 +111,7 @@
 if (is_win) {
   group("chrome_official_builder_no_unittests") {
     deps = [
+      "//base/win:eventlog_provider",
       "//chrome/installer/gcapi",
       "//chrome/installer/mini_installer",
       "//cloud_print",
diff --git a/DEPS b/DEPS
index 75cfadb..fed9fc00 100644
--- a/DEPS
+++ b/DEPS
@@ -40,11 +40,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': '40a82bd0f48d04680fbe7af063a4f2e3eae122e6',
+  'skia_revision': 'fa9193dcbe813e32376acb2411bfbb2420d03c28',
   # 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': '4bfecb6a9f37d83262c493545f43112266698e9a',
+  'v8_revision': '6908bae2d0b3fbb8216a6ac30aa2252b1854f6dc',
   # 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/android_webview/browser/DEPS b/android_webview/browser/DEPS
index 7ab5e1d..d601fd2a 100644
--- a/android_webview/browser/DEPS
+++ b/android_webview/browser/DEPS
@@ -44,8 +44,6 @@
 
   "+services/service_manager/public/cpp",
 
-  "+storage/browser/quota",
-
   "+ui/gfx",
   "+ui/gl",
 
diff --git a/android_webview/browser/aw_content_browser_client.cc b/android_webview/browser/aw_content_browser_client.cc
index f9a53509..b87bb97 100644
--- a/android_webview/browser/aw_content_browser_client.cc
+++ b/android_webview/browser/aw_content_browser_client.cc
@@ -47,7 +47,6 @@
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/render_view_host.h"
-#include "content/public/browser/storage_partition.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/common/service_names.mojom.h"
@@ -59,7 +58,6 @@
 #include "net/ssl/ssl_cert_request_info.h"
 #include "net/ssl/ssl_info.h"
 #include "services/service_manager/public/cpp/interface_registry.h"
-#include "storage/browser/quota/quota_settings.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/base/resource/resource_bundle_android.h"
 #include "ui/resources/grit/ui_resources.h"
@@ -359,17 +357,6 @@
   return new AwQuotaPermissionContext;
 }
 
-void AwContentBrowserClient::GetQuotaSettings(
-    content::BrowserContext* context,
-    content::StoragePartition* partition,
-    const storage::OptionalQuotaSettingsCallback& callback) {
-  content::BrowserThread::PostTaskAndReplyWithResult(
-      content::BrowserThread::FILE, FROM_HERE,
-      base::Bind(&storage::CalculateNominalDynamicSettings,
-                 partition->GetPath(), context->IsOffTheRecord()),
-      callback);
-}
-
 void AwContentBrowserClient::AllowCertificateError(
     content::WebContents* web_contents,
     int cert_error,
diff --git a/android_webview/browser/aw_content_browser_client.h b/android_webview/browser/aw_content_browser_client.h
index 6b8c6638..a3472c5 100644
--- a/android_webview/browser/aw_content_browser_client.h
+++ b/android_webview/browser/aw_content_browser_client.h
@@ -74,10 +74,6 @@
       content::ResourceContext* context,
       const std::vector<std::pair<int, int>>& render_frames) override;
   content::QuotaPermissionContext* CreateQuotaPermissionContext() override;
-  void GetQuotaSettings(
-      content::BrowserContext* context,
-      content::StoragePartition* partition,
-      const storage::OptionalQuotaSettingsCallback& callback) override;
   void AllowCertificateError(
       content::WebContents* web_contents,
       int cert_error,
diff --git a/ash/shell/content/client/DEPS b/ash/shell/content/client/DEPS
index 08c4461..f71262e8 100644
--- a/ash/shell/content/client/DEPS
+++ b/ash/shell/content/client/DEPS
@@ -1,5 +1,4 @@
 include_rules = [
   "+content/public",
   "+content/shell",
-  "+storage/browser/quota",
 ]
diff --git a/ash/shell/content/client/shell_content_browser_client.cc b/ash/shell/content/client/shell_content_browser_client.cc
index 7cb284d..60da706 100644
--- a/ash/shell/content/client/shell_content_browser_client.cc
+++ b/ash/shell/content/client/shell_content_browser_client.cc
@@ -8,10 +8,6 @@
 
 #include "ash/shell/content/client/shell_browser_main_parts.h"
 #include "base/command_line.h"
-#include "content/public/browser/browser_context.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/storage_partition.h"
-#include "storage/browser/quota/quota_settings.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 
 namespace ash {
@@ -28,16 +24,5 @@
   return shell_browser_main_parts_;
 }
 
-void ShellContentBrowserClient::GetQuotaSettings(
-    content::BrowserContext* context,
-    content::StoragePartition* partition,
-    const storage::OptionalQuotaSettingsCallback& callback) {
-  content::BrowserThread::PostTaskAndReplyWithResult(
-      content::BrowserThread::FILE, FROM_HERE,
-      base::Bind(&storage::CalculateNominalDynamicSettings,
-                 partition->GetPath(), context->IsOffTheRecord()),
-      callback);
-}
-
 }  // namespace examples
 }  // namespace views
diff --git a/ash/shell/content/client/shell_content_browser_client.h b/ash/shell/content/client/shell_content_browser_client.h
index c91183e3..29752753 100644
--- a/ash/shell/content/client/shell_content_browser_client.h
+++ b/ash/shell/content/client/shell_content_browser_client.h
@@ -28,10 +28,6 @@
   // Overridden from content::ContentBrowserClient:
   content::BrowserMainParts* CreateBrowserMainParts(
       const content::MainFunctionParams& parameters) override;
-  void GetQuotaSettings(
-      content::BrowserContext* context,
-      content::StoragePartition* partition,
-      const storage::OptionalQuotaSettingsCallback& callback) override;
 
  private:
   ShellBrowserMainParts* shell_browser_main_parts_;
diff --git a/base/task/cancelable_task_tracker.cc b/base/task/cancelable_task_tracker.cc
index 6a6e124..92d82cc 100644
--- a/base/task/cancelable_task_tracker.cc
+++ b/base/task/cancelable_task_tracker.cc
@@ -8,21 +8,14 @@
 
 #include <utility>
 
-#include "base/bind.h"
 #include "base/callback_helpers.h"
-#include "base/compiler_specific.h"
 #include "base/location.h"
 #include "base/memory/ref_counted.h"
-#include "base/single_thread_task_runner.h"
 #include "base/synchronization/cancellation_flag.h"
 #include "base/task_runner.h"
-#include "base/threading/thread_task_runner_handle.h"
+#include "base/threading/sequenced_task_runner_handle.h"
 
-using base::Bind;
-using base::CancellationFlag;
-using base::Closure;
-using base::hash_map;
-using base::TaskRunner;
+namespace base {
 
 namespace {
 
@@ -57,8 +50,6 @@
 
 }  // namespace
 
-namespace base {
-
 // static
 const CancelableTaskTracker::TaskId CancelableTaskTracker::kBadTaskId = 0;
 
@@ -66,7 +57,7 @@
     : next_id_(1),weak_factory_(this) {}
 
 CancelableTaskTracker::~CancelableTaskTracker() {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK(sequence_checker_.CalledOnValidSequence());
 
   TryCancelAll();
 }
@@ -75,7 +66,7 @@
     TaskRunner* task_runner,
     const tracked_objects::Location& from_here,
     const Closure& task) {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK(sequence_checker_.CalledOnValidSequence());
 
   return PostTaskAndReply(task_runner, from_here, task, Bind(&base::DoNothing));
 }
@@ -85,10 +76,10 @@
     const tracked_objects::Location& from_here,
     const Closure& task,
     const Closure& reply) {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK(sequence_checker_.CalledOnValidSequence());
 
-  // We need a MessageLoop to run reply.
-  DCHECK(base::ThreadTaskRunnerHandle::IsSet());
+  // We need a SequencedTaskRunnerHandle to run |reply|.
+  DCHECK(base::SequencedTaskRunnerHandle::IsSet());
 
   // Owned by reply callback below.
   CancellationFlag* flag = new CancellationFlag();
@@ -115,8 +106,8 @@
 
 CancelableTaskTracker::TaskId CancelableTaskTracker::NewTrackedTaskId(
     IsCanceledCallback* is_canceled_cb) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(base::ThreadTaskRunnerHandle::IsSet());
+  DCHECK(sequence_checker_.CalledOnValidSequence());
+  DCHECK(base::SequencedTaskRunnerHandle::IsSet());
 
   TaskId id = next_id_;
   next_id_++;  // int64_t is big enough that we ignore the potential overflow.
@@ -129,11 +120,11 @@
       Bind(&CancelableTaskTracker::Untrack, weak_factory_.GetWeakPtr(), id),
       flag);
 
-  // Will always run |untrack_and_delete_flag| on current MessageLoop.
+  // Will always run |untrack_and_delete_flag| on current sequence.
   base::ScopedClosureRunner* untrack_and_delete_flag_runner =
       new base::ScopedClosureRunner(
           Bind(&RunOrPostToTaskRunner,
-               RetainedRef(base::ThreadTaskRunnerHandle::Get()),
+               RetainedRef(base::SequencedTaskRunnerHandle::Get()),
                untrack_and_delete_flag));
 
   *is_canceled_cb =
@@ -144,7 +135,7 @@
 }
 
 void CancelableTaskTracker::TryCancel(TaskId id) {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK(sequence_checker_.CalledOnValidSequence());
 
   hash_map<TaskId, CancellationFlag*>::const_iterator it = task_flags_.find(id);
   if (it == task_flags_.end()) {
@@ -160,7 +151,7 @@
 }
 
 void CancelableTaskTracker::TryCancelAll() {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK(sequence_checker_.CalledOnValidSequence());
 
   for (hash_map<TaskId, CancellationFlag*>::const_iterator it =
            task_flags_.begin();
@@ -171,19 +162,19 @@
 }
 
 bool CancelableTaskTracker::HasTrackedTasks() const {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK(sequence_checker_.CalledOnValidSequence());
   return !task_flags_.empty();
 }
 
 void CancelableTaskTracker::Track(TaskId id, CancellationFlag* flag) {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK(sequence_checker_.CalledOnValidSequence());
 
   bool success = task_flags_.insert(std::make_pair(id, flag)).second;
   DCHECK(success);
 }
 
 void CancelableTaskTracker::Untrack(TaskId id) {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK(sequence_checker_.CalledOnValidSequence());
   size_t num = task_flags_.erase(id);
   DCHECK_EQ(1u, num);
 }
diff --git a/base/task/cancelable_task_tracker.h b/base/task/cancelable_task_tracker.h
index fd68a58..959c86f 100644
--- a/base/task/cancelable_task_tracker.h
+++ b/base/task/cancelable_task_tracker.h
@@ -15,24 +15,23 @@
 //
 // CancelableCallback (base/cancelable_callback.h) and WeakPtr binding are
 // preferred solutions for canceling a task. However, they don't support
-// cancelation from another thread. This is sometimes a performance critical
+// cancelation from another sequence. This is sometimes a performance critical
 // requirement. E.g. We need to cancel database lookup task on DB thread when
 // user changes inputed text. If it is performance critical to do a best effort
-// cancelation of a task, then CancelableTaskTracker is appropriate,
-// otherwise use one of the other mechanisms.
+// cancelation of a task, then CancelableTaskTracker is appropriate, otherwise
+// use one of the other mechanisms.
 //
 // THREAD-SAFETY:
 //
-// 1. CancelableTaskTracker objects are not thread safe. They must
-// be created, used, and destroyed on the originating thread that posts the
-// task. It's safe to destroy a CancelableTaskTracker while there
-// are outstanding tasks. This is commonly used to cancel all outstanding
-// tasks.
+// 1. A CancelableTaskTracker object must be created, used, and destroyed on a
+//    single sequence.
 //
-// 2. Both task and reply are deleted on the originating thread.
+// 2. It's safe to destroy a CancelableTaskTracker while there are outstanding
+//    tasks. This is commonly used to cancel all outstanding tasks.
 //
-// 3. IsCanceledCallback is thread safe and can be run or deleted on any
-// thread.
+// 3. Both task and reply are deleted on the originating sequence.
+//
+// 4. IsCanceledCallback can be run or deleted on any sequence.
 #ifndef BASE_TASK_CANCELABLE_TASK_TRACKER_H_
 #define BASE_TASK_CANCELABLE_TASK_TRACKER_H_
 
@@ -45,7 +44,7 @@
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "base/post_task_and_reply_with_result_internal.h"
-#include "base/threading/thread_checker.h"
+#include "base/sequence_checker.h"
 
 namespace tracked_objects {
 class Location;
@@ -131,7 +130,7 @@
   base::hash_map<TaskId, base::CancellationFlag*> task_flags_;
 
   TaskId next_id_;
-  base::ThreadChecker thread_checker_;
+  SequenceChecker sequence_checker_;
 
   base::WeakPtrFactory<CancelableTaskTracker> weak_factory_;
 
diff --git a/base/time/time.cc b/base/time/time.cc
index d1c6a47..f5cefd4 100644
--- a/base/time/time.cc
+++ b/base/time/time.cc
@@ -21,6 +21,11 @@
 
 // TimeDelta ------------------------------------------------------------------
 
+// static
+TimeDelta TimeDelta::Max() {
+  return TimeDelta(std::numeric_limits<int64_t>::max());
+}
+
 int TimeDelta::InDays() const {
   if (is_max()) {
     // Preserve max to prevent overflow.
diff --git a/base/time/time.h b/base/time/time.h
index 580d0e9e..322ff08 100644
--- a/base/time/time.h
+++ b/base/time/time.h
@@ -130,7 +130,7 @@
   // Returns the maximum time delta, which should be greater than any reasonable
   // time delta we might compare it to. Adding or subtracting the maximum time
   // delta to a time or another time delta has an undefined result.
-  static constexpr TimeDelta Max();
+  static TimeDelta Max();
 
   // Returns the internal numeric value of the TimeDelta object. Please don't
   // use this and do arithmetic on it, as it is more error prone than using the
@@ -656,11 +656,6 @@
 }
 
 // static
-constexpr TimeDelta TimeDelta::Max() {
-  return TimeDelta(std::numeric_limits<int64_t>::max());
-}
-
-// static
 constexpr TimeDelta TimeDelta::FromDouble(double value) {
   // TODO(crbug.com/612601): Use saturated_cast<int64_t>(value) once we sort out
   // the Min() behavior.
diff --git a/blimp/engine/DEPS b/blimp/engine/DEPS
index 50d5e50bd..7e4c0fe 100644
--- a/blimp/engine/DEPS
+++ b/blimp/engine/DEPS
@@ -14,7 +14,6 @@
   "+mojo/public",
   "+net",
   "+services/service_manager/public/cpp",
-  "+storage/browser/quota",
   "+third_party/blimp_fonts",
   "+third_party/khronos/GLES2/gl2.h",
   "+third_party/WebKit/public/platform/WebGestureEvent.h",
diff --git a/blimp/engine/app/blimp_content_browser_client.cc b/blimp/engine/app/blimp_content_browser_client.cc
index 0a94405..5e8c42b3 100644
--- a/blimp/engine/app/blimp_content_browser_client.cc
+++ b/blimp/engine/app/blimp_content_browser_client.cc
@@ -8,12 +8,9 @@
 #include "blimp/engine/app/settings_manager.h"
 #include "blimp/engine/grit/blimp_browser_resources.h"
 #include "blimp/engine/mojo/blob_channel_service.h"
-#include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_thread.h"
-#include "content/public/browser/storage_partition.h"
 #include "content/public/common/service_names.mojom.h"
 #include "services/service_manager/public/cpp/interface_registry.h"
-#include "storage/browser/quota/quota_settings.h"
 #include "ui/base/resource/resource_bundle.h"
 
 namespace blimp {
@@ -72,16 +69,5 @@
   return base::JSONReader::Read(manifest_contents);
 }
 
-void BlimpContentBrowserClient::GetQuotaSettings(
-    content::BrowserContext* context,
-    content::StoragePartition* partition,
-    const storage::OptionalQuotaSettingsCallback& callback) {
-  content::BrowserThread::PostTaskAndReplyWithResult(
-      content::BrowserThread::FILE, FROM_HERE,
-      base::Bind(&storage::CalculateNominalDynamicSettings,
-                 partition->GetPath(), context->IsOffTheRecord()),
-      callback);
-}
-
 }  // namespace engine
 }  // namespace blimp
diff --git a/blimp/engine/app/blimp_content_browser_client.h b/blimp/engine/app/blimp_content_browser_client.h
index 0aa2582..d843da0 100644
--- a/blimp/engine/app/blimp_content_browser_client.h
+++ b/blimp/engine/app/blimp_content_browser_client.h
@@ -33,10 +33,6 @@
       content::RenderProcessHost* render_process_host) override;
   std::unique_ptr<base::Value> GetServiceManifestOverlay(
       const std::string& name) override;
-  void GetQuotaSettings(
-      content::BrowserContext* context,
-      content::StoragePartition* partition,
-      const storage::OptionalQuotaSettingsCallback& callback) override;
 
   BlimpBrowserContext* GetBrowserContext();
 
diff --git a/build/android/PRESUBMIT.py b/build/android/PRESUBMIT.py
index 3c1e87e..ded427f 100644
--- a/build/android/PRESUBMIT.py
+++ b/build/android/PRESUBMIT.py
@@ -32,6 +32,7 @@
           J('gyp'),
           J('buildbot'),
           J('..', '..', 'third_party', 'catapult', 'common', 'py_trace_event'),
+          J('..', '..', 'third_party', 'catapult', 'common', 'py_utils'),
           J('..', '..', 'third_party', 'catapult', 'devil'),
           J('..', '..', 'third_party', 'catapult', 'tracing')
       ]))
diff --git a/build/android/pylib/__init__.py b/build/android/pylib/__init__.py
index c8a26de..b93eb4f 100644
--- a/build/android/pylib/__init__.py
+++ b/build/android/pylib/__init__.py
@@ -13,13 +13,19 @@
 
 _PYTRACE_PATH = os.path.join(_CATAPULT_PATH, 'common', 'py_trace_event')
 
+_PY_UTILS_PATH = os.path.join(_CATAPULT_PATH, 'common', 'py_utils')
+
 _TRACE2HTML_PATH = os.path.join(_CATAPULT_PATH, 'tracing')
 
+
 if _DEVIL_PATH not in sys.path:
   sys.path.append(_DEVIL_PATH)
 
 if _PYTRACE_PATH not in sys.path:
   sys.path.append(_PYTRACE_PATH)
 
+if _PY_UTILS_PATH not in sys.path:
+  sys.path.append(_PY_UTILS_PATH)
+
 if _TRACE2HTML_PATH not in sys.path:
   sys.path.append(_TRACE2HTML_PATH)
diff --git a/build/android/pylib/local/device/local_device_perf_test_run.py b/build/android/pylib/local/device/local_device_perf_test_run.py
index 03f6ed7..7bd9d9b3 100644
--- a/build/android/pylib/local/device/local_device_perf_test_run.py
+++ b/build/android/pylib/local/device/local_device_perf_test_run.py
@@ -3,7 +3,6 @@
 # found in the LICENSE file.
 
 import collections
-import contextlib
 import io
 import json
 import logging
@@ -31,6 +30,7 @@
 from pylib.local.device import local_device_environment
 from pylib.local.device import local_device_test_run
 from py_trace_event import trace_event
+from py_utils import contextlib_ext
 
 
 class HeartBeat(object):
@@ -96,20 +96,12 @@
 
     self._LogTest(test, cmd, timeout)
 
-    @contextlib.contextmanager
-    def trace_if_enabled(test):
-      try:
-        if self._test_instance.trace_output:
-          trace_event.trace_begin(test)
-        yield
-      finally:
-        if self._test_instance.trace_output:
-          trace_event.trace_end(test)
-
     try:
       start_time = time.time()
 
-      with trace_if_enabled(test):
+      with contextlib_ext.Optional(
+          trace_event.trace(test),
+          self._test_instance.trace_output):
         exit_code, output = cmd_helper.GetCmdStatusAndOutputWithTimeout(
             cmd, timeout, cwd=cwd, shell=True)
       end_time = time.time()
diff --git a/build/android/test_runner.py b/build/android/test_runner.py
index 612060af..26d53b94 100755
--- a/build/android/test_runner.py
+++ b/build/android/test_runner.py
@@ -39,6 +39,8 @@
 from pylib.results import json_results
 from pylib.results import report_results
 
+from py_utils import contextlib_ext
+
 
 _DEVIL_STATIC_CONFIG_FILE = os.path.abspath(os.path.join(
     host_paths.DIR_SOURCE_ROOT, 'build', 'android', 'devil_config.json'))
@@ -739,20 +741,16 @@
   all_iteration_results = []
 
   @contextlib.contextmanager
-  def noop():
-    yield
+  def write_json_file():
+    try:
+      yield
+    finally:
+      json_results.GenerateJsonResultsFile(
+          all_raw_results, args.json_results_file)
 
-  json_writer = noop()
-  if args.json_results_file:
-    @contextlib.contextmanager
-    def write_json_file():
-      try:
-        yield
-      finally:
-        json_results.GenerateJsonResultsFile(
-            all_raw_results, args.json_results_file)
-
-    json_writer = write_json_file()
+  json_writer = contextlib_ext.Optional(
+      write_json_file(),
+      args.json_results_file)
 
   ### Set up test objects.
 
diff --git a/build/android/test_runner.pydeps b/build/android/test_runner.pydeps
index ea43ae8b..2d4200c 100644
--- a/build/android/test_runner.pydeps
+++ b/build/android/test_runner.pydeps
@@ -11,6 +11,7 @@
 ../../third_party/catapult/common/py_utils/py_utils/__init__.py
 ../../third_party/catapult/common/py_utils/py_utils/cloud_storage.py
 ../../third_party/catapult/common/py_utils/py_utils/cloud_storage_global_lock.py
+../../third_party/catapult/common/py_utils/py_utils/contextlib_ext.py
 ../../third_party/catapult/common/py_utils/py_utils/lock.py
 ../../third_party/catapult/dependency_manager/dependency_manager/__init__.py
 ../../third_party/catapult/dependency_manager/dependency_manager/archive_info.py
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageView.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageView.java
index 0437008f..8412e5c9 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageView.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageView.java
@@ -22,7 +22,6 @@
 import android.support.v7.widget.RecyclerView;
 import android.support.v7.widget.RecyclerView.AdapterDataObserver;
 import android.support.v7.widget.RecyclerView.ViewHolder;
-import android.support.v7.widget.helper.ItemTouchHelper;
 import android.text.Editable;
 import android.text.TextUtils;
 import android.text.TextWatcher;
@@ -402,10 +401,7 @@
             mRecyclerView.getLinearLayoutManager().scrollToPositionWithOffset(
                     scrollPosition, scrollOffset);
 
-            // Set up swipe-to-dismiss
-            ItemTouchHelper helper =
-                    new ItemTouchHelper(mNewTabPageAdapter.getItemTouchCallbacks());
-            helper.attachToRecyclerView(mRecyclerView);
+            mRecyclerView.setUpSwipeToDismiss();
 
             initializeSearchBoxRecyclerViewScrollHandling();
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/ChildNode.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/ChildNode.java
index 0aaf26f..e293b674 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/ChildNode.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/ChildNode.java
@@ -45,4 +45,10 @@
     protected void notifyItemRemoved(int index) {
         notifyItemRangeRemoved(index, 1);
     }
+
+    protected void checkIndex(int position) {
+        if (position < 0 || position >= getItemCount()) {
+            throw new IndexOutOfBoundsException(position + "/" + getItemCount());
+        }
+    }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/InnerNode.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/InnerNode.java
index 0c57425..f54db9d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/InnerNode.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/InnerNode.java
@@ -4,6 +4,7 @@
 
 package org.chromium.chrome.browser.ntp.cards;
 
+import org.chromium.base.Callback;
 import org.chromium.base.VisibleForTesting;
 import org.chromium.chrome.browser.ntp.snippets.SnippetArticle;
 
@@ -17,16 +18,16 @@
     private final List<TreeNode> mChildren = new ArrayList<>();
 
     private int getChildIndexForPosition(int position) {
-        if (position < 0) {
-            throw new IndexOutOfBoundsException(Integer.toString(position));
-        }
+        checkIndex(position);
         int numItems = 0;
         int numChildren = mChildren.size();
         for (int i = 0; i < numChildren; i++) {
             numItems += mChildren.get(i).getItemCount();
             if (position < numItems) return i;
         }
-        throw new IndexOutOfBoundsException(position + "/" + numItems);
+        // checkIndex() will have caught this case already.
+        assert false;
+        return -1;
     }
 
     private int getStartingOffsetForChildIndex(int childIndex) {
@@ -84,6 +85,13 @@
     }
 
     @Override
+    public void dismissItem(int position, Callback<String> itemRemovedCallback) {
+        int index = getChildIndexForPosition(position);
+        getChildren().get(index).dismissItem(
+                position - getStartingOffsetForChildIndex(index), itemRemovedCallback);
+    }
+
+    @Override
     public int getDismissSiblingPosDelta(int position) {
         int index = getChildIndexForPosition(position);
         return mChildren.get(index).getDismissSiblingPosDelta(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/Leaf.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/Leaf.java
index ade8c74..0d984143 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/Leaf.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/Leaf.java
@@ -4,6 +4,7 @@
 
 package org.chromium.chrome.browser.ntp.cards;
 
+import org.chromium.base.Callback;
 import org.chromium.chrome.browser.ntp.snippets.SnippetArticle;
 
 /**
@@ -38,6 +39,11 @@
     }
 
     @Override
+    public void dismissItem(int position, Callback<String> itemRemovedCallback) {
+        assert false;
+    }
+
+    @Override
     public int getDismissSiblingPosDelta(int position) {
         return 0;
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapter.java
index 8b24a1a3..4d748070 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapter.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapter.java
@@ -4,25 +4,19 @@
 
 package org.chromium.chrome.browser.ntp.cards;
 
-import android.annotation.SuppressLint;
-import android.graphics.Canvas;
-import android.support.annotation.StringRes;
 import android.support.v7.widget.RecyclerView;
 import android.support.v7.widget.RecyclerView.Adapter;
 import android.support.v7.widget.RecyclerView.ViewHolder;
-import android.support.v7.widget.helper.ItemTouchHelper;
 import android.view.View;
 import android.view.ViewGroup;
 
-import org.chromium.base.Log;
+import org.chromium.base.Callback;
 import org.chromium.base.VisibleForTesting;
-import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ntp.NewTabPageView.NewTabPageManager;
 import org.chromium.chrome.browser.ntp.UiConfig;
 import org.chromium.chrome.browser.ntp.snippets.SectionHeaderViewHolder;
 import org.chromium.chrome.browser.ntp.snippets.SnippetArticle;
 import org.chromium.chrome.browser.ntp.snippets.SnippetArticleViewHolder;
-import org.chromium.chrome.browser.ntp.snippets.SuggestionsSource;
 import org.chromium.chrome.browser.offlinepages.OfflinePageBridge;
 
 /**
@@ -32,12 +26,9 @@
  * elements will be the cards shown to the user
  */
 public class NewTabPageAdapter extends Adapter<NewTabPageViewHolder> implements NodeParent {
-    private static final String TAG = "Ntp";
-
     private final NewTabPageManager mNewTabPageManager;
     private final View mAboveTheFoldView;
     private final UiConfig mUiConfig;
-    private final ItemTouchCallbacks mItemTouchCallbacks = new ItemTouchCallbacks();
     private NewTabPageRecyclerView mRecyclerView;
 
     private final InnerNode mRoot;
@@ -49,66 +40,6 @@
     private final Footer mFooter;
     private final SpacingItem mBottomSpacer = new SpacingItem();
 
-    private class ItemTouchCallbacks extends ItemTouchHelper.Callback {
-        @Override
-        public void onSwiped(ViewHolder viewHolder, int direction) {
-            mRecyclerView.onItemDismissStarted(viewHolder);
-            NewTabPageAdapter.this.dismissItem(viewHolder.getAdapterPosition());
-        }
-
-        @Override
-        public void clearView(RecyclerView recyclerView, ViewHolder viewHolder) {
-            // clearView() is called when an interaction with the item is finished, which does
-            // not mean that the user went all the way and dismissed the item before releasing it.
-            // We need to check that the item has been removed.
-            if (viewHolder.getAdapterPosition() == RecyclerView.NO_POSITION) {
-                mRecyclerView.onItemDismissFinished(viewHolder);
-            }
-
-            super.clearView(recyclerView, viewHolder);
-        }
-
-        @Override
-        public boolean onMove(RecyclerView recyclerView, ViewHolder viewHolder, ViewHolder target) {
-            assert false; // Drag and drop not supported, the method will never be called.
-            return false;
-        }
-
-        @Override
-        public int getMovementFlags(RecyclerView recyclerView, ViewHolder viewHolder) {
-            assert viewHolder instanceof NewTabPageViewHolder;
-
-            int swipeFlags = 0;
-            if (((NewTabPageViewHolder) viewHolder).isDismissable()) {
-                swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END;
-            }
-
-            return makeMovementFlags(0 /* dragFlags */, swipeFlags);
-        }
-
-        @Override
-        public void onChildDraw(Canvas c, RecyclerView recyclerView, ViewHolder viewHolder,
-                float dX, float dY, int actionState, boolean isCurrentlyActive) {
-            assert viewHolder instanceof NewTabPageViewHolder;
-
-            // The item has already been removed. We have nothing more to do.
-            // In some cases a removed children may call this method when unrelated items are
-            // interacted with, but this check also covers the case.
-            // See https://crbug.com/664466, b/32900699
-            if (viewHolder.getAdapterPosition() == RecyclerView.NO_POSITION) return;
-
-            // We use our own implementation of the dismissal animation, so we don't call the
-            // parent implementation. (by default it changes the translation-X and elevation)
-            mRecyclerView.updateViewStateForDismiss(dX, (NewTabPageViewHolder) viewHolder);
-
-            // If there is another item that should be animated at the same time, do the same to it.
-            NewTabPageViewHolder siblingViewHolder = getDismissSibling(viewHolder);
-            if (siblingViewHolder != null) {
-                mRecyclerView.updateViewStateForDismiss(dX, siblingViewHolder);
-            }
-        }
-    }
-
     /**
      * Creates the adapter that will manage all the cards to display on the NTP.
      *
@@ -139,11 +70,6 @@
         mRoot.setParent(this);
     }
 
-    /** Returns callbacks to configure the interactions with the RecyclerView's items. */
-    public ItemTouchHelper.Callback getItemTouchCallbacks() {
-        return mItemTouchCallbacks;
-    }
-
     @Override
     @ItemViewType
     public int getItemViewType(int position) {
@@ -271,59 +197,8 @@
      * Dismisses the item at the provided adapter position. Can also cause the dismissal of other
      * items or even entire sections.
      */
-    // TODO(crbug.com/635567): Fix this properly.
-    @SuppressLint("SwitchIntDef")
-    public void dismissItem(int position) {
-        int itemViewType = getItemViewType(position);
-
-        // TODO(dgn): Polymorphism is supposed to allow to avoid that kind of stuff.
-        switch (itemViewType) {
-            case ItemViewType.STATUS:
-            case ItemViewType.ACTION:
-                dismissSection(position);
-                return;
-
-            case ItemViewType.SNIPPET:
-                dismissSuggestion(position);
-                return;
-
-            case ItemViewType.PROMO:
-                dismissPromo();
-                return;
-
-            default:
-                Log.wtf(TAG, "Unsupported dismissal of item of type %d", itemViewType);
-                return;
-        }
-    }
-
-    private void dismissSection(int position) {
-        SuggestionsSection section = getSuggestionsSection(position);
-        mSections.dismissSection(section);
-        announceItemRemoved(section.getHeaderText());
-    }
-
-    private void dismissSuggestion(int position) {
-        SnippetArticle suggestion = mRoot.getSuggestionAt(position);
-        SuggestionsSource suggestionsSource = mNewTabPageManager.getSuggestionsSource();
-        if (suggestionsSource == null) {
-            // It is possible for this method to be called after the NewTabPage has had destroy()
-            // called. This can happen when NewTabPageRecyclerView.dismissWithAnimation() is called
-            // and the animation ends after the user has navigated away. In this case we cannot
-            // inform the native side that the snippet has been dismissed (http://crbug.com/649299).
-            return;
-        }
-
-        announceItemRemoved(suggestion.mTitle);
-
-        suggestionsSource.dismissSuggestion(suggestion);
-        SuggestionsSection section = getSuggestionsSection(position);
-        section.removeSuggestion(suggestion);
-    }
-
-    private void dismissPromo() {
-        announceItemRemoved(mSigninPromo.getHeader());
-        mSigninPromo.dismiss();
+    public void dismissItem(int position, Callback<String> itemRemovedCallback) {
+        mRoot.dismissItem(position, itemRemovedCallback);
     }
 
     /**
@@ -342,19 +217,6 @@
         return mSections.isEmpty() && !mSigninPromo.isVisible();
     }
 
-    /**
-     * @param itemPosition The position of an item in the adapter.
-     * @return Returns the {@link SuggestionsSection} that contains the item at
-     *     {@code itemPosition}, or null if the item is not part of one.
-     */
-    private SuggestionsSection getSuggestionsSection(int itemPosition) {
-        int relativePosition = itemPosition - mRoot.getStartingOffsetForChild(mSections);
-        assert relativePosition >= 0;
-        TreeNode child = mSections.getChildForPosition(relativePosition);
-        if (!(child instanceof SuggestionsSection)) return null;
-        return (SuggestionsSection) child;
-    }
-
     private int getChildPositionOffset(TreeNode child) {
         return mRoot.getStartingOffsetForChild(child);
     }
@@ -380,19 +242,4 @@
     InnerNode getRootForTesting() {
         return mRoot;
     }
-
-    private void announceItemRemoved(String itemTitle) {
-        // In tests the RecyclerView can be null.
-        if (mRecyclerView == null) return;
-
-        mRecyclerView.announceForAccessibility(mRecyclerView.getResources().getString(
-                R.string.ntp_accessibility_item_removed, itemTitle));
-    }
-
-    private void announceItemRemoved(@StringRes int stringToAnnounce) {
-        // In tests the RecyclerView can be null.
-        if (mRecyclerView == null) return;
-
-        announceItemRemoved(mRecyclerView.getResources().getString(stringToAnnounce));
-    }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerView.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerView.java
index e4673668..525d101 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerView.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerView.java
@@ -10,11 +10,13 @@
 import android.animation.ObjectAnimator;
 import android.content.Context;
 import android.content.res.Resources;
+import android.graphics.Canvas;
 import android.graphics.Region;
 import android.support.v4.view.animation.FastOutLinearInInterpolator;
 import android.support.v4.view.animation.LinearOutSlowInInterpolator;
 import android.support.v7.widget.LinearLayoutManager;
 import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.helper.ItemTouchHelper;
 import android.util.AttributeSet;
 import android.view.GestureDetector;
 import android.view.MotionEvent;
@@ -23,8 +25,10 @@
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputConnection;
 
+import org.chromium.base.Callback;
 import org.chromium.base.Log;
 import org.chromium.chrome.R;
+import org.chromium.chrome.R.string;
 import org.chromium.chrome.browser.ntp.ContextMenuManager.TouchDisableableView;
 import org.chromium.chrome.browser.ntp.NewTabPageLayout;
 import org.chromium.chrome.browser.ntp.snippets.SectionHeaderViewHolder;
@@ -51,6 +55,7 @@
 
     private final GestureDetector mGestureDetector;
     private final LinearLayoutManager mLayoutManager;
+
     private final int mToolbarHeight;
     private final int mMaxHeaderHeight;
     /** How much of the first card is visible above the fold with the increased visibility UI. */
@@ -126,6 +131,14 @@
         });
     }
 
+    /**
+     * Sets up swipe-to-dismiss functionality.
+     */
+    public void setUpSwipeToDismiss() {
+        ItemTouchHelper helper = new ItemTouchHelper(new ItemTouchCallbacks());
+        helper.attachToRecyclerView(this);
+    }
+
     public boolean isFirstItemVisible() {
         return mLayoutManager.findFirstVisibleItemPosition() == 0;
     }
@@ -484,9 +497,7 @@
             // The height of the region in which the the peeking card will snap.
             int snapScrollHeight = peekingHeight + headerView.getHeight();
 
-            scrollOutOfRegion(start,
-                              start + snapScrollHeight,
-                              start + snapScrollHeight);
+            scrollOutOfRegion(start, start + snapScrollHeight, start + snapScrollHeight);
         }
     }
 
@@ -544,7 +555,13 @@
             // The item does not exist anymore, so ignore.
             return;
         }
-        getNewTabPageAdapter().dismissItem(position);
+        getNewTabPageAdapter().dismissItem(position, new Callback<String>() {
+            @Override
+            public void onResult(String removedItemTitle) {
+                announceForAccessibility(getResources().getString(
+                        string.ntp_accessibility_item_removed, removedItemTitle));
+            }
+        });
     }
 
     /**
@@ -613,4 +630,65 @@
         ChromePreferenceManager.getInstance(getContext()).setCardsImpressionAfterAnimation(true);
         mCardImpressionAfterAnimationTracked = true;
     }
+
+    private class ItemTouchCallbacks extends ItemTouchHelper.Callback {
+        @Override
+        public void onSwiped(ViewHolder viewHolder, int direction) {
+            onItemDismissStarted(viewHolder);
+            dismissItemInternal(viewHolder);
+        }
+
+        @Override
+        public void clearView(RecyclerView recyclerView, ViewHolder viewHolder) {
+            // clearView() is called when an interaction with the item is finished, which does
+            // not mean that the user went all the way and dismissed the item before releasing it.
+            // We need to check that the item has been removed.
+            if (viewHolder.getAdapterPosition() == RecyclerView.NO_POSITION) {
+                onItemDismissFinished(viewHolder);
+            }
+
+            super.clearView(recyclerView, viewHolder);
+        }
+
+        @Override
+        public boolean onMove(RecyclerView recyclerView, ViewHolder viewHolder, ViewHolder target) {
+            assert false; // Drag and drop not supported, the method will never be called.
+            return false;
+        }
+
+        @Override
+        public int getMovementFlags(RecyclerView recyclerView, ViewHolder viewHolder) {
+            assert viewHolder instanceof NewTabPageViewHolder;
+
+            int swipeFlags = 0;
+            if (((NewTabPageViewHolder) viewHolder).isDismissable()) {
+                swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END;
+            }
+
+            return makeMovementFlags(0 /* dragFlags */, swipeFlags);
+        }
+
+        @Override
+        public void onChildDraw(Canvas c, RecyclerView recyclerView, ViewHolder viewHolder,
+                float dX, float dY, int actionState, boolean isCurrentlyActive) {
+            assert viewHolder instanceof NewTabPageViewHolder;
+
+            // The item has already been removed. We have nothing more to do.
+            // In some cases a removed child may call this method when unrelated items are
+            // interacted with, but this check also covers the case.
+            // See https://crbug.com/664466, b/32900699
+            if (viewHolder.getAdapterPosition() == RecyclerView.NO_POSITION) return;
+
+            // We use our own implementation of the dismissal animation, so we don't call the
+            // parent implementation. (by default it changes the translation-X and elevation)
+            updateViewStateForDismiss(dX, (NewTabPageViewHolder) viewHolder);
+
+            // If there is another item that should be animated at the same time, do the same to it.
+            NewTabPageViewHolder siblingViewHolder =
+                    getNewTabPageAdapter().getDismissSibling(viewHolder);
+            if (siblingViewHolder != null) {
+                updateViewStateForDismiss(dX, siblingViewHolder);
+            }
+        }
+    }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/OptionalLeaf.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/OptionalLeaf.java
index 1a3b7ff..fe95e48 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/OptionalLeaf.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/OptionalLeaf.java
@@ -6,6 +6,7 @@
 
 import android.support.annotation.CallSuper;
 
+import org.chromium.base.Callback;
 import org.chromium.chrome.browser.ntp.snippets.SnippetArticle;
 
 /**
@@ -43,12 +44,17 @@
     }
 
     @Override
+    public void dismissItem(int position, Callback<String> itemRemovedCallback) {
+        checkIndex(position);
+        dismiss(itemRemovedCallback);
+    }
+
+    @Override
     public int getDismissSiblingPosDelta(int position) {
         checkIndex(position);
         return 0;
     }
 
-
     /** @return Whether the optional item is currently visible. */
     public final boolean isVisible() {
         return mVisible;
@@ -86,9 +92,14 @@
     @ItemViewType
     protected abstract int getItemViewType();
 
-    protected void checkIndex(int position) {
-        if (position < 0 || position >= getItemCount()) {
-            throw new IndexOutOfBoundsException(position + "/" + getItemCount());
-        }
+    /**
+     * Dismiss this item. The default implementation asserts, as by default items can't be
+     * dismissed.
+     * @param itemRemovedCallback Should be called with the title of the dismissed item, to announce
+     * it for accessibility purposes.
+     * @see TreeNode#dismissItem
+     */
+    protected void dismiss(Callback<String> itemRemovedCallback) {
+        assert false;
     }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SectionList.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SectionList.java
index 5ac8614db..a0190f41 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SectionList.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SectionList.java
@@ -24,7 +24,8 @@
  * A node in the tree containing a list of all suggestions sections. It listens to changes in the
  * suggestions source and updates the corresponding sections.
  */
-public class SectionList extends InnerNode implements SuggestionsSource.Observer {
+public class SectionList
+        extends InnerNode implements SuggestionsSource.Observer, SuggestionsSection.Delegate {
     private static final String TAG = "Ntp";
 
     /** Maps suggestion categories to sections, with stable iteration ordering. */
@@ -91,7 +92,7 @@
 
         // Create the section if needed.
         if (section == null) {
-            section = new SuggestionsSection(mNewTabPageManager, mOfflinePageBridge, info);
+            section = new SuggestionsSection(this, mNewTabPageManager, mOfflinePageBridge, info);
             mSections.put(category, section);
             addChild(section);
         }
@@ -207,6 +208,7 @@
      * Dismisses a section.
      * @param section The section to be dismissed.
      */
+    @Override
     public void dismissSection(SuggestionsSection section) {
         assert SnippetsConfig.isSectionDismissalEnabled();
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SignInPromo.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SignInPromo.java
index a8c1ca1..15a6ffe 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SignInPromo.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SignInPromo.java
@@ -10,6 +10,7 @@
 import android.support.annotation.StringRes;
 import android.support.v7.widget.RecyclerView;
 
+import org.chromium.base.Callback;
 import org.chromium.base.ContextUtils;
 import org.chromium.base.VisibleForTesting;
 import org.chromium.base.metrics.RecordUserAction;
@@ -114,13 +115,15 @@
     }
 
     /** Hides the sign in promo and sets a preference to make sure it is not shown again. */
-    public void dismiss() {
+    @Override
+    public void dismiss(Callback<String> itemRemovedCallback) {
         mDismissed = true;
         setVisible(false);
 
         ChromePreferenceManager.getInstance(ContextUtils.getApplicationContext())
                 .setNewTabPageSigninPromoDismissed(true);
         mObserver.unregister();
+        itemRemovedCallback.onResult(ContextUtils.getApplicationContext().getString(getHeader()));
     }
 
     @VisibleForTesting
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSection.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSection.java
index cac3245b..b83ab1df 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSection.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSection.java
@@ -15,6 +15,7 @@
 import org.chromium.chrome.browser.ntp.snippets.SnippetArticle;
 import org.chromium.chrome.browser.ntp.snippets.SnippetArticleViewHolder;
 import org.chromium.chrome.browser.ntp.snippets.SnippetsBridge;
+import org.chromium.chrome.browser.ntp.snippets.SuggestionsSource;
 import org.chromium.chrome.browser.offlinepages.ClientId;
 import org.chromium.chrome.browser.offlinepages.OfflinePageBridge;
 import org.chromium.chrome.browser.offlinepages.OfflinePageItem;
@@ -30,6 +31,7 @@
 public class SuggestionsSection extends InnerNode {
     private static final String TAG = "NtpCards";
 
+    private final Delegate mDelegate;
     private final SuggestionsCategoryInfo mCategoryInfo;
     private final OfflinePageBridge mOfflinePageBridge;
 
@@ -42,13 +44,22 @@
 
     private boolean mIsNtpDestroyed;
 
-    public SuggestionsSection(NewTabPageManager manager, OfflinePageBridge offlinePageBridge,
-            SuggestionsCategoryInfo info) {
+    /**
+     * Delegate interface that allows dismissing this section without introducing
+     * a circular dependency.
+     */
+    public interface Delegate {
+        void dismissSection(SuggestionsSection section);
+    }
+
+    public SuggestionsSection(Delegate delegate, NewTabPageManager manager,
+            OfflinePageBridge offlinePageBridge, SuggestionsCategoryInfo info) {
+        mDelegate = delegate;
         mCategoryInfo = info;
         mOfflinePageBridge = offlinePageBridge;
 
         mHeader = new SectionHeader(info.getTitle());
-        mSuggestionsList = new SuggestionsList(info);
+        mSuggestionsList = new SuggestionsList(manager, info);
         mStatus = StatusItem.createNoSuggestionsItem(info);
         mMoreButton = new ActionItem(this);
         mProgressIndicator = new ProgressItem();
@@ -60,9 +71,12 @@
 
     private static class SuggestionsList extends ChildNode implements Iterable<SnippetArticle> {
         private final List<SnippetArticle> mSuggestions = new ArrayList<>();
+        private final NewTabPageManager mNewTabPageManager;
         private final SuggestionsCategoryInfo mCategoryInfo;
 
-        public SuggestionsList(SuggestionsCategoryInfo categoryInfo) {
+        public SuggestionsList(NewTabPageManager newTabPageManager,
+                SuggestionsCategoryInfo categoryInfo) {
+            mNewTabPageManager = newTabPageManager;
             mCategoryInfo = categoryInfo;
         }
 
@@ -74,11 +88,13 @@
         @Override
         @ItemViewType
         public int getItemViewType(int position) {
+            checkIndex(position);
             return ItemViewType.SNIPPET;
         }
 
         @Override
         public void onBindViewHolder(NewTabPageViewHolder holder, int position) {
+            checkIndex(position);
             assert holder instanceof SnippetArticleViewHolder;
             ((SnippetArticleViewHolder) holder)
                     .onBindViewHolder(getSuggestionAt(position), mCategoryInfo);
@@ -91,17 +107,10 @@
 
         @Override
         public int getDismissSiblingPosDelta(int position) {
+            checkIndex(position);
             return 0;
         }
 
-        public void remove(SnippetArticle suggestion) {
-            int removedIndex = mSuggestions.indexOf(suggestion);
-            if (removedIndex == -1) throw new IndexOutOfBoundsException();
-
-            mSuggestions.remove(removedIndex);
-            notifyItemRemoved(removedIndex);
-        }
-
         public void clear() {
             int itemCount = mSuggestions.size();
             if (itemCount == 0) return;
@@ -118,10 +127,34 @@
             notifyItemRangeInserted(insertionPointIndex, suggestions.size());
         }
 
+        public SnippetArticle remove(int position) {
+            SnippetArticle suggestion = mSuggestions.remove(position);
+            notifyItemRemoved(position);
+            return suggestion;
+        }
+
         @Override
         public Iterator<SnippetArticle> iterator() {
             return mSuggestions.iterator();
         }
+
+        @Override
+        public void dismissItem(int position, Callback<String> itemRemovedCallback) {
+            checkIndex(position);
+            SuggestionsSource suggestionsSource = mNewTabPageManager.getSuggestionsSource();
+            if (suggestionsSource == null) {
+                // It is possible for this method to be called after the NewTabPage has had
+                // destroy() called. This can happen when
+                // NewTabPageRecyclerView.dismissWithAnimation() is called and the animation ends
+                // after the user has navigated away. In this case we cannot inform the native side
+                // that the snippet has been dismissed (http://crbug.com/649299).
+                return;
+            }
+
+            SnippetArticle suggestion = remove(position);
+            suggestionsSource.dismissSuggestion(suggestion);
+            itemRemovedCallback.onResult(suggestion.mTitle);
+        }
     }
 
     private void setupOfflinePageBridgeObserver(NewTabPageManager manager) {
@@ -168,17 +201,35 @@
         mMoreButton.refreshVisibility();
     }
 
-    public void removeSuggestion(SnippetArticle suggestion) {
-        mSuggestionsList.remove(suggestion);
-        refreshChildrenVisibility();
+    @Override
+    public void dismissItem(int position, Callback<String> itemRemovedCallback) {
+        if (!hasSuggestions()) {
+            mDelegate.dismissSection(this);
+            itemRemovedCallback.onResult(getHeaderText());
+            return;
+        }
+
+        super.dismissItem(position, itemRemovedCallback);
     }
 
+    @Override
+    public void onItemRangeRemoved(TreeNode child, int index, int count) {
+        super.onItemRangeRemoved(child, index, count);
+        if (child == mSuggestionsList) refreshChildrenVisibility();
+    }
+
+    /**
+     * Removes a suggestion. Does nothing if the ID is unknown.
+     * @param idWithinCategory The ID of the suggestion to remove.
+     */
     public void removeSuggestionById(String idWithinCategory) {
+        int i = 0;
         for (SnippetArticle suggestion : mSuggestionsList) {
             if (suggestion.mIdWithinCategory.equals(idWithinCategory)) {
-                removeSuggestion(suggestion);
+                mSuggestionsList.remove(i);
                 return;
             }
+            i++;
         }
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/TreeNode.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/TreeNode.java
index 6816a1a..b1cfafa 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/TreeNode.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/TreeNode.java
@@ -4,6 +4,7 @@
 
 package org.chromium.chrome.browser.ntp.cards;
 
+import org.chromium.base.Callback;
 import org.chromium.chrome.browser.ntp.snippets.SnippetArticle;
 
 /**
@@ -50,6 +51,14 @@
     SnippetArticle getSuggestionAt(int position);
 
     /**
+     * Dismiss the item at the given {@code position}.
+     * @param position The position of the item to be dismissed.
+     * @param itemRemovedCallback Should be called with the title of the dismissed item, to announce
+     * it for accessibility purposes.
+     */
+    public void dismissItem(int position, Callback<String> itemRemovedCallback);
+
+    /**
      * The dismiss sibling is an item that should be dismissed at the same time as the provided
      * one. For example, if we want to dismiss a status card that has a More button attached, the
      * button is the card's dismiss sibling. This function returns the adapter position delta to
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerViewTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerViewTest.java
index 7dac055..7cead42 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerViewTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerViewTest.java
@@ -118,8 +118,7 @@
         // Scroll the last suggestion into view and click it.
         SnippetArticle suggestion = suggestions.get(suggestions.size() - 1);
         int suggestionPosition = getSuggestionPosition(suggestion);
-        scrollToPosition(suggestionPosition);
-        final View suggestionView = waitForView(suggestionPosition);
+        final View suggestionView = getViewHolderAtPosition(suggestionPosition).itemView;
         ChromeTabUtils.waitForTabPageLoaded(mTab, new Runnable() {
             @Override
             public void run() {
@@ -142,27 +141,20 @@
 
         // Dismiss the sign in promo.
         int signinPromoPosition = getAdapter().getFirstPositionForType(ItemViewType.PROMO);
-        scrollToPosition(signinPromoPosition);
-        View signinPromoView = waitForView(signinPromoPosition);
-        getAdapter().dismissItem(signinPromoPosition);
-        waitForViewToDetach(signinPromoView);
+        dismissItemAtPosition(signinPromoPosition);
 
         // Dismiss all the cards, including status cards, which dismisses the associated category.
-        int cardPosition = getAdapter().getFirstCardPosition();
-        while (cardPosition != RecyclerView.NO_POSITION) {
-            scrollToPosition(cardPosition);
-            View cardView = waitForView(cardPosition);
-            getAdapter().dismissItem(cardPosition);
-            waitForViewToDetach(cardView);
-            cardPosition = getAdapter().getFirstCardPosition();
+        while (true) {
+            int cardPosition = getAdapter().getFirstCardPosition();
+            if (cardPosition == RecyclerView.NO_POSITION) break;
+            dismissItemAtPosition(cardPosition);
         }
         assertEquals(0, mSource.getCategories().length);
 
         // Click the refresh button on the all dismissed item.
         int allDismissedPosition = getAdapter().getFirstPositionForType(ItemViewType.ALL_DISMISSED);
         assertTrue(allDismissedPosition != RecyclerView.NO_POSITION);
-        scrollToPosition(allDismissedPosition);
-        View allDismissedView = waitForView(allDismissedPosition);
+        View allDismissedView = getViewHolderAtPosition(allDismissedPosition).itemView;
         singleClickView(allDismissedView.findViewById(R.id.action_button));
         waitForViewToDetach(allDismissedView);
         assertEquals(1, mSource.getCategories().length);
@@ -180,8 +172,7 @@
 
         // Scroll a suggestion into view.
         int suggestionPosition = getSuggestionPosition(suggestions.get(suggestions.size() - 1));
-        scrollToPosition(suggestionPosition);
-        View suggestionView = waitForView(suggestionPosition);
+        View suggestionView = getViewHolderAtPosition(suggestionPosition).itemView;
 
         // Dismiss the suggestion using the context menu.
         invokeContextMenu(suggestionView, ContextMenuManager.ID_REMOVE);
@@ -203,8 +194,7 @@
         int cardPosition = getAdapter().getFirstCardPosition();
         assertEquals(ItemViewType.STATUS, getAdapter().getItemViewType(cardPosition));
 
-        scrollToPosition(cardPosition);
-        View statusCardView = waitForView(cardPosition);
+        View statusCardView = getViewHolderAtPosition(cardPosition).itemView;
 
         // Dismiss the status card using the context menu.
         invokeContextMenu(statusCardView, ContextMenuManager.ID_REMOVE);
@@ -224,8 +214,7 @@
         // Scroll the action item into view.
         int actionItemPosition = getAdapter().getFirstCardPosition() + 1;
         assertEquals(ItemViewType.ACTION, getAdapter().getItemViewType(actionItemPosition));
-        scrollToPosition(actionItemPosition);
-        View actionItemView = waitForView(actionItemPosition);
+        View actionItemView = getViewHolderAtPosition(actionItemPosition).itemView;
 
         // Dismiss the action item using the context menu.
         invokeContextMenu(actionItemView, ContextMenuManager.ID_REMOVE);
@@ -255,7 +244,13 @@
         return RecyclerView.NO_POSITION;
     }
 
-    private void scrollToPosition(final int position) {
+    /**
+     * Scroll the {@link View} at the given adapter position into view and returns
+     * its {@link ViewHolder}.
+     * @param position the adapter position for which to return the {@link ViewHolder}.
+     * @return the ViewHolder for the given {@code position}.
+     */
+    private ViewHolder getViewHolderAtPosition(final int position) {
         final NewTabPageRecyclerView recyclerView = getRecyclerView();
 
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@@ -263,9 +258,28 @@
             public void run() {
                 recyclerView.getLinearLayoutManager().scrollToPositionWithOffset(
                         position, getActivity().getResources().getDimensionPixelSize(
-                                          R.dimen.tab_strip_height));
+                                R.dimen.tab_strip_height));
             }
         });
+        return waitForView(position);
+    }
+
+    /**
+     * Dismiss the item at the given {@code position} and wait until it has been removed from the
+     * {@link RecyclerView}.
+     * @param position the adapter position to remove.
+     * @throws InterruptedException
+     * @throws TimeoutException
+     */
+    private void dismissItemAtPosition(int position) throws InterruptedException, TimeoutException {
+        final ViewHolder viewHolder = getViewHolderAtPosition(position);
+        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
+            @Override
+            public void run() {
+                getRecyclerView().dismissItemWithAnimation(viewHolder);
+            }
+        });
+        waitForViewToDetach(viewHolder.itemView);
     }
 
     private void setSuggestionsAndWaitForUpdate(final int suggestionsCount) {
@@ -298,7 +312,7 @@
                 getInstrumentation().invokeContextMenuAction(getActivity(), contextMenuItemId, 0));
     }
 
-    private View waitForView(final int position) {
+    private ViewHolder waitForView(final int position) {
         final NewTabPageRecyclerView recyclerView = getRecyclerView();
 
         CriteriaHelper.pollUiThread(new Criteria() {
@@ -322,7 +336,7 @@
 
         waitForStableRecyclerView();
 
-        return recyclerView.findViewHolderForAdapterPosition(position).itemView;
+        return recyclerView.findViewHolderForAdapterPosition(position);
     }
 
     private void waitForViewToDetach(final View view)
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapterTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapterTest.java
index 69e9330..f35d98f 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapterTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapterTest.java
@@ -10,6 +10,7 @@
 import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
+import static org.mockito.Mockito.anyString;
 import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.mock;
@@ -25,6 +26,7 @@
 import static org.chromium.chrome.browser.ntp.cards.ContentSuggestionsTestUtils.registerCategory;
 import static org.chromium.chrome.browser.ntp.cards.ContentSuggestionsTestUtils.viewTypeToString;
 
+import android.content.res.Resources;
 import android.support.v7.widget.RecyclerView;
 import android.support.v7.widget.RecyclerView.AdapterDataObserver;
 
@@ -38,10 +40,16 @@
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.shadows.ShadowResources;
 
+import org.chromium.base.Callback;
+import org.chromium.base.ContextUtils;
 import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.base.metrics.RecordUserAction;
 import org.chromium.base.test.util.Feature;
+import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ChromeFeatureList;
 import org.chromium.chrome.browser.EnableFeatures;
 import org.chromium.chrome.browser.ntp.NewTabPage.DestructionObserver;
@@ -163,6 +171,8 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
 
+        ContextUtils.initApplicationContextForTests(RuntimeEnvironment.application);
+
         // Initialise the sign in state. We will be signed in by default in the tests.
         assertFalse(ChromePreferenceManager.getInstance(RuntimeEnvironment.application)
                             .getNewTabPageSigninPromoDismissed());
@@ -412,9 +422,9 @@
         SuggestionsSection section42 =
                 mAdapter.getSectionListForTesting().getSectionForTesting(category);
         assertSectionMatches(section(3), section42);
-        section42.removeSuggestion(articles.get(0));
-        section42.removeSuggestion(articles.get(1));
-        section42.removeSuggestion(articles.get(2));
+        section42.removeSuggestionById(articles.get(0).mIdWithinCategory);
+        section42.removeSuggestionById(articles.get(1).mIdWithinCategory);
+        section42.removeSuggestionById(articles.get(2).mIdWithinCategory);
         assertItemsFor(sectionWithStatusCard());
 
         // Part 2: VisibleIfEmpty = false
@@ -467,9 +477,9 @@
         SuggestionsSection section42 =
                 mAdapter.getSectionListForTesting().getSectionForTesting(category);
         assertSectionMatches(section(3).withActionButton(), section42);
-        section42.removeSuggestion(articles.get(0));
-        section42.removeSuggestion(articles.get(1));
-        section42.removeSuggestion(articles.get(2));
+        section42.removeSuggestionById(articles.get(0).mIdWithinCategory);
+        section42.removeSuggestionById(articles.get(1).mIdWithinCategory);
+        section42.removeSuggestionById(articles.get(2).mIdWithinCategory);
         assertItemsFor(sectionWithStatusCard().withActionButton());
 
         // Part 1: Without "View All" action
@@ -491,9 +501,9 @@
         // 2.3 - When all suggestions are dismissed.
         section42 = mAdapter.getSectionListForTesting().getSectionForTesting(category);
         assertSectionMatches(section(3), section42);
-        section42.removeSuggestion(articles.get(0));
-        section42.removeSuggestion(articles.get(1));
-        section42.removeSuggestion(articles.get(2));
+        section42.removeSuggestionById(articles.get(0).mIdWithinCategory);
+        section42.removeSuggestionById(articles.get(1).mIdWithinCategory);
+        section42.removeSuggestionById(articles.get(2).mIdWithinCategory);
         assertItemsFor(sectionWithStatusCard());
     }
 
@@ -620,6 +630,9 @@
         registerCategory(suggestionsSource, KnownCategories.ARTICLES, 3);
         when(mNewTabPageManager.getSuggestionsSource()).thenReturn(suggestionsSource);
 
+        @SuppressWarnings("unchecked")
+        Callback<String> itemDismissedCallback = mock(Callback.class);
+
         reloadNtp();
         AdapterDataObserver dataObserver = mock(AdapterDataObserver.class);
         mAdapter.registerAdapterDataObserver(dataObserver);
@@ -633,19 +646,23 @@
         // 5   | Footer
         // 6   | Spacer
 
-        mAdapter.dismissItem(3); // Dismiss the second suggestion of the second section.
+        // Dismiss the second suggestion of the second section.
+        mAdapter.dismissItem(3, itemDismissedCallback);
+        verify(itemDismissedCallback).onResult(anyString());
         verify(dataObserver).onItemRangeRemoved(3, 1);
         verify(dataObserver).onItemRangeChanged(5, 1, null);
 
         // Make sure the call with the updated position works properly.
-        mAdapter.dismissItem(3);
+        mAdapter.dismissItem(3, itemDismissedCallback);
+        verify(itemDismissedCallback, times(2)).onResult(anyString());
         verify(dataObserver, times(2)).onItemRangeRemoved(3, 1);
         verify(dataObserver).onItemRangeChanged(4, 1, null);
         verifyNoMoreInteractions(dataObserver);
 
         // Dismiss the last suggestion in the section. We should now show the status card.
         reset(dataObserver);
-        mAdapter.dismissItem(2);
+        mAdapter.dismissItem(2, itemDismissedCallback);
+        verify(itemDismissedCallback, times(3)).onResult(anyString());
         verify(dataObserver).onItemRangeRemoved(2, 1); // Suggestion removed
         verify(dataObserver).onItemRangeChanged(3, 1, null); // Spacer refresh
         verify(dataObserver).onItemRangeInserted(2, 1); // Status card added
@@ -743,7 +760,12 @@
 
     @Test
     @Feature({"Ntp"})
+    @Config(shadows = MyShadowResources.class)
     public void testSigninPromoDismissal() {
+        final String signInPromoText = "sign in";
+        when(MyShadowResources.sResources.getText(R.string.snippets_disabled_generic_prompt))
+                .thenReturn(signInPromoText);
+
         when(mMockSigninManager.isSignInAllowed()).thenReturn(true);
         when(mMockSigninManager.isSignedInOnNative()).thenReturn(false);
         ChromePreferenceManager.getInstance(RuntimeEnvironment.application)
@@ -752,8 +774,11 @@
 
         final int signInPromoPosition = mAdapter.getFirstPositionForType(ItemViewType.PROMO);
         assertNotEquals(RecyclerView.NO_POSITION, signInPromoPosition);
-        mAdapter.dismissItem(signInPromoPosition);
+        @SuppressWarnings("unchecked")
+        Callback<String> itemDismissedCallback = mock(Callback.class);
+        mAdapter.dismissItem(signInPromoPosition, itemDismissedCallback);
 
+        verify(itemDismissedCallback).onResult(anyString());
         assertFalse(isSignInPromoVisible());
         assertTrue(ChromePreferenceManager.getInstance(RuntimeEnvironment.application)
                            .getNewTabPageSigninPromoDismissed());
@@ -778,6 +803,9 @@
             }
         }
 
+        @SuppressWarnings("unchecked")
+        Callback<String> itemDismissedCallback = mock(Callback.class);
+
         // By default, there is no All Dismissed item.
         // Adapter content:
         // Idx | Item
@@ -793,7 +821,10 @@
                 mAdapter.getFirstPositionForType(ItemViewType.ALL_DISMISSED));
 
         // When we remove the section, the All Dismissed item should be there.
-        mAdapter.dismissItem(2);
+        mAdapter.dismissItem(2, itemDismissedCallback);
+
+        verify(itemDismissedCallback).onResult(anyString());
+
         // Adapter content:
         // Idx | Item
         // ----|--------------------
@@ -872,6 +903,20 @@
     }
 
     /**
+     * Robolectric shadow to mock out calls to {@link Resources#getString}.
+     */
+    @Implements(Resources.class)
+    public static class MyShadowResources extends ShadowResources {
+        public static final Resources sResources = mock(Resources.class);
+
+        @Override
+        @Implementation
+        public CharSequence getText(int id) {
+            return sResources.getText(id);
+        }
+    }
+
+    /**
      * Asserts that the given {@link TreeNode} is a {@link SuggestionsSection} that matches the
      * given {@link SectionDescriptor}.
      * @param descriptor The section descriptor to match against.
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSectionTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSectionTest.java
index 4ae471a..7802f8ab 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSectionTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSectionTest.java
@@ -29,7 +29,10 @@
 import org.mockito.MockitoAnnotations;
 import org.robolectric.annotation.Config;
 
+import org.chromium.base.Callback;
 import org.chromium.base.test.util.Feature;
+import org.chromium.chrome.browser.ChromeFeatureList;
+import org.chromium.chrome.browser.EnableFeatures;
 import org.chromium.chrome.browser.ntp.NewTabPageView.NewTabPageManager;
 import org.chromium.chrome.browser.ntp.cards.ContentSuggestionsTestUtils.CategoryInfoBuilder;
 import org.chromium.chrome.browser.ntp.snippets.CategoryStatus;
@@ -47,8 +50,10 @@
 @RunWith(LocalRobolectricTestRunner.class)
 @Config(manifest = Config.NONE)
 public class SuggestionsSectionTest {
-
-    @Mock private NodeParent mParent;
+    @Mock
+    private SuggestionsSection.Delegate mDelegate;
+    @Mock
+    private NodeParent mParent;
     @Mock private NewTabPageManager mManager;
     private FakeOfflinePageBridge mBridge;
 
@@ -92,6 +97,7 @@
         reset(mParent);
 
         assertEquals(2, section.getItemCount()); // When empty, we have the header and status card.
+        assertEquals(ItemViewType.STATUS, section.getItemViewType(1));
 
         section.addSuggestions(snippets, CategoryStatus.AVAILABLE);
         verify(mParent).onItemRangeInserted(section, 1, suggestionCount);
@@ -128,12 +134,12 @@
         verifyNoMoreInteractions(mParent);
     }
 
-    @Test(expected = IndexOutOfBoundsException.class)
+    @Test
     @Feature({"Ntp"})
     public void testRemoveUnknownSuggestion() {
         SuggestionsSection section = createSectionWithReloadAction(false);
         section.setStatus(CategoryStatus.AVAILABLE);
-        section.removeSuggestion(createDummySuggestions(1).get(0));
+        section.removeSuggestionById("foobar");
     }
 
     @Test
@@ -148,12 +154,15 @@
 
         section.addSuggestions(snippets, CategoryStatus.AVAILABLE);
 
-        section.removeSuggestion(snippets.get(1));
+        section.removeSuggestionById(snippets.get(1).mIdWithinCategory);
         verify(mParent).onItemRangeRemoved(section, 2, 1);
 
-        section.removeSuggestion(snippets.get(0));
+        section.removeSuggestionById(snippets.get(0).mIdWithinCategory);
         verify(mParent).onItemRangeRemoved(section, 1, 1);
         verify(mParent).onItemRangeInserted(section, 1, 1);
+
+        assertEquals(2, section.getItemCount());
+        assertEquals(ItemViewType.STATUS, section.getItemViewType(1));
     }
 
     @Test
@@ -174,13 +183,33 @@
         assertEquals(3, section.getItemCount()); // We have the header and status card and a button.
 
         section.addSuggestions(snippets, CategoryStatus.AVAILABLE);
+        assertEquals(4, section.getItemCount());
 
-        section.removeSuggestion(snippets.get(0));
+        section.removeSuggestionById(snippets.get(0).mIdWithinCategory);
         verify(mParent).onItemRangeRemoved(section, 1, 1);
 
-        section.removeSuggestion(snippets.get(1));
+        section.removeSuggestionById(snippets.get(1).mIdWithinCategory);
         verify(mParent, times(2)).onItemRangeRemoved(section, 1, 1);
         verify(mParent).onItemRangeInserted(section, 1, 1); // Only the status card is added.
+        assertEquals(3, section.getItemCount());
+        assertEquals(ItemViewType.STATUS, section.getItemViewType(1));
+        assertEquals(ItemViewType.ACTION, section.getItemViewType(2));
+    }
+
+    @Test
+    @Feature({"Ntp"})
+    @EnableFeatures({ChromeFeatureList.NTP_SUGGESTIONS_SECTION_DISMISSAL})
+    public void testDismissSection() {
+        SuggestionsSection section = createSectionWithReloadAction(false);
+        section.setStatus(CategoryStatus.AVAILABLE);
+        reset(mParent);
+        assertEquals(2, section.getItemCount());
+
+        @SuppressWarnings("unchecked")
+        Callback<String> callback = mock(Callback.class);
+        section.dismissItem(1, callback);
+        verify(mDelegate).dismissSection(section);
+        verify(callback).onResult(section.getHeaderText());
     }
 
     @Test
@@ -347,7 +376,7 @@
     }
 
     private SuggestionsSection createSection(SuggestionsCategoryInfo info) {
-        SuggestionsSection section = new SuggestionsSection(mManager, mBridge, info);
+        SuggestionsSection section = new SuggestionsSection(mDelegate, mManager, mBridge, info);
         section.setParent(mParent);
         return section;
     }
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 46c660b3..32d7c62 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -352,6 +352,8 @@
     "download/save_package_file_picker.h",
     "engagement/important_sites_util.cc",
     "engagement/important_sites_util.h",
+    "engagement/site_engagement_eviction_policy.cc",
+    "engagement/site_engagement_eviction_policy.h",
     "engagement/site_engagement_helper.cc",
     "engagement/site_engagement_helper.h",
     "engagement/site_engagement_metrics.cc",
diff --git a/chrome/browser/browsing_data/browsing_data_quota_helper_unittest.cc b/chrome/browser/browsing_data/browsing_data_quota_helper_unittest.cc
index 2c5781d..e8a97eb3 100644
--- a/chrome/browser/browsing_data/browsing_data_quota_helper_unittest.cc
+++ b/chrome/browser/browsing_data/browsing_data_quota_helper_unittest.cc
@@ -37,8 +37,8 @@
     quota_manager_ = new storage::QuotaManager(
         false, dir_.GetPath(),
         BrowserThread::GetTaskRunnerForThread(BrowserThread::IO).get(),
-        BrowserThread::GetTaskRunnerForThread(BrowserThread::DB).get(), nullptr,
-        storage::GetQuotaSettingsFunc());
+        BrowserThread::GetTaskRunnerForThread(BrowserThread::DB).get(),
+        nullptr);
     helper_ = new BrowsingDataQuotaHelperImpl(quota_manager_.get());
   }
 
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index b9b18e8..e26d7b0 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -47,6 +47,7 @@
 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
 #include "chrome/browser/defaults.h"
 #include "chrome/browser/download/download_prefs.h"
+#include "chrome/browser/engagement/site_engagement_eviction_policy.h"
 #include "chrome/browser/field_trial_recorder.h"
 #include "chrome/browser/font_family_cache.h"
 #include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h"
@@ -405,8 +406,6 @@
 // thread.
 base::LazyInstance<std::string> g_io_thread_application_locale;
 
-const storage::QuotaSettings* g_default_quota_settings;
-
 #if BUILDFLAG(ENABLE_PLUGINS)
 // TODO(teravest): Add renderer-side API-specific checking for these APIs so
 // that blanket permission isn't granted to all dev channel APIs for these.
@@ -2162,20 +2161,12 @@
   return new ChromeQuotaPermissionContext();
 }
 
-void ChromeContentBrowserClient::GetQuotaSettings(
-    content::BrowserContext* context,
-    content::StoragePartition* partition,
-    const storage::OptionalQuotaSettingsCallback& callback) {
-  if (g_default_quota_settings) {
-    // For debugging tests harness can inject settings.
-    callback.Run(*g_default_quota_settings);
-    return;
-  }
-  content::BrowserThread::PostTaskAndReplyWithResult(
-      content::BrowserThread::FILE, FROM_HERE,
-      base::Bind(&storage::CalculateNominalDynamicSettings,
-                 partition->GetPath(), context->IsOffTheRecord()),
-      callback);
+std::unique_ptr<storage::QuotaEvictionPolicy>
+ChromeContentBrowserClient::GetTemporaryStorageEvictionPolicy(
+    content::BrowserContext* context) {
+  return SiteEngagementEvictionPolicy::IsEnabled()
+             ? base::MakeUnique<SiteEngagementEvictionPolicy>(context)
+             : nullptr;
 }
 
 void ChromeContentBrowserClient::AllowCertificateError(
@@ -3384,9 +3375,3 @@
   return variations::GetVariationParamValue(
              "BrowserScheduler", "RedirectNonUINonIOBrowserThreads") == "true";
 }
-
-// static
-void ChromeContentBrowserClient::SetDefaultQuotaSettingsForTesting(
-    const storage::QuotaSettings* settings) {
-  g_default_quota_settings = settings;
-}
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h
index 84551bf..7b6e2066d 100644
--- a/chrome/browser/chrome_content_browser_client.h
+++ b/chrome/browser/chrome_content_browser_client.h
@@ -171,11 +171,8 @@
       const GURL& url,
       content::ResourceContext* context) override;
   content::QuotaPermissionContext* CreateQuotaPermissionContext() override;
-  void GetQuotaSettings(
-      content::BrowserContext* context,
-      content::StoragePartition* partition,
-      const storage::OptionalQuotaSettingsCallback& callback) override;
-
+  std::unique_ptr<storage::QuotaEvictionPolicy>
+  GetTemporaryStorageEvictionPolicy(content::BrowserContext* context) override;
   void AllowCertificateError(
       content::WebContents* web_contents,
       int cert_error,
@@ -330,7 +327,6 @@
 
  private:
   friend class DisableWebRtcEncryptionFlagTest;
-  friend class InProcessBrowserTest;
 
 #if BUILDFLAG(ENABLE_WEBRTC)
   // Copies disable WebRTC encryption switch depending on the channel.
@@ -361,11 +357,6 @@
       const base::Callback<void(bool)>& callback);
 #endif
 
-  // The value pointed to by |settings| should remain valid until the
-  // the function is called again with a new value or a nullptr.
-  static void SetDefaultQuotaSettingsForTesting(
-      const storage::QuotaSettings *settings);
-
 #if BUILDFLAG(ENABLE_PLUGINS)
   // Set of origins that can use TCP/UDP private APIs from NaCl.
   std::set<std::string> allowed_socket_origins_;
diff --git a/chrome/browser/engagement/site_engagement_eviction_policy.cc b/chrome/browser/engagement/site_engagement_eviction_policy.cc
new file mode 100644
index 0000000..7d52f56
--- /dev/null
+++ b/chrome/browser/engagement/site_engagement_eviction_policy.cc
@@ -0,0 +1,144 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/engagement/site_engagement_eviction_policy.h"
+
+#include "base/command_line.h"
+#include "base/metrics/field_trial.h"
+#include "base/strings/string_util.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/engagement/site_engagement_service.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/common/chrome_switches.h"
+#include "content/public/browser/browser_thread.h"
+
+namespace {
+
+const int kExpectedEngagementSites = 200;
+
+// Gets the quota that an origin deserves based on its site engagement.
+int64_t GetSoftQuotaForOrigin(const GURL& origin,
+                              int score,
+                              int total_engagement_points,
+                              int64_t global_quota) {
+  double quota_per_point =
+      global_quota /
+      std::max(kExpectedEngagementSites * SiteEngagementService::GetMaxPoints(),
+               static_cast<double>(total_engagement_points));
+
+  return score * quota_per_point;
+}
+
+GURL DoCalculateEvictionOrigin(
+    const scoped_refptr<storage::SpecialStoragePolicy>& special_storage_policy,
+    SiteEngagementScoreProvider* score_provider,
+    const std::set<GURL>& exceptions,
+    const std::map<GURL, int64_t>& usage_map,
+    int64_t global_quota) {
+  // TODO(calamity): Integrate storage access frequency as an input to this
+  // heuristic.
+
+  // This heuristic is intended to optimize for two criteria:
+  // - evict the site that the user cares about least
+  // - evict the least number of sites to get under the quota limit
+  //
+  // The heuristic for deciding the next eviction origin calculates a soft
+  // quota for each origin which is the amount the origin should be allowed to
+  // use based on its engagement and the global quota. The origin that most
+  // exceeds its soft quota is chosen.
+  GURL origin_to_evict;
+  int64_t max_overuse = std::numeric_limits<int64_t>::min();
+  int total_engagement_points = score_provider->GetTotalEngagementPoints();
+
+  for (const auto& usage : usage_map) {
+    GURL origin = usage.first;
+    if (special_storage_policy &&
+        (special_storage_policy->IsStorageUnlimited(origin) ||
+         special_storage_policy->IsStorageDurable(origin))) {
+      continue;
+    }
+
+    // |overuse| can be negative if the soft quota exceeds the usage.
+    int64_t overuse =
+        usage.second -
+        GetSoftQuotaForOrigin(origin, score_provider->GetScore(origin),
+                              total_engagement_points, global_quota);
+    if (overuse > max_overuse && !base::ContainsKey(exceptions, origin)) {
+      max_overuse = overuse;
+      origin_to_evict = origin;
+    }
+  }
+
+  return origin_to_evict;
+}
+
+GURL GetSiteEngagementEvictionOriginOnUIThread(
+    const scoped_refptr<storage::SpecialStoragePolicy>& special_storage_policy,
+    content::BrowserContext* browser_context,
+    const std::set<GURL>& exceptions,
+    const std::map<GURL, int64_t>& usage_map,
+    int64_t global_quota) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+  Profile* profile = Profile::FromBrowserContext(browser_context);
+  SiteEngagementScoreProvider* score_provider =
+      g_browser_process->profile_manager()->IsValidProfile(profile)
+          ? SiteEngagementService::Get(profile)
+          : nullptr;
+
+  if (!score_provider)
+    return GURL();
+
+  return DoCalculateEvictionOrigin(special_storage_policy, score_provider,
+                                   exceptions, usage_map, global_quota);
+}
+
+}  // namespace
+
+// static
+bool SiteEngagementEvictionPolicy::IsEnabled() {
+  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+      switches::kEnableSiteEngagementEvictionPolicy)) {
+    return true;
+  }
+
+  const std::string group_name = base::FieldTrialList::FindFullName(
+      SiteEngagementService::kEngagementParams);
+  return base::StartsWith(group_name, "StorageEvictionEnabled",
+                          base::CompareCase::SENSITIVE);
+}
+
+SiteEngagementEvictionPolicy::SiteEngagementEvictionPolicy(
+    content::BrowserContext* browser_context)
+    : browser_context_(browser_context) {}
+
+SiteEngagementEvictionPolicy::~SiteEngagementEvictionPolicy() {}
+
+void SiteEngagementEvictionPolicy::GetEvictionOrigin(
+    const scoped_refptr<storage::SpecialStoragePolicy>& special_storage_policy,
+    const std::set<GURL>& exceptions,
+    const std::map<GURL, int64_t>& usage_map,
+    int64_t global_quota,
+    const storage::GetOriginCallback& callback) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+
+  content::BrowserThread::PostTaskAndReplyWithResult(
+      content::BrowserThread::UI, FROM_HERE,
+      base::Bind(&GetSiteEngagementEvictionOriginOnUIThread,
+                 special_storage_policy, browser_context_, exceptions,
+                 usage_map, global_quota),
+      callback);
+}
+
+// static
+GURL SiteEngagementEvictionPolicy::CalculateEvictionOriginForTests(
+    const scoped_refptr<storage::SpecialStoragePolicy>& special_storage_policy,
+    SiteEngagementScoreProvider* score_provider,
+    const std::set<GURL>& exceptions,
+    const std::map<GURL, int64_t>& usage_map,
+    int64_t global_quota) {
+  return DoCalculateEvictionOrigin(special_storage_policy, score_provider,
+                                   exceptions, usage_map, global_quota);
+}
diff --git a/chrome/browser/engagement/site_engagement_eviction_policy.h b/chrome/browser/engagement/site_engagement_eviction_policy.h
new file mode 100644
index 0000000..4266449
--- /dev/null
+++ b/chrome/browser/engagement/site_engagement_eviction_policy.h
@@ -0,0 +1,56 @@
+// 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_ENGAGEMENT_SITE_ENGAGEMENT_EVICTION_POLICY_H_
+#define CHROME_BROWSER_ENGAGEMENT_SITE_ENGAGEMENT_EVICTION_POLICY_H_
+
+#include <stdint.h>
+
+#include <map>
+#include <memory>
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "storage/browser/quota/quota_manager.h"
+#include "url/gurl.h"
+
+namespace content {
+class BrowserContext;
+}
+
+class SiteEngagementScoreProvider;
+
+class SiteEngagementEvictionPolicy : public storage::QuotaEvictionPolicy {
+ public:
+  static bool IsEnabled();
+
+  explicit SiteEngagementEvictionPolicy(
+      content::BrowserContext* browser_context);
+  ~SiteEngagementEvictionPolicy() override;
+
+  // Overridden from storage::QuotaEvictionPolicy:
+  void GetEvictionOrigin(const scoped_refptr<storage::SpecialStoragePolicy>&
+                             special_storage_policy,
+                         const std::set<GURL>& exceptions,
+                         const std::map<GURL, int64_t>& usage_map,
+                         int64_t global_quota,
+                         const storage::GetOriginCallback& callback) override;
+
+ private:
+  friend class SiteEngagementEvictionPolicyTest;
+
+  static GURL CalculateEvictionOriginForTests(
+      const scoped_refptr<storage::SpecialStoragePolicy>&
+          special_storage_policy,
+      SiteEngagementScoreProvider* score_provider,
+      const std::set<GURL>& exceptions,
+      const std::map<GURL, int64_t>& usage_map,
+      int64_t global_quota);
+
+  content::BrowserContext* const browser_context_;
+
+  DISALLOW_COPY_AND_ASSIGN(SiteEngagementEvictionPolicy);
+};
+
+#endif  // CHROME_BROWSER_ENGAGEMENT_SITE_ENGAGEMENT_EVICTION_POLICY_H_
diff --git a/chrome/browser/engagement/site_engagement_eviction_policy_unittest.cc b/chrome/browser/engagement/site_engagement_eviction_policy_unittest.cc
new file mode 100644
index 0000000..edfb8e1e
--- /dev/null
+++ b/chrome/browser/engagement/site_engagement_eviction_policy_unittest.cc
@@ -0,0 +1,173 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/engagement/site_engagement_eviction_policy.h"
+
+#include <stdint.h>
+
+#include <memory>
+
+#include "base/files/scoped_temp_dir.h"
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "base/run_loop.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "chrome/browser/engagement/site_engagement_service.h"
+#include "content/public/test/mock_special_storage_policy.h"
+#include "content/public/test/mock_storage_client.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "storage/browser/quota/quota_manager.h"
+#include "storage/browser/quota/quota_manager_proxy.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+const int64_t kGlobalQuota = 25 * 1024;
+
+}  // namespace
+
+class TestSiteEngagementScoreProvider : public SiteEngagementScoreProvider {
+ public:
+  TestSiteEngagementScoreProvider() {}
+
+  virtual ~TestSiteEngagementScoreProvider() {}
+
+  double GetScore(const GURL& url) const override {
+    const auto& it = engagement_score_map_.find(url);
+    if (it != engagement_score_map_.end())
+      return it->second;
+    return 0.0;
+  }
+
+  double GetTotalEngagementPoints() const override {
+    double total = 0;
+    for (const auto& site : engagement_score_map_)
+      total += site.second;
+    return total;
+  }
+
+  void SetScore(const GURL& origin, double score) {
+    engagement_score_map_[origin] = score;
+  }
+
+ private:
+  std::map<GURL, double> engagement_score_map_;
+
+  DISALLOW_COPY_AND_ASSIGN(TestSiteEngagementScoreProvider);
+};
+
+class SiteEngagementEvictionPolicyTest : public testing::Test {
+ public:
+  SiteEngagementEvictionPolicyTest()
+      : score_provider_(new TestSiteEngagementScoreProvider()),
+        storage_policy_(new content::MockSpecialStoragePolicy()) {}
+
+  ~SiteEngagementEvictionPolicyTest() override {}
+
+  GURL CalculateEvictionOriginWithExceptions(
+      const std::map<GURL, int64_t>& usage,
+      const std::set<GURL>& exceptions) {
+    return SiteEngagementEvictionPolicy::CalculateEvictionOriginForTests(
+        storage_policy_, score_provider_.get(), exceptions, usage,
+        kGlobalQuota);
+  }
+
+  GURL CalculateEvictionOrigin(const std::map<GURL, int64_t>& usage) {
+    return CalculateEvictionOriginWithExceptions(usage, std::set<GURL>());
+  }
+
+  TestSiteEngagementScoreProvider* score_provider() {
+    return score_provider_.get();
+  }
+
+  content::MockSpecialStoragePolicy* storage_policy() {
+    return storage_policy_.get();
+  }
+
+ private:
+  std::unique_ptr<TestSiteEngagementScoreProvider> score_provider_;
+  scoped_refptr<content::MockSpecialStoragePolicy> storage_policy_;
+
+  DISALLOW_COPY_AND_ASSIGN(SiteEngagementEvictionPolicyTest);
+};
+
+TEST_F(SiteEngagementEvictionPolicyTest, GetEvictionOrigin) {
+  GURL url1("http://www.google.com");
+  GURL url2("http://www.example.com");
+  GURL url3("http://www.spam.me");
+
+  std::map<GURL, int64_t> usage;
+  usage[url1] = 10 * 1024;
+  usage[url2] = 10 * 1024;
+  usage[url3] = 10 * 1024;
+
+  score_provider()->SetScore(url1, 50);
+  score_provider()->SetScore(url2, 25);
+
+  // When 3 sites have equal usage, evict the site with the least engagement.
+  EXPECT_EQ(url3, CalculateEvictionOrigin(usage));
+
+  usage[url2] = usage[url3] + 10;
+
+  // Now |url2| has the most usage but |url3| has the least engagement score so
+  // one of them should be evicted. In this case the heuristic chooses |url3|.
+  EXPECT_EQ(url3, CalculateEvictionOrigin(usage));
+
+  // But exceeding allocated usage too much will still result in being evicted
+  // even though the engagement with |url2| is higher.
+  usage[url2] = 15 * 1024;
+  EXPECT_EQ(url2, CalculateEvictionOrigin(usage));
+
+  // When all origins have the same engagement, the origin with the highest
+  // usage is evicted.
+  score_provider()->SetScore(url1, 50);
+  score_provider()->SetScore(url2, 50);
+  score_provider()->SetScore(url3, 50);
+
+  usage[url2] = 10 * 1024;
+  usage[url3] = 20 * 1024;
+  EXPECT_EQ(url3, CalculateEvictionOrigin(usage));
+}
+
+// Test that durable and unlimited storage origins are exempt from eviction.
+TEST_F(SiteEngagementEvictionPolicyTest, SpecialStoragePolicy) {
+  GURL url1("http://www.google.com");
+  GURL url2("http://www.example.com");
+
+  std::map<GURL, int64_t> usage;
+  usage[url1] = 10 * 1024;
+  usage[url2] = 10 * 1024;
+
+  score_provider()->SetScore(url1, 50);
+  score_provider()->SetScore(url2, 25);
+
+  EXPECT_EQ(url2, CalculateEvictionOrigin(usage));
+
+  // Durable storage doesn't get evicted.
+  storage_policy()->AddDurable(url2);
+  EXPECT_EQ(url1, CalculateEvictionOrigin(usage));
+
+  // Unlimited storage doesn't get evicted.
+  storage_policy()->AddUnlimited(url1);
+  EXPECT_EQ(GURL(), CalculateEvictionOrigin(usage));
+}
+
+TEST_F(SiteEngagementEvictionPolicyTest, Exceptions) {
+  GURL url1("http://www.google.com");
+  GURL url2("http://www.example.com");
+
+  std::map<GURL, int64_t> usage;
+  usage[url1] = 10 * 1024;
+  usage[url2] = 10 * 1024;
+
+  score_provider()->SetScore(url1, 50);
+  score_provider()->SetScore(url2, 25);
+
+  EXPECT_EQ(url2, CalculateEvictionOrigin(usage));
+
+  // The policy should respect exceptions.
+  std::set<GURL> exceptions;
+  exceptions.insert(url2);
+  EXPECT_EQ(url1, CalculateEvictionOriginWithExceptions(usage, exceptions));
+}
diff --git a/chrome/browser/engagement/site_engagement_service.cc b/chrome/browser/engagement/site_engagement_service.cc
index 7ebb7b6..9d9c08a1 100644
--- a/chrome/browser/engagement/site_engagement_service.cc
+++ b/chrome/browser/engagement/site_engagement_service.cc
@@ -20,6 +20,7 @@
 #include "base/values.h"
 #include "chrome/browser/banners/app_banner_settings_helper.h"
 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
+#include "chrome/browser/engagement/site_engagement_eviction_policy.h"
 #include "chrome/browser/engagement/site_engagement_helper.h"
 #include "chrome/browser/engagement/site_engagement_metrics.h"
 #include "chrome/browser/engagement/site_engagement_score.h"
diff --git a/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc b/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc
index ab6d4a2a..a8a9eca7 100644
--- a/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc
+++ b/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc
@@ -17,8 +17,8 @@
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
 #include "base/message_loop/message_loop.h"
-#include "base/run_loop.h"
 #include "base/strings/stringprintf.h"
+#include "base/synchronization/waitable_event.h"
 #include "build/build_config.h"
 #include "chrome/browser/download/download_file_icon_extractor.h"
 #include "chrome/browser/download/download_service.h"
@@ -703,25 +703,29 @@
     }
     // Invoke the fileapi to copy it into the sandboxed filesystem.
     bool result = false;
-    base::RunLoop run_loop;
+    base::WaitableEvent done_event(
+        base::WaitableEvent::ResetPolicy::MANUAL,
+        base::WaitableEvent::InitialState::NOT_SIGNALED);
     BrowserThread::PostTask(
         BrowserThread::IO, FROM_HERE,
-        base::Bind(&CreateFileForTestingOnIOThread, base::Unretained(context),
-                   path, temp_file, base::Unretained(&result),
-                   run_loop.QuitClosure()));
+        base::Bind(&CreateFileForTestingOnIOThread,
+                   base::Unretained(context),
+                   path, temp_file,
+                   base::Unretained(&result),
+                   base::Unretained(&done_event)));
     // Wait for that to finish.
-    run_loop.Run();
+    done_event.Wait();
     base::DeleteFile(temp_file, false);
     return result;
   }
 
  private:
   static void CopyInCompletion(bool* result,
-                               const base::Closure& quit_closure,
+                               base::WaitableEvent* done_event,
                                base::File::Error error) {
     DCHECK_CURRENTLY_ON(BrowserThread::IO);
     *result = error == base::File::FILE_OK;
-    BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, quit_closure);
+    done_event->Signal();
   }
 
   static void CreateFileForTestingOnIOThread(
@@ -729,11 +733,13 @@
       const storage::FileSystemURL& path,
       const base::FilePath& temp_file,
       bool* result,
-      const base::Closure& quit_closure) {
+      base::WaitableEvent* done_event) {
     DCHECK_CURRENTLY_ON(BrowserThread::IO);
     context->operation_runner()->CopyInForeignFile(
         temp_file, path,
-        base::Bind(&CopyInCompletion, base::Unretained(result), quit_closure));
+        base::Bind(&CopyInCompletion,
+                   base::Unretained(result),
+                   base::Unretained(done_event)));
   }
 };
 
diff --git a/chrome/browser/extensions/api/sync_file_system/sync_file_system_apitest.cc b/chrome/browser/extensions/api/sync_file_system/sync_file_system_apitest.cc
index 18b1bf3..1ee2199 100644
--- a/chrome/browser/extensions/api/sync_file_system/sync_file_system_apitest.cc
+++ b/chrome/browser/extensions/api/sync_file_system/sync_file_system_apitest.cc
@@ -18,7 +18,6 @@
 #include "chrome/browser/sync_file_system/sync_status_code.h"
 #include "chrome/browser/sync_file_system/syncable_file_system_util.h"
 #include "chrome/test/base/test_switches.h"
-#include "content/public/browser/storage_partition.h"
 #include "extensions/browser/extension_function.h"
 #include "storage/browser/fileapi/file_system_url.h"
 #include "storage/browser/quota/quota_manager.h"
@@ -41,11 +40,16 @@
  public:
   SyncFileSystemApiTest()
       : mock_remote_service_(NULL),
+        real_minimum_preserved_space_(0),
         real_default_quota_(0) {}
 
   void SetUpInProcessBrowserTestFixture() override {
     ExtensionApiTest::SetUpInProcessBrowserTestFixture();
 
+    real_minimum_preserved_space_ =
+        storage::QuotaManager::kMinimumPreserveForSystem;
+    storage::QuotaManager::kMinimumPreserveForSystem = 0;
+
     // TODO(calvinlo): Update test code after default quota is made const
     // (http://crbug.com/155488).
     real_default_quota_ =
@@ -54,6 +58,8 @@
   }
 
   void TearDownInProcessBrowserTestFixture() override {
+    storage::QuotaManager::kMinimumPreserveForSystem =
+        real_minimum_preserved_space_;
     storage::QuotaManager::kSyncableStorageDefaultHostQuota =
         real_default_quota_;
     ExtensionApiTest::TearDownInProcessBrowserTestFixture();
@@ -75,6 +81,7 @@
 
  private:
   ::testing::NiceMock<MockRemoteFileSyncService>* mock_remote_service_;
+  int64_t real_minimum_preserved_space_;
   int64_t real_default_quota_;
 };
 
diff --git a/chrome/browser/extensions/api/sync_file_system/sync_file_system_browsertest.cc b/chrome/browser/extensions/api/sync_file_system/sync_file_system_browsertest.cc
index 0e13258..549b4aaa 100644
--- a/chrome/browser/extensions/api/sync_file_system/sync_file_system_browsertest.cc
+++ b/chrome/browser/extensions/api/sync_file_system/sync_file_system_browsertest.cc
@@ -18,7 +18,6 @@
 #include "chrome/browser/sync_file_system/sync_file_system_service.h"
 #include "chrome/browser/sync_file_system/sync_file_system_service_factory.h"
 #include "components/drive/service/fake_drive_service.h"
-#include "content/public/browser/storage_partition.h"
 #include "extensions/test/extension_test_message_listener.h"
 #include "extensions/test/result_catcher.h"
 #include "storage/browser/quota/quota_manager.h"
@@ -62,6 +61,19 @@
       : remote_service_(NULL) {
   }
 
+  void SetUpInProcessBrowserTestFixture() override {
+    ExtensionApiTest::SetUpInProcessBrowserTestFixture();
+    real_minimum_preserved_space_ =
+        storage::QuotaManager::kMinimumPreserveForSystem;
+    storage::QuotaManager::kMinimumPreserveForSystem = 0;
+  }
+
+  void TearDownInProcessBrowserTestFixture() override {
+    storage::QuotaManager::kMinimumPreserveForSystem =
+        real_minimum_preserved_space_;
+    ExtensionApiTest::TearDownInProcessBrowserTestFixture();
+  }
+
   scoped_refptr<base::SequencedTaskRunner> MakeSequencedTaskRunner() {
     scoped_refptr<base::SequencedWorkerPool> worker_pool =
         content::BrowserThread::GetBlockingPool();
@@ -145,6 +157,8 @@
 
   drive_backend::SyncEngine* remote_service_;
 
+  int64_t real_minimum_preserved_space_;
+
   DISALLOW_COPY_AND_ASSIGN(SyncFileSystemTest);
 };
 
diff --git a/chrome/browser/extensions/extension_special_storage_policy.cc b/chrome/browser/extensions/extension_special_storage_policy.cc
index 331c9a3..2abb046 100644
--- a/chrome/browser/extensions/extension_special_storage_policy.cc
+++ b/chrome/browser/extensions/extension_special_storage_policy.cc
@@ -114,6 +114,11 @@
   return cookie_settings_->IsCookieSessionOnly(origin);
 }
 
+bool ExtensionSpecialStoragePolicy::CanQueryDiskSize(const GURL& origin) {
+  base::AutoLock locker(lock_);
+  return installed_apps_.Contains(origin);
+}
+
 bool ExtensionSpecialStoragePolicy::HasSessionOnlyOrigins() {
   if (cookie_settings_.get() == NULL)
     return false;
@@ -172,6 +177,9 @@
       extension->is_app()) {
     if (NeedsProtection(extension) && protected_apps_.Add(extension))
       change_flags |= SpecialStoragePolicy::STORAGE_PROTECTED;
+    // FIXME: Does GrantRightsForExtension imply |extension| is installed?
+    if (extension->is_app())
+      installed_apps_.Add(extension);
 
     if (extension->permissions_data()->HasAPIPermission(
             APIPermission::kUnlimitedStorage) &&
@@ -217,6 +225,9 @@
     if (NeedsProtection(extension) && protected_apps_.Remove(extension))
       change_flags |= SpecialStoragePolicy::STORAGE_PROTECTED;
 
+    if (extension->is_app())
+      installed_apps_.Remove(extension);
+
     if (extension->permissions_data()->HasAPIPermission(
             APIPermission::kUnlimitedStorage) &&
         unlimited_extensions_.Remove(extension))
@@ -240,6 +251,7 @@
   {
     base::AutoLock locker(lock_);
     protected_apps_.Clear();
+    installed_apps_.Clear();
     unlimited_extensions_.Clear();
     file_handler_extensions_.Clear();
     isolated_extensions_.Clear();
diff --git a/chrome/browser/extensions/extension_special_storage_policy.h b/chrome/browser/extensions/extension_special_storage_policy.h
index cce5b043..5f4ffbb 100644
--- a/chrome/browser/extensions/extension_special_storage_policy.h
+++ b/chrome/browser/extensions/extension_special_storage_policy.h
@@ -39,6 +39,7 @@
   bool IsStorageProtected(const GURL& origin) override;
   bool IsStorageUnlimited(const GURL& origin) override;
   bool IsStorageSessionOnly(const GURL& origin) override;
+  bool CanQueryDiskSize(const GURL& origin) override;
   bool HasIsolatedStorage(const GURL& origin) override;
   bool HasSessionOnlyOrigins() override;
   bool IsStorageDurable(const GURL& origin) override;
@@ -87,6 +88,7 @@
 
   base::Lock lock_;  // Synchronize all access to the collections.
   SpecialCollection protected_apps_;
+  SpecialCollection installed_apps_;
   SpecialCollection unlimited_extensions_;
   SpecialCollection file_handler_extensions_;
   SpecialCollection isolated_extensions_;
diff --git a/chrome/browser/extensions/extension_special_storage_policy_unittest.cc b/chrome/browser/extensions/extension_special_storage_policy_unittest.cc
index 1916e30..b25b31f 100644
--- a/chrome/browser/extensions/extension_special_storage_policy_unittest.cc
+++ b/chrome/browser/extensions/extension_special_storage_policy_unittest.cc
@@ -251,6 +251,23 @@
   EXPECT_FALSE(policy_->IsStorageUnlimited(GURL("https://bar.wildcards/")));
 }
 
+TEST_F(ExtensionSpecialStoragePolicyTest, CanQueryDiskSize) {
+  const GURL kHttpUrl("http://foo");
+  const GURL kExtensionUrl("chrome-extension://bar");
+  scoped_refptr<Extension> regular_app(CreateRegularApp());
+  scoped_refptr<Extension> protected_app(CreateProtectedApp());
+  scoped_refptr<Extension> unlimited_app(CreateUnlimitedApp());
+  policy_->GrantRightsForExtension(regular_app.get(), NULL);
+  policy_->GrantRightsForExtension(protected_app.get(), NULL);
+  policy_->GrantRightsForExtension(unlimited_app.get(), NULL);
+
+  EXPECT_FALSE(policy_->CanQueryDiskSize(kHttpUrl));
+  EXPECT_FALSE(policy_->CanQueryDiskSize(kExtensionUrl));
+  EXPECT_TRUE(policy_->CanQueryDiskSize(regular_app->url()));
+  EXPECT_TRUE(policy_->CanQueryDiskSize(protected_app->url()));
+  EXPECT_TRUE(policy_->CanQueryDiskSize(unlimited_app->url()));
+}
+
 TEST_F(ExtensionSpecialStoragePolicyTest, HasIsolatedStorage) {
   const GURL kHttpUrl("http://foo");
   const GURL kExtensionUrl("chrome-extension://bar");
diff --git a/chrome/browser/extensions/extension_storage_monitor.cc b/chrome/browser/extensions/extension_storage_monitor.cc
index 81394f5..7294fbd4 100644
--- a/chrome/browser/extensions/extension_storage_monitor.cc
+++ b/chrome/browser/extensions/extension_storage_monitor.cc
@@ -84,16 +84,17 @@
       extension_id, ExtensionRegistry::EVERYTHING);
 }
 
-void LogTemporaryStorageUsage(
-    scoped_refptr<storage::QuotaManager> quota_manager,
-    int64_t usage) {
-  const storage::QuotaSettings& settings = quota_manager->settings();
-  if (settings.per_host_quota > 0) {
+void LogTemporaryStorageUsage(int64_t usage,
+                              storage::QuotaStatusCode status,
+                              int64_t global_quota) {
+  if (status == storage::kQuotaStatusOk) {
+    int64_t per_app_quota =
+        global_quota / storage::QuotaManager::kPerHostTemporaryPortion;
     // Note we use COUNTS_100 (instead of PERCENT) because this can potentially
     // exceed 100%.
     UMA_HISTOGRAM_COUNTS_100(
         "Extensions.HostedAppUnlimitedStorageTemporaryStorageUsage",
-        100.0 * usage / settings.per_host_quota);
+        100.0 * usage / per_app_quota);
   }
 }
 
@@ -234,9 +235,12 @@
       } else {
         // We can't use the quota in the event because it assumes unlimited
         // storage.
-        BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
-                                base::Bind(&LogTemporaryStorageUsage,
-                                           state.quota_manager, event.usage));
+        BrowserThread::PostTask(
+            BrowserThread::IO,
+            FROM_HERE,
+            base::Bind(&storage::QuotaManager::GetTemporaryGlobalQuota,
+                       state.quota_manager,
+                       base::Bind(&LogTemporaryStorageUsage, event.usage)));
       }
     }
 
diff --git a/chrome/browser/extensions/mock_extension_special_storage_policy.cc b/chrome/browser/extensions/mock_extension_special_storage_policy.cc
index ca32e2d..d4d609b 100644
--- a/chrome/browser/extensions/mock_extension_special_storage_policy.cc
+++ b/chrome/browser/extensions/mock_extension_special_storage_policy.cc
@@ -20,6 +20,10 @@
   return false;
 }
 
+bool MockExtensionSpecialStoragePolicy::CanQueryDiskSize(const GURL& origin) {
+  return false;
+}
+
 bool MockExtensionSpecialStoragePolicy::HasSessionOnlyOrigins() {
   return false;
 }
diff --git a/chrome/browser/extensions/mock_extension_special_storage_policy.h b/chrome/browser/extensions/mock_extension_special_storage_policy.h
index f25676de..edc142e7 100644
--- a/chrome/browser/extensions/mock_extension_special_storage_policy.h
+++ b/chrome/browser/extensions/mock_extension_special_storage_policy.h
@@ -23,6 +23,7 @@
   bool IsStorageProtected(const GURL& origin) override;
   bool IsStorageUnlimited(const GURL& origin) override;
   bool IsStorageSessionOnly(const GURL& origin) override;
+  bool CanQueryDiskSize(const GURL& origin) override;
   bool HasSessionOnlyOrigins() override;
 
   void AddProtected(const GURL& origin) {
diff --git a/chrome/browser/importer/external_process_importer_client.cc b/chrome/browser/importer/external_process_importer_client.cc
index 469ce144..a0e8106b 100644
--- a/chrome/browser/importer/external_process_importer_client.cc
+++ b/chrome/browser/importer/external_process_importer_client.cc
@@ -44,8 +44,7 @@
 void ExternalProcessImporterClient::Start() {
   AddRef();  // balanced in Cleanup.
 
-  chrome::mojom::ProfileImportRequest request =
-      mojo::MakeRequest(&profile_import_);
+  chrome::mojom::ProfileImportRequest request(&profile_import_);
 
   BrowserThread::ID thread_id;
   CHECK(BrowserThread::GetCurrentThreadIdentifier(&thread_id));
diff --git a/chrome/browser/sync_file_system/local/canned_syncable_file_system.cc b/chrome/browser/sync_file_system/local/canned_syncable_file_system.cc
index cbac4c7..73d9b608 100644
--- a/chrome/browser/sync_file_system/local/canned_syncable_file_system.cc
+++ b/chrome/browser/sync_file_system/local/canned_syncable_file_system.cc
@@ -242,8 +242,7 @@
   if (quota_mode == QUOTA_ENABLED) {
     quota_manager_ = new QuotaManager(
         false /* is_incognito */, data_dir_.GetPath(), io_task_runner_.get(),
-        base::ThreadTaskRunnerHandle::Get().get(), storage_policy.get(),
-        storage::GetQuotaSettingsFunc());
+        base::ThreadTaskRunnerHandle::Get().get(), storage_policy.get());
   }
 
   std::vector<std::string> additional_allowed_schemes;
diff --git a/chrome/browser/task_manager/providers/child_process_task.cc b/chrome/browser/task_manager/providers/child_process_task.cc
index b4ed48f..e5f7fa1 100644
--- a/chrome/browser/task_manager/providers/child_process_task.cc
+++ b/chrome/browser/task_manager/providers/child_process_task.cc
@@ -136,8 +136,7 @@
 ProcessResourceUsage* CreateProcessResourcesSampler(
     int unique_child_process_id) {
   chrome::mojom::ResourceUsageReporterPtr usage_reporter;
-  chrome::mojom::ResourceUsageReporterRequest request =
-      mojo::MakeRequest(&usage_reporter);
+  chrome::mojom::ResourceUsageReporterRequest request(&usage_reporter);
   content::BrowserThread::PostTask(
       content::BrowserThread::IO,
       FROM_HERE,
diff --git a/chrome/browser/ui/webui/quota_internals/quota_internals_proxy.cc b/chrome/browser/ui/webui/quota_internals/quota_internals_proxy.cc
index 2e88070b..11decea0 100644
--- a/chrome/browser/ui/webui/quota_internals/quota_internals_proxy.cc
+++ b/chrome/browser/ui/webui/quota_internals/quota_internals_proxy.cc
@@ -32,12 +32,19 @@
     return;
   }
   quota_manager_ = quota_manager;
+  {
+    // crbug.com/349708
+    TRACE_EVENT0("io", "QuotaInternalsProxy::RequestInfo");
 
-  quota_manager_->GetQuotaSettings(base::Bind(
-      &QuotaInternalsProxy::DidGetSettings, weak_factory_.GetWeakPtr()));
+    quota_manager_->GetAvailableSpace(
+        base::Bind(&QuotaInternalsProxy::DidGetAvailableSpace,
+                   weak_factory_.GetWeakPtr()));
+  }
 
-  quota_manager_->GetStorageCapacity(base::Bind(
-      &QuotaInternalsProxy::DidGetCapacity, weak_factory_.GetWeakPtr()));
+  quota_manager_->GetTemporaryGlobalQuota(
+      base::Bind(&QuotaInternalsProxy::DidGetGlobalQuota,
+                 weak_factory_.GetWeakPtr(),
+                 storage::kStorageTypeTemporary));
 
   quota_manager_->GetGlobalUsage(
       storage::kStorageTypeTemporary,
@@ -94,18 +101,23 @@
 
 #undef RELAY_TO_HANDLER
 
-void QuotaInternalsProxy::DidGetSettings(
-    const storage::QuotaSettings& settings) {
-  // TODO(michaeln): also report the other config fields
-  GlobalStorageInfo info(storage::kStorageTypeTemporary);
-  info.set_quota(settings.pool_size);
-  ReportGlobalInfo(info);
+void QuotaInternalsProxy::DidGetAvailableSpace(storage::QuotaStatusCode status,
+                                               int64_t space) {
+  // crbug.com/349708
+  TRACE_EVENT0("io", "QuotaInternalsProxy::DidGetAvailableSpace");
+
+  if (status == storage::kQuotaStatusOk)
+    ReportAvailableSpace(space);
 }
 
-void QuotaInternalsProxy::DidGetCapacity(int64_t total_space,
-                                         int64_t available_space) {
-  // TODO(michaeln): also report total_space
-  ReportAvailableSpace(available_space);
+void QuotaInternalsProxy::DidGetGlobalQuota(storage::StorageType type,
+                                            storage::QuotaStatusCode status,
+                                            int64_t quota) {
+  if (status == storage::kQuotaStatusOk) {
+    GlobalStorageInfo info(type);
+    info.set_quota(quota);
+    ReportGlobalInfo(info);
+  }
 }
 
 void QuotaInternalsProxy::DidGetGlobalUsage(storage::StorageType type,
diff --git a/chrome/browser/ui/webui/quota_internals/quota_internals_proxy.h b/chrome/browser/ui/webui/quota_internals/quota_internals_proxy.h
index c8e750f..b3e3d661 100644
--- a/chrome/browser/ui/webui/quota_internals/quota_internals_proxy.h
+++ b/chrome/browser/ui/webui/quota_internals/quota_internals_proxy.h
@@ -58,8 +58,10 @@
   void ReportStatistics(const Statistics& stats);
 
   // Called on IO Thread by QuotaManager as callback.
-  void DidGetSettings(const storage::QuotaSettings& settings);
-  void DidGetCapacity(int64_t total_space, int64_t available_space);
+  void DidGetAvailableSpace(storage::QuotaStatusCode status, int64_t space);
+  void DidGetGlobalQuota(storage::StorageType type,
+                         storage::QuotaStatusCode status,
+                         int64_t quota);
   void DidGetGlobalUsage(storage::StorageType type,
                          int64_t usage,
                          int64_t unlimited_usage);
diff --git a/chrome/gpu/gpu_arc_video_service.cc b/chrome/gpu/gpu_arc_video_service.cc
index 822566f..6bd5fd5 100644
--- a/chrome/gpu/gpu_arc_video_service.cc
+++ b/chrome/gpu/gpu_arc_video_service.cc
@@ -136,8 +136,7 @@
   service->client_.set_connection_error_handler(base::Bind(&OnConnectionError));
 
   ::arc::mojom::VideoAcceleratorServicePtr service_proxy;
-  ::arc::mojom::VideoAcceleratorServiceRequest request =
-      mojo::MakeRequest(&service_proxy);
+  ::arc::mojom::VideoAcceleratorServiceRequest request(&service_proxy);
   service->client_->DeprecatedInit(std::move(service_proxy));
 
   auto binding = mojo::MakeStrongBinding(std::move(service),
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 9cd89792..5da09985 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -3120,6 +3120,7 @@
     "../browser/download/download_target_determiner_unittest.cc",
     "../browser/download/download_ui_controller_unittest.cc",
     "../browser/engagement/important_sites_util_unittest.cc",
+    "../browser/engagement/site_engagement_eviction_policy_unittest.cc",
     "../browser/engagement/site_engagement_helper_unittest.cc",
     "../browser/engagement/site_engagement_score_unittest.cc",
     "../browser/engagement/site_engagement_service_unittest.cc",
diff --git a/chrome/test/DEPS b/chrome/test/DEPS
index c65a276..a975b8f 100644
--- a/chrome/test/DEPS
+++ b/chrome/test/DEPS
@@ -13,8 +13,6 @@
   "+mojo",
   "+rlz/features",
   "+services",
-  "+storage/browser",
-  "+storage/common",
 
   # Tests under chrome/ shouldn't need to access the internals of content/ and
   # as such are allowed only content/public. If you find yourself wanting to
diff --git a/chrome/test/base/in_process_browser_test.cc b/chrome/test/base/in_process_browser_test.cc
index 48ac9eea..2f8ecb4 100644
--- a/chrome/test/base/in_process_browser_test.cc
+++ b/chrome/test/base/in_process_browser_test.cc
@@ -22,7 +22,6 @@
 #include "build/build_config.h"
 #include "chrome/browser/after_startup_task_utils.h"
 #include "chrome/browser/browser_process.h"
-#include "chrome/browser/chrome_content_browser_client.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/devtools/devtools_window.h"
 #include "chrome/browser/lifetime/application_lifetime.h"
@@ -249,12 +248,6 @@
 
   google_util::SetMockLinkDoctorBaseURLForTesting();
 
-  // Use hardcoded quota settings to have a consistent testing environment.
-  const int kQuota = 5 * 1024 * 1024;
-  quota_settings_ = storage::QuotaSettings(kQuota * 5, kQuota, 0);
-  ChromeContentBrowserClient::SetDefaultQuotaSettingsForTesting(
-      &quota_settings_);
-
   BrowserTestBase::SetUp();
 }
 
@@ -364,7 +357,6 @@
 #endif
   BrowserTestBase::TearDown();
   OSCryptMocker::TearDown();
-  ChromeContentBrowserClient::SetDefaultQuotaSettingsForTesting(nullptr);
 }
 
 void InProcessBrowserTest::CloseBrowserSynchronously(Browser* browser) {
diff --git a/chrome/test/base/in_process_browser_test.h b/chrome/test/base/in_process_browser_test.h
index 5dd5428..c66260e 100644
--- a/chrome/test/base/in_process_browser_test.h
+++ b/chrome/test/base/in_process_browser_test.h
@@ -14,7 +14,6 @@
 #include "content/public/browser/web_contents.h"
 #include "content/public/test/browser_test.h"
 #include "content/public/test/browser_test_base.h"
-#include "storage/browser/quota/quota_settings.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/base/page_transition_types.h"
 
@@ -261,9 +260,6 @@
   // This is reset for every test case.
   bool run_accessibility_checks_for_test_case_;
 
-  // We use hardcoded quota settings to have a consistent testing environment.
-  storage::QuotaSettings quota_settings_;
-
 #if defined(OS_MACOSX)
   base::mac::ScopedNSAutoreleasePool* autorelease_pool_;
   std::unique_ptr<ScopedBundleSwizzlerMac> bundle_swizzler_;
diff --git a/chromecast/browser/cast_content_browser_client.cc b/chromecast/browser/cast_content_browser_client.cc
index 071298b5..7d9e4a3 100644
--- a/chromecast/browser/cast_content_browser_client.cc
+++ b/chromecast/browser/cast_content_browser_client.cc
@@ -47,7 +47,6 @@
 #include "content/public/browser/client_certificate_delegate.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/resource_dispatcher_host.h"
-#include "content/public/browser/storage_partition.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/content_descriptors.h"
 #include "content/public/common/content_switches.h"
@@ -323,16 +322,6 @@
   return new CastQuotaPermissionContext();
 }
 
-void CastContentBrowserClient::GetQuotaSettings(
-    content::BrowserContext* context,
-    content::StoragePartition* partition,
-    const storage::OptionalQuotaSettingsCallback& callback) {
-  content::BrowserThread::PostTaskAndReplyWithResult(
-      content::BrowserThread::FILE, FROM_HERE,
-      base::Bind(&storage::CalculateNominalDynamicSettings,
-                 partition->GetPath(), context->IsOffTheRecord()),
-      callback);
-}
 void CastContentBrowserClient::AllowCertificateError(
     content::WebContents* web_contents,
     int cert_error,
diff --git a/chromecast/browser/cast_content_browser_client.h b/chromecast/browser/cast_content_browser_client.h
index cc07dcb..0ed31c1 100644
--- a/chromecast/browser/cast_content_browser_client.h
+++ b/chromecast/browser/cast_content_browser_client.h
@@ -117,10 +117,6 @@
   void ResourceDispatcherHostCreated() override;
   std::string GetApplicationLocale() override;
   content::QuotaPermissionContext* CreateQuotaPermissionContext() override;
-  void GetQuotaSettings(
-      content::BrowserContext* context,
-      content::StoragePartition* partition,
-      const storage::OptionalQuotaSettingsCallback& callback) override;
   void AllowCertificateError(
       content::WebContents* web_contents,
       int cert_error,
diff --git a/components/exo/surface.cc b/components/exo/surface.cc
index 0f32435..6c81151 100644
--- a/components/exo/surface.cc
+++ b/components/exo/surface.cc
@@ -179,8 +179,8 @@
                          ->context_factory_private()
                          ->AllocateFrameSinkId()) {
   cc::mojom::MojoCompositorFrameSinkClientPtr frame_sink_holder_ptr;
-  cc::mojom::MojoCompositorFrameSinkClientRequest frame_sink_client_request =
-      mojo::MakeRequest(&frame_sink_holder_ptr);
+  cc::mojom::MojoCompositorFrameSinkClientRequest frame_sink_client_request(
+      &frame_sink_holder_ptr);
   std::unique_ptr<CompositorFrameSink> frame_sink(new CompositorFrameSink(
       frame_sink_id_,
       aura::Env::GetInstance()->context_factory_private()->GetSurfaceManager(),
diff --git a/components/leveldb/leveldb_mojo_proxy.cc b/components/leveldb/leveldb_mojo_proxy.cc
index 1e51f106..74446206 100644
--- a/components/leveldb/leveldb_mojo_proxy.cc
+++ b/components/leveldb/leveldb_mojo_proxy.cc
@@ -226,7 +226,7 @@
     std::vector<std::string>* out_contents,
     filesystem::mojom::FileError* out_error) {
   filesystem::mojom::DirectoryPtr target;
-  filesystem::mojom::DirectoryRequest proxy = MakeRequest(&target);
+  filesystem::mojom::DirectoryRequest proxy(&target);
   bool completed = dir->directory->OpenDirectory(
       name, std::move(proxy),
       filesystem::mojom::kFlagRead | filesystem::mojom::kFlagWrite, out_error);
@@ -292,7 +292,7 @@
   // Since a lock is associated with a file descriptor, we need to open and
   // have a persistent file on the other side of the connection.
   filesystem::mojom::FilePtr target;
-  filesystem::mojom::FileRequest proxy = MakeRequest(&target);
+  filesystem::mojom::FileRequest proxy(&target);
   bool completed = dir->directory->OpenFile(path, std::move(proxy),
                                             filesystem::mojom::kFlagOpenAlways |
                                                 filesystem::mojom::kFlagRead |
diff --git a/components/ntp_snippets/offline_pages/recent_tab_suggestions_provider.cc b/components/ntp_snippets/offline_pages/recent_tab_suggestions_provider.cc
index 6d689db..7ff4cc7 100644
--- a/components/ntp_snippets/offline_pages/recent_tab_suggestions_provider.cc
+++ b/components/ntp_snippets/offline_pages/recent_tab_suggestions_provider.cc
@@ -69,6 +69,12 @@
   return builder.Build(model->GetPolicyController());
 }
 
+bool IsRecentTab(offline_pages::ClientPolicyController* policy_controller,
+                 const OfflinePageItem& offline_page) {
+  return policy_controller->IsShownAsRecentlyVisitedSite(
+      offline_page.client_id.name_space);
+}
+
 }  // namespace
 
 RecentTabSuggestionsProvider::RecentTabSuggestionsProvider(
@@ -212,7 +218,9 @@
     offline_pages::OfflinePageModel* model,
     const offline_pages::OfflinePageItem& added_page) {
   DCHECK_EQ(offline_page_model_, model);
-  FetchRecentTabs();
+  if (IsRecentTab(model->GetPolicyController(), added_page)) {
+    FetchRecentTabs();
+  }
 }
 
 void RecentTabSuggestionsProvider::
diff --git a/components/ntp_snippets/offline_pages/recent_tab_suggestions_provider_unittest.cc b/components/ntp_snippets/offline_pages/recent_tab_suggestions_provider_unittest.cc
index ee2e20c..862b24b 100644
--- a/components/ntp_snippets/offline_pages/recent_tab_suggestions_provider_unittest.cc
+++ b/components/ntp_snippets/offline_pages/recent_tab_suggestions_provider_unittest.cc
@@ -182,11 +182,14 @@
                    .has_view_all_action());
 }
 
+// TODO(vitaliii): Break this test into multiple tests. Currently if it fails,
+// it takes long time to find which part of it actually fails.
 TEST_F(RecentTabSuggestionsProviderTest, ShouldDismiss) {
-  EXPECT_CALL(*observer(), OnNewSuggestions(_, _, _)).Times(4);
-  auto recent_tabs_list = CreateDummyRecentTabs({1, 2, 3, 4});
-  for (OfflinePageItem& recent_tab : recent_tabs_list)
+  EXPECT_CALL(*observer(), OnNewSuggestions(_, _, _)).Times(3);
+  auto recent_tabs_list = CreateDummyRecentTabs({1, 2, 3});
+  for (OfflinePageItem& recent_tab : recent_tabs_list) {
     AddOfflinePageToModel(recent_tab);
+  }
 
   // Dismiss 2 and 3.
   EXPECT_CALL(*observer(), OnNewSuggestions(_, _, _)).Times(0);
@@ -197,15 +200,13 @@
   // They should disappear from the reported suggestions.
   EXPECT_CALL(
       *observer(),
-      OnNewSuggestions(_, recent_tabs_category(),
-                       UnorderedElementsAre(
-                           Property(&ContentSuggestion::url,
-                                    GURL("http://dummy.com/1")),
-                           Property(&ContentSuggestion::url,
-                                    GURL("http://dummy.com/4")))));
+      OnNewSuggestions(
+          _, recent_tabs_category(),
+          UnorderedElementsAre(
+              Property(&ContentSuggestion::url, GURL("http://dummy.com/1")),
+              Property(&ContentSuggestion::url, GURL("http://dummy.com/4")))));
 
-  AddOfflinePageToModel(ntp_snippets::test::CreateDummyOfflinePageItem(
-      4, offline_pages::kDefaultNamespace));
+  AddOfflinePageToModel(CreateDummyRecentTab(4));
   Mock::VerifyAndClearExpectations(observer());
 
   // And appear in the dismissed suggestions.
@@ -232,9 +233,8 @@
 
   // And appear in the reported suggestions for the category again.
   EXPECT_CALL(*observer(),
-              OnNewSuggestions(_, recent_tabs_category(), SizeIs(4)));
-  AddOfflinePageToModel(ntp_snippets::test::CreateDummyOfflinePageItem(
-      5, offline_pages::kDefaultNamespace));
+              OnNewSuggestions(_, recent_tabs_category(), SizeIs(5)));
+  AddOfflinePageToModel(CreateDummyRecentTab(5));
   Mock::VerifyAndClearExpectations(observer());
 }
 
@@ -306,4 +306,31 @@
   AddOfflinePageToModel(offline_pages[2]);
 }
 
+TEST_F(RecentTabSuggestionsProviderTest,
+       ShouldNotFetchIfAddedOfflinePageIsNotRecentTab) {
+  // The provider is not notified about the first recent tab yet.
+  model()->mutable_items()->push_back(CreateDummyRecentTab(1));
+  // It should not fetch when not a recent tab is added, thus, it should not
+  // report the first recent tab (which it is not aware about).
+  EXPECT_CALL(*observer(), OnNewSuggestions(_, _, _)).Times(0);
+  AddOfflinePageToModel(ntp_snippets::test::CreateDummyOfflinePageItem(
+      2, offline_pages::kDefaultNamespace));
+}
+
+TEST_F(RecentTabSuggestionsProviderTest,
+       ShouldFetchIfAddedOfflinePageIsRecentTab) {
+  // The provider is not notified about the first recent tab yet.
+  model()->mutable_items()->push_back(CreateDummyRecentTab(1));
+  // However, it must return the first recent tab (i.e. manually fetch it) even
+  // when notified about a different recent tab.
+  EXPECT_CALL(
+      *observer(),
+      OnNewSuggestions(
+          _, recent_tabs_category(),
+          UnorderedElementsAre(
+              Property(&ContentSuggestion::url, GURL("http://dummy.com/1")),
+              Property(&ContentSuggestion::url, GURL("http://dummy.com/2")))));
+  AddOfflinePageToModel(CreateDummyRecentTab(2));
+}
+
 }  // namespace ntp_snippets
diff --git a/components/password_manager/content/browser/content_password_manager_driver.cc b/components/password_manager/content/browser/content_password_manager_driver.cc
index 61e35ebf..779bfb7 100644
--- a/components/password_manager/content/browser/content_password_manager_driver.cc
+++ b/components/password_manager/content/browser/content_password_manager_driver.cc
@@ -308,8 +308,8 @@
 const autofill::mojom::PasswordAutofillAgentPtr&
 ContentPasswordManagerDriver::GetPasswordAutofillAgent() {
   if (!password_autofill_agent_) {
-    autofill::mojom::PasswordAutofillAgentRequest request =
-        mojo::MakeRequest(&password_autofill_agent_);
+    autofill::mojom::PasswordAutofillAgentRequest request(
+        &password_autofill_agent_);
     // Some test codes may have no initialized remote interfaces.
     if (render_frame_host_->GetRemoteInterfaces()) {
       render_frame_host_->GetRemoteInterfaces()->GetInterface(
diff --git a/components/password_manager/content/browser/credential_manager_impl.cc b/components/password_manager/content/browser/credential_manager_impl.cc
index 7e6e528..80b11b9 100644
--- a/components/password_manager/content/browser/credential_manager_impl.cc
+++ b/components/password_manager/content/browser/credential_manager_impl.cc
@@ -7,6 +7,7 @@
 #include <utility>
 
 #include "base/bind.h"
+#include "base/memory/ptr_util.h"
 #include "base/metrics/user_metrics.h"
 #include "base/strings/string16.h"
 #include "base/strings/utf_string_conversions.h"
@@ -15,6 +16,7 @@
 #include "components/password_manager/content/browser/content_password_manager_driver_factory.h"
 #include "components/password_manager/core/browser/affiliated_match_helper.h"
 #include "components/password_manager/core/browser/credential_manager_logger.h"
+#include "components/password_manager/core/browser/form_saver.h"
 #include "components/password_manager/core/browser/password_manager_client.h"
 #include "components/password_manager/core/browser/password_manager_metrics_util.h"
 #include "components/password_manager/core/browser/password_manager_util.h"
@@ -74,9 +76,9 @@
   std::unique_ptr<autofill::PasswordForm> form(
       CreatePasswordFormFromCredentialInfo(credential, origin));
 
-  form_manager_.reset(new CredentialManagerPasswordFormManager(
+  form_manager_ = base::MakeUnique<CredentialManagerPasswordFormManager>(
       client_, GetDriver(), *CreateObservedPasswordFormFromOrigin(origin),
-      std::move(form), this));
+      std::move(form), this, nullptr, nullptr);
 }
 
 void CredentialManagerImpl::OnProvisionalSaveComplete() {
diff --git a/components/password_manager/core/browser/BUILD.gn b/components/password_manager/core/browser/BUILD.gn
index deecfff1..b1acc89 100644
--- a/components/password_manager/core/browser/BUILD.gn
+++ b/components/password_manager/core/browser/BUILD.gn
@@ -260,6 +260,7 @@
     "affiliation_utils_unittest.cc",
     "browser_save_password_progress_logger_unittest.cc",
     "credential_manager_logger_unittest.cc",
+    "credential_manager_password_form_manager_unittest.cc",
     "export/csv_writer_unittest.cc",
     "export/password_csv_writer_unittest.cc",
     "export/password_exporter_unittest.cc",
diff --git a/components/password_manager/core/browser/credential_manager_password_form_manager.cc b/components/password_manager/core/browser/credential_manager_password_form_manager.cc
index 51e6bb34..38224508 100644
--- a/components/password_manager/core/browser/credential_manager_password_form_manager.cc
+++ b/components/password_manager/core/browser/credential_manager_password_form_manager.cc
@@ -6,8 +6,10 @@
 
 #include <utility>
 
+#include "base/callback.h"
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
+#include "base/threading/sequenced_task_runner_handle.h"
 #include "components/autofill/core/common/password_form.h"
 #include "components/password_manager/core/browser/form_saver_impl.h"
 #include "components/password_manager/core/browser/password_manager_client.h"
@@ -22,16 +24,20 @@
     base::WeakPtr<PasswordManagerDriver> driver,
     const PasswordForm& observed_form,
     std::unique_ptr<autofill::PasswordForm> saved_form,
-    CredentialManagerPasswordFormManagerDelegate* delegate)
-    : PasswordFormManager(
-          driver->GetPasswordManager(),
-          client,
-          driver,
-          observed_form,
-          base::WrapUnique(new FormSaverImpl(client->GetPasswordStore())),
-          nullptr),
+    CredentialManagerPasswordFormManagerDelegate* delegate,
+    std::unique_ptr<FormSaver> form_saver,
+    FormFetcher* form_fetcher)
+    : PasswordFormManager(driver->GetPasswordManager(),
+                          client,
+                          driver,
+                          observed_form,
+                          (form_saver ? std::move(form_saver)
+                                      : base::MakeUnique<FormSaverImpl>(
+                                            client->GetPasswordStore())),
+                          form_fetcher),
       delegate_(delegate),
-      saved_form_(std::move(saved_form)) {
+      saved_form_(std::move(saved_form)),
+      weak_factory_(this) {
   DCHECK(saved_form_);
 }
 
@@ -47,6 +53,18 @@
   // indeed the credential set that the user used to sign into the site.
   saved_form_->preferred = true;
   ProvisionallySave(*saved_form_, IGNORE_OTHER_POSSIBLE_USERNAMES);
+
+  // Notify the delegate. This might result in deleting |this|, while
+  // ProcessMatches is being called from FormFetcherImpl, owned by |this|. If
+  // done directly, once ProcessMatches returns, the FormFetcherImpl will be
+  // used after free. Therefore the call is posted to a separate task.
+  base::SequencedTaskRunnerHandle::Get()->PostTask(
+      FROM_HERE,
+      base::Bind(&CredentialManagerPasswordFormManager::NotifyDelegate,
+                 weak_factory_.GetWeakPtr()));
+}
+
+void CredentialManagerPasswordFormManager::NotifyDelegate() {
   delegate_->OnProvisionalSaveComplete();
 }
 
diff --git a/components/password_manager/core/browser/credential_manager_password_form_manager.h b/components/password_manager/core/browser/credential_manager_password_form_manager.h
index c7a9efc..6ac5a18 100644
--- a/components/password_manager/core/browser/credential_manager_password_form_manager.h
+++ b/components/password_manager/core/browser/credential_manager_password_form_manager.h
@@ -33,7 +33,9 @@
   // Given a |client| and an |observed_form|, kick off the process of fetching
   // matching logins from the password store; if |observed_form| doesn't map to
   // a blacklisted origin, provisionally save |saved_form|. Once saved, let the
-  // delegate know that it's safe to poke at the UI.
+  // delegate know that it's safe to poke at the UI. |form_fetcher| is passed
+  // to PasswordFormManager. |form_saver| can be null, in which case it is
+  // created automatically.
   //
   // This class does not take ownership of |delegate|.
   CredentialManagerPasswordFormManager(
@@ -41,7 +43,9 @@
       base::WeakPtr<PasswordManagerDriver> driver,
       const autofill::PasswordForm& observed_form,
       std::unique_ptr<autofill::PasswordForm> saved_form,
-      CredentialManagerPasswordFormManagerDelegate* delegate);
+      CredentialManagerPasswordFormManagerDelegate* delegate,
+      std::unique_ptr<FormSaver> form_saver,
+      FormFetcher* form_fetcher);
   ~CredentialManagerPasswordFormManager() override;
 
   void ProcessMatches(
@@ -49,9 +53,14 @@
       size_t filtered_count) override;
 
  private:
+  // Calls OnProvisionalSaveComplete on |delegate_|.
+  void NotifyDelegate();
+
   CredentialManagerPasswordFormManagerDelegate* delegate_;
   std::unique_ptr<autofill::PasswordForm> saved_form_;
 
+  base::WeakPtrFactory<CredentialManagerPasswordFormManager> weak_factory_;
+
   DISALLOW_COPY_AND_ASSIGN(CredentialManagerPasswordFormManager);
 };
 
diff --git a/components/password_manager/core/browser/credential_manager_password_form_manager_unittest.cc b/components/password_manager/core/browser/credential_manager_password_form_manager_unittest.cc
new file mode 100644
index 0000000..b25176a7
--- /dev/null
+++ b/components/password_manager/core/browser/credential_manager_password_form_manager_unittest.cc
@@ -0,0 +1,78 @@
+// 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/password_manager/core/browser/credential_manager_password_form_manager.h"
+
+#include <memory>
+
+#include "base/macros.h"
+#include "base/memory/ptr_util.h"
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
+#include "components/autofill/core/common/password_form.h"
+#include "components/password_manager/core/browser/fake_form_fetcher.h"
+#include "components/password_manager/core/browser/stub_form_saver.h"
+#include "components/password_manager/core/browser/stub_password_manager_client.h"
+#include "components/password_manager/core/browser/stub_password_manager_driver.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using autofill::PasswordForm;
+using ::testing::Invoke;
+
+namespace password_manager {
+
+namespace {
+
+class MockDelegate : public CredentialManagerPasswordFormManagerDelegate {
+ public:
+  MOCK_METHOD0(OnProvisionalSaveComplete, void());
+};
+
+}  // namespace
+
+class CredentialManagerPasswordFormManagerTest : public testing::Test {
+ public:
+  CredentialManagerPasswordFormManagerTest() = default;
+
+ protected:
+  // Necessary for callbacks, and for TestAutofillDriver.
+  base::MessageLoop message_loop_;
+
+  StubPasswordManagerClient client_;
+  StubPasswordManagerDriver driver_;
+
+  DISALLOW_COPY_AND_ASSIGN(CredentialManagerPasswordFormManagerTest);
+};
+
+// Test that aborting early does not cause use after free.
+TEST_F(CredentialManagerPasswordFormManagerTest, AbortEarly) {
+  PasswordForm observed_form;
+  MockDelegate delegate;
+  auto form_fetcher = base::MakeUnique<FakeFormFetcher>();
+  form_fetcher->Fetch();
+  CredentialManagerPasswordFormManager form_manager(
+      &client_, driver_.AsWeakPtr(), observed_form,
+      base::MakeUnique<PasswordForm>(observed_form), &delegate,
+      base::MakeUnique<StubFormSaver>(), form_fetcher.get());
+
+  auto deleter = [&form_fetcher]() { form_fetcher.reset(); };
+
+  // Simulate that the PasswordStore responded to the FormFetcher. As a result,
+  // |form_manager| should call the delegate's OnProvisionalSaveComplete, which
+  // in turn should delete |form_fetcher|.
+  EXPECT_CALL(delegate, OnProvisionalSaveComplete()).WillOnce(Invoke(deleter));
+  form_fetcher->SetNonFederated(std::vector<const PasswordForm*>(), 0u);
+  // Check that |form_fetcher| was not deleted yet; doing so would have caused
+  // use after free during SetNonFederated.
+  EXPECT_TRUE(form_fetcher);
+
+  base::RunLoop().RunUntilIdle();
+
+  // Ultimately, |form_fetcher| should have been deleted. It just should happen
+  // after it finishes executing.
+  EXPECT_FALSE(form_fetcher);
+}
+
+}  // namespace password_manager
diff --git a/components/security_interstitials_strings.grdp b/components/security_interstitials_strings.grdp
index 8004a6e..780a4e6 100644
--- a/components/security_interstitials_strings.grdp
+++ b/components/security_interstitials_strings.grdp
@@ -54,7 +54,7 @@
     https://www.google.com/chrome/browser/privacy/#safe-browsing-policies
   </message>
   <message name="IDS_SAFE_BROWSING_WHITEPAPER_URL" translateable="false">
-    https://www.google.com/chrome/browser/privacy/whitepaper.html#malware
+    https://www.google.com/chrome/browser/privacy/whitepaper.html#extendedreport
   </message>
 
   <!-- SSL error page -->
diff --git a/content/browser/appcache/appcache_host_unittest.cc b/content/browser/appcache/appcache_host_unittest.cc
index 221afb21..1e19f24 100644
--- a/content/browser/appcache/appcache_host_unittest.cc
+++ b/content/browser/appcache/appcache_host_unittest.cc
@@ -110,7 +110,7 @@
     void GetUsageAndQuota(base::SequencedTaskRunner* original_task_runner,
                           const GURL& origin,
                           storage::StorageType type,
-                          const UsageAndQuotaCallback& callback) override {}
+                          const GetUsageAndQuotaCallback& callback) override {}
 
     void NotifyOriginInUse(const GURL& origin) override { inuse_[origin] += 1; }
 
diff --git a/content/browser/appcache/appcache_storage_impl_unittest.cc b/content/browser/appcache/appcache_storage_impl_unittest.cc
index d1ed641..b754546 100644
--- a/content/browser/appcache/appcache_storage_impl_unittest.cc
+++ b/content/browser/appcache/appcache_storage_impl_unittest.cc
@@ -277,13 +277,12 @@
                        base::FilePath(),
                        io_thread->task_runner().get(),
                        db_thread->task_runner().get(),
-                       nullptr,
-                       storage::GetQuotaSettingsFunc()),
+                       NULL),
           async_(false) {}
 
     void GetUsageAndQuota(const GURL& origin,
                           storage::StorageType type,
-                          const UsageAndQuotaCallback& callback) override {
+                          const GetUsageAndQuotaCallback& callback) override {
       EXPECT_EQ(storage::kStorageTypeTemporary, type);
       if (async_) {
         base::ThreadTaskRunnerHandle::Get()->PostTask(
@@ -294,7 +293,7 @@
       CallCallback(callback);
     }
 
-    void CallCallback(const UsageAndQuotaCallback& callback) {
+    void CallCallback(const GetUsageAndQuotaCallback& callback) {
       callback.Run(storage::kQuotaStatusOk, 0, kMockQuota);
     }
 
@@ -346,7 +345,7 @@
     void GetUsageAndQuota(base::SequencedTaskRunner* original_task_runner,
                           const GURL& origin,
                           storage::StorageType type,
-                          const UsageAndQuotaCallback& callback) override {}
+                          const GetUsageAndQuotaCallback& callback) override {}
 
     int notify_storage_accessed_count_;
     int notify_storage_modified_count_;
diff --git a/content/browser/background_sync/background_sync_manager_unittest.cc b/content/browser/background_sync/background_sync_manager_unittest.cc
index 7219d1f..3127778 100644
--- a/content/browser/background_sync/background_sync_manager_unittest.cc
+++ b/content/browser/background_sync/background_sync_manager_unittest.cc
@@ -136,7 +136,9 @@
     // Create a StoragePartition with the correct BrowserContext so that the
     // BackgroundSyncManager can find the BrowserContext through it.
     storage_partition_impl_.reset(new StoragePartitionImpl(
-        helper_->browser_context(), base::FilePath(), nullptr));
+        helper_->browser_context(), base::FilePath(), nullptr, nullptr, nullptr,
+        nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+        nullptr, nullptr, nullptr));
     helper_->context_wrapper()->set_storage_partition(
         storage_partition_impl_.get());
 
diff --git a/content/browser/background_sync/background_sync_service_impl_unittest.cc b/content/browser/background_sync/background_sync_service_impl_unittest.cc
index 197cf17..c49c4ff 100644
--- a/content/browser/background_sync/background_sync_service_impl_unittest.cc
+++ b/content/browser/background_sync/background_sync_service_impl_unittest.cc
@@ -133,7 +133,9 @@
     // Creates a StoragePartition so that the BackgroundSyncManager can
     // use it to access the BrowserContext.
     storage_partition_impl_.reset(new StoragePartitionImpl(
-        embedded_worker_helper_->browser_context(), base::FilePath(), nullptr));
+        embedded_worker_helper_->browser_context(), base::FilePath(), nullptr,
+        nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+        nullptr, nullptr, nullptr, nullptr, nullptr));
     embedded_worker_helper_->context_wrapper()->set_storage_partition(
         storage_partition_impl_.get());
   }
diff --git a/content/browser/browser_context.cc b/content/browser/browser_context.cc
index 540fbc99..30ff8d4 100644
--- a/content/browser/browser_context.cc
+++ b/content/browser/browser_context.cc
@@ -438,8 +438,7 @@
     // Mojo or the global service manager connection.
 
     service_manager::mojom::ServicePtr service;
-    service_manager::mojom::ServiceRequest service_request =
-        mojo::MakeRequest(&service);
+    service_manager::mojom::ServiceRequest service_request(&service);
 
     service_manager::mojom::PIDReceiverPtr pid_receiver;
     service_manager::Connector::ConnectParams params(
diff --git a/content/browser/browsing_data/clear_site_data_throttle_browsertest.cc b/content/browser/browsing_data/clear_site_data_throttle_browsertest.cc
index f8ae1b6d..f5e4364 100644
--- a/content/browser/browsing_data/clear_site_data_throttle_browsertest.cc
+++ b/content/browser/browsing_data/clear_site_data_throttle_browsertest.cc
@@ -21,7 +21,6 @@
 #include "net/dns/mock_host_resolver.h"
 #include "net/test/embedded_test_server/http_request.h"
 #include "net/test/embedded_test_server/http_response.h"
-#include "storage/browser/quota/quota_settings.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "url/origin.h"
 #include "url/url_constants.h"
@@ -41,13 +40,6 @@
                     bool remove_storage,
                     bool remove_cache,
                     const base::Closure& callback));
-
-  void GetQuotaSettings(
-      content::BrowserContext* context,
-      content::StoragePartition* partition,
-      const storage::OptionalQuotaSettingsCallback& callback) override {
-    callback.Run(storage::GetHardCodedSettings(100 * 1024 * 1024));
-  }
 };
 
 class TestContentBrowserClient : public MockContentBrowserClient {
diff --git a/content/browser/database_tracker_unittest.cc b/content/browser/database_tracker_unittest.cc
index f3eea24..c1ec078 100644
--- a/content/browser/database_tracker_unittest.cc
+++ b/content/browser/database_tracker_unittest.cc
@@ -140,7 +140,7 @@
   void GetUsageAndQuota(base::SequencedTaskRunner* original_task_runner,
                         const GURL& origin,
                         storage::StorageType type,
-                        const UsageAndQuotaCallback& callback) override {}
+                        const GetUsageAndQuotaCallback& callback) override {}
 
   void SimulateQuotaManagerDestroyed() {
     if (registered_client_) {
diff --git a/content/browser/fileapi/file_system_browsertest.cc b/content/browser/fileapi/file_system_browsertest.cc
index ed7fa379..1bc55e74 100644
--- a/content/browser/fileapi/file_system_browsertest.cc
+++ b/content/browser/fileapi/file_system_browsertest.cc
@@ -55,27 +55,29 @@
 class FileSystemBrowserTestWithLowQuota : public FileSystemBrowserTest {
  public:
   void SetUpOnMainThread() override {
-    SetLowQuota(BrowserContext::GetDefaultStoragePartition(
-                    shell()->web_contents()->GetBrowserContext())
-                    ->GetQuotaManager());
+    const int kInitialQuotaKilobytes = 5000;
+    const int kTemporaryStorageQuotaMaxSize =
+        kInitialQuotaKilobytes * 1024 * QuotaManager::kPerHostTemporaryPortion;
+    SetTempQuota(
+        kTemporaryStorageQuotaMaxSize,
+        BrowserContext::GetDefaultStoragePartition(
+            shell()->web_contents()->GetBrowserContext())->GetQuotaManager());
   }
 
-  static void SetLowQuota(scoped_refptr<QuotaManager> qm) {
+  static void SetTempQuota(int64_t bytes, scoped_refptr<QuotaManager> qm) {
     if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
       BrowserThread::PostTask(
           BrowserThread::IO, FROM_HERE,
-          base::Bind(&FileSystemBrowserTestWithLowQuota::SetLowQuota, qm));
+          base::Bind(&FileSystemBrowserTestWithLowQuota::SetTempQuota, bytes,
+                     qm));
       return;
     }
     DCHECK_CURRENTLY_ON(BrowserThread::IO);
-    // These sizes must correspond with expectations in html and js.
-    const int kMeg = 1000 * 1024;
-    storage::QuotaSettings settings;
-    settings.pool_size = 25 * kMeg;
-    settings.per_host_quota = 5 * kMeg;
-    settings.must_remain_available = 100 * kMeg;
-    settings.refresh_interval = base::TimeDelta::Max();
-    qm->SetQuotaSettings(settings);
+    qm->SetTemporaryGlobalOverrideQuota(bytes, storage::QuotaCallback());
+    // Don't return until the quota has been set.
+    scoped_refptr<base::ThreadTestHelper> helper(new base::ThreadTestHelper(
+        BrowserThread::GetTaskRunnerForThread(BrowserThread::DB).get()));
+    ASSERT_TRUE(helper->Run());
   }
 };
 
diff --git a/content/browser/fileapi/obfuscated_file_util_unittest.cc b/content/browser/fileapi/obfuscated_file_util_unittest.cc
index 8086c6bc..9eb3d5fa 100644
--- a/content/browser/fileapi/obfuscated_file_util_unittest.cc
+++ b/content/browser/fileapi/obfuscated_file_util_unittest.cc
@@ -167,14 +167,7 @@
     quota_manager_ = new storage::QuotaManager(
         false /* is_incognito */, data_dir_.GetPath(),
         base::ThreadTaskRunnerHandle::Get().get(),
-        base::ThreadTaskRunnerHandle::Get().get(), storage_policy_.get(),
-        storage::GetQuotaSettingsFunc());
-    storage::QuotaSettings settings;
-    settings.per_host_quota = 25 * 1024 * 1024;
-    settings.pool_size = settings.per_host_quota * 5;
-    settings.must_remain_available = 10 * 1024 * 1024;
-    settings.refresh_interval = base::TimeDelta::Max();
-    quota_manager_->SetQuotaSettings(settings);
+        base::ThreadTaskRunnerHandle::Get().get(), storage_policy_.get());
 
     // Every time we create a new sandbox_file_system helper,
     // it creates another context, which creates another path manager,
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
index daff90df..61ca001 100644
--- a/content/browser/frame_host/render_frame_host_impl.cc
+++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -2645,8 +2645,8 @@
                              frame_host_binding_.CreateInterfacePtrAndBind());
 
   service_manager::mojom::InterfaceProviderPtr remote_interfaces;
-  service_manager::mojom::InterfaceProviderRequest remote_interfaces_request =
-      MakeRequest(&remote_interfaces);
+  service_manager::mojom::InterfaceProviderRequest remote_interfaces_request(
+      &remote_interfaces);
   remote_interfaces_.reset(new service_manager::InterfaceProvider);
   remote_interfaces_->Bind(std::move(remote_interfaces));
   frame_->GetInterfaceProvider(std::move(remote_interfaces_request));
diff --git a/content/browser/indexed_db/indexed_db_browsertest.cc b/content/browser/indexed_db/indexed_db_browsertest.cc
index f4e7668c..8c151a35 100644
--- a/content/browser/indexed_db/indexed_db_browsertest.cc
+++ b/content/browser/indexed_db/indexed_db_browsertest.cc
@@ -122,25 +122,27 @@
     return static_cast<IndexedDBContextImpl*>(partition->GetIndexedDBContext());
   }
 
-  void SetQuota(int per_host_quota_kilobytes) {
-    SetTempQuota(per_host_quota_kilobytes,
-                 BrowserContext::GetDefaultStoragePartition(
-                     shell()->web_contents()->GetBrowserContext())
-                     ->GetQuotaManager());
+  void SetQuota(int quota_kilobytes) {
+    const int kTemporaryStorageQuotaSize =
+        quota_kilobytes * 1024 * QuotaManager::kPerHostTemporaryPortion;
+    SetTempQuota(kTemporaryStorageQuotaSize,
+        BrowserContext::GetDefaultStoragePartition(
+            shell()->web_contents()->GetBrowserContext())->GetQuotaManager());
   }
 
-  static void SetTempQuota(int per_host_quota_kilobytes,
-                           scoped_refptr<QuotaManager> qm) {
+  static void SetTempQuota(int64_t bytes, scoped_refptr<QuotaManager> qm) {
     if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
-      BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
-                              base::Bind(&IndexedDBBrowserTest::SetTempQuota,
-                                         per_host_quota_kilobytes, qm));
+      BrowserThread::PostTask(
+          BrowserThread::IO, FROM_HERE,
+          base::Bind(&IndexedDBBrowserTest::SetTempQuota, bytes, qm));
       return;
     }
     DCHECK_CURRENTLY_ON(BrowserThread::IO);
-    const int KB = 1024;
-    qm->SetQuotaSettings(
-        storage::GetHardCodedSettings(per_host_quota_kilobytes * KB));
+    qm->SetTemporaryGlobalOverrideQuota(bytes, storage::QuotaCallback());
+    // Don't return until the quota has been set.
+    scoped_refptr<base::ThreadTestHelper> helper(new base::ThreadTestHelper(
+        BrowserThread::GetTaskRunnerForThread(BrowserThread::DB)));
+    ASSERT_TRUE(helper->Run());
   }
 
   virtual int64_t RequestDiskUsage() {
diff --git a/content/browser/payments/payment_app_content_unittest_base.cc b/content/browser/payments/payment_app_content_unittest_base.cc
index f5b70ce..939ac9b 100644
--- a/content/browser/payments/payment_app_content_unittest_base.cc
+++ b/content/browser/payments/payment_app_content_unittest_base.cc
@@ -46,9 +46,10 @@
           new TestBrowserThreadBundle(TestBrowserThreadBundle::IO_MAINLOOP)),
       embedded_worker_helper_(new EmbeddedWorkerTestHelper(base::FilePath())),
       storage_partition_impl_(
-          new StoragePartitionImpl(embedded_worker_helper_->browser_context(),
-                                   base::FilePath(),
-                                   nullptr)),
+          new StoragePartitionImpl(
+              embedded_worker_helper_->browser_context(), base::FilePath(),
+              nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+              nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)),
       payment_app_context_(new PaymentAppContextImpl()) {
   embedded_worker_helper_->context_wrapper()->set_storage_partition(
       storage_partition_impl_.get());
diff --git a/content/browser/quota/mock_quota_manager.cc b/content/browser/quota/mock_quota_manager.cc
index 65e197a..7340797 100644
--- a/content/browser/quota/mock_quota_manager.cc
+++ b/content/browser/quota/mock_quota_manager.cc
@@ -44,13 +44,14 @@
                    profile_path,
                    io_thread,
                    db_thread,
-                   special_storage_policy,
-                   storage::GetQuotaSettingsFunc()),
-      weak_factory_(this) {}
+                   special_storage_policy),
+      weak_factory_(this) {
+}
 
-void MockQuotaManager::GetUsageAndQuota(const GURL& origin,
-                                        storage::StorageType type,
-                                        const UsageAndQuotaCallback& callback) {
+void MockQuotaManager::GetUsageAndQuota(
+    const GURL& origin,
+    storage::StorageType type,
+    const GetUsageAndQuotaCallback& callback) {
   StorageInfo& info = usage_and_quota_map_[std::make_pair(origin, type)];
   callback.Run(storage::kQuotaStatusOk, info.usage, info.quota);
 }
diff --git a/content/browser/quota/mock_quota_manager.h b/content/browser/quota/mock_quota_manager.h
index 6289f319..172b7e92 100644
--- a/content/browser/quota/mock_quota_manager.h
+++ b/content/browser/quota/mock_quota_manager.h
@@ -56,7 +56,7 @@
   // a helper method MockQuotaManagerProxy::SetQuota().
   void GetUsageAndQuota(const GURL& origin,
                         storage::StorageType type,
-                        const UsageAndQuotaCallback& callback) override;
+                        const GetUsageAndQuotaCallback& callback) override;
 
   // Overrides QuotaManager's implementation with a canned implementation that
   // allows clients to set up the origin database that should be queried. This
diff --git a/content/browser/quota/mock_quota_manager_proxy.cc b/content/browser/quota/mock_quota_manager_proxy.cc
index 8ca0293..697577b 100644
--- a/content/browser/quota/mock_quota_manager_proxy.cc
+++ b/content/browser/quota/mock_quota_manager_proxy.cc
@@ -40,7 +40,7 @@
     base::SequencedTaskRunner* original_task_runner,
     const GURL& origin,
     StorageType type,
-    const QuotaManager::UsageAndQuotaCallback& callback) {
+    const QuotaManager::GetUsageAndQuotaCallback& callback) {
   if (mock_manager()) {
     mock_manager()->GetUsageAndQuota(origin, type, callback);
   }
diff --git a/content/browser/quota/mock_quota_manager_proxy.h b/content/browser/quota/mock_quota_manager_proxy.h
index 3f9ddab..e550a9d9 100644
--- a/content/browser/quota/mock_quota_manager_proxy.h
+++ b/content/browser/quota/mock_quota_manager_proxy.h
@@ -41,7 +41,7 @@
       base::SequencedTaskRunner* original_task_runner,
       const GURL& origin,
       StorageType type,
-      const QuotaManager::UsageAndQuotaCallback& callback) override;
+      const QuotaManager::GetUsageAndQuotaCallback& callback) override;
 
   // Validates the |client_id| and updates the internal access count
   // which can be accessed via notify_storage_accessed_count().
diff --git a/content/browser/quota/quota_backend_impl_unittest.cc b/content/browser/quota/quota_backend_impl_unittest.cc
index 6054e32..12e76e6 100644
--- a/content/browser/quota/quota_backend_impl_unittest.cc
+++ b/content/browser/quota/quota_backend_impl_unittest.cc
@@ -70,7 +70,7 @@
   void GetUsageAndQuota(base::SequencedTaskRunner* original_task_runner,
                         const GURL& origin,
                         storage::StorageType type,
-                        const UsageAndQuotaCallback& callback) override {
+                        const GetUsageAndQuotaCallback& callback) override {
     callback.Run(storage::kQuotaStatusOk, usage_, quota_);
   }
 
diff --git a/content/browser/quota/quota_manager_unittest.cc b/content/browser/quota/quota_manager_unittest.cc
index 3613ec8..580d68e 100644
--- a/content/browser/quota/quota_manager_unittest.cc
+++ b/content/browser/quota/quota_manager_unittest.cc
@@ -44,6 +44,7 @@
 using storage::QuotaManager;
 using storage::QuotaStatusCode;
 using storage::StorageType;
+using storage::UsageAndQuota;
 using storage::UsageInfo;
 using storage::UsageInfoEntries;
 
@@ -58,26 +59,42 @@
 
 const int kAllClients = QuotaClient::kAllClientsMask;
 
-// Values in bytes.
 const int64_t kAvailableSpaceForApp = 13377331U;
-const int64_t kMustRemainAvailableForSystem = kAvailableSpaceForApp / 2;
-const int64_t kDefaultPoolSize = 1000;
-const int64_t kDefaultPerHostQuota = 200;
+
+const int64_t kMinimumPreserveForSystem =
+    QuotaManager::kMinimumPreserveForSystem;
+const int kPerHostTemporaryPortion = QuotaManager::kPerHostTemporaryPortion;
 
 const GURL kTestEvictionOrigin = GURL("http://test.eviction.policy/result");
 
 // Returns a deterministic value for the amount of available disk space.
 int64_t GetAvailableDiskSpaceForTest() {
-  return kAvailableSpaceForApp + kMustRemainAvailableForSystem;
+  return kAvailableSpaceForApp + kMinimumPreserveForSystem;
 }
 
-std::pair<int64_t, int64_t> GetVolumeInfoForTests(
-    const base::FilePath& unused) {
-  int64_t available = static_cast<uint64_t>(GetAvailableDiskSpaceForTest());
-  int64_t total = available * 2;
-  return std::make_pair(total, available);
+bool GetVolumeInfoForTests(const base::FilePath&,
+                           uint64_t* available, uint64_t* total) {
+  *available = static_cast<uint64_t>(GetAvailableDiskSpaceForTest());
+  *total = *available * 2;
+  return true;
 }
 
+class TestEvictionPolicy : public storage::QuotaEvictionPolicy {
+ public:
+  TestEvictionPolicy() {}
+  ~TestEvictionPolicy() override {}
+
+  // Overridden from storage::QuotaEvictionPolicy:
+  void GetEvictionOrigin(const scoped_refptr<storage::SpecialStoragePolicy>&
+                             special_storage_policy,
+                         const std::set<GURL>& exceptions,
+                         const std::map<GURL, int64_t>& usage_map,
+                         int64_t global_quota,
+                         const storage::GetOriginCallback& callback) override {
+    callback.Run(kTestEvictionOrigin);
+  }
+};
+
 }  // namespace
 
 class QuotaManagerTest : public testing::Test {
@@ -109,11 +126,7 @@
     quota_manager_ = new QuotaManager(is_incognito, data_dir_.GetPath(),
                                       base::ThreadTaskRunnerHandle::Get().get(),
                                       base::ThreadTaskRunnerHandle::Get().get(),
-                                      mock_special_storage_policy_.get(),
-                                      storage::GetQuotaSettingsFunc());
-    SetQuotaSettings(kDefaultPoolSize, kDefaultPerHostQuota,
-                     is_incognito ? INT64_C(0) : kMustRemainAvailableForSystem);
-
+                                      mock_special_storage_policy_.get());
     // Don't (automatically) start the eviction for testing.
     quota_manager_->eviction_disabled_ = true;
     // Don't query the hard disk for remaining capacity.
@@ -160,15 +173,21 @@
                                  weak_factory_.GetWeakPtr()));
   }
 
-  void SetQuotaSettings(int64_t pool_size,
-                        int64_t per_host_quota,
-                        int64_t must_remain_available) {
-    storage::QuotaSettings settings;
-    settings.pool_size = pool_size;
-    settings.per_host_quota = per_host_quota;
-    settings.must_remain_available = must_remain_available;
-    settings.refresh_interval = base::TimeDelta::Max();
-    quota_manager_->SetQuotaSettings(settings);
+  void GetTemporaryGlobalQuota() {
+    quota_status_ = kQuotaStatusUnknown;
+    quota_ = -1;
+    quota_manager_->GetTemporaryGlobalQuota(
+        base::Bind(&QuotaManagerTest::DidGetQuota,
+                   weak_factory_.GetWeakPtr()));
+  }
+
+  void SetTemporaryGlobalQuota(int64_t new_quota) {
+    quota_status_ = kQuotaStatusUnknown;
+    quota_ = -1;
+    quota_manager_->SetTemporaryGlobalOverrideQuota(
+        new_quota,
+        base::Bind(&QuotaManagerTest::DidGetQuota,
+                   weak_factory_.GetWeakPtr()));
   }
 
   void GetPersistentHostQuota(const std::string& host) {
@@ -253,21 +272,22 @@
                    weak_factory_.GetWeakPtr()));
   }
 
-  void GetStorageCapacity() {
+  void GetAvailableSpace() {
+    quota_status_ = kQuotaStatusUnknown;
     available_space_ = -1;
-    total_space_ = -1;
-    quota_manager_->GetStorageCapacity(base::Bind(
-        &QuotaManagerTest::DidGetStorageCapacity, weak_factory_.GetWeakPtr()));
+    quota_manager_->GetAvailableSpace(
+        base::Bind(&QuotaManagerTest::DidGetAvailableSpace,
+                   weak_factory_.GetWeakPtr()));
   }
 
-  void GetEvictionRoundInfo() {
+  void GetUsageAndQuotaForEviction() {
     quota_status_ = kQuotaStatusUnknown;
-    settings_ = storage::QuotaSettings();
-    available_space_ = -1;
-    total_space_ = -1;
     usage_ = -1;
-    quota_manager_->GetEvictionRoundInfo(
-        base::Bind(&QuotaManagerTest::DidGetEvictionRoundInfo,
+    unlimited_usage_ = -1;
+    quota_ = -1;
+    available_space_ = -1;
+    quota_manager_->GetUsageAndQuotaForEviction(
+        base::Bind(&QuotaManagerTest::DidGetUsageAndQuotaForEviction,
                    weak_factory_.GetWeakPtr()));
   }
 
@@ -277,6 +297,12 @@
     quota_manager_->GetCachedOrigins(type, origins);
   }
 
+  bool GetVolumeInfo(const base::FilePath& path,
+                     uint64_t* available_space,
+                     uint64_t* total_size) {
+    return QuotaManager::GetVolumeInfo(path, available_space, total_size);
+  }
+
   void NotifyStorageAccessed(QuotaClient* client,
                              const GURL& origin,
                              StorageType type) {
@@ -347,8 +373,8 @@
     quota_ = quota;
   }
 
-  void DidGetStorageCapacity(int64_t total_space, int64_t available_space) {
-    total_space_ = total_space;
+  void DidGetAvailableSpace(QuotaStatusCode status, int64_t available_space) {
+    quota_status_ = status;
     available_space_ = available_space;
   }
 
@@ -369,17 +395,12 @@
     quota_status_ = status;
   }
 
-  void DidGetEvictionRoundInfo(QuotaStatusCode status,
-                               const storage::QuotaSettings& settings,
-                               int64_t available_space,
-                               int64_t total_space,
-                               int64_t global_usage,
-                               bool global_usage_is_complete) {
+  void DidGetUsageAndQuotaForEviction(QuotaStatusCode status,
+                                      const UsageAndQuota& usage_and_quota) {
     quota_status_ = status;
-    settings_ = settings;
-    available_space_ = available_space;
-    total_space_ = total_space;
-    usage_ = global_usage;
+    limited_usage_ = usage_and_quota.global_limited_usage;
+    quota_ = usage_and_quota.quota;
+    available_space_ = usage_and_quota.available_disk_space;
   }
 
   void DidGetEvictionOrigin(const GURL& origin) {
@@ -424,7 +445,6 @@
   int64_t limited_usage() const { return limited_usage_; }
   int64_t unlimited_usage() const { return unlimited_usage_; }
   int64_t quota() const { return quota_; }
-  int64_t total_space() const { return total_space_; }
   int64_t available_space() const { return available_space_; }
   const GURL& eviction_origin() const { return eviction_origin_; }
   const std::set<GURL>& modified_origins() const { return modified_origins_; }
@@ -433,7 +453,6 @@
   const OriginInfoTableEntries& origin_info_entries() const {
     return origin_info_entries_;
   }
-  const storage::QuotaSettings& settings() const { return settings_; }
   base::FilePath profile_path() const { return data_dir_.GetPath(); }
   int status_callback_count() const { return status_callback_count_; }
   void reset_status_callback_count() { status_callback_count_ = 0; }
@@ -456,14 +475,12 @@
   int64_t limited_usage_;
   int64_t unlimited_usage_;
   int64_t quota_;
-  int64_t total_space_;
   int64_t available_space_;
   GURL eviction_origin_;
   std::set<GURL> modified_origins_;
   StorageType modified_origins_type_;
   QuotaTableEntries quota_entries_;
   OriginInfoTableEntries origin_info_entries_;
-  storage::QuotaSettings settings_;
   int status_callback_count_;
 
   int additional_callback_count_;
@@ -616,17 +633,20 @@
       QuotaClient::kFileSystem));
 
   // This time explicitly sets a temporary global quota.
-  const int kPoolSize = 100;
-  const int kPerHostQuota = 20;
-  SetQuotaSettings(kPoolSize, kPerHostQuota, kMustRemainAvailableForSystem);
+  SetTemporaryGlobalQuota(100);
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(kQuotaStatusOk, status());
+  EXPECT_EQ(100, quota());
 
   GetUsageAndQuotaForWebApps(GURL("http://foo.com/"), kTemp);
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(kQuotaStatusOk, status());
   EXPECT_EQ(10 + 20, usage());
 
+  const int kPerHostQuota = 100 / kPerHostTemporaryPortion;
+
   // The host's quota should be its full portion of the global quota
-  // since there's plenty of diskspace.
+  // since global usage is under the global quota.
   EXPECT_EQ(kPerHostQuota, quota());
 
   GetUsageAndQuotaForWebApps(GURL("http://bar.com/"), kTemp);
@@ -642,39 +662,39 @@
     { "http://bar.com/",              kTemp, 2 },
     { "http://bar.com/",              kPerm, 4 },
     { "http://unlimited/",            kPerm, 8 },
+    { "http://installed/",            kPerm, 16 },
   };
   static const MockOriginData kData2[] = {
     { "https://foo.com/",             kTemp, 128 },
     { "http://example.com/",          kPerm, 256 },
     { "http://unlimited/",            kTemp, 512 },
+    { "http://installed/",            kTemp, 1024 },
   };
   mock_special_storage_policy()->AddUnlimited(GURL("http://unlimited/"));
+  mock_special_storage_policy()->GrantQueryDiskSize(GURL("http://installed/"));
   RegisterClient(CreateClient(kData1, arraysize(kData1),
       QuotaClient::kFileSystem));
   RegisterClient(CreateClient(kData2, arraysize(kData2),
       QuotaClient::kDatabase));
 
-  const int64_t kPoolSize = GetAvailableDiskSpaceForTest();
-  const int64_t kPerHostQuota = kPoolSize / 5;
-  SetQuotaSettings(kPoolSize, kPerHostQuota, kMustRemainAvailableForSystem);
+  const int64_t kTempQuotaBase =
+      GetAvailableDiskSpaceForTest() / kPerHostTemporaryPortion;
 
   GetUsageAndQuotaForWebApps(GURL("http://foo.com/"), kTemp);
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(kQuotaStatusOk, status());
   EXPECT_EQ(1 + 128, usage());
-  EXPECT_EQ(kPerHostQuota, quota());
 
   GetUsageAndQuotaForWebApps(GURL("http://bar.com/"), kPerm);
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(kQuotaStatusOk, status());
   EXPECT_EQ(4, usage());
-  EXPECT_EQ(0, quota());
 
   GetUsageAndQuotaForWebApps(GURL("http://unlimited/"), kTemp);
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(kQuotaStatusOk, status());
   EXPECT_EQ(512, usage());
-  EXPECT_EQ(kAvailableSpaceForApp + usage(), quota());
+  EXPECT_EQ(std::min(kAvailableSpaceForApp, kTempQuotaBase) + usage(), quota());
 
   GetUsageAndQuotaForWebApps(GURL("http://unlimited/"), kPerm);
   base::RunLoop().RunUntilIdle();
@@ -682,16 +702,33 @@
   EXPECT_EQ(8, usage());
   EXPECT_EQ(kAvailableSpaceForApp + usage(), quota());
 
+  GetAvailableSpace();
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(kQuotaStatusOk, status());
+  EXPECT_LE(0, available_space());
+
+  GetUsageAndQuotaForWebApps(GURL("http://installed/"), kTemp);
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(kQuotaStatusOk, status());
+  EXPECT_EQ(1024, usage());
+  EXPECT_EQ(std::min(kAvailableSpaceForApp, kTempQuotaBase) + usage(), quota());
+
+  GetUsageAndQuotaForWebApps(GURL("http://installed/"), kPerm);
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(kQuotaStatusOk, status());
+  EXPECT_EQ(16, usage());
+  EXPECT_EQ(usage(), quota());  // Over-budget case.
+
   GetGlobalUsage(kTemp);
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(kQuotaStatusOk, status());
-  EXPECT_EQ(1 + 2 + 128 + 512, usage());
+  EXPECT_EQ(1 + 2 + 128 + 512 + 1024, usage());
   EXPECT_EQ(512, unlimited_usage());
 
   GetGlobalUsage(kPerm);
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(kQuotaStatusOk, status());
-  EXPECT_EQ(4 + 8 + 256, usage());
+  EXPECT_EQ(4 + 8 + 16 + 256, usage());
   EXPECT_EQ(8, unlimited_usage());
 }
 
@@ -744,10 +781,10 @@
   };
   RegisterClient(CreateClient(kData, arraysize(kData),
       QuotaClient::kFileSystem));
+  SetTemporaryGlobalQuota(100);
+  base::RunLoop().RunUntilIdle();
 
-  const int kPoolSize = 100;
-  const int kPerHostQuota = 20;
-  SetQuotaSettings(kPoolSize, kPerHostQuota, kMustRemainAvailableForSystem);
+  const int kPerHostQuota = 100 / QuotaManager::kPerHostTemporaryPortion;
 
   GetUsageAndQuotaForWebApps(GURL("http://foo.com/"), kTemp);
   GetUsageAndQuotaForWebApps(GURL("http://foo.com/"), kTemp);
@@ -778,9 +815,8 @@
   };
   RegisterClient(CreateClient(kData, arraysize(kData),
       QuotaClient::kFileSystem));
-  const int kPoolSize = 100;
-  const int kPerHostQuota = 20;
-  SetQuotaSettings(kPoolSize, kPerHostQuota, kMustRemainAvailableForSystem);
+  SetTemporaryGlobalQuota(100);
+  base::RunLoop().RunUntilIdle();
 
   set_additional_callback_count(0);
   GetUsageAndQuotaForWebApps(GURL("http://foo.com/"), kTemp);
@@ -806,28 +842,22 @@
   };
   RegisterClient(CreateClient(kData, arraysize(kData),
       QuotaClient::kFileSystem));
-  const int kPoolSize = 100;
-  const int kPerHostQuota = 20;
-  SetQuotaSettings(kPoolSize, kPerHostQuota, kMustRemainAvailableForSystem);
-
-  // Provided diskspace is not tight, global usage does not affect the
-  // quota calculations for an individual origin, so despite global usage
-  // in excess of our poolsize, we still get the nominal quota value.
-  GetStorageCapacity();
+  SetTemporaryGlobalQuota(100);
   base::RunLoop().RunUntilIdle();
-  EXPECT_LE(kMustRemainAvailableForSystem, available_space());
+
+  const int kPerHostQuota = 100 / QuotaManager::kPerHostTemporaryPortion;
 
   GetUsageAndQuotaForWebApps(GURL("http://usage1/"), kTemp);
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(kQuotaStatusOk, status());
   EXPECT_EQ(1, usage());
-  EXPECT_EQ(kPerHostQuota, quota());
+  EXPECT_EQ(1, quota());  // should be clamped to our current usage
 
   GetUsageAndQuotaForWebApps(GURL("http://usage10/"), kTemp);
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(kQuotaStatusOk, status());
   EXPECT_EQ(10, usage());
-  EXPECT_EQ(kPerHostQuota, quota());
+  EXPECT_EQ(10, quota());
 
   GetUsageAndQuotaForWebApps(GURL("http://usage200/"), kTemp);
   base::RunLoop().RunUntilIdle();
@@ -848,14 +878,17 @@
   RegisterClient(client);
 
   // Test when not overbugdet.
-  const int kPerHostQuotaFor1000 = 200;
-  SetQuotaSettings(1000, kPerHostQuotaFor1000, kMustRemainAvailableForSystem);
+  SetTemporaryGlobalQuota(1000);
+  base::RunLoop().RunUntilIdle();
 
   GetGlobalUsage(kTemp);
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(10 + 50 + 4000, usage());
   EXPECT_EQ(4000, unlimited_usage());
 
+  const int kPerHostQuotaFor1000 =
+      1000 / QuotaManager::kPerHostTemporaryPortion;
+
   GetUsageAndQuotaForWebApps(GURL("http://usage10/"), kTemp);
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(kQuotaStatusOk, status());
@@ -881,8 +914,11 @@
   EXPECT_EQ(QuotaManager::kNoLimit, quota());
 
   // Test when overbugdet.
-  const int kPerHostQuotaFor100 = 20;
-  SetQuotaSettings(100, kPerHostQuotaFor100, kMustRemainAvailableForSystem);
+  SetTemporaryGlobalQuota(100);
+  base::RunLoop().RunUntilIdle();
+
+  const int kPerHostQuotaFor100 =
+      100 / QuotaManager::kPerHostTemporaryPortion;
 
   GetUsageAndQuotaForWebApps(GURL("http://usage10/"), kTemp);
   base::RunLoop().RunUntilIdle();
@@ -921,7 +957,7 @@
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(kQuotaStatusOk, status());
   EXPECT_EQ(10, usage());
-  EXPECT_EQ(kPerHostQuotaFor100, quota());
+  EXPECT_EQ(10, quota());  // should be clamped to our current usage
 
   GetUsageAndQuotaForWebApps(GURL("http://usage50/"), kTemp);
   base::RunLoop().RunUntilIdle();
@@ -1007,7 +1043,14 @@
   EXPECT_EQ(0, usage());
   EXPECT_EQ(100, quota());
 
-  // The actual space avaialble is given to 'unlimited' origins as their quota.
+  // For installed app GetUsageAndQuotaForWebApps returns the capped quota.
+  mock_special_storage_policy()->GrantQueryDiskSize(GURL("http://installed/"));
+  SetPersistentHostQuota("installed", kAvailableSpaceForApp + 100);
+  GetUsageAndQuotaForWebApps(GURL("http://installed/"), kPerm);
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(kAvailableSpaceForApp, quota());
+
+  // Ditto for unlimited apps.
   mock_special_storage_policy()->AddUnlimited(GURL("http://unlimited/"));
   GetUsageAndQuotaForWebApps(GURL("http://unlimited/"), kPerm);
   base::RunLoop().RunUntilIdle();
@@ -1029,14 +1072,22 @@
   EXPECT_LE(kAvailableSpaceForApp,
             QuotaManager::kSyncableStorageDefaultHostQuota);
 
-  // For unlimited origins the quota manager should return
+  // For installed apps the quota manager should return
   // kAvailableSpaceForApp as syncable quota (because of the pre-condition).
-  mock_special_storage_policy()->AddUnlimited(GURL("http://unlimited/"));
-  GetUsageAndQuotaForWebApps(GURL("http://unlimited/"), kSync);
+  mock_special_storage_policy()->GrantQueryDiskSize(GURL("http://installed/"));
+  GetUsageAndQuotaForWebApps(GURL("http://installed/"), kSync);
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(kQuotaStatusOk, status());
   EXPECT_EQ(0, usage());
   EXPECT_EQ(kAvailableSpaceForApp, quota());
+
+  // If it's not installed (which shouldn't happen in real case) it
+  // should just return the default host quota for syncable.
+  GetUsageAndQuotaForWebApps(GURL("http://foo/"), kSync);
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(kQuotaStatusOk, status());
+  EXPECT_EQ(0, usage());
+  EXPECT_EQ(QuotaManager::kSyncableStorageDefaultHostQuota, quota());
 }
 
 TEST_F(QuotaManagerTest, GetPersistentUsageAndQuota_MultiOrigins) {
@@ -1243,13 +1294,22 @@
   EXPECT_EQ(predelete_host_pers, usage());
 }
 
-TEST_F(QuotaManagerTest, GetStorageCapacity) {
-  GetStorageCapacity();
+TEST_F(QuotaManagerTest, GetAvailableSpaceTest) {
+  GetAvailableSpace();
   base::RunLoop().RunUntilIdle();
-  EXPECT_LE(0, total_space());
+  EXPECT_EQ(kQuotaStatusOk, status());
   EXPECT_LE(0, available_space());
 }
 
+TEST_F(QuotaManagerTest, SetTemporaryStorageEvictionPolicy) {
+  quota_manager()->SetTemporaryStorageEvictionPolicy(
+      base::WrapUnique(new TestEvictionPolicy));
+
+  GetEvictionOrigin(kTemp);
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(kTestEvictionOrigin, eviction_origin());
+}
+
 TEST_F(QuotaManagerTest, EvictOriginData) {
   static const MockOriginData kData1[] = {
     { "http://foo.com/",   kTemp,     1 },
@@ -1468,7 +1528,7 @@
   EXPECT_EQ(predelete_host_pers, usage());
 }
 
-TEST_F(QuotaManagerTest, GetEvictionRoundInfo) {
+TEST_F(QuotaManagerTest, GetUsageAndQuotaForEviction) {
   static const MockOriginData kData[] = {
     { "http://foo.com/",   kTemp,       1 },
     { "http://foo.com:1/", kTemp,      20 },
@@ -1481,15 +1541,14 @@
       QuotaClient::kFileSystem);
   RegisterClient(client);
 
-  const int kPoolSize = 10000000;
-  const int kPerHostQuota = kPoolSize / 5;
-  SetQuotaSettings(kPoolSize, kPerHostQuota, kMustRemainAvailableForSystem);
+  SetTemporaryGlobalQuota(10000000);
+  base::RunLoop().RunUntilIdle();
 
-  GetEvictionRoundInfo();
+  GetUsageAndQuotaForEviction();
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(kQuotaStatusOk, status());
-  EXPECT_EQ(21, usage());
-  EXPECT_EQ(kPoolSize, settings().pool_size);
+  EXPECT_EQ(21, limited_usage());
+  EXPECT_EQ(10000000, quota());
   EXPECT_LE(0, available_space());
 }
 
@@ -1742,19 +1801,16 @@
   GetCachedOrigins(kTemp, &origins);
   EXPECT_TRUE(origins.empty());
 
+  // No matter how we make queries the quota manager tries to cache all
+  // the origins at startup.
   GetHostUsage("a.com", kTemp);
   base::RunLoop().RunUntilIdle();
   GetCachedOrigins(kTemp, &origins);
-  EXPECT_EQ(2U, origins.size());
+  EXPECT_EQ(3U, origins.size());
 
   GetHostUsage("b.com", kTemp);
   base::RunLoop().RunUntilIdle();
   GetCachedOrigins(kTemp, &origins);
-  EXPECT_EQ(2U, origins.size());
-
-  GetHostUsage("c.com", kTemp);
-  base::RunLoop().RunUntilIdle();
-  GetCachedOrigins(kTemp, &origins);
   EXPECT_EQ(3U, origins.size());
 
   GetCachedOrigins(kPerm, &origins);
@@ -2211,44 +2267,44 @@
   RegisterClient(CreateClient(kData, arraysize(kData),
       QuotaClient::kFileSystem));
 
-  // Query global usage to warmup the usage tracker caching.
-  GetGlobalUsage(kTemp);
-  GetGlobalUsage(kPerm);
-  base::RunLoop().RunUntilIdle();
-
   GetUsageAndQuotaForWebApps(GURL("http://foo.com/"), kPerm);
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(kQuotaStatusOk, status());
   EXPECT_EQ(80, usage());
   EXPECT_EQ(0, quota());
 
-  const int kPoolSize = 1000;
-  const int kPerHostQuota = kPoolSize / 5;
-  SetQuotaSettings(kPoolSize, kPerHostQuota, INT64_C(0));
-
-  GetStorageCapacity();
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(kPoolSize, total_space());
-  EXPECT_EQ(kPoolSize - 80 - 10, available_space());
-
+  SetTemporaryGlobalQuota(100);
   GetUsageAndQuotaForWebApps(GURL("http://foo.com/"), kTemp);
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(kQuotaStatusOk, status());
   EXPECT_EQ(10, usage());
-  EXPECT_LE(kPerHostQuota, quota());
+  EXPECT_LE(std::min(static_cast<int64_t>(100 / kPerHostTemporaryPortion),
+                     QuotaManager::kIncognitoDefaultQuotaLimit),
+            quota());
 
   mock_special_storage_policy()->AddUnlimited(GURL("http://foo.com/"));
   GetUsageAndQuotaForWebApps(GURL("http://foo.com/"), kPerm);
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(kQuotaStatusOk, status());
   EXPECT_EQ(80, usage());
-  EXPECT_EQ(available_space() + usage(), quota());
+  EXPECT_EQ(QuotaManager::kIncognitoDefaultQuotaLimit, quota());
 
   GetUsageAndQuotaForWebApps(GURL("http://foo.com/"), kTemp);
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(kQuotaStatusOk, status());
   EXPECT_EQ(10, usage());
-  EXPECT_EQ(available_space() + usage(), quota());
+  EXPECT_EQ(QuotaManager::kIncognitoDefaultQuotaLimit, quota());
+}
+
+TEST_F(QuotaManagerTest, GetVolumeInfo) {
+  // We aren't actually testing that it's correct, just that it's sane.
+  base::FilePath tmp_dir;
+  ASSERT_TRUE(base::GetTempDir(&tmp_dir));
+  uint64_t available_space = 0;
+  uint64_t total_size = 0;
+  EXPECT_TRUE(GetVolumeInfo(tmp_dir, &available_space, &total_size));
+  EXPECT_GT(available_space, 0u) << tmp_dir.value();
+  EXPECT_GT(total_size, 0u) << tmp_dir.value();
 }
 
 }  // namespace content
diff --git a/content/browser/quota/quota_temporary_storage_evictor_unittest.cc b/content/browser/quota/quota_temporary_storage_evictor_unittest.cc
index ef417c708..989c63d 100644
--- a/content/browser/quota/quota_temporary_storage_evictor_unittest.cc
+++ b/content/browser/quota/quota_temporary_storage_evictor_unittest.cc
@@ -21,6 +21,7 @@
 
 using storage::QuotaTemporaryStorageEvictor;
 using storage::StorageType;
+using storage::UsageAndQuota;
 
 namespace content {
 
@@ -30,14 +31,15 @@
 
 class MockQuotaEvictionHandler : public storage::QuotaEvictionHandler {
  public:
-  explicit MockQuotaEvictionHandler(QuotaTemporaryStorageEvictorTest* test)
-      : available_space_(0),
+  explicit MockQuotaEvictionHandler(QuotaTemporaryStorageEvictorTest *test)
+      : quota_(0),
+        available_space_(0),
         error_on_evict_origin_data_(false),
         error_on_get_usage_and_quota_(false) {}
 
   void EvictOriginData(const GURL& origin,
                        StorageType type,
-                       const storage::StatusCallback& callback) override {
+                       const EvictOriginDataCallback& callback) override {
     if (error_on_evict_origin_data_) {
       callback.Run(storage::kQuotaErrorInvalidModification);
       return;
@@ -48,17 +50,22 @@
     callback.Run(storage::kQuotaStatusOk);
   }
 
-  void GetEvictionRoundInfo(
-      const EvictionRoundInfoCallback& callback) override {
+  void AsyncGetVolumeInfo(const VolumeInfoCallback& callback) override {
+    uint64_t available = static_cast<uint64_t>(available_space_);
+    uint64_t total = (1024 * 1024 * 1024) + (2 * available);  // 1G plus some.
+    callback.Run(true, available, total);
+  }
+
+  void GetUsageAndQuotaForEviction(
+      const UsageAndQuotaCallback& callback) override {
     if (error_on_get_usage_and_quota_) {
-      callback.Run(storage::kQuotaErrorAbort, storage::QuotaSettings(), 0, 0, 0,
-                   false);
+      callback.Run(storage::kQuotaErrorInvalidAccess, UsageAndQuota());
       return;
     }
     if (!task_for_get_usage_and_quota_.is_null())
       task_for_get_usage_and_quota_.Run();
-    callback.Run(storage::kQuotaStatusOk, settings_, available_space_,
-                 available_space_ * 2, GetUsage(), true);
+    UsageAndQuota quota_and_usage(-1, GetUsage(), quota_, available_space_);
+    callback.Run(storage::kQuotaStatusOk, quota_and_usage);
   }
 
   void GetEvictionOrigin(StorageType type,
@@ -79,13 +86,7 @@
     return total_usage;
   }
 
-  const storage::QuotaSettings& settings() const { return settings_; }
-  void SetPoolSize(int64_t pool_size) {
-    settings_.pool_size = pool_size;
-    settings_.per_host_quota = pool_size / 5;
-    settings_.must_remain_available = pool_size / 5;
-    settings_.refresh_interval = base::TimeDelta::Max();
-  }
+  void set_quota(int64_t quota) { quota_ = quota; }
   void set_available_space(int64_t available_space) {
     available_space_ = available_space;
   }
@@ -129,7 +130,7 @@
     return origin_usage;
   }
 
-  storage::QuotaSettings settings_;
+  int64_t quota_;
   int64_t available_space_;
   std::list<GURL> origin_order_;
   std::map<GURL, int64_t> origins_;
@@ -168,20 +169,20 @@
       int expected_usage_after_second) {
     EXPECT_GE(4, num_get_usage_and_quota_for_eviction_);
     switch (num_get_usage_and_quota_for_eviction_) {
-      case 2:
-        EXPECT_EQ(expected_usage_after_first,
-                  quota_eviction_handler()->GetUsage());
-        if (!origin_to_be_added.first.is_empty())
-          quota_eviction_handler()->AddOrigin(origin_to_be_added.first,
-                                              origin_to_be_added.second);
-        if (!origin_to_be_accessed.is_empty())
-          quota_eviction_handler()->AccessOrigin(origin_to_be_accessed);
-        break;
-      case 3:
-        EXPECT_EQ(expected_usage_after_second,
-                  quota_eviction_handler()->GetUsage());
-        temporary_storage_evictor()->timer_disabled_for_testing_ = true;
-        break;
+    case 2:
+      EXPECT_EQ(expected_usage_after_first,
+                quota_eviction_handler()->GetUsage());
+      if (!origin_to_be_added.first.is_empty())
+        quota_eviction_handler()->AddOrigin(origin_to_be_added.first,
+                                            origin_to_be_added.second);
+      if (!origin_to_be_accessed.is_empty())
+        quota_eviction_handler()->AccessOrigin(origin_to_be_accessed);
+      break;
+    case 3:
+      EXPECT_EQ(expected_usage_after_second,
+                quota_eviction_handler()->GetUsage());
+      temporary_storage_evictor()->set_repeated_eviction(false);
+      break;
     }
     ++num_get_usage_and_quota_for_eviction_;
   }
@@ -200,19 +201,36 @@
     return temporary_storage_evictor()->statistics_;
   }
 
-  void disable_timer_for_testing() const {
-    temporary_storage_evictor_->timer_disabled_for_testing_ = true;
+  void set_repeated_eviction(bool repeated_eviction) const {
+    return temporary_storage_evictor_->set_repeated_eviction(repeated_eviction);
   }
 
   int num_get_usage_and_quota_for_eviction() const {
     return num_get_usage_and_quota_for_eviction_;
   }
 
+  int64_t default_min_available_disk_space_to_start_eviction() const {
+    return 1000 * 1000 * 500;
+  }
+
+  void set_min_available_disk_space_to_start_eviction(int64_t value) const {
+    temporary_storage_evictor_->set_min_available_disk_space_to_start_eviction(
+        value);
+  }
+
+  void reset_min_available_disk_space_to_start_eviction() const {
+    temporary_storage_evictor_->
+        reset_min_available_disk_space_to_start_eviction();
+  }
+
   base::MessageLoop message_loop_;
   std::unique_ptr<MockQuotaEvictionHandler> quota_eviction_handler_;
   std::unique_ptr<QuotaTemporaryStorageEvictor> temporary_storage_evictor_;
+
   int num_get_usage_and_quota_for_eviction_;
+
   base::WeakPtrFactory<QuotaTemporaryStorageEvictorTest> weak_factory_;
+
   DISALLOW_COPY_AND_ASSIGN(QuotaTemporaryStorageEvictorTest);
 };
 
@@ -220,10 +238,10 @@
   quota_eviction_handler()->AddOrigin(GURL("http://www.z.com"), 3000);
   quota_eviction_handler()->AddOrigin(GURL("http://www.y.com"), 200);
   quota_eviction_handler()->AddOrigin(GURL("http://www.x.com"), 500);
-  quota_eviction_handler()->SetPoolSize(4000);
+  quota_eviction_handler()->set_quota(4000);
   quota_eviction_handler()->set_available_space(1000000000);
   EXPECT_EQ(3000 + 200 + 500, quota_eviction_handler()->GetUsage());
-  disable_timer_for_testing();
+  set_repeated_eviction(false);
   temporary_storage_evictor()->Start();
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(200 + 500, quota_eviction_handler()->GetUsage());
@@ -240,10 +258,10 @@
   quota_eviction_handler()->AddOrigin(GURL("http://www.y.com"), 2900);
   quota_eviction_handler()->AddOrigin(GURL("http://www.x.com"), 450);
   quota_eviction_handler()->AddOrigin(GURL("http://www.w.com"), 400);
-  quota_eviction_handler()->SetPoolSize(4000);
+  quota_eviction_handler()->set_quota(4000);
   quota_eviction_handler()->set_available_space(1000000000);
   EXPECT_EQ(20 + 2900 + 450 + 400, quota_eviction_handler()->GetUsage());
-  disable_timer_for_testing();
+  set_repeated_eviction(false);
   temporary_storage_evictor()->Start();
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(450 + 400, quota_eviction_handler()->GetUsage());
@@ -267,7 +285,7 @@
   quota_eviction_handler()->AddOrigin(GURL("http://www.c.com"), c_size);
   quota_eviction_handler()->AddOrigin(GURL("http://www.b.com"), b_size);
   quota_eviction_handler()->AddOrigin(GURL("http://www.a.com"), a_size);
-  quota_eviction_handler()->SetPoolSize(1000);
+  quota_eviction_handler()->set_quota(1000);
   quota_eviction_handler()->set_available_space(1000000000);
   quota_eviction_handler()->set_task_for_get_usage_and_quota(
       base::Bind(&QuotaTemporaryStorageEvictorTest::TaskForRepeatedEvictionTest,
@@ -300,14 +318,14 @@
   quota_eviction_handler()->AddOrigin(GURL("http://www.c.com"), c_size);
   quota_eviction_handler()->AddOrigin(GURL("http://www.b.com"), b_size);
   quota_eviction_handler()->AddOrigin(GURL("http://www.a.com"), a_size);
-  quota_eviction_handler()->SetPoolSize(1000);
+  quota_eviction_handler()->set_quota(1000);
   quota_eviction_handler()->set_available_space(1000000000);
   quota_eviction_handler()->set_task_for_get_usage_and_quota(
       base::Bind(&QuotaTemporaryStorageEvictorTest::TaskForRepeatedEvictionTest,
                  weak_factory_.GetWeakPtr(), std::make_pair(GURL(), 0), GURL(),
                  initial_total_size - d_size, initial_total_size - d_size));
   EXPECT_EQ(initial_total_size, quota_eviction_handler()->GetUsage());
-  // disable_timer_for_testing();
+  set_repeated_eviction(true);
   temporary_storage_evictor()->Start();
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(initial_total_size - d_size, quota_eviction_handler()->GetUsage());
@@ -332,7 +350,7 @@
   quota_eviction_handler()->AddOrigin(GURL("http://www.c.com"), c_size);
   quota_eviction_handler()->AddOrigin(GURL("http://www.b.com"), b_size);
   quota_eviction_handler()->AddOrigin(GURL("http://www.a.com"), a_size);
-  quota_eviction_handler()->SetPoolSize(1000);
+  quota_eviction_handler()->set_quota(1000);
   quota_eviction_handler()->set_available_space(1000000000);
   quota_eviction_handler()->set_task_for_get_usage_and_quota(
       base::Bind(&QuotaTemporaryStorageEvictorTest::TaskForRepeatedEvictionTest,
@@ -356,18 +374,17 @@
 }
 
 TEST_F(QuotaTemporaryStorageEvictorTest, DiskSpaceNonEvictionTest) {
-  // If we're using so little that evicting all of it wouldn't
-  // do enough to alleviate a diskspace shortage, we don't evict.
-  quota_eviction_handler()->AddOrigin(GURL("http://www.z.com"), 10);
-  quota_eviction_handler()->AddOrigin(GURL("http://www.x.com"), 20);
-  quota_eviction_handler()->SetPoolSize(10000);
+  quota_eviction_handler()->AddOrigin(GURL("http://www.z.com"), 414);
+  quota_eviction_handler()->AddOrigin(GURL("http://www.x.com"), 450);
+  quota_eviction_handler()->set_quota(10000);
   quota_eviction_handler()->set_available_space(
-      quota_eviction_handler()->settings().must_remain_available - 350);
-  EXPECT_EQ(10 + 20, quota_eviction_handler()->GetUsage());
-  disable_timer_for_testing();
+      default_min_available_disk_space_to_start_eviction() - 350);
+  EXPECT_EQ(414 + 450, quota_eviction_handler()->GetUsage());
+  reset_min_available_disk_space_to_start_eviction();
+  set_repeated_eviction(false);
   temporary_storage_evictor()->Start();
   base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(10 + 20, quota_eviction_handler()->GetUsage());
+  EXPECT_EQ(414 + 450, quota_eviction_handler()->GetUsage());
 
   EXPECT_EQ(0, statistics().num_errors_on_evicting_origin);
   EXPECT_EQ(0, statistics().num_errors_on_getting_usage_and_quota);
@@ -381,11 +398,13 @@
   quota_eviction_handler()->AddOrigin(GURL("http://www.y.com"), 120);
   quota_eviction_handler()->AddOrigin(GURL("http://www.x.com"), 150);
   quota_eviction_handler()->AddOrigin(GURL("http://www.w.com"), 300);
-  quota_eviction_handler()->SetPoolSize(10000);
+  quota_eviction_handler()->set_quota(10000);
   quota_eviction_handler()->set_available_space(
-      quota_eviction_handler()->settings().must_remain_available - 350);
+      default_min_available_disk_space_to_start_eviction() - 350);
   EXPECT_EQ(294 + 120 + 150 + 300, quota_eviction_handler()->GetUsage());
-  disable_timer_for_testing();
+  set_min_available_disk_space_to_start_eviction(
+      default_min_available_disk_space_to_start_eviction());
+  set_repeated_eviction(false);
   temporary_storage_evictor()->Start();
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(150 + 300, quota_eviction_handler()->GetUsage());
diff --git a/content/browser/quota/storage_monitor_unittest.cc b/content/browser/quota/storage_monitor_unittest.cc
index 12512cf..7cbeb91 100644
--- a/content/browser/quota/storage_monitor_unittest.cc
+++ b/content/browser/quota/storage_monitor_unittest.cc
@@ -68,8 +68,7 @@
                      base::FilePath(),
                      base::ThreadTaskRunnerHandle::Get().get(),
                      base::ThreadTaskRunnerHandle::Get().get(),
-                     special_storage_policy,
-                     storage::GetQuotaSettingsFunc()),
+                     special_storage_policy),
         callback_usage_(0),
         callback_quota_(0),
         callback_status_(kQuotaStatusOk),
@@ -89,7 +88,7 @@
   void GetUsageAndQuotaForWebApps(
       const GURL& origin,
       StorageType type,
-      const UsageAndQuotaCallback& callback) override {
+      const GetUsageAndQuotaCallback& callback) override {
     if (initialized_)
       callback.Run(callback_status_, callback_usage_, callback_quota_);
     else
@@ -104,7 +103,7 @@
   int64_t callback_quota_;
   QuotaStatusCode callback_status_;
   bool initialized_;
-  UsageAndQuotaCallback delayed_callback_;
+  GetUsageAndQuotaCallback delayed_callback_;
 };
 
 }  // namespace
@@ -650,8 +649,7 @@
     storage_policy_ = new MockSpecialStoragePolicy();
     quota_manager_ = new QuotaManager(
         false, data_dir_.GetPath(), base::ThreadTaskRunnerHandle::Get().get(),
-        base::ThreadTaskRunnerHandle::Get().get(), storage_policy_.get(),
-        storage::GetQuotaSettingsFunc());
+        base::ThreadTaskRunnerHandle::Get().get(), storage_policy_.get());
 
     client_ = new MockStorageClient(quota_manager_->proxy(),
                                     NULL,
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
index 5cbe9463..f75c596 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -934,8 +934,7 @@
       // ServiceManagerConnection prior to this point. This class of test code
       // doesn't care about render processes, so we can initialize a dummy
       // connection.
-      service_manager::mojom::ServiceRequest request =
-          mojo::MakeRequest(&test_service_);
+      service_manager::mojom::ServiceRequest request(&test_service_);
       ServiceManagerConnection::SetForProcess(ServiceManagerConnection::Create(
           std::move(request), io_task_runner));
     }
diff --git a/content/browser/service_manager/service_manager_context.cc b/content/browser/service_manager/service_manager_context.cc
index b0f2dea7..7eab342 100644
--- a/content/browser/service_manager/service_manager_context.cc
+++ b/content/browser/service_manager/service_manager_context.cc
@@ -161,8 +161,8 @@
   service_manager::mojom::ServiceRequest Start(
       std::unique_ptr<BuiltinManifestProvider> manifest_provider) {
     service_manager::mojom::ServicePtr embedder_service_proxy;
-    service_manager::mojom::ServiceRequest embedder_service_request =
-        mojo::MakeRequest(&embedder_service_proxy);
+    service_manager::mojom::ServiceRequest embedder_service_request(
+        &embedder_service_proxy);
     service_manager::mojom::ServicePtrInfo embedder_service_proxy_info =
         embedder_service_proxy.PassInterface();
     BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)->PostTask(
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc
index 2c2b2f4..931e7447 100644
--- a/content/browser/storage_partition_impl.cc
+++ b/content/browser/storage_partition_impl.cc
@@ -22,12 +22,10 @@
 #include "content/common/dom_storage/dom_storage_types.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_thread.h"
-#include "content/public/browser/content_browser_client.h"
 #include "content/public/browser/dom_storage_context.h"
 #include "content/public/browser/indexed_db_context.h"
 #include "content/public/browser/local_storage_usage_info.h"
 #include "content/public/browser/session_storage_usage_info.h"
-#include "content/public/common/content_client.h"
 #include "net/base/completion_callback.h"
 #include "net/base/net_errors.h"
 #include "net/cookies/canonical_cookie.h"
@@ -365,11 +363,36 @@
 StoragePartitionImpl::StoragePartitionImpl(
     BrowserContext* browser_context,
     const base::FilePath& partition_path,
-    storage::SpecialStoragePolicy* special_storage_policy)
+    storage::QuotaManager* quota_manager,
+    ChromeAppCacheService* appcache_service,
+    storage::FileSystemContext* filesystem_context,
+    storage::DatabaseTracker* database_tracker,
+    DOMStorageContextWrapper* dom_storage_context,
+    IndexedDBContextImpl* indexed_db_context,
+    CacheStorageContextImpl* cache_storage_context,
+    ServiceWorkerContextWrapper* service_worker_context,
+    storage::SpecialStoragePolicy* special_storage_policy,
+    HostZoomLevelContext* host_zoom_level_context,
+    PlatformNotificationContextImpl* platform_notification_context,
+    BackgroundSyncContext* background_sync_context,
+    PaymentAppContextImpl* payment_app_context,
+    scoped_refptr<BroadcastChannelProvider> broadcast_channel_provider)
     : partition_path_(partition_path),
+      quota_manager_(quota_manager),
+      appcache_service_(appcache_service),
+      filesystem_context_(filesystem_context),
+      database_tracker_(database_tracker),
+      dom_storage_context_(dom_storage_context),
+      indexed_db_context_(indexed_db_context),
+      cache_storage_context_(cache_storage_context),
+      service_worker_context_(service_worker_context),
       special_storage_policy_(special_storage_policy),
-      browser_context_(browser_context),
-      weak_factory_(this) {}
+      host_zoom_level_context_(host_zoom_level_context),
+      platform_notification_context_(platform_notification_context),
+      background_sync_context_(background_sync_context),
+      payment_app_context_(payment_app_context),
+      broadcast_channel_provider_(std::move(broadcast_channel_provider)),
+      browser_context_(browser_context) {}
 
 StoragePartitionImpl::~StoragePartitionImpl() {
   browser_context_ = nullptr;
@@ -417,38 +440,34 @@
   base::FilePath partition_path =
       context->GetPath().Append(relative_partition_path);
 
-  std::unique_ptr<StoragePartitionImpl> partition =
-      base::WrapUnique(new StoragePartitionImpl(
-          context, partition_path, context->GetSpecialStoragePolicy()));
-
   // All of the clients have to be created and registered with the
   // QuotaManager prior to the QuotaManger being used. We do them
   // all together here prior to handing out a reference to anything
   // that utilizes the QuotaManager.
-  partition->quota_manager_ = new storage::QuotaManager(
-      in_memory, partition_path,
-      BrowserThread::GetTaskRunnerForThread(BrowserThread::IO).get(),
-      BrowserThread::GetTaskRunnerForThread(BrowserThread::DB).get(),
-      context->GetSpecialStoragePolicy(),
-      base::Bind(&StoragePartitionImpl::GetQuotaSettings,
-                 partition->weak_factory_.GetWeakPtr()));
-  scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy =
-      partition->quota_manager_->proxy();
+  scoped_refptr<storage::QuotaManager> quota_manager =
+      new storage::QuotaManager(
+          in_memory, partition_path,
+          BrowserThread::GetTaskRunnerForThread(BrowserThread::IO).get(),
+          BrowserThread::GetTaskRunnerForThread(BrowserThread::DB).get(),
+          context->GetSpecialStoragePolicy());
 
   // Each consumer is responsible for registering its QuotaClient during
   // its construction.
-  partition->filesystem_context_ = CreateFileSystemContext(
-      context, partition_path, in_memory, quota_manager_proxy.get());
+  scoped_refptr<storage::FileSystemContext> filesystem_context =
+      CreateFileSystemContext(
+          context, partition_path, in_memory, quota_manager->proxy());
 
-  partition->database_tracker_ = new storage::DatabaseTracker(
-      partition_path, in_memory, context->GetSpecialStoragePolicy(),
-      quota_manager_proxy.get(),
-      BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE).get());
+  scoped_refptr<storage::DatabaseTracker> database_tracker =
+      new storage::DatabaseTracker(
+          partition_path, in_memory, context->GetSpecialStoragePolicy(),
+          quota_manager->proxy(),
+          BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE).get());
 
-  partition->dom_storage_context_ = new DOMStorageContextWrapper(
-      BrowserContext::GetConnectorFor(context),
-      in_memory ? base::FilePath() : context->GetPath(),
-      relative_partition_path, context->GetSpecialStoragePolicy());
+  scoped_refptr<DOMStorageContextWrapper> dom_storage_context =
+      new DOMStorageContextWrapper(
+          BrowserContext::GetConnectorFor(context),
+          in_memory ? base::FilePath() : context->GetPath(),
+          relative_partition_path, context->GetSpecialStoragePolicy());
 
   // BrowserMainLoop may not be initialized in unit tests. Tests will
   // need to inject their own task runner into the IndexedDBContext.
@@ -462,38 +481,61 @@
           : NULL;
 
   base::FilePath path = in_memory ? base::FilePath() : partition_path;
-  partition->indexed_db_context_ =
-      new IndexedDBContextImpl(path, context->GetSpecialStoragePolicy(),
-                               quota_manager_proxy.get(), idb_task_runner);
+  scoped_refptr<IndexedDBContextImpl> indexed_db_context =
+      new IndexedDBContextImpl(path,
+                               context->GetSpecialStoragePolicy(),
+                               quota_manager->proxy(),
+                               idb_task_runner);
 
-  partition->cache_storage_context_ = new CacheStorageContextImpl(context);
-  partition->cache_storage_context_->Init(path, quota_manager_proxy);
+  scoped_refptr<CacheStorageContextImpl> cache_storage_context =
+      new CacheStorageContextImpl(context);
+  cache_storage_context->Init(path, make_scoped_refptr(quota_manager->proxy()));
 
-  partition->service_worker_context_ = new ServiceWorkerContextWrapper(context);
-  partition->service_worker_context_->Init(path, quota_manager_proxy.get(),
-                                           context->GetSpecialStoragePolicy());
-  partition->service_worker_context_->set_storage_partition(partition.get());
+  scoped_refptr<ServiceWorkerContextWrapper> service_worker_context =
+      new ServiceWorkerContextWrapper(context);
+  service_worker_context->Init(path, quota_manager->proxy(),
+                               context->GetSpecialStoragePolicy());
 
-  partition->appcache_service_ =
-      new ChromeAppCacheService(quota_manager_proxy.get());
+  scoped_refptr<ChromeAppCacheService> appcache_service =
+      new ChromeAppCacheService(quota_manager->proxy());
 
-  partition->host_zoom_level_context_ = new HostZoomLevelContext(
-      context->CreateZoomLevelDelegate(partition_path));
+  scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy(
+      context->GetSpecialStoragePolicy());
 
-  partition->platform_notification_context_ =
+  scoped_refptr<HostZoomLevelContext> host_zoom_level_context(
+      new HostZoomLevelContext(
+          context->CreateZoomLevelDelegate(partition_path)));
+
+  scoped_refptr<PlatformNotificationContextImpl> platform_notification_context =
       new PlatformNotificationContextImpl(path, context,
-                                          partition->service_worker_context_);
-  partition->platform_notification_context_->Initialize();
+                                          service_worker_context);
+  platform_notification_context->Initialize();
 
-  partition->background_sync_context_ = new BackgroundSyncContext();
-  partition->background_sync_context_->Init(partition->service_worker_context_);
+  scoped_refptr<BackgroundSyncContext> background_sync_context =
+      new BackgroundSyncContext();
+  background_sync_context->Init(service_worker_context);
 
-  partition->payment_app_context_ = new PaymentAppContextImpl();
-  partition->payment_app_context_->Init(partition->service_worker_context_);
+  scoped_refptr<PaymentAppContextImpl> payment_app_context =
+      new PaymentAppContextImpl();
+  payment_app_context->Init(service_worker_context);
 
-  partition->broadcast_channel_provider_ = new BroadcastChannelProvider();
+  scoped_refptr<BroadcastChannelProvider>
+      broadcast_channel_provider = new BroadcastChannelProvider();
 
-  return partition;
+  std::unique_ptr<StoragePartitionImpl> storage_partition(
+      new StoragePartitionImpl(
+          context, partition_path, quota_manager.get(), appcache_service.get(),
+          filesystem_context.get(), database_tracker.get(),
+          dom_storage_context.get(), indexed_db_context.get(),
+          cache_storage_context.get(), service_worker_context.get(),
+          special_storage_policy.get(), host_zoom_level_context.get(),
+          platform_notification_context.get(), background_sync_context.get(),
+          payment_app_context.get(),
+          std::move(broadcast_channel_provider)));
+
+  service_worker_context->set_storage_partition(storage_partition.get());
+
+  return storage_partition;
 }
 
 base::FilePath StoragePartitionImpl::GetPath() {
@@ -891,10 +933,4 @@
   media_url_request_context_ = media_url_request_context;
 }
 
-void StoragePartitionImpl::GetQuotaSettings(
-    const storage::OptionalQuotaSettingsCallback& callback) {
-  GetContentClient()->browser()->GetQuotaSettings(browser_context_, this,
-                                                  callback);
-}
-
 }  // namespace content
diff --git a/content/browser/storage_partition_impl.h b/content/browser/storage_partition_impl.h
index 9833a36..50100a9 100644
--- a/content/browser/storage_partition_impl.h
+++ b/content/browser/storage_partition_impl.h
@@ -14,7 +14,6 @@
 #include "base/gtest_prod_util.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
-#include "base/memory/weak_ptr.h"
 #include "content/browser/appcache/chrome_appcache_service.h"
 #include "content/browser/background_sync/background_sync_context.h"
 #include "content/browser/broadcast_channel/broadcast_channel_provider.h"
@@ -165,9 +164,23 @@
       bool in_memory,
       const base::FilePath& relative_partition_path);
 
-  StoragePartitionImpl(BrowserContext* browser_context,
-                       const base::FilePath& partition_path,
-                       storage::SpecialStoragePolicy* special_storage_policy);
+  StoragePartitionImpl(
+      BrowserContext* browser_context,
+      const base::FilePath& partition_path,
+      storage::QuotaManager* quota_manager,
+      ChromeAppCacheService* appcache_service,
+      storage::FileSystemContext* filesystem_context,
+      storage::DatabaseTracker* database_tracker,
+      DOMStorageContextWrapper* dom_storage_context,
+      IndexedDBContextImpl* indexed_db_context,
+      CacheStorageContextImpl* cache_storage_context,
+      ServiceWorkerContextWrapper* service_worker_context,
+      storage::SpecialStoragePolicy* special_storage_policy,
+      HostZoomLevelContext* host_zoom_level_context,
+      PlatformNotificationContextImpl* platform_notification_context,
+      BackgroundSyncContext* background_sync_context,
+      PaymentAppContextImpl* payment_app_context,
+      scoped_refptr<BroadcastChannelProvider>broadcast_channel_provider);
 
   // We will never have both remove_origin be populated and a cookie_matcher.
   void ClearDataImpl(uint32_t remove_mask,
@@ -197,10 +210,6 @@
   void SetMediaURLRequestContext(
       net::URLRequestContextGetter* media_url_request_context);
 
-  // Function used by the quota system to ask the embedder for the
-  // storage configuration info.
-  void GetQuotaSettings(const storage::OptionalQuotaSettingsCallback& callback);
-
   base::FilePath partition_path_;
   scoped_refptr<net::URLRequestContextGetter> url_request_context_;
   scoped_refptr<net::URLRequestContextGetter> media_url_request_context_;
@@ -226,8 +235,6 @@
   // BrowserContext is destroyed, |this| will be destroyed too.
   BrowserContext* browser_context_;
 
-  base::WeakPtrFactory<StoragePartitionImpl> weak_factory_;
-
   DISALLOW_COPY_AND_ASSIGN(StoragePartitionImpl);
 };
 
diff --git a/content/browser/storage_partition_impl_map.cc b/content/browser/storage_partition_impl_map.cc
index 3e65c39d..0e85d8a 100644
--- a/content/browser/storage_partition_impl_map.cc
+++ b/content/browser/storage_partition_impl_map.cc
@@ -399,6 +399,10 @@
   StoragePartitionImpl* partition = partition_ptr.get();
   partitions_[partition_config] = std::move(partition_ptr);
 
+  partition->GetQuotaManager()->SetTemporaryStorageEvictionPolicy(
+      GetContentClient()->browser()->GetTemporaryStorageEvictionPolicy(
+          browser_context_));
+
   ChromeBlobStorageContext* blob_storage_context =
       ChromeBlobStorageContext::GetFor(browser_context_);
   StreamContext* stream_context = StreamContext::GetFor(browser_context_);
diff --git a/content/common/service_manager/child_connection.cc b/content/common/service_manager/child_connection.cc
index 45bbdaa..d86117f 100644
--- a/content/common/service_manager/child_connection.cc
+++ b/content/common/service_manager/child_connection.cc
@@ -91,8 +91,8 @@
     service_manager::mojom::ServicePtr service;
     service.Bind(mojo::InterfacePtrInfo<service_manager::mojom::Service>(
         std::move(service_pipe), 0u));
-    service_manager::mojom::PIDReceiverRequest pid_receiver_request =
-        mojo::MakeRequest(&pid_receiver_);
+    service_manager::mojom::PIDReceiverRequest pid_receiver_request(
+        &pid_receiver_);
 
     service_manager::Connector::ConnectParams params(child_identity);
     params.set_client_process_connection(std::move(service),
diff --git a/content/public/browser/BUILD.gn b/content/public/browser/BUILD.gn
index 021e8f5..18ad2f7 100644
--- a/content/public/browser/BUILD.gn
+++ b/content/public/browser/BUILD.gn
@@ -299,9 +299,6 @@
 
     # We expose skia headers in the public API.
     "//skia",
-
-    # We expose storage headers for quota in the public API.
-    "//storage/browser",
     "//third_party/WebKit/public:mojo_bindings",
   ]
   deps = [
@@ -314,6 +311,7 @@
     "//media",
     "//net",
     "//ppapi/c",
+    "//storage/browser",
     "//ui/accessibility",
     "//ui/base",
     "//ui/events",
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc
index 53c4b23..0a55325f 100644
--- a/content/public/browser/content_browser_client.cc
+++ b/content/public/browser/content_browser_client.cc
@@ -6,7 +6,6 @@
 
 #include "base/files/file_path.h"
 #include "base/guid.h"
-#include "base/logging.h"
 #include "build/build_config.h"
 #include "content/public/browser/client_certificate_delegate.h"
 #include "content/public/browser/memory_coordinator_delegate.h"
@@ -233,12 +232,10 @@
   return nullptr;
 }
 
-void ContentBrowserClient::GetQuotaSettings(
-    BrowserContext* context,
-    StoragePartition* partition,
-    const storage::OptionalQuotaSettingsCallback& callback) {
-  // By default, no quota is provided, embedders should override.
-  callback.Run(storage::GetNoQuotaSettings());
+std::unique_ptr<storage::QuotaEvictionPolicy>
+ContentBrowserClient::GetTemporaryStorageEvictionPolicy(
+    content::BrowserContext* context) {
+  return std::unique_ptr<storage::QuotaEvictionPolicy>();
 }
 
 void ContentBrowserClient::SelectClientCertificate(
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
index a7d5b8b..44dcf998 100644
--- a/content/public/browser/content_browser_client.h
+++ b/content/public/browser/content_browser_client.h
@@ -32,7 +32,6 @@
 #include "net/base/mime_util.h"
 #include "net/cookies/canonical_cookie.h"
 #include "storage/browser/fileapi/file_system_context.h"
-#include "storage/browser/quota/quota_manager.h"
 #include "third_party/WebKit/public/platform/WebPageVisibilityState.h"
 #include "ui/base/page_transition_types.h"
 #include "ui/base/window_open_disposition.h"
@@ -101,6 +100,7 @@
 
 namespace storage {
 class FileSystemBackend;
+class QuotaEvictionPolicy;
 }
 
 namespace content {
@@ -127,7 +127,6 @@
 class ResourceContext;
 class SiteInstance;
 class SpeechRecognitionManagerDelegate;
-class StoragePartition;
 class TracingDelegate;
 class VpnServiceProxy;
 class WebContents;
@@ -463,13 +462,10 @@
   // Create and return a new quota permission context.
   virtual QuotaPermissionContext* CreateQuotaPermissionContext();
 
-  // Allows the embedder to provide settings that determine the amount
-  // of disk space that may be used by content facing storage apis like
-  // IndexedDatabase and ServiceWorker::CacheStorage and others.
-  virtual void GetQuotaSettings(
-      content::BrowserContext* context,
-      content::StoragePartition* partition,
-      const storage::OptionalQuotaSettingsCallback& callback);
+  // Gives the embedder a chance to register a custom QuotaEvictionPolicy for
+  // temporary storage.
+  virtual std::unique_ptr<storage::QuotaEvictionPolicy>
+  GetTemporaryStorageEvictionPolicy(BrowserContext* context);
 
   // Informs the embedder that a certificate error has occured.  If
   // |overridable| is true and if |strict_enforcement| is false, the user
diff --git a/content/public/browser/utility_process_mojo_client.h b/content/public/browser/utility_process_mojo_client.h
index b8e7388..29e76fa 100644
--- a/content/public/browser/utility_process_mojo_client.h
+++ b/content/public/browser/utility_process_mojo_client.h
@@ -56,7 +56,7 @@
 
     start_called_ = true;
 
-    mojo::InterfaceRequest<MojoInterface> req = mojo::MakeRequest(&service_);
+    mojo::InterfaceRequest<MojoInterface> req(&service_);
     service_.set_connection_error_handler(on_error_callback_);
     helper_->Start(MojoInterface::Name_, req.PassMessagePipe());
   }
diff --git a/content/public/test/mock_special_storage_policy.cc b/content/public/test/mock_special_storage_policy.cc
index 0226b98e..f3b3c02 100644
--- a/content/public/test/mock_special_storage_policy.cc
+++ b/content/public/test/mock_special_storage_policy.cc
@@ -26,6 +26,10 @@
   return base::ContainsKey(session_only_, origin);
 }
 
+bool MockSpecialStoragePolicy::CanQueryDiskSize(const GURL& origin) {
+  return base::ContainsKey(can_query_disk_size_, origin);
+}
+
 bool MockSpecialStoragePolicy::HasIsolatedStorage(const GURL& origin) {
   return base::ContainsKey(isolated_, origin);
 }
diff --git a/content/public/test/mock_special_storage_policy.h b/content/public/test/mock_special_storage_policy.h
index b4a2a6c..96003e8c 100644
--- a/content/public/test/mock_special_storage_policy.h
+++ b/content/public/test/mock_special_storage_policy.h
@@ -22,6 +22,7 @@
   bool IsStorageProtected(const GURL& origin) override;
   bool IsStorageUnlimited(const GURL& origin) override;
   bool IsStorageSessionOnly(const GURL& origin) override;
+  bool CanQueryDiskSize(const GURL& origin) override;
   bool HasIsolatedStorage(const GURL& origin) override;
   bool HasSessionOnlyOrigins() override;
   bool IsStorageDurable(const GURL& origin) override;
@@ -42,6 +43,10 @@
     session_only_.insert(origin);
   }
 
+  void GrantQueryDiskSize(const GURL& origin) {
+    can_query_disk_size_.insert(origin);
+  }
+
   void AddIsolated(const GURL& origin) {
     isolated_.insert(origin);
   }
@@ -62,6 +67,7 @@
     protected_.clear();
     unlimited_.clear();
     session_only_.clear();
+    can_query_disk_size_.clear();
     file_handlers_.clear();
     isolated_.clear();
     all_unlimited_ = false;
@@ -86,6 +92,7 @@
   std::set<GURL> protected_;
   std::set<GURL> unlimited_;
   std::set<GURL> session_only_;
+  std::set<GURL> can_query_disk_size_;
   std::set<GURL> isolated_;
   std::set<GURL> durable_;
   std::set<std::string> file_handlers_;
diff --git a/content/renderer/device_sensors/device_sensor_event_pump.h b/content/renderer/device_sensors/device_sensor_event_pump.h
index 35a5e45a..b5859079 100644
--- a/content/renderer/device_sensors/device_sensor_event_pump.h
+++ b/content/renderer/device_sensors/device_sensor_event_pump.h
@@ -24,8 +24,7 @@
   template <typename... Args>
   explicit DeviceSensorMojoClientMixin(Args&&... args)
       : Base(std::forward<Args>(args)...) {
-    mojo::InterfaceRequest<MojoInterface> request =
-        mojo::MakeRequest(&mojo_interface_);
+    mojo::InterfaceRequest<MojoInterface> request(&mojo_interface_);
 
     // When running layout tests, those observers should not listen to the
     // actual hardware changes. In order to make that happen, don't connect
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 3d231cf..807848cc 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -1166,8 +1166,7 @@
 #if BUILDFLAG(ENABLE_MEDIA_REMOTING)
   // Create the RemotingSinkObserver to monitor the remoting sink availablity.
   media::mojom::RemotingSourcePtr remoting_source;
-  media::mojom::RemotingSourceRequest remoting_source_request =
-      mojo::MakeRequest(&remoting_source);
+  media::mojom::RemotingSourceRequest remoting_source_request(&remoting_source);
   media::mojom::RemoterPtr remoter;
   GetRemoterFactory()->Create(std::move(remoting_source),
                               mojo::MakeRequest(&remoter));
@@ -2767,8 +2766,7 @@
 std::unique_ptr<media::RemotingRendererController>
 RenderFrameImpl::CreateRemotingRendererController() {
   media::mojom::RemotingSourcePtr remoting_source;
-  media::mojom::RemotingSourceRequest remoting_source_request =
-      mojo::MakeRequest(&remoting_source);
+  media::mojom::RemotingSourceRequest remoting_source_request(&remoting_source);
   media::mojom::RemoterPtr remoter;
   GetRemoterFactory()->Create(std::move(remoting_source),
                               mojo::MakeRequest(&remoter));
diff --git a/content/shell/browser/layout_test/layout_test_browser_main_parts.cc b/content/shell/browser/layout_test/layout_test_browser_main_parts.cc
index 7f01424a..acb5e2a4 100644
--- a/content/shell/browser/layout_test/layout_test_browser_main_parts.cc
+++ b/content/shell/browser/layout_test/layout_test_browser_main_parts.cc
@@ -27,6 +27,7 @@
 #include "net/base/net_module.h"
 #include "net/grit/net_resources.h"
 #include "ppapi/features/features.h"
+#include "storage/browser/quota/quota_manager.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "url/gurl.h"
 
@@ -50,6 +51,13 @@
 
 namespace content {
 
+namespace {
+
+// Default quota for each origin is 5MB.
+const int kDefaultLayoutTestQuotaBytes = 5 * 1024 * 1024;
+
+}  // namespace
+
 LayoutTestBrowserMainParts::LayoutTestBrowserMainParts(
     const MainFunctionParams& parameters)
     : ShellBrowserMainParts(parameters) {
@@ -64,6 +72,18 @@
 }
 
 void LayoutTestBrowserMainParts::InitializeMessageLoopContext() {
+  storage::QuotaManager* quota_manager =
+      BrowserContext::GetDefaultStoragePartition(browser_context())
+          ->GetQuotaManager();
+  BrowserThread::PostTask(
+      BrowserThread::IO,
+      FROM_HERE,
+      base::Bind(&storage::QuotaManager::SetTemporaryGlobalOverrideQuota,
+                 quota_manager,
+                 kDefaultLayoutTestQuotaBytes *
+                     storage::QuotaManager::kPerHostTemporaryPortion,
+                 storage::QuotaCallback()));
+
 #if BUILDFLAG(ENABLE_PLUGINS)
   PluginService* plugin_service = PluginService::GetInstance();
   plugin_service_filter_.reset(new ShellPluginServiceFilter);
diff --git a/content/shell/browser/layout_test/layout_test_content_browser_client.cc b/content/shell/browser/layout_test/layout_test_content_browser_client.cc
index f913fdb..3b25ecd 100644
--- a/content/shell/browser/layout_test/layout_test_content_browser_client.cc
+++ b/content/shell/browser/layout_test/layout_test_content_browser_client.cc
@@ -128,13 +128,6 @@
   return shell_browser_main_parts();
 }
 
-void LayoutTestContentBrowserClient::GetQuotaSettings(
-    BrowserContext* context,
-    StoragePartition* partition,
-    const storage::OptionalQuotaSettingsCallback& callback) {
-  callback.Run(storage::GetHardCodedSettings(5 * 1024 * 1024));
-}
-
 PlatformNotificationService*
 LayoutTestContentBrowserClient::GetPlatformNotificationService() {
   return layout_test_notification_manager_.get();
diff --git a/content/shell/browser/layout_test/layout_test_content_browser_client.h b/content/shell/browser/layout_test/layout_test_content_browser_client.h
index f2091ea..e3fe22f 100644
--- a/content/shell/browser/layout_test/layout_test_content_browser_client.h
+++ b/content/shell/browser/layout_test/layout_test_content_browser_client.h
@@ -37,10 +37,6 @@
                                       int child_process_id) override;
   BrowserMainParts* CreateBrowserMainParts(
       const MainFunctionParams& parameters) override;
-  void GetQuotaSettings(
-      content::BrowserContext* context,
-      content::StoragePartition* partition,
-      const storage::OptionalQuotaSettingsCallback& callback) override;
 
   PlatformNotificationService* GetPlatformNotificationService() override;
 
diff --git a/content/shell/browser/layout_test/layout_test_message_filter.cc b/content/shell/browser/layout_test/layout_test_message_filter.cc
index fe7ddf46..248f3e1 100644
--- a/content/shell/browser/layout_test/layout_test_message_filter.cc
+++ b/content/shell/browser/layout_test/layout_test_message_filter.cc
@@ -119,7 +119,9 @@
 }
 
 void LayoutTestMessageFilter::OnSetDatabaseQuota(int quota) {
-  quota_manager_->SetQuotaSettings(storage::GetHardCodedSettings(quota));
+  quota_manager_->SetTemporaryGlobalOverrideQuota(
+      quota * storage::QuotaManager::kPerHostTemporaryPortion,
+      storage::QuotaCallback());
 }
 
 void LayoutTestMessageFilter::OnSimulateWebNotificationClick(
diff --git a/content/shell/browser/shell_content_browser_client.cc b/content/shell/browser/shell_content_browser_client.cc
index cb70799..2b44625 100644
--- a/content/shell/browser/shell_content_browser_client.cc
+++ b/content/shell/browser/shell_content_browser_client.cc
@@ -39,7 +39,6 @@
 #include "content/shell/common/shell_switches.h"
 #include "grit/shell_resources.h"
 #include "net/url_request/url_request_context_getter.h"
-#include "storage/browser/quota/quota_settings.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "url/gurl.h"
 #include "url/origin.h"
@@ -293,13 +292,6 @@
   return new ShellQuotaPermissionContext();
 }
 
-void ShellContentBrowserClient::GetQuotaSettings(
-    BrowserContext* context,
-    StoragePartition* partition,
-    const storage::OptionalQuotaSettingsCallback& callback) {
-  callback.Run(storage::GetHardCodedSettings(100 * 1024 * 1024));
-}
-
 void ShellContentBrowserClient::SelectClientCertificate(
     WebContents* web_contents,
     net::SSLCertRequestInfo* cert_request_info,
diff --git a/content/shell/browser/shell_content_browser_client.h b/content/shell/browser/shell_content_browser_client.h
index 84365ef..d1937bfb 100644
--- a/content/shell/browser/shell_content_browser_client.h
+++ b/content/shell/browser/shell_content_browser_client.h
@@ -47,10 +47,6 @@
   WebContentsViewDelegate* GetWebContentsViewDelegate(
       WebContents* web_contents) override;
   QuotaPermissionContext* CreateQuotaPermissionContext() override;
-  void GetQuotaSettings(
-      content::BrowserContext* context,
-      content::StoragePartition* partition,
-      const storage::OptionalQuotaSettingsCallback& callback) override;
   void SelectClientCertificate(
       WebContents* web_contents,
       net::SSLCertRequestInfo* cert_request_info,
diff --git a/content/test/test_content_browser_client.cc b/content/test/test_content_browser_client.cc
index 52a7ba6..b766e537 100644
--- a/content/test/test_content_browser_client.cc
+++ b/content/test/test_content_browser_client.cc
@@ -6,7 +6,6 @@
 
 #include "base/files/file_path.h"
 #include "base/logging.h"
-#include "storage/browser/quota/quota_settings.h"
 
 namespace content {
 
@@ -24,11 +23,4 @@
   return download_dir_.GetPath();
 }
 
-void TestContentBrowserClient::GetQuotaSettings(
-    BrowserContext* context,
-    StoragePartition* partition,
-    const storage::OptionalQuotaSettingsCallback& callback) {
-  callback.Run(storage::GetHardCodedSettings(100 * 1024 * 1024));
-}
-
 }  // namespace content
diff --git a/content/test/test_content_browser_client.h b/content/test/test_content_browser_client.h
index 6511df27..5945806 100644
--- a/content/test/test_content_browser_client.h
+++ b/content/test/test_content_browser_client.h
@@ -20,10 +20,6 @@
   TestContentBrowserClient();
   ~TestContentBrowserClient() override;
   base::FilePath GetDefaultDownloadDirectory() override;
-  void GetQuotaSettings(
-      content::BrowserContext* context,
-      content::StoragePartition* partition,
-      const storage::OptionalQuotaSettingsCallback& callback) override;
 
  private:
   // Temporary directory for GetDefaultDownloadDirectory.
diff --git a/extensions/shell/browser/shell_content_browser_client.cc b/extensions/shell/browser/shell_content_browser_client.cc
index f90a299..c3d37aec 100644
--- a/extensions/shell/browser/shell_content_browser_client.cc
+++ b/extensions/shell/browser/shell_content_browser_client.cc
@@ -37,7 +37,6 @@
 #include "extensions/shell/browser/shell_extension_system.h"
 #include "extensions/shell/browser/shell_navigation_ui_data.h"
 #include "extensions/shell/browser/shell_speech_recognition_manager_delegate.h"
-#include "storage/browser/quota/quota_settings.h"
 #include "url/gurl.h"
 
 #if !defined(DISABLE_NACL)
@@ -121,17 +120,6 @@
   return true;
 }
 
-void ShellContentBrowserClient::GetQuotaSettings(
-    content::BrowserContext* context,
-    content::StoragePartition* partition,
-    const storage::OptionalQuotaSettingsCallback& callback) {
-  content::BrowserThread::PostTaskAndReplyWithResult(
-      content::BrowserThread::FILE, FROM_HERE,
-      base::Bind(&storage::CalculateNominalDynamicSettings,
-                 partition->GetPath(), context->IsOffTheRecord()),
-      callback);
-}
-
 bool ShellContentBrowserClient::IsHandledURL(const GURL& url) {
   if (!url.is_valid())
     return false;
diff --git a/extensions/shell/browser/shell_content_browser_client.h b/extensions/shell/browser/shell_content_browser_client.h
index d626afa..f3621dc 100644
--- a/extensions/shell/browser/shell_content_browser_client.h
+++ b/extensions/shell/browser/shell_content_browser_client.h
@@ -43,10 +43,7 @@
   void RenderProcessWillLaunch(content::RenderProcessHost* host) override;
   bool ShouldUseProcessPerSite(content::BrowserContext* browser_context,
                                const GURL& effective_url) override;
-  void GetQuotaSettings(
-      content::BrowserContext* context,
-      content::StoragePartition* partition,
-      const storage::OptionalQuotaSettingsCallback& callback) override;
+  // TODO(jamescook): Quota management?
   bool IsHandledURL(const GURL& url) override;
   void SiteInstanceGotProcess(content::SiteInstance* site_instance) override;
   void SiteInstanceDeleting(content::SiteInstance* site_instance) override;
diff --git a/extensions/shell/browser/shell_special_storage_policy.cc b/extensions/shell/browser/shell_special_storage_policy.cc
index 26b9dc2..d43c71b 100644
--- a/extensions/shell/browser/shell_special_storage_policy.cc
+++ b/extensions/shell/browser/shell_special_storage_policy.cc
@@ -30,6 +30,10 @@
   return false;
 }
 
+bool ShellSpecialStoragePolicy::CanQueryDiskSize(const GURL& origin) {
+  return true;
+}
+
 bool ShellSpecialStoragePolicy::HasSessionOnlyOrigins() {
   return false;
 }
diff --git a/extensions/shell/browser/shell_special_storage_policy.h b/extensions/shell/browser/shell_special_storage_policy.h
index 0973c3a..dc78154 100644
--- a/extensions/shell/browser/shell_special_storage_policy.h
+++ b/extensions/shell/browser/shell_special_storage_policy.h
@@ -20,6 +20,7 @@
   bool IsStorageUnlimited(const GURL& origin) override;
   bool IsStorageDurable(const GURL& origin) override;
   bool IsStorageSessionOnly(const GURL& origin) override;
+  bool CanQueryDiskSize(const GURL& origin) override;
   bool HasIsolatedStorage(const GURL& origin) override;
   bool HasSessionOnlyOrigins() override;
 
diff --git a/headless/lib/browser/DEPS b/headless/lib/browser/DEPS
index 0df32e1..1704e22 100644
--- a/headless/lib/browser/DEPS
+++ b/headless/lib/browser/DEPS
@@ -1,5 +1,4 @@
 include_rules = [
   "+components/security_state",
-  "+storage/browser/quota",
   "+ui/aura",
 ]
diff --git a/headless/lib/browser/headless_content_browser_client.cc b/headless/lib/browser/headless_content_browser_client.cc
index e81f084..1bfe88ff 100644
--- a/headless/lib/browser/headless_content_browser_client.cc
+++ b/headless/lib/browser/headless_content_browser_client.cc
@@ -14,14 +14,12 @@
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/render_view_host.h"
-#include "content/public/browser/storage_partition.h"
 #include "content/public/common/service_names.mojom.h"
 #include "headless/grit/headless_lib_resources.h"
 #include "headless/lib/browser/headless_browser_context_impl.h"
 #include "headless/lib/browser/headless_browser_impl.h"
 #include "headless/lib/browser/headless_browser_main_parts.h"
 #include "headless/lib/browser/headless_devtools_manager_delegate.h"
-#include "storage/browser/quota/quota_settings.h"
 #include "ui/base/resource/resource_bundle.h"
 
 namespace headless {
@@ -88,15 +86,4 @@
   return manifest;
 }
 
-void HeadlessContentBrowserClient::GetQuotaSettings(
-    content::BrowserContext* context,
-    content::StoragePartition* partition,
-    const storage::OptionalQuotaSettingsCallback& callback) {
-  content::BrowserThread::PostTaskAndReplyWithResult(
-      content::BrowserThread::FILE, FROM_HERE,
-      base::Bind(&storage::CalculateNominalDynamicSettings,
-                 partition->GetPath(), context->IsOffTheRecord()),
-      callback);
-}
-
 }  // namespace headless
diff --git a/headless/lib/browser/headless_content_browser_client.h b/headless/lib/browser/headless_content_browser_client.h
index 82c5d9e7..511083bf 100644
--- a/headless/lib/browser/headless_content_browser_client.h
+++ b/headless/lib/browser/headless_content_browser_client.h
@@ -24,10 +24,6 @@
   content::DevToolsManagerDelegate* GetDevToolsManagerDelegate() override;
   std::unique_ptr<base::Value> GetServiceManifestOverlay(
       const std::string& name) override;
-  void GetQuotaSettings(
-      content::BrowserContext* context,
-      content::StoragePartition* partition,
-      const storage::OptionalQuotaSettingsCallback& callback) override;
 
  private:
   HeadlessBrowserImpl* browser_;  // Not owned.
diff --git a/ios/chrome/app/app_delegate.mm b/ios/chrome/app/app_delegate.mm
index 2f2b3aa2..5d0ab60 100644
--- a/ios/chrome/app/app_delegate.mm
+++ b/ios/chrome/app/app_delegate.mm
@@ -111,7 +111,6 @@
     [[StartChromeMain alloc] init],
     [[SetBrowserState alloc] init],
     [[BeginForegrounding alloc] init],
-    [[BrowserStateInitializer alloc] init],
     [[PrepareForUI alloc] init],
     [[CompleteForegrounding alloc] init],
     [[TabGridCoordinator alloc] init],
diff --git a/ios/chrome/app/main_controller.mm b/ios/chrome/app/main_controller.mm
index fa6b767..a2ac1bc 100644
--- a/ios/chrome/app/main_controller.mm
+++ b/ios/chrome/app/main_controller.mm
@@ -488,8 +488,6 @@
 - (void)markEulaAsAccepted;
 // Sends any feedback that happens to still be on local storage.
 - (void)sendQueuedFeedback;
-// Sets the iOS cookie policy to match that of the given browser state.
-- (void)setInitialCookiesPolicy:(ios::ChromeBrowserState*)browserState;
 // Called whenever an orientation change is received.
 - (void)orientationDidChange:(NSNotification*)notification;
 // Register to receive orientation change notification to update breakpad
@@ -790,7 +788,6 @@
 
 - (void)initializeBrowserState:(ios::ChromeBrowserState*)browserState {
   DCHECK(!browserState->IsOffTheRecord());
-  [self setInitialCookiesPolicy:browserState];
   search_engines::UpdateSearchEnginesIfNeeded(
       browserState->GetPrefs(),
       ios::TemplateURLServiceFactory::GetForBrowserState(browserState));
@@ -1046,43 +1043,6 @@
                   }];
 }
 
-- (void)setInitialCookiesPolicy:(ios::ChromeBrowserState*)browserState {
-  DCHECK(browserState);
-  net::CookieStoreIOS::CookiePolicy policy = net::CookieStoreIOS::BLOCK;
-
-  auto settingsFactory =
-      ios::HostContentSettingsMapFactory::GetForBrowserState(browserState);
-  DCHECK(settingsFactory);
-  ContentSetting cookieSetting = settingsFactory->GetDefaultContentSetting(
-      CONTENT_SETTINGS_TYPE_COOKIES, nullptr);
-
-  if (!web::IsAcceptCookieControlSupported()) {
-    // Override the Accept Cookie policy as ALLOW is the only policy
-    // supported by //web.
-    policy = net::CookieStoreIOS::ALLOW;
-    if (cookieSetting == CONTENT_SETTING_BLOCK) {
-      settingsFactory->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_COOKIES,
-                                                CONTENT_SETTING_ALLOW);
-    }
-  } else {
-    switch (cookieSetting) {
-      case CONTENT_SETTING_ALLOW:
-        policy = net::CookieStoreIOS::ALLOW;
-        break;
-      case CONTENT_SETTING_BLOCK:
-        policy = net::CookieStoreIOS::BLOCK;
-        break;
-      default:
-        NOTREACHED() << "Unsupported cookie policy.";
-        break;
-    }
-  }
-
-  web::WebThread::PostTask(
-      web::WebThread::IO, FROM_HERE,
-      base::Bind(&net::CookieStoreIOS::SetCookiePolicy, policy));
-}
-
 - (void)orientationDidChange:(NSNotification*)notification {
   breakpad_helper::SetCurrentOrientation(
       [[UIApplication sharedApplication] statusBarOrientation],
diff --git a/ios/chrome/app/steps/launch_to_foreground.h b/ios/chrome/app/steps/launch_to_foreground.h
index 4738131..3bf368d 100644
--- a/ios/chrome/app/steps/launch_to_foreground.h
+++ b/ios/chrome/app/steps/launch_to_foreground.h
@@ -22,14 +22,6 @@
 @interface BeginForegrounding : NSObject<ApplicationStep>
 @end
 
-// Initializes the browser state held by the application state, setting its
-// initial cookie policies and any other pre-foreground inialization.
-//  Pre:  Application phase is APPLICATION_BACKGROUNDED and the application
-//        state has a non-null browser state.
-//  Post: Application phase is (still) APPLICATION_BACKGROUNDED.
-@interface BrowserStateInitializer : NSObject<ApplicationStep>
-@end
-
 // Creates the main window and makes it key, but doesn't make it visible yet.
 //  Pre:  Application phase is APPLICATION_BACKGROUNDED.
 //  Post: Application phase is (still) APPLICATION_BACKGROUNDED.
diff --git a/ios/chrome/app/steps/launch_to_foreground.mm b/ios/chrome/app/steps/launch_to_foreground.mm
index 9b9b357e..4ec0b58 100644
--- a/ios/chrome/app/steps/launch_to_foreground.mm
+++ b/ios/chrome/app/steps/launch_to_foreground.mm
@@ -13,7 +13,6 @@
 #include "ios/chrome/browser/application_context.h"
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
 #include "ios/chrome/browser/content_settings/host_content_settings_map_factory.h"
-#include "ios/net/cookies/cookie_store_ios.h"
 #include "ios/web/public/web_capabilities.h"
 #include "ios/web/public/web_thread.h"
 
@@ -37,57 +36,6 @@
 
 @end
 
-@implementation BrowserStateInitializer
-
-- (BOOL)canRunInState:(ApplicationState*)state {
-  return state.browserState && state.phase == APPLICATION_BACKGROUNDED;
-}
-
-- (void)runInState:(ApplicationState*)state {
-  DCHECK(!state.browserState->IsOffTheRecord());
-  [self setInitialCookiesPolicy:state.browserState];
-}
-
-// Copied verbatim from MainController.
-- (void)setInitialCookiesPolicy:(ios::ChromeBrowserState*)browserState {
-  DCHECK(browserState);
-  net::CookieStoreIOS::CookiePolicy policy = net::CookieStoreIOS::BLOCK;
-
-  auto settingsFactory =
-      ios::HostContentSettingsMapFactory::GetForBrowserState(browserState);
-  DCHECK(settingsFactory);
-  ContentSetting cookieSetting = settingsFactory->GetDefaultContentSetting(
-      CONTENT_SETTINGS_TYPE_COOKIES, nullptr);
-
-  if (!web::IsAcceptCookieControlSupported()) {
-    // Override the Accept Cookie policy as ALLOW is the only policy
-    // supported by //web.
-    policy = net::CookieStoreIOS::ALLOW;
-    if (cookieSetting == CONTENT_SETTING_BLOCK) {
-      settingsFactory->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_COOKIES,
-                                                CONTENT_SETTING_ALLOW);
-    }
-  } else {
-    switch (cookieSetting) {
-      case CONTENT_SETTING_ALLOW:
-        policy = net::CookieStoreIOS::ALLOW;
-        break;
-      case CONTENT_SETTING_BLOCK:
-        policy = net::CookieStoreIOS::BLOCK;
-        break;
-      default:
-        NOTREACHED() << "Unsupported cookie policy.";
-        break;
-    }
-  }
-
-  web::WebThread::PostTask(
-      web::WebThread::IO, FROM_HERE,
-      base::Bind(&net::CookieStoreIOS::SetCookiePolicy, policy));
-}
-
-@end
-
 @implementation PrepareForUI
 
 - (BOOL)canRunInState:(ApplicationState*)state {
diff --git a/ios/chrome/browser/BUILD.gn b/ios/chrome/browser/BUILD.gn
index 81b92b1..14b6799 100644
--- a/ios/chrome/browser/BUILD.gn
+++ b/ios/chrome/browser/BUILD.gn
@@ -281,7 +281,6 @@
     "//ios/chrome/browser/ui:browser_list",
     "//ios/chrome/browser/ui/autofill:autofill_internal",
     "//ios/chrome/browser/ui/bookmarks",
-    "//ios/chrome/browser/ui/infobars",
     "//ios/chrome/browser/ui/webui:webui_internal",
     "//ios/chrome/common",
   ]
diff --git a/ios/chrome/browser/downstream_chromium_browser_provider.h b/ios/chrome/browser/downstream_chromium_browser_provider.h
index 978e5ae..2e812fd 100644
--- a/ios/chrome/browser/downstream_chromium_browser_provider.h
+++ b/ios/chrome/browser/downstream_chromium_browser_provider.h
@@ -21,9 +21,6 @@
   // converted to not go through the provider API at all.
   void RegisterProfilePrefs(
       user_prefs::PrefRegistrySyncable* registry) override;
-  InfoBarViewPlaceholder CreateInfoBarView(
-      CGRect frame,
-      InfoBarViewDelegate* delegate) override NS_RETURNS_RETAINED;
   ios::LiveTabContextProvider* GetLiveTabContextProvider() override;
   void SetUIViewAlphaWithAnimation(UIView* view, float alpha) override;
   autofill::CardUnmaskPromptView* CreateCardUnmaskPromptView(
diff --git a/ios/chrome/browser/downstream_chromium_browser_provider.mm b/ios/chrome/browser/downstream_chromium_browser_provider.mm
index de3c9f4..2e4b3aa 100644
--- a/ios/chrome/browser/downstream_chromium_browser_provider.mm
+++ b/ios/chrome/browser/downstream_chromium_browser_provider.mm
@@ -17,7 +17,6 @@
 #import "ios/chrome/browser/ui/bookmarks/bookmark_interaction_controller.h"
 #import "ios/chrome/browser/ui/bookmarks/bookmark_promo_controller.h"
 #import "ios/chrome/browser/ui/browser_list_ios.h"
-#import "ios/chrome/browser/ui/infobars/infobar_view.h"
 #include "ios/chrome/browser/ui/webui/chrome_web_ui_ios_controller_factory.h"
 #import "ios/chrome/common/material_timing.h"
 
@@ -35,12 +34,6 @@
   [HandoffManager registerBrowserStatePrefs:registry];
 }
 
-InfoBarViewPlaceholder DownstreamChromiumBrowserProvider::CreateInfoBarView(
-    CGRect frame,
-    InfoBarViewDelegate* delegate) NS_RETURNS_RETAINED {
-  return [[InfoBarView alloc] initWithFrame:frame delegate:delegate];
-}
-
 ios::LiveTabContextProvider*
 DownstreamChromiumBrowserProvider::GetLiveTabContextProvider() {
   return tab_restore_service_delegate_provider_.get();
diff --git a/ios/chrome/browser/infobars/BUILD.gn b/ios/chrome/browser/infobars/BUILD.gn
index 042c3ce..d58f015 100644
--- a/ios/chrome/browser/infobars/BUILD.gn
+++ b/ios/chrome/browser/infobars/BUILD.gn
@@ -24,8 +24,8 @@
   deps = [
     "//base",
     "//components/translate/core/browser",
+    "//ios/chrome/browser/ui/infobars",
     "//ios/public/provider/chrome/browser",
-    "//ios/public/provider/chrome/browser/ui",
     "//ios/web",
     "//ui/base",
     "//ui/gfx",
diff --git a/ios/chrome/browser/infobars/confirm_infobar_controller.mm b/ios/chrome/browser/infobars/confirm_infobar_controller.mm
index 10ab652..0cdbbdf 100644
--- a/ios/chrome/browser/infobars/confirm_infobar_controller.mm
+++ b/ios/chrome/browser/infobars/confirm_infobar_controller.mm
@@ -8,9 +8,9 @@
 #include "base/strings/string_util.h"
 #include "base/strings/sys_string_conversions.h"
 #include "components/infobars/core/confirm_infobar_delegate.h"
-#include "ios/public/provider/chrome/browser/chrome_browser_provider.h"
-#import "ios/public/provider/chrome/browser/ui/infobar_view_delegate.h"
-#import "ios/public/provider/chrome/browser/ui/infobar_view_protocol.h"
+#import "ios/chrome/browser/ui/infobars/infobar_view.h"
+#import "ios/chrome/browser/ui/infobars/infobar_view_delegate.h"
+#import "ios/chrome/browser/ui/infobars/infobar_view_protocol.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/window_open_disposition.h"
 #include "ui/gfx/image/image.h"
@@ -63,7 +63,7 @@
   UIView<InfoBarViewProtocol>* infoBarView;
   _confirmInfobarDelegate = delegate->AsConfirmInfoBarDelegate();
   infoBarView =
-      ios::GetChromeBrowserProvider()->CreateInfoBarView(frame, self.delegate);
+      [[InfoBarView alloc] initWithFrame:frame delegate:self.delegate];
   // Model data.
   gfx::Image modelIcon = _confirmInfobarDelegate->GetIcon();
   int buttons = _confirmInfobarDelegate->GetButtons();
diff --git a/ios/chrome/browser/infobars/infobar.h b/ios/chrome/browser/infobars/infobar.h
index a6cf4b11..a106a88 100644
--- a/ios/chrome/browser/infobars/infobar.h
+++ b/ios/chrome/browser/infobars/infobar.h
@@ -10,7 +10,7 @@
 #include "base/mac/scoped_nsobject.h"
 #include "base/macros.h"
 #include "components/infobars/core/infobar.h"
-#import "ios/public/provider/chrome/browser/ui/infobar_view_delegate.h"
+#import "ios/chrome/browser/ui/infobars/infobar_view_delegate.h"
 
 @class InfoBarController;
 @class UIView;
diff --git a/ios/chrome/browser/infobars/infobar_container_view.mm b/ios/chrome/browser/infobars/infobar_container_view.mm
index e3fdaa3..1278cac 100644
--- a/ios/chrome/browser/infobars/infobar_container_view.mm
+++ b/ios/chrome/browser/infobars/infobar_container_view.mm
@@ -6,7 +6,7 @@
 
 #include "base/logging.h"
 #include "ios/chrome/browser/infobars/infobar.h"
-#include "ios/public/provider/chrome/browser/ui/infobar_view_protocol.h"
+#include "ios/chrome/browser/ui/infobars/infobar_view_protocol.h"
 #include "ui/base/device_form_factor.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
diff --git a/ios/chrome/browser/infobars/infobar_controller.mm b/ios/chrome/browser/infobars/infobar_controller.mm
index 29d9fe2..47da32a 100644
--- a/ios/chrome/browser/infobars/infobar_controller.mm
+++ b/ios/chrome/browser/infobars/infobar_controller.mm
@@ -7,7 +7,7 @@
 #include <memory>
 
 #include "base/logging.h"
-#import "ios/public/provider/chrome/browser/ui/infobar_view_protocol.h"
+#import "ios/chrome/browser/ui/infobars/infobar_view_protocol.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
diff --git a/ios/chrome/browser/native_app_launcher/BUILD.gn b/ios/chrome/browser/native_app_launcher/BUILD.gn
index a4de503..271bd7d 100644
--- a/ios/chrome/browser/native_app_launcher/BUILD.gn
+++ b/ios/chrome/browser/native_app_launcher/BUILD.gn
@@ -17,9 +17,8 @@
     "//components/infobars/core",
     "//ios/chrome/app/strings",
     "//ios/chrome/browser/infobars",
-    "//ios/public/provider/chrome/browser",
+    "//ios/chrome/browser/ui/infobars",
     "//ios/public/provider/chrome/browser/native_app_launcher",
-    "//ios/public/provider/chrome/browser/ui",
     "//ui/base",
     "//url",
   ]
diff --git a/ios/chrome/browser/native_app_launcher/native_app_infobar_controller.mm b/ios/chrome/browser/native_app_launcher/native_app_infobar_controller.mm
index 4824360..0f0a823 100644
--- a/ios/chrome/browser/native_app_launcher/native_app_infobar_controller.mm
+++ b/ios/chrome/browser/native_app_launcher/native_app_infobar_controller.mm
@@ -8,10 +8,10 @@
 #include "base/mac/scoped_nsobject.h"
 #include "base/strings/sys_string_conversions.h"
 #include "ios/chrome/browser/native_app_launcher/native_app_infobar_delegate.h"
+#import "ios/chrome/browser/ui/infobars/infobar_view.h"
+#include "ios/chrome/browser/ui/infobars/infobar_view_protocol.h"
 #include "ios/chrome/grit/ios_strings.h"
-#include "ios/public/provider/chrome/browser/chrome_browser_provider.h"
 #import "ios/public/provider/chrome/browser/native_app_launcher/native_app_types.h"
-#include "ios/public/provider/chrome/browser/ui/infobar_view_protocol.h"
 #include "ui/base/l10n/l10n_util.h"
 
 @interface NativeAppInfoBarController ()
@@ -41,7 +41,7 @@
   nativeAppInfoBarDelegate_ = static_cast<NativeAppInfoBarDelegate*>(delegate);
   DCHECK(nativeAppInfoBarDelegate_);
   infoBarView.reset(
-      ios::GetChromeBrowserProvider()->CreateInfoBarView(frame, self.delegate));
+      [[InfoBarView alloc] initWithFrame:frame delegate:self.delegate]);
 
   // Lays out widgets common to all NativeAppInfobars.
   [infoBarView
diff --git a/ios/chrome/browser/passwords/BUILD.gn b/ios/chrome/browser/passwords/BUILD.gn
index d0bd285..9412649e 100644
--- a/ios/chrome/browser/passwords/BUILD.gn
+++ b/ios/chrome/browser/passwords/BUILD.gn
@@ -69,6 +69,7 @@
     "//ios/chrome/browser/ui",
     "//ios/chrome/browser/ui/commands",
     "//ios/chrome/browser/ui/elements",
+    "//ios/chrome/browser/ui/infobars",
     "//ios/public/provider/chrome/browser",
     "//ios/public/provider/chrome/browser/ui",
     "//ios/web",
diff --git a/ios/chrome/browser/passwords/credential_manager.mm b/ios/chrome/browser/passwords/credential_manager.mm
index 942a550..3fd022a 100644
--- a/ios/chrome/browser/passwords/credential_manager.mm
+++ b/ios/chrome/browser/passwords/credential_manager.mm
@@ -11,6 +11,7 @@
 #include "base/memory/scoped_vector.h"
 #include "base/strings/sys_string_conversions.h"
 #include "base/threading/thread_task_runner_handle.h"
+#include "components/password_manager/core/browser/form_saver.h"
 #include "components/password_manager/core/browser/password_store_consumer.h"
 #include "components/password_manager/core/common/credential_manager_types.h"
 #include "components/password_manager/core/common/password_manager_pref_names.h"
@@ -206,7 +207,7 @@
       new password_manager::CredentialManagerPasswordFormManager(
           client_, driver_->AsWeakPtr(),
           *password_manager::CreateObservedPasswordFormFromOrigin(page_url),
-          std::move(form), this));
+          std::move(form), this, nullptr, nullptr));
 }
 
 void CredentialManager::SignedOut(int request_id, const GURL& source_url) {
diff --git a/ios/chrome/browser/passwords/update_password_infobar_controller.mm b/ios/chrome/browser/passwords/update_password_infobar_controller.mm
index cbdea348..5cca482 100644
--- a/ios/chrome/browser/passwords/update_password_infobar_controller.mm
+++ b/ios/chrome/browser/passwords/update_password_infobar_controller.mm
@@ -10,7 +10,7 @@
 #include "ios/chrome/browser/infobars/confirm_infobar_controller+protected.h"
 #include "ios/chrome/browser/passwords/ios_chrome_update_password_infobar_delegate.h"
 #import "ios/chrome/browser/ui/elements/selector_coordinator.h"
-#import "ios/public/provider/chrome/browser/ui/infobar_view_protocol.h"
+#import "ios/chrome/browser/ui/infobars/infobar_view_protocol.h"
 
 namespace {
 // Tag for the account link in the info bar message. Set to 10 to avoid conflict
diff --git a/ios/chrome/browser/translate/BUILD.gn b/ios/chrome/browser/translate/BUILD.gn
index 46432c0..ced2a6a 100644
--- a/ios/chrome/browser/translate/BUILD.gn
+++ b/ios/chrome/browser/translate/BUILD.gn
@@ -36,8 +36,7 @@
     "//ios/chrome/browser",
     "//ios/chrome/browser/browser_state",
     "//ios/chrome/browser/infobars",
-    "//ios/public/provider/chrome/browser",
-    "//ios/public/provider/chrome/browser/ui",
+    "//ios/chrome/browser/ui/infobars",
     "//ios/web",
     "//ui/base",
     "//ui/gfx",
diff --git a/ios/chrome/browser/translate/after_translate_infobar_controller.mm b/ios/chrome/browser/translate/after_translate_infobar_controller.mm
index 8ec9e2d..e7740b9 100644
--- a/ios/chrome/browser/translate/after_translate_infobar_controller.mm
+++ b/ios/chrome/browser/translate/after_translate_infobar_controller.mm
@@ -10,9 +10,9 @@
 #include "components/strings/grit/components_strings.h"
 #include "components/translate/core/browser/translate_infobar_delegate.h"
 #include "ios/chrome/browser/translate/translate_infobar_tags.h"
-#include "ios/public/provider/chrome/browser/chrome_browser_provider.h"
-#import "ios/public/provider/chrome/browser/ui/infobar_view_delegate.h"
-#import "ios/public/provider/chrome/browser/ui/infobar_view_protocol.h"
+#import "ios/chrome/browser/ui/infobars/infobar_view.h"
+#import "ios/chrome/browser/ui/infobars/infobar_view_delegate.h"
+#import "ios/chrome/browser/ui/infobars/infobar_view_protocol.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/gfx/image/image.h"
 
@@ -37,7 +37,7 @@
   _translateInfoBarDelegate = delegate->AsTranslateInfoBarDelegate();
   DCHECK(_translateInfoBarDelegate);
   infoBarView.reset(
-      ios::GetChromeBrowserProvider()->CreateInfoBarView(frame, self.delegate));
+      [[InfoBarView alloc] initWithFrame:frame delegate:self.delegate]);
   // Icon
   gfx::Image icon = _translateInfoBarDelegate->GetIcon();
   if (!icon.IsEmpty())
diff --git a/ios/chrome/browser/translate/before_translate_infobar_controller.mm b/ios/chrome/browser/translate/before_translate_infobar_controller.mm
index d9624865..909f1f91 100644
--- a/ios/chrome/browser/translate/before_translate_infobar_controller.mm
+++ b/ios/chrome/browser/translate/before_translate_infobar_controller.mm
@@ -14,9 +14,9 @@
 #include "components/strings/grit/components_strings.h"
 #include "components/translate/core/browser/translate_infobar_delegate.h"
 #include "ios/chrome/browser/translate/translate_infobar_tags.h"
-#include "ios/public/provider/chrome/browser/chrome_browser_provider.h"
-#import "ios/public/provider/chrome/browser/ui/infobar_view_delegate.h"
-#import "ios/public/provider/chrome/browser/ui/infobar_view_protocol.h"
+#import "ios/chrome/browser/ui/infobars/infobar_view.h"
+#import "ios/chrome/browser/ui/infobars/infobar_view_delegate.h"
+#import "ios/chrome/browser/ui/infobars/infobar_view_protocol.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/gfx/image/image.h"
 
@@ -134,7 +134,7 @@
   base::scoped_nsobject<UIView<InfoBarViewProtocol>> infoBarView;
   _translateInfoBarDelegate = delegate->AsTranslateInfoBarDelegate();
   infoBarView.reset(
-      ios::GetChromeBrowserProvider()->CreateInfoBarView(frame, self.delegate));
+      [[InfoBarView alloc] initWithFrame:frame delegate:self.delegate]);
   // Icon
   gfx::Image icon = _translateInfoBarDelegate->GetIcon();
   if (!icon.IsEmpty())
diff --git a/ios/chrome/browser/translate/never_translate_infobar_controller.mm b/ios/chrome/browser/translate/never_translate_infobar_controller.mm
index 257790a..d9b2224 100644
--- a/ios/chrome/browser/translate/never_translate_infobar_controller.mm
+++ b/ios/chrome/browser/translate/never_translate_infobar_controller.mm
@@ -10,10 +10,10 @@
 #include "components/strings/grit/components_strings.h"
 #include "components/translate/core/browser/translate_infobar_delegate.h"
 #include "ios/chrome/browser/translate/translate_infobar_tags.h"
+#import "ios/chrome/browser/ui/infobars/infobar_view.h"
+#import "ios/chrome/browser/ui/infobars/infobar_view_delegate.h"
+#import "ios/chrome/browser/ui/infobars/infobar_view_protocol.h"
 #include "ios/chrome/grit/ios_chromium_strings.h"
-#include "ios/public/provider/chrome/browser/chrome_browser_provider.h"
-#import "ios/public/provider/chrome/browser/ui/infobar_view_delegate.h"
-#import "ios/public/provider/chrome/browser/ui/infobar_view_protocol.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/gfx/image/image.h"
 
@@ -35,8 +35,8 @@
   base::scoped_nsobject<UIView<InfoBarViewProtocol>> infoBarView;
   translate::TranslateInfoBarDelegate* translateInfoBarDelegate =
       delegate->AsTranslateInfoBarDelegate();
-  ios::ChromeBrowserProvider* provider = ios::GetChromeBrowserProvider();
-  infoBarView.reset(provider->CreateInfoBarView(frame, self.delegate));
+  infoBarView.reset(
+      [[InfoBarView alloc] initWithFrame:frame delegate:self.delegate]);
   // Icon
   gfx::Image icon = translateInfoBarDelegate->GetIcon();
   if (!icon.IsEmpty())
diff --git a/ios/chrome/browser/translate/translate_message_infobar_controller.mm b/ios/chrome/browser/translate/translate_message_infobar_controller.mm
index 7b51728..b02e16f 100644
--- a/ios/chrome/browser/translate/translate_message_infobar_controller.mm
+++ b/ios/chrome/browser/translate/translate_message_infobar_controller.mm
@@ -8,9 +8,9 @@
 #include "base/strings/sys_string_conversions.h"
 #include "components/translate/core/browser/translate_infobar_delegate.h"
 #include "ios/chrome/browser/translate/translate_infobar_tags.h"
-#include "ios/public/provider/chrome/browser/chrome_browser_provider.h"
-#import "ios/public/provider/chrome/browser/ui/infobar_view_delegate.h"
-#import "ios/public/provider/chrome/browser/ui/infobar_view_protocol.h"
+#import "ios/chrome/browser/ui/infobars/infobar_view.h"
+#import "ios/chrome/browser/ui/infobars/infobar_view_delegate.h"
+#import "ios/chrome/browser/ui/infobars/infobar_view_protocol.h"
 #include "ui/gfx/image/image.h"
 
 @interface TranslateMessageInfoBarController ()
@@ -29,7 +29,7 @@
   translate::TranslateInfoBarDelegate* translateInfoBarDelegate =
       delegate->AsTranslateInfoBarDelegate();
   infoBarView.reset(
-      ios::GetChromeBrowserProvider()->CreateInfoBarView(frame, self.delegate));
+      [[InfoBarView alloc] initWithFrame:frame delegate:self.delegate]);
   // Icon
   gfx::Image icon = translateInfoBarDelegate->GetIcon();
   if (!icon.IsEmpty())
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm
index b56a670e..894d4e24 100644
--- a/ios/chrome/browser/ui/browser_view_controller.mm
+++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -33,8 +33,6 @@
 #include "base/metrics/histogram.h"
 #include "base/metrics/user_metrics.h"
 #include "base/metrics/user_metrics_action.h"
-#include "base/strings/string_piece.h"
-#include "base/strings/string_util.h"
 #include "base/strings/sys_string_conversions.h"
 #include "components/bookmarks/browser/base_bookmark_model_observer.h"
 #include "components/bookmarks/browser/bookmark_model.h"
@@ -690,11 +688,11 @@
 // Induces an intentional crash in the browser process.
 - (void)induceBrowserCrash;
 // Saves the image or display error message, based on privacy settings.
-- (void)managePermissionAndSaveImage:(NSData*)data fileName:(NSString*)fileName;
+- (void)managePermissionAndSaveImage:(NSData*)data;
 // Saves the image. In order to keep the metadata of the image, the image is
 // saved as a temporary file on disk then saved in photos.
 // This should be called on FILE thread.
-- (void)saveImage:(NSData*)data fileName:(NSString*)fileName;
+- (void)saveImage:(NSData*)data;
 // Called when Chrome has been denied access to the photos or videos and the
 // user can change it.
 // Shows a privacy alert on the main queue, allowing the user to go to Chrome's
@@ -3048,46 +3046,18 @@
               referrer:(const web::Referrer&)referrer {
   DCHECK(url.is_valid());
 
-  NSString* fileName = [NSString
-      stringWithFormat:@"%@.png",
-                       [[NSProcessInfo processInfo] globallyUniqueString]];
-
-  if (url.SchemeIs(base::StringPiece("data"))) {
-    if (!base::StartsWith(url.GetContent(), "image",
-                          base::CompareCase::INSENSITIVE_ASCII)) {
-      // Not an image, return.
-      return;
-    }
-
-    // Find the type of the image. It should be positionned like here:
-    // "image/png;base...", between the '/' and the ';'.
-    size_t semiColonPosition = url.GetContent().find(std::string(";"));
-    size_t slashPosition = url.GetContent().find(std::string("/"));
-    size_t substrLength = semiColonPosition - slashPosition - 1;
-    if (substrLength > 1) {
-      // Make sure there is a type.
-      fileName = [NSString
-          stringWithFormat:@"image.%@",
-                           base::SysUTF8ToNSString(url.GetContent().substr(
-                               slashPosition + 1, substrLength))];
-    }
-  } else {
-    fileName = base::SysUTF8ToNSString(url.ExtractFileName());
-  }
-
   web::ImageFetchedCallback callback =
       ^(const GURL& original_url, int response_code, NSData* data) {
         DCHECK(data);
 
-        [self managePermissionAndSaveImage:data fileName:fileName];
+        [self managePermissionAndSaveImage:data];
       };
   _imageFetcher->StartDownload(
       url, callback, web::ReferrerHeaderValueForNavigation(url, referrer),
       web::PolicyForNavigation(url, referrer));
 }
 
-- (void)managePermissionAndSaveImage:(NSData*)data
-                            fileName:(NSString*)fileName {
+- (void)managePermissionAndSaveImage:(NSData*)data {
   switch ([PHPhotoLibrary authorizationStatus]) {
     // User was never asked for permission to access photos.
     case PHAuthorizationStatusNotDetermined:
@@ -3095,7 +3065,7 @@
         // Call -saveImage again to check if chrome needs to display an error or
         // saves the image.
         if (status != PHAuthorizationStatusNotDetermined)
-          [self managePermissionAndSaveImage:data fileName:fileName];
+          [self managePermissionAndSaveImage:data];
       }];
       break;
 
@@ -3117,14 +3087,16 @@
     default: {
       web::WebThread::PostTask(web::WebThread::FILE, FROM_HERE,
                                base::BindBlock(^{
-                                 [self saveImage:data fileName:fileName];
+                                 [self saveImage:data];
                                }));
       break;
     }
   }
 }
 
-- (void)saveImage:(NSData*)data fileName:(NSString*)fileName {
+- (void)saveImage:(NSData*)data {
+  NSString* fileName = [[[NSProcessInfo processInfo] globallyUniqueString]
+      stringByAppendingString:@".png"];
   NSURL* fileURL =
       [NSURL fileURLWithPath:[NSTemporaryDirectory()
                                  stringByAppendingPathComponent:fileName]];
diff --git a/ios/chrome/browser/ui/infobars/BUILD.gn b/ios/chrome/browser/ui/infobars/BUILD.gn
index 1f0e2f4..43f41a7 100644
--- a/ios/chrome/browser/ui/infobars/BUILD.gn
+++ b/ios/chrome/browser/ui/infobars/BUILD.gn
@@ -2,35 +2,12 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-bundle_data("resources") {
-  sources = [
-    "resources/infobar_close.png",
-    "resources/infobar_close@2x.png",
-    "resources/infobar_close@3x.png",
-    "resources/infobar_downloading.png",
-    "resources/infobar_downloading@2x.png",
-    "resources/infobar_downloading@3x.png",
-    "resources/infobar_popup_blocker.png",
-    "resources/infobar_popup_blocker@2x.png",
-    "resources/infobar_popup_blocker@3x.png",
-    "resources/infobar_shadow.png",
-    "resources/infobar_shadow@2x.png",
-    "resources/infobar_update.png",
-    "resources/infobar_update@2x.png",
-    "resources/infobar_update@3x.png",
-    "resources/infobar_warning.png",
-    "resources/infobar_warning@2x.png",
-    "resources/infobar_warning@3x.png",
-  ]
-  outputs = [
-    "{{bundle_resources_dir}}/{{source_file_part}}",
-  ]
-}
-
 source_set("infobars") {
   sources = [
     "infobar_view.h",
     "infobar_view.mm",
+    "infobar_view_delegate.h",
+    "infobar_view_protocol.h",
   ]
   deps = [
     "//base",
@@ -84,3 +61,28 @@
   ]
   libs = [ "XCTest.framework" ]
 }
+
+bundle_data("resources") {
+  sources = [
+    "resources/infobar_close.png",
+    "resources/infobar_close@2x.png",
+    "resources/infobar_close@3x.png",
+    "resources/infobar_downloading.png",
+    "resources/infobar_downloading@2x.png",
+    "resources/infobar_downloading@3x.png",
+    "resources/infobar_popup_blocker.png",
+    "resources/infobar_popup_blocker@2x.png",
+    "resources/infobar_popup_blocker@3x.png",
+    "resources/infobar_shadow.png",
+    "resources/infobar_shadow@2x.png",
+    "resources/infobar_update.png",
+    "resources/infobar_update@2x.png",
+    "resources/infobar_update@3x.png",
+    "resources/infobar_warning.png",
+    "resources/infobar_warning@2x.png",
+    "resources/infobar_warning@3x.png",
+  ]
+  outputs = [
+    "{{bundle_resources_dir}}/{{source_file_part}}",
+  ]
+}
diff --git a/ios/chrome/browser/ui/infobars/infobar_view.h b/ios/chrome/browser/ui/infobars/infobar_view.h
index d994c86..bdd312ab 100644
--- a/ios/chrome/browser/ui/infobars/infobar_view.h
+++ b/ios/chrome/browser/ui/infobars/infobar_view.h
@@ -7,7 +7,7 @@
 #import <UIKit/UIKit.h>
 
 #import "ios/chrome/browser/ui/fancy_ui/bidi_container_view.h"
-#import "ios/public/provider/chrome/browser/ui/infobar_view_protocol.h"
+#import "ios/chrome/browser/ui/infobars/infobar_view_protocol.h"
 
 class InfoBarViewDelegate;
 @protocol InfoBarViewProtocol;
diff --git a/ios/chrome/browser/ui/infobars/infobar_view.mm b/ios/chrome/browser/ui/infobars/infobar_view.mm
index 7248230..7b2ffc0 100644
--- a/ios/chrome/browser/ui/infobars/infobar_view.mm
+++ b/ios/chrome/browser/ui/infobars/infobar_view.mm
@@ -15,10 +15,10 @@
 #include "base/strings/sys_string_conversions.h"
 #include "components/strings/grit/components_strings.h"
 #import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h"
+#import "ios/chrome/browser/ui/infobars/infobar_view_delegate.h"
 #include "ios/chrome/browser/ui/ui_util.h"
 #import "ios/chrome/browser/ui/uikit_ui_util.h"
 #import "ios/chrome/browser/ui/util/label_link_controller.h"
-#import "ios/public/provider/chrome/browser/ui/infobar_view_delegate.h"
 #import "ios/third_party/material_components_ios/src/components/Buttons/src/MaterialButtons.h"
 #import "ios/third_party/material_components_ios/src/components/Typography/src/MaterialTypography.h"
 #include "ui/base/l10n/l10n_util.h"
diff --git a/ios/public/provider/chrome/browser/ui/infobar_view_delegate.h b/ios/chrome/browser/ui/infobars/infobar_view_delegate.h
similarity index 75%
rename from ios/public/provider/chrome/browser/ui/infobar_view_delegate.h
rename to ios/chrome/browser/ui/infobars/infobar_view_delegate.h
index f694f337..6cbc7f2 100644
--- a/ios/public/provider/chrome/browser/ui/infobar_view_delegate.h
+++ b/ios/chrome/browser/ui/infobars/infobar_view_delegate.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef IOS_PUBLIC_PROVIDER_CHROME_BROWSER_UI_INFOBAR_VIEW_DELEGATE_H_
-#define IOS_PUBLIC_PROVIDER_CHROME_BROWSER_UI_INFOBAR_VIEW_DELEGATE_H_
+#ifndef IOS_CHROME_BROWSER_UI_INFOBARS_INFOBAR_VIEW_DELEGATE_H_
+#define IOS_CHROME_BROWSER_UI_INFOBARS_INFOBAR_VIEW_DELEGATE_H_
 
 #import <Foundation/Foundation.h>
 
@@ -23,4 +23,4 @@
   virtual ~InfoBarViewDelegate() {}
 };
 
-#endif  // IOS_PUBLIC_PROVIDER_CHROME_BROWSER_UI_INFOBAR_VIEW_DELEGATE_H_
+#endif  // IOS_CHROME_BROWSER_UI_INFOBARS_INFOBAR_VIEW_DELEGATE_H_
diff --git a/ios/public/provider/chrome/browser/ui/infobar_view_protocol.h b/ios/chrome/browser/ui/infobars/infobar_view_protocol.h
similarity index 91%
rename from ios/public/provider/chrome/browser/ui/infobar_view_protocol.h
rename to ios/chrome/browser/ui/infobars/infobar_view_protocol.h
index 52e90e9..68642f8 100644
--- a/ios/public/provider/chrome/browser/ui/infobar_view_protocol.h
+++ b/ios/chrome/browser/ui/infobars/infobar_view_protocol.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef IOS_PUBLIC_PROVIDER_CHROME_BROWSER_UI_INFOBAR_VIEW_PROTOCOL_H_
-#define IOS_PUBLIC_PROVIDER_CHROME_BROWSER_UI_INFOBAR_VIEW_PROTOCOL_H_
+#ifndef IOS_CHROME_BROWSER_UI_INFOBARS_INFOBAR_VIEW_PROTOCOL_H_
+#define IOS_CHROME_BROWSER_UI_INFOBARS_INFOBAR_VIEW_PROTOCOL_H_
 
 #import <CoreGraphics/CoreGraphics.h>
 #import <Foundation/Foundation.h>
@@ -73,4 +73,4 @@
 
 @end
 
-#endif  // IOS_PUBLIC_PROVIDER_CHROME_BROWSER_UI_INFOBAR_VIEW_PROTOCOL_H_
+#endif  // IOS_CHROME_BROWSER_UI_INFOBARS_INFOBAR_VIEW_PROTOCOL_H_
diff --git a/ios/net/cookies/cookie_store_ios.h b/ios/net/cookies/cookie_store_ios.h
index 5419a93..80610d5 100644
--- a/ios/net/cookies/cookie_store_ios.h
+++ b/ios/net/cookies/cookie_store_ios.h
@@ -37,9 +37,6 @@
   // Called when any cookie is added, deleted or changed in
   // |NSHTTPCookieStorge sharedHTTPCookieStorage|.
   virtual void OnSystemCookiesChanged() = 0;
-  // Called when the cookie policy changes on
-  // |NSHTTPCookieStorge sharedHTTPCookieStorage|.
-  virtual void OnSystemCookiePolicyChanged() = 0;
 };
 
 // The CookieStoreIOS is an implementation of CookieStore relying on
@@ -78,11 +75,6 @@
 
   enum CookiePolicy { ALLOW, BLOCK };
 
-  // Must be called on the thread where CookieStoreIOS instances live.
-  // Affects only those CookieStoreIOS instances that are backed by
-  // |NSHTTPCookieStorage sharedHTTPCookieStorage|.
-  static void SetCookiePolicy(CookiePolicy setting);
-
   // Create an instance of CookieStoreIOS that is generated from the cookies
   // stored in |cookie_storage|. The CookieStoreIOS uses the |cookie_storage|
   // as its default backend and is initially synchronized with it.
@@ -199,7 +191,6 @@
 
   // Inherited CookieNotificationObserver methods.
   void OnSystemCookiesChanged() override;
-  void OnSystemCookiePolicyChanged() override;
 
   void DeleteCookiesWithFilter(const CookieFilterFunction& filter,
                                const DeleteCallback& callback);
diff --git a/ios/net/cookies/cookie_store_ios.mm b/ios/net/cookies/cookie_store_ios.mm
index edbbb82..a6d844cd 100644
--- a/ios/net/cookies/cookie_store_ios.mm
+++ b/ios/net/cookies/cookie_store_ios.mm
@@ -61,7 +61,6 @@
 
   // Notify the observers.
   void NotifyCookiesChanged();
-  void NotifyCookiePolicyChanged();
 
  private:
   NotificationTrampoline();
@@ -95,11 +94,6 @@
     observer.OnSystemCookiesChanged();
 }
 
-void NotificationTrampoline::NotifyCookiePolicyChanged() {
-  for (auto& observer : observer_list_)
-    observer.OnSystemCookiePolicyChanged();
-}
-
 NotificationTrampoline::NotificationTrampoline() {
 }
 
@@ -317,19 +311,6 @@
 }
 
 // static
-void CookieStoreIOS::SetCookiePolicy(CookiePolicy setting) {
-  NSHTTPCookieAcceptPolicy policy = (setting == ALLOW)
-                                        ? NSHTTPCookieAcceptPolicyAlways
-                                        : NSHTTPCookieAcceptPolicyNever;
-  NSHTTPCookieStorage* store = [NSHTTPCookieStorage sharedHTTPCookieStorage];
-  NSHTTPCookieAcceptPolicy current_policy = [store cookieAcceptPolicy];
-  if (current_policy == policy)
-    return;
-  [store setCookieAcceptPolicy:policy];
-  NotificationTrampoline::GetInstance()->NotifyCookiePolicyChanged();
-}
-
-// static
 std::unique_ptr<CookieStoreIOS> CookieStoreIOS::CreateCookieStore(
     NSHTTPCookieStorage* cookie_storage) {
   DCHECK(cookie_storage);
@@ -767,44 +748,6 @@
   creation_time_manager_->Clear();
 }
 
-void CookieStoreIOS::OnSystemCookiePolicyChanged() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-
-  // If the CookieStoreIOS is not synchronized or is not backed by
-  // |NSHTTPCookieStorage sharedHTTPCookieStorage| this callback is irrelevant.
-  if (synchronization_state_ == NOT_SYNCHRONIZED ||
-      system_store_ != [NSHTTPCookieStorage sharedHTTPCookieStorage]) {
-    return;
-  }
-
-  NSHTTPCookieAcceptPolicy policy =
-      [system_store_ cookieAcceptPolicy];
-  if (policy == NSHTTPCookieAcceptPolicyAlways) {
-    // If cookies are disabled, the system cookie store should be empty.
-    DCHECK(![[system_store_ cookies] count]);
-    DCHECK(synchronization_state_ != SYNCHRONIZING);
-    synchronization_state_ = SYNCHRONIZING;
-    cookie_monster_->GetAllCookiesAsync(base::Bind(
-        &CookieStoreIOS::AddCookiesToSystemStore, weak_factory_.GetWeakPtr()));
-  } else {
-    DCHECK_EQ(NSHTTPCookieAcceptPolicyNever, policy);
-    // FlushStore() does not write the cookies to disk when they are disabled.
-    // Explicitly copy them.
-    WriteToCookieMonster([system_store_ cookies]);
-    FlushStore(base::Closure());
-    ClearSystemStore();
-    if (synchronization_state_ == SYNCHRONIZING) {
-      // If synchronization was in progress, abort it and leave the cookie store
-      // empty.
-      // Temporarily toggle the synchronization state so that pending tasks are
-      // redirected to cookie_monster_ and can complete normally.
-      synchronization_state_ = NOT_SYNCHRONIZED;
-      RunAllPendingTasks();
-      synchronization_state_ = SYNCHRONIZED;
-    }
-  }
-}
-
 void CookieStoreIOS::SetSynchronizedWithSystemStore(bool synchronized) {
   DCHECK(thread_checker_.CalledOnValidThread());
 
diff --git a/ios/net/cookies/cookie_store_ios_unittest.mm b/ios/net/cookies/cookie_store_ios_unittest.mm
index 87c7bd4..98e63bdb 100644
--- a/ios/net/cookies/cookie_store_ios_unittest.mm
+++ b/ios/net/cookies/cookie_store_ios_unittest.mm
@@ -373,7 +373,6 @@
         kTestCookieURL4("http://bar.google.com/bar"),
         backend_(new TestPersistentCookieStore),
         store_(new net::CookieStoreIOS(backend_.get())) {
-    net::CookieStoreIOS::SetCookiePolicy(net::CookieStoreIOS::ALLOW);
     cookie_changed_callback_ = store_->AddCallbackForCookie(
         kTestCookieURL, "abc",
         base::Bind(&RecordCookieChanges, &cookies_changed_, &cookies_removed_));
@@ -544,15 +543,7 @@
   options.set_include_httponly();
   cookie_store->SetCookieWithOptionsAsync(
       kTestCookieURL, "a=b", options, net::CookieStore::SetCookiesCallback());
-  // Disallow cookies.
-  CookieStoreIOS::SetCookiePolicy(CookieStoreIOS::BLOCK);
-  // No cookie in the system store.
-  NSHTTPCookieStorage* system_store =
-      [NSHTTPCookieStorage sharedHTTPCookieStorage];
-  EXPECT_EQ(0u, [[system_store cookies] count]);
-  // Flushing should not have any effect.
-  cookie_store->FlushStore(base::Closure());
-  // Check we can get the cookie even though cookies are disabled.
+  // Check we can get the cookie.
   GetAllCookiesCallback callback;
   cookie_store->GetAllCookiesForURLAsync(
       kTestCookieURL,
@@ -562,11 +553,6 @@
   net::CanonicalCookie cookie = callback.cookie_list()[0];
   EXPECT_EQ("a", cookie.Name());
   EXPECT_EQ("b", cookie.Value());
-  // Re-enable cookies.
-  CookieStoreIOS::SetCookiePolicy(CookieStoreIOS::ALLOW);
-  // Cookie is back in the system store.
-  EXPECT_EQ(1u, [[system_store cookies] count]);
-  cookie_store->UnSynchronize();
 }
 
 // Tests that cookies can be read before the backend is loaded.
@@ -593,24 +579,6 @@
   store_->UnSynchronize();
 }
 
-// Tests that cookies can be read before synchronization is complete, when
-// triggered by a change in cookie policy.
-TEST_F(CookieStoreIOSWithBackend, SynchronizingAfterPolicyChange) {
-  ClearCookies();
-  CookieStoreIOS::SetCookiePolicy(CookieStoreIOS::BLOCK);
-  // SwitchSynchronizedStore() does nothing when cookies are blocked.
-  CookieStoreIOS::SwitchSynchronizedStore(nullptr, store_.get());
-  // Start synchronization by allowing cookies.
-  CookieStoreIOS::SetCookiePolicy(CookieStoreIOS::ALLOW);
-  GetCookieCallback callback;
-  GetCookies(base::Bind(&GetCookieCallback::Run, base::Unretained(&callback)));
-  // Backend loading completes (end of synchronization).
-  backend_->RunLoadedCallback();
-  EXPECT_TRUE(callback.did_run());
-  EXPECT_EQ("a=b", callback.cookie_line());
-  store_->UnSynchronize();
-}
-
 // Tests that Synchronization can be "aborted" (i.e. the cookie store is
 // unsynchronized while synchronization is in progress).
 TEST_F(CookieStoreIOSWithBackend, SyncThenUnsync) {
@@ -652,55 +620,6 @@
   dummy_store->UnSynchronize();
 }
 
-TEST_F(CookieStoreIOSWithBackend, ChangePolicyOnceDuringSynchronization) {
-  // Start synchronization.
-  CookieStoreIOS::SwitchSynchronizedStore(nullptr, store_.get());
-  // Toggle cookie policy to trigger another synchronization while the first one
-  // is still in progress.
-  CookieStoreIOS::SetCookiePolicy(CookieStoreIOS::BLOCK);
-  // Backend loading completes (end of synchronization).
-  backend_->RunLoadedCallback();
-  CookieStoreIOS::SetCookiePolicy(CookieStoreIOS::ALLOW);
-  GetCookieCallback callback;
-  GetCookies(base::Bind(&GetCookieCallback::Run, base::Unretained(&callback)));
-  EXPECT_TRUE(callback.did_run());
-  EXPECT_EQ("a=b", callback.cookie_line());
-  store_->UnSynchronize();
-}
-
-TEST_F(CookieStoreIOSWithBackend,
-       ChangePolicyDuringSynchronizationWithPendingTask) {
-  // Start synchronization.
-  CookieStoreIOS::SwitchSynchronizedStore(nullptr, store_.get());
-  // Create a pending task while synchronization is in progress.
-  GetCookieCallback callback;
-  GetCookies(base::Bind(&GetCookieCallback::Run, base::Unretained(&callback)));
-  // Toggle cookie policy to trigger another synchronization while the first one
-  // is still in progress.
-  CookieStoreIOS::SetCookiePolicy(CookieStoreIOS::BLOCK);
-  // Backend loading completes (end of synchronization).
-  backend_->RunLoadedCallback();
-  EXPECT_TRUE(callback.did_run());
-  EXPECT_EQ("a=b", callback.cookie_line());
-  store_->UnSynchronize();
-}
-
-TEST_F(CookieStoreIOSWithBackend, ChangePolicyTwiceDuringSynchronization) {
-  // Start synchronization.
-  CookieStoreIOS::SwitchSynchronizedStore(nullptr, store_.get());
-  // Toggle cookie policy to trigger another synchronization while the first one
-  // is still in progress.
-  CookieStoreIOS::SetCookiePolicy(CookieStoreIOS::BLOCK);
-  CookieStoreIOS::SetCookiePolicy(CookieStoreIOS::ALLOW);
-  // Backend loading completes (end of synchronization).
-  backend_->RunLoadedCallback();
-  GetCookieCallback callback;
-  GetCookies(base::Bind(&GetCookieCallback::Run, base::Unretained(&callback)));
-  EXPECT_TRUE(callback.did_run());
-  EXPECT_EQ("a=b", callback.cookie_line());
-  store_->UnSynchronize();
-}
-
 TEST_F(CookieStoreIOSWithBackend, UnSynchronizeBeforeLoadComplete) {
   ClearCookies();
   // Switch back and forth before synchronization can complete.
@@ -767,17 +686,6 @@
   store_->UnSynchronize();
 }
 
-TEST_F(CookieStoreIOSWithBackend, FlushOnPolicyChange) {
-  // Start synchronization.
-  CookieStoreIOS::SwitchSynchronizedStore(nullptr, store_.get());
-  // Toggle cookie policy to trigger a flush.
-  EXPECT_FALSE(backend_->flushed());
-  CookieStoreIOS::SetCookiePolicy(CookieStoreIOS::BLOCK);
-  EXPECT_TRUE(backend_->flushed());
-  store_->UnSynchronize();
-  CookieStoreIOS::SetCookiePolicy(CookieStoreIOS::ALLOW);
-}
-
 TEST_F(CookieStoreIOSWithBackend, NoInitialNotifyWithNoCookie) {
   CookieStoreIOS::SwitchSynchronizedStore(nullptr, store_.get());
   std::vector<net::CanonicalCookie> cookies;
diff --git a/ios/public/provider/chrome/browser/chrome_browser_provider.h b/ios/public/provider/chrome/browser/chrome_browser_provider.h
index 305cfe0..7ba4ca5 100644
--- a/ios/public/provider/chrome/browser/chrome_browser_provider.h
+++ b/ios/public/provider/chrome/browser/chrome_browser_provider.h
@@ -20,7 +20,6 @@
 class AppDistributionProvider;
 class BrandedImageProvider;
 class GURL;
-class InfoBarViewDelegate;
 class OmahaServiceProvider;
 class PrefService;
 class SpotlightProvider;
@@ -91,11 +90,6 @@
   // Registers all prefs that will be used via a PrefService attached to a
   // Profile.
   virtual void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
-  // Returns an infobar view conforming to the InfoBarViewProtocol. The returned
-  // object is retained.
-  virtual InfoBarViewPlaceholder CreateInfoBarView(
-      CGRect frame,
-      InfoBarViewDelegate* delegate) NS_RETURNS_RETAINED;
   // Returns an instance of a signing error provider.
   virtual SigninErrorProvider* GetSigninErrorProvider();
   // Returns an instance of a signin resources provider.
diff --git a/ios/public/provider/chrome/browser/chrome_browser_provider.mm b/ios/public/provider/chrome/browser/chrome_browser_provider.mm
index 95d9aec..9e85795 100644
--- a/ios/public/provider/chrome/browser/chrome_browser_provider.mm
+++ b/ios/public/provider/chrome/browser/chrome_browser_provider.mm
@@ -24,12 +24,12 @@
   return g_chrome_browser_provider;
 }
 
-ChromeBrowserProvider::~ChromeBrowserProvider() {}
-
 // A dummy implementation of ChromeBrowserProvider.
 
 ChromeBrowserProvider::ChromeBrowserProvider() {}
 
+ChromeBrowserProvider::~ChromeBrowserProvider() {}
+
 void ChromeBrowserProvider::Initialize() const {}
 
 void ChromeBrowserProvider::AssertBrowserContextKeyedFactoriesBuilt() {}
@@ -37,12 +37,6 @@
 void ChromeBrowserProvider::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {}
 
-InfoBarViewPlaceholder ChromeBrowserProvider::CreateInfoBarView(
-    CGRect frame,
-    InfoBarViewDelegate* delegate) {
-  return nullptr;
-}
-
 SigninErrorProvider* ChromeBrowserProvider::GetSigninErrorProvider() {
   return nullptr;
 }
diff --git a/ios/public/provider/chrome/browser/test_chrome_browser_provider.h b/ios/public/provider/chrome/browser/test_chrome_browser_provider.h
index 22ddbea7..8b40256 100644
--- a/ios/public/provider/chrome/browser/test_chrome_browser_provider.h
+++ b/ios/public/provider/chrome/browser/test_chrome_browser_provider.h
@@ -22,9 +22,6 @@
   static TestChromeBrowserProvider* GetTestProvider();
 
   // ChromeBrowserProvider:
-  InfoBarViewPlaceholder CreateInfoBarView(
-      CGRect frame,
-      InfoBarViewDelegate* delegate) override NS_RETURNS_RETAINED;
   SigninResourcesProvider* GetSigninResourcesProvider() override;
   void SetChromeIdentityServiceForTesting(
       std::unique_ptr<ChromeIdentityService> service) override;
diff --git a/ios/public/provider/chrome/browser/test_chrome_browser_provider.mm b/ios/public/provider/chrome/browser/test_chrome_browser_provider.mm
index be379676..7b22cb3 100644
--- a/ios/public/provider/chrome/browser/test_chrome_browser_provider.mm
+++ b/ios/public/provider/chrome/browser/test_chrome_browser_provider.mm
@@ -17,7 +17,6 @@
 #include "ios/public/provider/chrome/browser/signin/fake_chrome_identity_service.h"
 #include "ios/public/provider/chrome/browser/signin/test_signin_resources_provider.h"
 #import "ios/public/provider/chrome/browser/spotlight/test_spotlight_provider.h"
-#import "ios/public/provider/chrome/browser/ui/test_infobar_view.h"
 #import "ios/public/provider/chrome/browser/ui/test_styled_text_field.h"
 #import "ios/public/provider/chrome/browser/user_feedback/test_user_feedback_provider.h"
 #import "ios/public/provider/chrome/browser/voice/test_voice_search_provider.h"
@@ -47,12 +46,6 @@
   return static_cast<TestChromeBrowserProvider*>(provider);
 }
 
-InfoBarViewPlaceholder TestChromeBrowserProvider::CreateInfoBarView(
-    CGRect frame,
-    InfoBarViewDelegate* delegate) {
-  return [[TestInfoBarView alloc] init];
-}
-
 SigninResourcesProvider*
 TestChromeBrowserProvider::GetSigninResourcesProvider() {
   return signin_resources_provider_.get();
diff --git a/ios/public/provider/chrome/browser/ui/BUILD.gn b/ios/public/provider/chrome/browser/ui/BUILD.gn
index fb800d66..cc0f8a2 100644
--- a/ios/public/provider/chrome/browser/ui/BUILD.gn
+++ b/ios/public/provider/chrome/browser/ui/BUILD.gn
@@ -7,8 +7,6 @@
     "app_rating_prompt.h",
     "default_ios_web_view_factory.h",
     "default_ios_web_view_factory.mm",
-    "infobar_view_delegate.h",
-    "infobar_view_protocol.h",
     "logo_vendor.h",
     "text_field_styling.h",
   ]
@@ -22,8 +20,6 @@
 source_set("test_support") {
   testonly = true
   sources = [
-    "test_infobar_view.h",
-    "test_infobar_view.mm",
     "test_styled_text_field.h",
     "test_styled_text_field.mm",
   ]
diff --git a/ios/public/provider/chrome/browser/ui/test_infobar_view.h b/ios/public/provider/chrome/browser/ui/test_infobar_view.h
deleted file mode 100644
index 6c6e8805..0000000
--- a/ios/public/provider/chrome/browser/ui/test_infobar_view.h
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef IOS_PUBLIC_PROVIDER_CHROME_BROWSER_UI_TEST_INFOBAR_VIEW_H_
-#define IOS_PUBLIC_PROVIDER_CHROME_BROWSER_UI_TEST_INFOBAR_VIEW_H_
-
-#import "ios/public/provider/chrome/browser/ui/infobar_view_protocol.h"
-
-#import <UIKit/UIKit.h>
-
-@interface TestInfoBarView : UIView<InfoBarViewProtocol>
-@end
-
-#endif  // IOS_PUBLIC_PROVIDER_CHROME_BROWSER_UI_TEST_INFOBAR_VIEW_H_
diff --git a/ios/public/provider/chrome/browser/ui/test_infobar_view.mm b/ios/public/provider/chrome/browser/ui/test_infobar_view.mm
deleted file mode 100644
index ac66f1e..0000000
--- a/ios/public/provider/chrome/browser/ui/test_infobar_view.mm
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#import "ios/public/provider/chrome/browser/ui/test_infobar_view.h"
-
-@implementation TestInfoBarView
-@synthesize visibleHeight = _visibleHeight;
-
-- (NSString*)markedLabel {
-  return @"";
-}
-
-+ (NSString*)stringAsLink:(NSString*)str tag:(NSUInteger)tag {
-  return str;
-}
-
-- (void)resetDelegate {
-}
-
-- (void)addCloseButtonWithTag:(NSInteger)tag
-                       target:(id)target
-                       action:(SEL)action {
-}
-
-- (void)addLeftIcon:(UIImage*)image {
-}
-
-- (void)addPlaceholderTransparentIcon:(CGSize const&)imageSize {
-}
-
-- (void)addLeftIconWithRoundedCornersAndShadow:(UIImage*)image {
-}
-
-- (void)addLabel:(NSString*)label {
-}
-
-- (void)addLabel:(NSString*)label target:(id)target action:(SEL)action {
-}
-
-- (void)addButton1:(NSString*)title1
-              tag1:(NSInteger)tag1
-           button2:(NSString*)title2
-              tag2:(NSInteger)tag2
-            target:(id)target
-            action:(SEL)action {
-}
-
-- (void)addButton:(NSString*)title
-              tag:(NSInteger)tag
-           target:(id)target
-           action:(SEL)action {
-}
-
-- (void)addSwitchWithLabel:(NSString*)label
-                      isOn:(BOOL)isOn
-                       tag:(NSInteger)tag
-                    target:(id)target
-                    action:(SEL)action {
-}
-
-@end
diff --git a/ios/web/public/web_capabilities.cc b/ios/web/public/web_capabilities.cc
index 48632d9..8e423193 100644
--- a/ios/web/public/web_capabilities.cc
+++ b/ios/web/public/web_capabilities.cc
@@ -6,12 +6,6 @@
 
 namespace web {
 
-bool IsAcceptCookieControlSupported() {
-  // TODO(crbug.com/462424): WKWebView supports only the ALLOW policy on iOS9.
-  // Revisit this issue with the next major release of iOS.
-  return false;
-}
-
 bool IsAutoDetectEncodingSupported() {
   // TODO(crbug.com/600765): WKWebView does not provide API for auto-detection
   // of the page encoding. Revisit this issue with the next major of iOS.
diff --git a/ios/web/public/web_capabilities.h b/ios/web/public/web_capabilities.h
index 94b48c6..2eeeb98 100644
--- a/ios/web/public/web_capabilities.h
+++ b/ios/web/public/web_capabilities.h
@@ -7,10 +7,6 @@
 
 namespace web {
 
-// Returns true if fine control of "Accept Cookie" policy is supported
-// by //web.
-bool IsAcceptCookieControlSupported();
-
 // Returns true if auto-detection of page encoding is supported by //web.
 bool IsAutoDetectEncodingSupported();
 
diff --git a/ios/web/shell/view_controller.mm b/ios/web/shell/view_controller.mm
index d49cb54..893fb86 100644
--- a/ios/web/shell/view_controller.mm
+++ b/ios/web/shell/view_controller.mm
@@ -13,7 +13,6 @@
 
 #import "base/mac/scoped_nsobject.h"
 #include "base/strings/sys_string_conversions.h"
-#include "ios/net/cookies/cookie_store_ios.h"
 #import "ios/net/crn_http_protocol_handler.h"
 #import "ios/net/empty_nsurlcache.h"
 #import "ios/net/request_tracker.h"
@@ -165,7 +164,6 @@
 - (void)setUpNetworkStack {
   // Disable the default cache.
   [NSURLCache setSharedURLCache:[EmptyNSURLCache emptyNSURLCache]];
-  net::CookieStoreIOS::SetCookiePolicy(net::CookieStoreIOS::ALLOW);
 }
 
 - (void)didReceiveMemoryWarning {
diff --git a/mash/task_viewer/task_viewer.cc b/mash/task_viewer/task_viewer.cc
index 3023a49..cd9d8a4 100644
--- a/mash/task_viewer/task_viewer.cc
+++ b/mash/task_viewer/task_viewer.cc
@@ -318,8 +318,7 @@
       service_manager::mojom::kServiceName, &service_manager);
 
   service_manager::mojom::ServiceManagerListenerPtr listener;
-  service_manager::mojom::ServiceManagerListenerRequest request =
-      MakeRequest(&listener);
+  service_manager::mojom::ServiceManagerListenerRequest request(&listener);
   service_manager->AddListener(std::move(listener));
 
   catalog::mojom::CatalogPtr catalog;
diff --git a/mash/webtest/webtest.cc b/mash/webtest/webtest.cc
index 59273ab..128b177e 100644
--- a/mash/webtest/webtest.cc
+++ b/mash/webtest/webtest.cc
@@ -191,8 +191,7 @@
   context()->connector()->ConnectToInterface("navigation", &view_factory);
   navigation::mojom::ViewPtr view;
   navigation::mojom::ViewClientPtr view_client;
-  navigation::mojom::ViewClientRequest view_client_request =
-      MakeRequest(&view_client);
+  navigation::mojom::ViewClientRequest view_client_request(&view_client);
   view_factory->CreateView(std::move(view_client), MakeRequest(&view));
   UI* ui = new UI(this, std::move(view), std::move(view_client_request));
   views::Widget* window = views::Widget::CreateWindowWithContextAndBounds(
diff --git a/media/remoting/fake_remoting_controller.cc b/media/remoting/fake_remoting_controller.cc
index aacd5ea..d5dafea 100644
--- a/media/remoting/fake_remoting_controller.cc
+++ b/media/remoting/fake_remoting_controller.cc
@@ -177,8 +177,7 @@
 scoped_refptr<RemotingSourceImpl> CreateRemotingSourceImpl(
     bool start_will_fail) {
   mojom::RemotingSourcePtr remoting_source;
-  mojom::RemotingSourceRequest remoting_source_request =
-      mojo::MakeRequest(&remoting_source);
+  mojom::RemotingSourceRequest remoting_source_request(&remoting_source);
   mojom::RemoterPtr remoter;
   std::unique_ptr<mojom::RemoterFactory> remoter_factory =
       base::MakeUnique<FakeRemoterFactory>(start_will_fail);
diff --git a/media/remoting/remoting_cdm_factory.cc b/media/remoting/remoting_cdm_factory.cc
index e24b80a..dd34779 100644
--- a/media/remoting/remoting_cdm_factory.cc
+++ b/media/remoting/remoting_cdm_factory.cc
@@ -29,8 +29,7 @@
 std::unique_ptr<RemotingCdmController>
 RemotingCdmFactory::CreateRemotingCdmController() {
   mojom::RemotingSourcePtr remoting_source;
-  mojom::RemotingSourceRequest remoting_source_request =
-      mojo::MakeRequest(&remoting_source);
+  mojom::RemotingSourceRequest remoting_source_request(&remoting_source);
   mojom::RemoterPtr remoter;
   remoter_factory_->Create(std::move(remoting_source),
                            mojo::MakeRequest(&remoter));
diff --git a/mojo/public/cpp/bindings/interface_request.h b/mojo/public/cpp/bindings/interface_request.h
index 773e05db..ab23765 100644
--- a/mojo/public/cpp/bindings/interface_request.h
+++ b/mojo/public/cpp/bindings/interface_request.h
@@ -31,6 +31,19 @@
   InterfaceRequest() {}
   InterfaceRequest(decltype(nullptr)) {}
 
+  // Creates a new message pipe over which Interface is to be served, binding
+  // the specified InterfacePtr to one end of the message pipe and this
+  // InterfaceRequest to the other. For example usage, see comments on
+  // MakeRequest(InterfacePtr*) below.
+  explicit InterfaceRequest(InterfacePtr<Interface>* ptr,
+                            scoped_refptr<base::SingleThreadTaskRunner> runner =
+                                base::ThreadTaskRunnerHandle::Get()) {
+    MessagePipe pipe;
+    ptr->Bind(InterfacePtrInfo<Interface>(std::move(pipe.handle0), 0u),
+              std::move(runner));
+    Bind(std::move(pipe.handle1));
+  }
+
   // Takes the message pipe from another InterfaceRequest.
   InterfaceRequest(InterfaceRequest&& other) {
     handle_ = std::move(other.handle_);
@@ -136,7 +149,7 @@
 //
 //   CollectorPtr collector = ...;  // Connect to Collector.
 //   SourcePtr source;
-//   InterfaceRequest<Source> source_request = MakeRequest(&source);
+//   InterfaceRequest<Source> source_request(&source);
 //   collector->RegisterSource(std::move(source));
 //   CreateSource(std::move(source_request));  // Create implementation locally.
 //
@@ -145,10 +158,7 @@
     InterfacePtr<Interface>* ptr,
     scoped_refptr<base::SingleThreadTaskRunner> runner =
         base::ThreadTaskRunnerHandle::Get()) {
-  MessagePipe pipe;
-  ptr->Bind(InterfacePtrInfo<Interface>(std::move(pipe.handle0), 0u),
-            std::move(runner));
-  return MakeRequest<Interface>(std::move(pipe.handle1));
+  return InterfaceRequest<Interface>(ptr, runner);
 }
 
 // Fuses an InterfaceRequest<T> endpoint with an InterfacePtrInfo<T> endpoint.
diff --git a/mojo/public/cpp/bindings/tests/handle_passing_unittest.cc b/mojo/public/cpp/bindings/tests/handle_passing_unittest.cc
index 9d31620..fcdebda3 100644
--- a/mojo/public/cpp/bindings/tests/handle_passing_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/handle_passing_unittest.cc
@@ -327,7 +327,7 @@
   sample::NamedObjectPtr object1;
   EXPECT_FALSE(object1);
 
-  InterfaceRequest<sample::NamedObject> object1_request = MakeRequest(&object1);
+  InterfaceRequest<sample::NamedObject> object1_request(&object1);
   EXPECT_TRUE(object1_request.is_pending());
   factory->CreateNamedObject(std::move(object1_request));
   EXPECT_FALSE(object1_request.is_pending());  // We've passed the request.
diff --git a/mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc b/mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc
index 138a9271..1765a062 100644
--- a/mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc
@@ -708,7 +708,7 @@
 
   // Create another PingTest pipe.
   sample::PingTestPtr ptr;
-  sample::PingTestRequest request = MakeRequest(&ptr);
+  sample::PingTestRequest request(&ptr);
 
   // Fuse the new pipe to the one hanging off |impl|.
   EXPECT_TRUE(FuseInterface(std::move(request), proxy.PassInterface()));
@@ -796,7 +796,7 @@
 
 TEST_F(InterfacePtrTest, CallbackOwnsInterfacePtr) {
   sample::PingTestPtr ptr;
-  sample::PingTestRequest request = MakeRequest(&ptr);
+  sample::PingTestRequest request(&ptr);
 
   base::RunLoop run_loop;
 
diff --git a/mojo/public/cpp/bindings/tests/pickle_unittest.cc b/mojo/public/cpp/bindings/tests/pickle_unittest.cc
index 92a5c13..39ce6b4 100644
--- a/mojo/public/cpp/bindings/tests/pickle_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/pickle_unittest.cc
@@ -160,7 +160,7 @@
   template <typename ProxyType = PicklePasser>
   InterfacePtr<ProxyType> ConnectToChromiumService() {
     InterfacePtr<ProxyType> proxy;
-    InterfaceRequest<ProxyType> request = MakeRequest(&proxy);
+    InterfaceRequest<ProxyType> request(&proxy);
     chromium_bindings_.AddBinding(
         &chromium_service_,
         ConvertInterfaceRequest<PicklePasser>(std::move(request)));
@@ -170,7 +170,7 @@
   template <typename ProxyType = blink::PicklePasser>
   InterfacePtr<ProxyType> ConnectToBlinkService() {
     InterfacePtr<ProxyType> proxy;
-    InterfaceRequest<ProxyType> request = MakeRequest(&proxy);
+    InterfaceRequest<ProxyType> request(&proxy);
     blink_bindings_.AddBinding(
         &blink_service_,
         ConvertInterfaceRequest<blink::PicklePasser>(std::move(request)));
diff --git a/net/log/net_log_event_type_list.h b/net/log/net_log_event_type_list.h
index c7cb11d..37cb814 100644
--- a/net/log/net_log_event_type_list.h
+++ b/net/log/net_log_event_type_list.h
@@ -1435,6 +1435,14 @@
 
 // Event when the creation of a stream is stalled because we're at
 // the maximum number of concurrent streams.
+//  {
+//
+//    "num_active_streams": <Number of active streams>,
+//    "num_created_streams": <Number of created streams>,
+//    "num_pushed_streams": <Number of pushed streams>,
+//    "max_concurrent_streams": <Maximum number of concurrent streams>,
+//    "url": <Request URL>,
+//  }
 EVENT_TYPE(HTTP2_SESSION_STALLED_MAX_STREAMS)
 
 // Received an out-of-range value for initial window size in SETTINGS
diff --git a/net/quic/chromium/quic_chromium_client_stream.cc b/net/quic/chromium/quic_chromium_client_stream.cc
index b533b49..0bf3d21 100644
--- a/net/quic/chromium/quic_chromium_client_stream.cc
+++ b/net/quic/chromium/quic_chromium_client_stream.cc
@@ -123,8 +123,7 @@
 size_t QuicChromiumClientStream::WriteHeaders(
     SpdyHeaderBlock header_block,
     bool fin,
-    QuicReferenceCountedPointer<QuicAckListenerInterface>
-        ack_notifier_delegate) {
+    QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) {
   if (!session()->IsCryptoHandshakeConfirmed()) {
     auto entry = header_block.find(":method");
     DCHECK(entry != header_block.end());
@@ -135,7 +134,7 @@
       base::Bind(&QuicRequestNetLogCallback, id(), &header_block,
                  QuicSpdyStream::priority()));
   return QuicSpdyStream::WriteHeaders(std::move(header_block), fin,
-                                      std::move(ack_notifier_delegate));
+                                      std::move(ack_listener));
 }
 
 SpdyPriority QuicChromiumClientStream::priority() const {
diff --git a/net/quic/chromium/quic_chromium_client_stream.h b/net/quic/chromium/quic_chromium_client_stream.h
index 7b41e6790..01afae7 100644
--- a/net/quic/chromium/quic_chromium_client_stream.h
+++ b/net/quic/chromium/quic_chromium_client_stream.h
@@ -81,7 +81,7 @@
   size_t WriteHeaders(SpdyHeaderBlock header_block,
                       bool fin,
                       QuicReferenceCountedPointer<QuicAckListenerInterface>
-                          ack_notifier_delegate) override;
+                          ack_listener) override;
   SpdyPriority priority() const override;
 
   // While the server's set_priority shouldn't be called externally, the creator
diff --git a/net/quic/chromium/quic_chromium_client_stream_test.cc b/net/quic/chromium/quic_chromium_client_stream_test.cc
index aa50e05..8965bbb 100644
--- a/net/quic/chromium/quic_chromium_client_stream_test.cc
+++ b/net/quic/chromium/quic_chromium_client_stream_test.cc
@@ -112,9 +112,9 @@
                       bool fin,
                       SpdyPriority priority,
                       QuicReferenceCountedPointer<QuicAckListenerInterface>
-                          ack_notifier_delegate) override {
+                          ack_listener) override {
     return WriteHeadersMock(id, headers, fin, priority,
-                            std::move(ack_notifier_delegate));
+                            std::move(ack_listener));
   }
   MOCK_METHOD5(
       WriteHeadersMock,
@@ -123,7 +123,7 @@
              bool fin,
              SpdyPriority priority,
              const QuicReferenceCountedPointer<QuicAckListenerInterface>&
-                 ack_notifier_delegate));
+                 ack_listener));
   MOCK_METHOD1(OnHeadersHeadOfLineBlocking, void(QuicTime::Delta delta));
 
   using QuicSession::ActivateStream;
@@ -135,7 +135,7 @@
       const QuicIOVector& data,
       QuicStreamOffset offset,
       bool fin,
-      QuicAckListenerInterface* ack_notifier_delegate);
+      QuicAckListenerInterface* ack_listener);
 
   void OnProofValid(
       const QuicCryptoClientConfig::CachedState& cached) override {}
diff --git a/net/quic/core/quic_ack_listener_interface.cc b/net/quic/core/quic_ack_listener_interface.cc
index dc8d406..f0bd0be 100644
--- a/net/quic/core/quic_ack_listener_interface.cc
+++ b/net/quic/core/quic_ack_listener_interface.cc
@@ -9,9 +9,9 @@
 QuicAckListenerInterface::~QuicAckListenerInterface() {}
 
 AckListenerWrapper::AckListenerWrapper(
-    QuicReferenceCountedPointer<QuicAckListenerInterface> listener,
+    QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener,
     QuicPacketLength data_length)
-    : ack_listener(std::move(listener)), length(data_length) {}
+    : ack_listener(std::move(ack_listener)), length(data_length) {}
 
 AckListenerWrapper::AckListenerWrapper(const AckListenerWrapper& other) =
     default;
diff --git a/net/quic/core/quic_ack_listener_interface.h b/net/quic/core/quic_ack_listener_interface.h
index cd3373a..6082ff3e 100644
--- a/net/quic/core/quic_ack_listener_interface.h
+++ b/net/quic/core/quic_ack_listener_interface.h
@@ -34,7 +34,7 @@
 
 struct QUIC_EXPORT_PRIVATE AckListenerWrapper {
   AckListenerWrapper(
-      QuicReferenceCountedPointer<QuicAckListenerInterface> listener,
+      QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener,
       QuicPacketLength data_length);
   AckListenerWrapper(const AckListenerWrapper& other);
   ~AckListenerWrapper();
diff --git a/net/quic/core/quic_connection.cc b/net/quic/core/quic_connection.cc
index 762c63e..7822020 100644
--- a/net/quic/core/quic_connection.cc
+++ b/net/quic/core/quic_connection.cc
@@ -1115,7 +1115,7 @@
     QuicIOVector iov,
     QuicStreamOffset offset,
     bool fin,
-    QuicReferenceCountedPointer<QuicAckListenerInterface> listener) {
+    QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) {
   if (!fin && iov.total_length == 0) {
     QUIC_BUG << "Attempt to send empty stream frame";
     return QuicConsumedData(0, false);
@@ -1134,10 +1134,10 @@
       iov.total_length > kMaxPacketSize) {
     // Use the fast path to send full data packets.
     return packet_generator_.ConsumeDataFastPath(id, iov, offset, fin,
-                                                 std::move(listener));
+                                                 std::move(ack_listener));
   }
   return packet_generator_.ConsumeData(id, iov, offset, fin,
-                                       std::move(listener));
+                                       std::move(ack_listener));
 }
 
 void QuicConnection::SendRstStream(QuicStreamId id,
diff --git a/net/quic/core/quic_connection.h b/net/quic/core/quic_connection.h
index 926f4bc2..fda3d63 100644
--- a/net/quic/core/quic_connection.h
+++ b/net/quic/core/quic_connection.h
@@ -352,7 +352,7 @@
       QuicIOVector iov,
       QuicStreamOffset offset,
       bool fin,
-      QuicReferenceCountedPointer<QuicAckListenerInterface> listener);
+      QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener);
 
   // Send a RST_STREAM frame to the peer.
   virtual void SendRstStream(QuicStreamId id,
diff --git a/net/quic/core/quic_connection_test.cc b/net/quic/core/quic_connection_test.cc
index 3637805..e89b563 100644
--- a/net/quic/core/quic_connection_test.cc
+++ b/net/quic/core/quic_connection_test.cc
@@ -518,14 +518,14 @@
       StringPiece data,
       QuicStreamOffset offset,
       bool fin,
-      QuicReferenceCountedPointer<QuicAckListenerInterface> listener) {
+      QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) {
     if (id != kCryptoStreamId && this->encryption_level() == ENCRYPTION_NONE) {
       this->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
     }
     struct iovec iov;
     QuicIOVector data_iov(MakeIOVector(data, &iov));
     return QuicConnection::SendStreamData(id, data_iov, offset, fin,
-                                          std::move(listener));
+                                          std::move(ack_listener));
   }
 
   QuicConsumedData SendStreamData3() {
diff --git a/net/quic/core/quic_headers_stream.cc b/net/quic/core/quic_headers_stream.cc
index 6fb5860..6c162fd5 100644
--- a/net/quic/core/quic_headers_stream.cc
+++ b/net/quic/core/quic_headers_stream.cc
@@ -382,20 +382,19 @@
     QuicStreamId id,
     StringPiece data,
     bool fin,
-    QuicReferenceCountedPointer<QuicAckListenerInterface>
-        ack_notifier_delegate) {
+    QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) {
   SpdyDataIR spdy_data(id, data);
   spdy_data.set_fin(fin);
   SpdySerializedFrame frame(spdy_framer_.SerializeFrame(spdy_data));
-  QuicReferenceCountedPointer<ForceHolAckListener> ack_listener;
-  if (ack_notifier_delegate != nullptr) {
-    ack_listener = new ForceHolAckListener(std::move(ack_notifier_delegate),
-                                           frame.size() - data.length());
+  QuicReferenceCountedPointer<ForceHolAckListener> force_hol_ack_listener;
+  if (ack_listener != nullptr) {
+    force_hol_ack_listener = new ForceHolAckListener(
+        std::move(ack_listener), frame.size() - data.length());
   }
   // Use buffered writes so that coherence of framing is preserved
   // between streams.
   WriteOrBufferData(StringPiece(frame.data(), frame.size()), false,
-                    std::move(ack_listener));
+                    std::move(force_hol_ack_listener));
 }
 
 QuicConsumedData QuicHeadersStream::WritevStreamData(
@@ -403,8 +402,7 @@
     QuicIOVector iov,
     QuicStreamOffset offset,
     bool fin,
-    QuicReferenceCountedPointer<QuicAckListenerInterface>
-        ack_notifier_delegate) {
+    QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) {
   const size_t max_len =
       kSpdyInitialFrameSizeLimit - SpdyConstants::kDataFrameMinimumSize;
 
@@ -412,7 +410,7 @@
   size_t total_length = iov.total_length;
 
   if (total_length == 0 && fin) {
-    WriteDataFrame(id, StringPiece(), true, std::move(ack_notifier_delegate));
+    WriteDataFrame(id, StringPiece(), true, std::move(ack_listener));
     result.fin_consumed = true;
     return result;
   }
@@ -439,8 +437,7 @@
       bool last_iov = i == iov.iov_count - 1;
       bool last_fragment_within_iov = src_iov_offset >= src_iov->iov_len;
       bool frame_fin = (last_iov && last_fragment_within_iov) ? fin : false;
-      WriteDataFrame(id, StringPiece(data, len), frame_fin,
-                     ack_notifier_delegate);
+      WriteDataFrame(id, StringPiece(data, len), frame_fin, ack_listener);
       result.bytes_consumed += len;
       if (frame_fin) {
         result.fin_consumed = true;
diff --git a/net/quic/core/quic_headers_stream.h b/net/quic/core/quic_headers_stream.h
index f517e2d..1dff775f 100644
--- a/net/quic/core/quic_headers_stream.h
+++ b/net/quic/core/quic_headers_stream.h
@@ -72,8 +72,7 @@
       QuicIOVector iov,
       QuicStreamOffset offset,
       bool fin,
-      QuicReferenceCountedPointer<QuicAckListenerInterface>
-          ack_notifier_delegate);
+      QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener);
 
   // QuicStream implementation
   void OnDataAvailable() override;
@@ -142,11 +141,11 @@
   bool OnDataFrameHeader(QuicStreamId stream_id, size_t length, bool fin);
   bool OnStreamFrameData(QuicStreamId stream_id, const char* data, size_t len);
   // Helper for |WritevStreamData()|.
-  void WriteDataFrame(QuicStreamId stream_id,
-                      base::StringPiece data,
-                      bool fin,
-                      QuicReferenceCountedPointer<QuicAckListenerInterface>
-                          ack_notifier_delegate);
+  void WriteDataFrame(
+      QuicStreamId stream_id,
+      base::StringPiece data,
+      bool fin,
+      QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener);
 
   // Returns true if the session is still connected.
   bool IsConnected();
diff --git a/net/quic/core/quic_packet_creator.cc b/net/quic/core/quic_packet_creator.cc
index 3798b55..c44091e 100644
--- a/net/quic/core/quic_packet_creator.cc
+++ b/net/quic/core/quic_packet_creator.cc
@@ -353,7 +353,7 @@
     QuicStreamOffset iov_offset,
     QuicStreamOffset stream_offset,
     bool fin,
-    QuicReferenceCountedPointer<QuicAckListenerInterface> listener,
+    QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener,
     size_t* num_bytes_consumed) {
   DCHECK(queued_frames_.empty());
   // Write out the packet header
@@ -412,8 +412,8 @@
   packet_size_ = 0;
   packet_.encrypted_buffer = encrypted_buffer;
   packet_.encrypted_length = encrypted_length;
-  if (listener != nullptr) {
-    packet_.listeners.emplace_back(std::move(listener), bytes_consumed);
+  if (ack_listener != nullptr) {
+    packet_.listeners.emplace_back(std::move(ack_listener), bytes_consumed);
   }
   packet_.retransmittable_frames.push_back(QuicFrame(frame.release()));
   OnSerializedPacket();
@@ -465,10 +465,10 @@
 }
 
 void QuicPacketCreator::AddAckListener(
-    QuicReferenceCountedPointer<QuicAckListenerInterface> listener,
+    QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener,
     QuicPacketLength length) {
   DCHECK(!queued_frames_.empty());
-  packet_.listeners.emplace_back(std::move(listener), length);
+  packet_.listeners.emplace_back(std::move(ack_listener), length);
 }
 
 void QuicPacketCreator::SerializePacket(char* encrypted_buffer,
diff --git a/net/quic/core/quic_packet_generator.cc b/net/quic/core/quic_packet_generator.cc
index a51463ba..9d896f6 100644
--- a/net/quic/core/quic_packet_generator.cc
+++ b/net/quic/core/quic_packet_generator.cc
@@ -53,7 +53,7 @@
     QuicIOVector iov,
     QuicStreamOffset offset,
     bool fin,
-    QuicReferenceCountedPointer<QuicAckListenerInterface> listener) {
+    QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) {
   bool has_handshake = (id == kCryptoStreamId);
   QUIC_BUG_IF(has_handshake && fin)
       << "Handshake packets should never send a fin";
@@ -89,8 +89,8 @@
 
     // A stream frame is created and added.
     size_t bytes_consumed = frame.stream_frame->data_length;
-    if (listener != nullptr) {
-      packet_creator_.AddAckListener(listener, bytes_consumed);
+    if (ack_listener != nullptr) {
+      packet_creator_.AddAckListener(ack_listener, bytes_consumed);
     }
     total_bytes_consumed += bytes_consumed;
     fin_consumed = fin && total_bytes_consumed == iov.total_length;
@@ -125,7 +125,7 @@
     const QuicIOVector& iov,
     QuicStreamOffset offset,
     bool fin,
-    QuicReferenceCountedPointer<QuicAckListenerInterface> listener) {
+    QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) {
   DCHECK_NE(id, kCryptoStreamId);
   size_t total_bytes_consumed = 0;
   while (total_bytes_consumed < iov.total_length &&
@@ -135,7 +135,7 @@
     size_t bytes_consumed = 0;
     packet_creator_.CreateAndSerializeStreamFrame(
         id, iov, total_bytes_consumed, offset + total_bytes_consumed, fin,
-        listener, &bytes_consumed);
+        ack_listener, &bytes_consumed);
     total_bytes_consumed += bytes_consumed;
   }
 
@@ -145,7 +145,7 @@
 
 void QuicPacketGenerator::GenerateMtuDiscoveryPacket(
     QuicByteCount target_mtu,
-    QuicReferenceCountedPointer<QuicAckListenerInterface> listener) {
+    QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) {
   // MTU discovery frames must be sent by themselves.
   if (!packet_creator_.CanSetMaxPacketLength()) {
     QUIC_BUG << "MTU discovery packets should only be sent when no other "
@@ -162,8 +162,8 @@
   // Send the probe packet with the new length.
   SetMaxPacketLength(target_mtu);
   const bool success = packet_creator_.AddPaddedSavedFrame(frame);
-  if (listener != nullptr) {
-    packet_creator_.AddAckListener(std::move(listener), 0);
+  if (ack_listener != nullptr) {
+    packet_creator_.AddAckListener(std::move(ack_listener), 0);
   }
   packet_creator_.Flush();
   // The only reason AddFrame can fail is that the packet is too full to fit in
diff --git a/net/quic/core/quic_packet_generator.h b/net/quic/core/quic_packet_generator.h
index d578e48..c451a46 100644
--- a/net/quic/core/quic_packet_generator.h
+++ b/net/quic/core/quic_packet_generator.h
@@ -98,7 +98,7 @@
       QuicIOVector iov,
       QuicStreamOffset offset,
       bool fin,
-      QuicReferenceCountedPointer<QuicAckListenerInterface> listener);
+      QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener);
 
   // Sends as many data only packets as allowed by the send algorithm and the
   // available iov.
@@ -108,12 +108,12 @@
       const QuicIOVector& iov,
       QuicStreamOffset offset,
       bool fin,
-      QuicReferenceCountedPointer<QuicAckListenerInterface> listener);
+      QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener);
 
   // Generates an MTU discovery packet of specified size.
   void GenerateMtuDiscoveryPacket(
       QuicByteCount target_mtu,
-      QuicReferenceCountedPointer<QuicAckListenerInterface> listener);
+      QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener);
 
   // Indicates whether batch mode is currently enabled.
   bool InBatchMode();
diff --git a/net/quic/core/quic_session.cc b/net/quic/core/quic_session.cc
index 047e528..3f8e578 100644
--- a/net/quic/core/quic_session.cc
+++ b/net/quic/core/quic_session.cc
@@ -283,8 +283,7 @@
     QuicIOVector iov,
     QuicStreamOffset offset,
     bool fin,
-    QuicReferenceCountedPointer<QuicAckListenerInterface>
-        ack_notifier_delegate) {
+    QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) {
   // This check is an attempt to deal with potential memory corruption
   // in which |id| ends up set to 1 (the crypto stream id). If this happen
   // it might end up resulting in unencrypted stream data being sent.
@@ -303,8 +302,8 @@
     // up write blocked until OnCanWrite is next called.
     return QuicConsumedData(0, false);
   }
-  QuicConsumedData data = connection_->SendStreamData(
-      id, iov, offset, fin, std::move(ack_notifier_delegate));
+  QuicConsumedData data = connection_->SendStreamData(id, iov, offset, fin,
+                                                      std::move(ack_listener));
   write_blocked_streams_.UpdateBytesForStream(id, data.bytes_consumed);
   return data;
 }
diff --git a/net/quic/core/quic_session.h b/net/quic/core/quic_session.h
index 621e8671..7397b719 100644
--- a/net/quic/core/quic_session.h
+++ b/net/quic/core/quic_session.h
@@ -122,8 +122,7 @@
       QuicIOVector iov,
       QuicStreamOffset offset,
       bool fin,
-      QuicReferenceCountedPointer<QuicAckListenerInterface>
-          ack_notifier_delegate);
+      QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener);
 
   // Called by streams when they want to close the stream in both directions.
   virtual void SendRstStream(QuicStreamId id,
diff --git a/net/quic/core/quic_session_test.cc b/net/quic/core/quic_session_test.cc
index 58023dbc..660e2d8 100644
--- a/net/quic/core/quic_session_test.cc
+++ b/net/quic/core/quic_session_test.cc
@@ -169,12 +169,12 @@
       QuicIOVector data,
       QuicStreamOffset offset,
       bool fin,
-      QuicReferenceCountedPointer<QuicAckListenerInterface>
-          ack_notifier_delegate) override {
+      QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener)
+      override {
     QuicConsumedData consumed(data.total_length, fin);
     if (!writev_consumes_all_data_) {
       consumed = QuicSession::WritevData(stream, id, data, offset, fin,
-                                         std::move(ack_notifier_delegate));
+                                         std::move(ack_listener));
     }
     stream->set_stream_bytes_written(stream->stream_bytes_written() +
                                      consumed.bytes_consumed);
diff --git a/net/quic/core/quic_spdy_session.h b/net/quic/core/quic_spdy_session.h
index d5963f1..73e5405 100644
--- a/net/quic/core/quic_spdy_session.h
+++ b/net/quic/core/quic_spdy_session.h
@@ -65,8 +65,7 @@
       SpdyHeaderBlock headers,
       bool fin,
       SpdyPriority priority,
-      QuicReferenceCountedPointer<QuicAckListenerInterface>
-          ack_notifier_delegate);
+      QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener);
 
   QuicHeadersStream* headers_stream() { return headers_stream_.get(); }
 
diff --git a/net/quic/core/quic_spdy_stream.cc b/net/quic/core/quic_spdy_stream.cc
index f44d3fb..592c03d 100644
--- a/net/quic/core/quic_spdy_stream.cc
+++ b/net/quic/core/quic_spdy_stream.cc
@@ -61,11 +61,9 @@
 size_t QuicSpdyStream::WriteHeaders(
     SpdyHeaderBlock header_block,
     bool fin,
-    QuicReferenceCountedPointer<QuicAckListenerInterface>
-        ack_notifier_delegate) {
-  size_t bytes_written =
-      spdy_session_->WriteHeaders(id(), std::move(header_block), fin, priority_,
-                                  std::move(ack_notifier_delegate));
+    QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) {
+  size_t bytes_written = spdy_session_->WriteHeaders(
+      id(), std::move(header_block), fin, priority_, std::move(ack_listener));
   if (fin) {
     // TODO(rch): Add test to ensure fin_sent_ is set whenever a fin is sent.
     set_fin_sent(true);
@@ -77,15 +75,13 @@
 void QuicSpdyStream::WriteOrBufferBody(
     const string& data,
     bool fin,
-    QuicReferenceCountedPointer<QuicAckListenerInterface>
-        ack_notifier_delegate) {
-  WriteOrBufferData(data, fin, std::move(ack_notifier_delegate));
+    QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) {
+  WriteOrBufferData(data, fin, std::move(ack_listener));
 }
 
 size_t QuicSpdyStream::WriteTrailers(
     SpdyHeaderBlock trailer_block,
-    QuicReferenceCountedPointer<QuicAckListenerInterface>
-        ack_notifier_delegate) {
+    QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) {
   if (fin_sent()) {
     QUIC_BUG << "Trailers cannot be sent after a FIN.";
     return 0;
@@ -102,9 +98,8 @@
   // Write the trailing headers with a FIN, and close stream for writing:
   // trailers are the last thing to be sent on a stream.
   const bool kFin = true;
-  size_t bytes_written =
-      spdy_session_->WriteHeaders(id(), std::move(trailer_block), kFin,
-                                  priority_, std::move(ack_notifier_delegate));
+  size_t bytes_written = spdy_session_->WriteHeaders(
+      id(), std::move(trailer_block), kFin, priority_, std::move(ack_listener));
   set_fin_sent(kFin);
 
   // Trailers are the last thing to be sent on a stream, but if there is still
@@ -335,15 +330,13 @@
     QuicIOVector iov,
     QuicStreamOffset offset,
     bool fin,
-    QuicReferenceCountedPointer<QuicAckListenerInterface>
-        ack_notifier_delegate) {
+    QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) {
   if (spdy_session_->headers_stream() != nullptr &&
       spdy_session_->force_hol_blocking()) {
     return spdy_session_->headers_stream()->WritevStreamData(
-        id(), iov, offset, fin, std::move(ack_notifier_delegate));
+        id(), iov, offset, fin, std::move(ack_listener));
   }
-  return QuicStream::WritevDataInner(iov, offset, fin,
-                                     std::move(ack_notifier_delegate));
+  return QuicStream::WritevDataInner(iov, offset, fin, std::move(ack_listener));
 }
 
 }  // namespace net
diff --git a/net/quic/core/quic_spdy_stream.h b/net/quic/core/quic_spdy_stream.h
index ef0e1c4..d470e80 100644
--- a/net/quic/core/quic_spdy_stream.h
+++ b/net/quic/core/quic_spdy_stream.h
@@ -105,21 +105,19 @@
   virtual size_t WriteHeaders(
       SpdyHeaderBlock header_block,
       bool fin,
-      QuicReferenceCountedPointer<QuicAckListenerInterface>
-          ack_notifier_delegate);
+      QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener);
 
   // Sends |data| to the peer, or buffers if it can't be sent immediately.
-  void WriteOrBufferBody(const std::string& data,
-                         bool fin,
-                         QuicReferenceCountedPointer<QuicAckListenerInterface>
-                             ack_notifier_delegate);
+  void WriteOrBufferBody(
+      const std::string& data,
+      bool fin,
+      QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener);
 
   // Writes the trailers contained in |trailer_block| to the dedicated
   // headers stream. Trailers will always have the FIN set.
   virtual size_t WriteTrailers(
       SpdyHeaderBlock trailer_block,
-      QuicReferenceCountedPointer<QuicAckListenerInterface>
-          ack_notifier_delegate);
+      QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener);
 
   // Marks the trailers as consumed. This applies to the case where this object
   // receives headers and trailers as QuicHeaderLists via calls to
@@ -203,8 +201,8 @@
       QuicIOVector iov,
       QuicStreamOffset offset,
       bool fin,
-      QuicReferenceCountedPointer<QuicAckListenerInterface>
-          ack_notifier_delegate) override;
+      QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener)
+      override;
 
   void set_headers_decompressed(bool val) { headers_decompressed_ = val; }
 
diff --git a/net/quic/core/quic_stream.cc b/net/quic/core/quic_stream.cc
index 8a3d4a1..3287a09 100644
--- a/net/quic/core/quic_stream.cc
+++ b/net/quic/core/quic_stream.cc
@@ -43,10 +43,10 @@
 
 QuicStream::PendingData::PendingData(
     string data_in,
-    QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener_in)
+    QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener)
     : data(std::move(data_in)),
       offset(0),
-      ack_listener(std::move(ack_listener_in)) {}
+      ack_listener(std::move(ack_listener)) {}
 
 QuicStream::PendingData::~PendingData() {}
 
@@ -351,10 +351,9 @@
     QuicIOVector iov,
     QuicStreamOffset offset,
     bool fin,
-    QuicReferenceCountedPointer<QuicAckListenerInterface>
-        ack_notifier_delegate) {
+    QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) {
   return session()->WritevData(this, id(), iov, offset, fin,
-                               std::move(ack_notifier_delegate));
+                               std::move(ack_listener));
 }
 
 void QuicStream::CloseReadSide() {
diff --git a/net/quic/core/quic_stream.h b/net/quic/core/quic_stream.h
index 4220ba5..3b3ca6ad0d 100644
--- a/net/quic/core/quic_stream.h
+++ b/net/quic/core/quic_stream.h
@@ -206,8 +206,7 @@
       QuicIOVector iov,
       QuicStreamOffset offset,
       bool fin,
-      QuicReferenceCountedPointer<QuicAckListenerInterface>
-          ack_notifier_delegate);
+      QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener);
 
   // Close the write side of the socket.  Further writes will fail.
   // Can be called by the subclass or internally.
@@ -240,7 +239,7 @@
   struct PendingData {
     PendingData(
         std::string data_in,
-        QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener_in);
+        QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener);
     ~PendingData();
 
     // Pending data to be written.
diff --git a/net/quic/core/quic_stream_test.cc b/net/quic/core/quic_stream_test.cc
index 22b9a96d..22a32c277 100644
--- a/net/quic/core/quic_stream_test.cc
+++ b/net/quic/core/quic_stream_test.cc
@@ -144,7 +144,7 @@
       QuicStreamOffset /*offset*/,
       bool /*fin*/,
       const QuicReferenceCountedPointer<
-          QuicAckListenerInterface>& /*ack_notifier_delegate*/) {
+          QuicAckListenerInterface>& /*ack_listener*/) {
     session_->CloseStream(id);
     return QuicConsumedData(1, false);
   }
@@ -388,15 +388,15 @@
 // TODO(ianswett): It's not clear this method is still needed now that
 // ProxyAckNotifierDelegate has been removed.
 void SaveAckListener(
-    QuicReferenceCountedPointer<QuicAckListenerInterface>* listener_out,
-    QuicReferenceCountedPointer<QuicAckListenerInterface> listener) {
-  *listener_out = std::move(listener);
+    QuicReferenceCountedPointer<QuicAckListenerInterface>* ack_listener_out,
+    QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) {
+  *ack_listener_out = std::move(ack_listener);
 }
 
 TEST_F(QuicStreamTest, WriteOrBufferDataWithQuicAckNotifier) {
   Initialize(kShouldProcessData);
 
-  QuicReferenceCountedPointer<MockAckListener> delegate(
+  QuicReferenceCountedPointer<MockAckListener> mock_ack_listener(
       new StrictMock<MockAckListener>);
 
   const int kDataSize = 16 * 1024;
@@ -416,7 +416,7 @@
       .WillOnce(DoAll(
           WithArgs<5>(Invoke(CreateFunctor(SaveAckListener, &ack_listener))),
           Return(QuicConsumedData(kFirstWriteSize, false))));
-  stream_->WriteOrBufferData(kData, false, delegate);
+  stream_->WriteOrBufferData(kData, false, mock_ack_listener);
   EXPECT_TRUE(HasWriteBlockedStreams());
 
   EXPECT_CALL(*session_,
@@ -441,7 +441,7 @@
 TEST_F(QuicStreamTest, WriteOrBufferDataAckNotificationBeforeFlush) {
   Initialize(kShouldProcessData);
 
-  QuicReferenceCountedPointer<MockAckListener> ack_listener(
+  QuicReferenceCountedPointer<MockAckListener> mock_ack_listener(
       new StrictMock<MockAckListener>);
 
   const int kDataSize = 16 * 1024;
@@ -453,18 +453,18 @@
   stream_->flow_controller()->UpdateSendWindowOffset(kDataSize + 1);
   session_->flow_controller()->UpdateSendWindowOffset(kDataSize + 1);
 
-  QuicReferenceCountedPointer<QuicAckListenerInterface> proxy_delegate;
+  QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener;
 
   EXPECT_CALL(*session_, WritevData(stream_, kTestStreamId, _, _, _, _))
       .WillOnce(DoAll(
-          WithArgs<5>(Invoke(CreateFunctor(SaveAckListener, &proxy_delegate))),
+          WithArgs<5>(Invoke(CreateFunctor(SaveAckListener, &ack_listener))),
           Return(QuicConsumedData(kInitialWriteSize, false))));
-  stream_->WriteOrBufferData(kData, false, ack_listener);
+  stream_->WriteOrBufferData(kData, false, mock_ack_listener);
   EXPECT_TRUE(HasWriteBlockedStreams());
 
   EXPECT_CALL(*session_, WritevData(stream_, kTestStreamId, _, _, _, _))
       .WillOnce(DoAll(
-          WithArgs<5>(Invoke(CreateFunctor(SaveAckListener, &proxy_delegate))),
+          WithArgs<5>(Invoke(CreateFunctor(SaveAckListener, &ack_listener))),
           Return(QuicConsumedData(kDataSize - kInitialWriteSize, false))));
   stream_->OnCanWrite();
 }
@@ -473,16 +473,16 @@
 TEST_F(QuicStreamTest, WriteAndBufferDataWithAckNotiferNoBuffer) {
   Initialize(kShouldProcessData);
 
-  QuicReferenceCountedPointer<MockAckListener> delegate(
+  QuicReferenceCountedPointer<MockAckListener> mock_ack_listener(
       new StrictMock<MockAckListener>);
 
-  QuicReferenceCountedPointer<QuicAckListenerInterface> proxy_delegate;
+  QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener;
 
   EXPECT_CALL(*session_, WritevData(stream_, kTestStreamId, _, _, _, _))
       .WillOnce(DoAll(
-          WithArgs<5>(Invoke(CreateFunctor(SaveAckListener, &proxy_delegate))),
+          WithArgs<5>(Invoke(CreateFunctor(SaveAckListener, &ack_listener))),
           Return(QuicConsumedData(kDataLen, true))));
-  stream_->WriteOrBufferData(kData1, true, delegate);
+  stream_->WriteOrBufferData(kData1, true, mock_ack_listener);
   EXPECT_FALSE(HasWriteBlockedStreams());
 }
 
@@ -490,19 +490,19 @@
 TEST_F(QuicStreamTest, BufferOnWriteAndBufferDataWithAckNotifer) {
   Initialize(kShouldProcessData);
 
-  QuicReferenceCountedPointer<MockAckListener> delegate(
+  QuicReferenceCountedPointer<MockAckListener> mock_ack_listener(
       new StrictMock<MockAckListener>);
 
-  QuicReferenceCountedPointer<QuicAckListenerInterface> proxy_delegate;
+  QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener;
 
   EXPECT_CALL(*session_, WritevData(stream_, kTestStreamId, _, _, _, _))
       .WillOnce(Return(QuicConsumedData(0, false)));
-  stream_->WriteOrBufferData(kData1, true, delegate);
+  stream_->WriteOrBufferData(kData1, true, mock_ack_listener);
   EXPECT_TRUE(HasWriteBlockedStreams());
 
   EXPECT_CALL(*session_, WritevData(stream_, kTestStreamId, _, _, _, _))
       .WillOnce(DoAll(
-          WithArgs<5>(Invoke(CreateFunctor(SaveAckListener, &proxy_delegate))),
+          WithArgs<5>(Invoke(CreateFunctor(SaveAckListener, &ack_listener))),
           Return(QuicConsumedData(kDataLen, true))));
   stream_->OnCanWrite();
 }
@@ -512,21 +512,21 @@
 TEST_F(QuicStreamTest, WriteAndBufferDataWithAckNotiferOnlyFinRemains) {
   Initialize(kShouldProcessData);
 
-  QuicReferenceCountedPointer<MockAckListener> delegate(
+  QuicReferenceCountedPointer<MockAckListener> mock_ack_listener(
       new StrictMock<MockAckListener>);
 
-  QuicReferenceCountedPointer<QuicAckListenerInterface> proxy_delegate;
+  QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener;
 
   EXPECT_CALL(*session_, WritevData(stream_, kTestStreamId, _, _, _, _))
       .WillOnce(DoAll(
-          WithArgs<5>(Invoke(CreateFunctor(SaveAckListener, &proxy_delegate))),
+          WithArgs<5>(Invoke(CreateFunctor(SaveAckListener, &ack_listener))),
           Return(QuicConsumedData(kDataLen, false))));
-  stream_->WriteOrBufferData(kData1, true, delegate);
+  stream_->WriteOrBufferData(kData1, true, mock_ack_listener);
   EXPECT_TRUE(HasWriteBlockedStreams());
 
   EXPECT_CALL(*session_, WritevData(stream_, kTestStreamId, _, _, _, _))
       .WillOnce(DoAll(
-          WithArgs<5>(Invoke(CreateFunctor(SaveAckListener, &proxy_delegate))),
+          WithArgs<5>(Invoke(CreateFunctor(SaveAckListener, &ack_listener))),
           Return(QuicConsumedData(0, true))));
   stream_->OnCanWrite();
 }
diff --git a/net/quic/test_tools/quic_stream_peer.cc b/net/quic/test_tools/quic_stream_peer.cc
index 8e7db46..b35ec1a12 100644
--- a/net/quic/test_tools/quic_stream_peer.cc
+++ b/net/quic/test_tools/quic_stream_peer.cc
@@ -88,9 +88,8 @@
     QuicStream* stream,
     StringPiece data,
     bool fin,
-    QuicReferenceCountedPointer<QuicAckListenerInterface>
-        ack_notifier_delegate) {
-  stream->WriteOrBufferData(data, fin, std::move(ack_notifier_delegate));
+    QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) {
+  stream->WriteOrBufferData(data, fin, std::move(ack_listener));
 }
 
 // static
diff --git a/net/quic/test_tools/quic_stream_peer.h b/net/quic/test_tools/quic_stream_peer.h
index 0ddb373a..3d9b4f4 100644
--- a/net/quic/test_tools/quic_stream_peer.h
+++ b/net/quic/test_tools/quic_stream_peer.h
@@ -42,8 +42,7 @@
       QuicStream* stream,
       base::StringPiece data,
       bool fin,
-      QuicReferenceCountedPointer<QuicAckListenerInterface>
-          ack_notifier_delegate);
+      QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener);
 
   static net::QuicStreamSequencer* sequencer(QuicStream* stream);
 
diff --git a/net/quic/test_tools/quic_test_utils.cc b/net/quic/test_tools/quic_test_utils.cc
index a95af0d..4e3df7c4 100644
--- a/net/quic/test_tools/quic_test_utils.cc
+++ b/net/quic/test_tools/quic_test_utils.cc
@@ -377,7 +377,7 @@
     QuicStreamOffset /*offset*/,
     bool fin,
     const QuicReferenceCountedPointer<
-        QuicAckListenerInterface>& /*ack_notifier_delegate*/) {
+        QuicAckListenerInterface>& /*ack_listener*/) {
   return QuicConsumedData(data.total_length, fin);
 }
 
diff --git a/net/quic/test_tools/quic_test_utils.h b/net/quic/test_tools/quic_test_utils.h
index 2c3d17f..30ebef8 100644
--- a/net/quic/test_tools/quic_test_utils.h
+++ b/net/quic/test_tools/quic_test_utils.h
@@ -545,7 +545,7 @@
       QuicStreamOffset offset,
       bool fin,
       const QuicReferenceCountedPointer<QuicAckListenerInterface>&
-          ack_notifier_delegate);
+          ack_listener);
 
  private:
   std::unique_ptr<QuicCryptoStream> crypto_stream_;
@@ -617,10 +617,9 @@
                       bool fin,
                       SpdyPriority priority,
                       QuicReferenceCountedPointer<QuicAckListenerInterface>
-                          ack_notifier_delegate) override {
+                          ack_listener) override {
     write_headers_ = std::move(headers);
-    return WriteHeadersMock(id, write_headers_, fin, priority,
-                            ack_notifier_delegate);
+    return WriteHeadersMock(id, write_headers_, fin, priority, ack_listener);
   }
   MOCK_METHOD5(
       WriteHeadersMock,
@@ -629,7 +628,7 @@
              bool fin,
              SpdyPriority priority,
              const QuicReferenceCountedPointer<QuicAckListenerInterface>&
-                 ack_notifier_delegate));
+                 ack_listener));
   MOCK_METHOD1(OnHeadersHeadOfLineBlocking, void(QuicTime::Delta delta));
   MOCK_METHOD4(
       OnStreamFrameData,
diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc
index dfafe1b30..59e331a 100644
--- a/net/spdy/spdy_session.cc
+++ b/net/spdy/spdy_session.cc
@@ -265,6 +265,22 @@
   return std::move(dict);
 }
 
+std::unique_ptr<base::Value> NetLogSpdySessionStalledCallback(
+    size_t num_active_streams,
+    size_t num_created_streams,
+    size_t num_pushed_streams,
+    size_t max_concurrent_streams,
+    const std::string& url,
+    NetLogCaptureMode capture_mode) {
+  auto dict = base::MakeUnique<base::DictionaryValue>();
+  dict->SetInteger("num_active_streams", num_active_streams);
+  dict->SetInteger("num_created_streams", num_created_streams);
+  dict->SetInteger("num_pushed_streams", num_pushed_streams);
+  dict->SetInteger("max_concurrent_streams", max_concurrent_streams);
+  dict->SetString("url", url);
+  return std::move(dict);
+}
+
 // Helper function to return the total size of an array of objects
 // with .size() member functions.
 template <typename T, size_t N> size_t GetTotalSize(const T (&arr)[N]) {
@@ -824,7 +840,13 @@
     return CreateStream(*request, stream);
   }
 
-  net_log().AddEvent(NetLogEventType::HTTP2_SESSION_STALLED_MAX_STREAMS);
+  if (net_log().IsCapturing()) {
+    net_log().AddEvent(
+        NetLogEventType::HTTP2_SESSION_STALLED_MAX_STREAMS,
+        base::Bind(&NetLogSpdySessionStalledCallback, active_streams_.size(),
+                   created_streams_.size(), num_pushed_streams_,
+                   max_concurrent_streams_, request->url().spec()));
+  }
   RequestPriority priority = request->priority();
   CHECK_GE(priority, MINIMUM_PRIORITY);
   CHECK_LE(priority, MAXIMUM_PRIORITY);
diff --git a/net/tools/quic/end_to_end_test.cc b/net/tools/quic/end_to_end_test.cc
index 40166e2..898d42c 100644
--- a/net/tools/quic/end_to_end_test.cc
+++ b/net/tools/quic/end_to_end_test.cc
@@ -1974,7 +1974,8 @@
   client_->SendMessage(headers, "", /*fin=*/false);
 
   // The TestAckListener will cause a failure if not notified.
-  QuicReferenceCountedPointer<TestAckListener> delegate(new TestAckListener(2));
+  QuicReferenceCountedPointer<TestAckListener> ack_listener(
+      new TestAckListener(2));
 
   // Test the AckNotifier's ability to track multiple packets by making the
   // request body exceed the size of a single packet.
@@ -1982,7 +1983,7 @@
       "a request body bigger than one packet" + string(kMaxPacketSize, '.');
 
   // Send the request, and register the delegate for ACKs.
-  client_->SendData(request_string, true, delegate);
+  client_->SendData(request_string, true, ack_listener);
   client_->WaitForResponse();
   EXPECT_EQ(kFooResponseBody, client_->response_body());
   EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
@@ -1991,7 +1992,7 @@
   client_->SendSynchronousRequest("/bar");
 
   // Make sure the delegate does get the notification it expects.
-  while (!delegate->has_been_notified()) {
+  while (!ack_listener->has_been_notified()) {
     // Waits for up to 50 ms.
     client_->client()->WaitForEvents();
   }
diff --git a/net/tools/quic/quic_client_test.cc b/net/tools/quic/quic_client_test.cc
index 2af9571..9300e3b 100644
--- a/net/tools/quic/quic_client_test.cc
+++ b/net/tools/quic/quic_client_test.cc
@@ -9,6 +9,8 @@
 
 #include <memory>
 
+#include "base/files/file_enumerator.h"
+#include "base/files/file_util.h"
 #include "base/strings/string_util.h"
 #include "net/quic/test_tools/crypto_test_utils.h"
 #include "net/quic/test_tools/quic_test_utils.h"
@@ -23,18 +25,28 @@
 namespace test {
 namespace {
 
-int NumOpenFDs() {
-  int number_of_open_fds = 0;
-  char buf[256];
-  struct dirent* dp;
+const char* kPathToFds = "/proc/self/fd";
 
-  base::snprintf(buf, arraysize(buf), "/proc/%i/fd/", getpid());
-  DIR* dir = opendir(buf);
-  while ((dp = readdir(dir)) != NULL)
-    number_of_open_fds++;
-  closedir(dir);
+// Counts the number of open sockets for the current process.
+size_t NumOpenSocketFDs() {
+  base::FileEnumerator fd_entries(
+      base::FilePath(kPathToFds), false,
+      base::FileEnumerator::FILES | base::FileEnumerator::SHOW_SYM_LINKS);
 
-  return number_of_open_fds;
+  size_t socket_count = 0;
+  for (base::FilePath entry = fd_entries.Next(); !entry.empty();
+       entry = fd_entries.Next()) {
+    base::FilePath fd_path;
+    if (!base::ReadSymbolicLink(entry, &fd_path)) {
+      continue;
+    }
+    if (base::StartsWith(fd_path.value(), "socket:",
+                         base::CompareCase::SENSITIVE)) {
+      socket_count++;
+    }
+  }
+
+  return socket_count;
 }
 
 // Creates a new QuicClient and Initializes it. Caller is responsible for
@@ -53,6 +65,9 @@
 }
 
 TEST(QuicClientTest, DoNotLeakFDs) {
+  // Make sure that the QuicClient doesn't leak socket FDs. Doing so could cause
+  // port exhaustion in long running processes which repeatedly create clients.
+
   // Create a ProofVerifier before counting the number of open FDs to work
   // around some ASAN weirdness.
   CryptoTestUtils::ProofVerifierForTesting().reset();
@@ -62,7 +77,7 @@
 
   // Record initial number of FDs, after creation of EpollServer.
   EpollServer eps;
-  int number_of_open_fds = NumOpenFDs();
+  size_t number_of_open_fds = NumOpenSocketFDs();
 
   // Create a number of clients, initialize them, and verify this has resulted
   // in additional FDs being opened.
@@ -72,11 +87,11 @@
         CreateAndInitializeQuicClient(&eps, net::test::kTestPort + i));
 
     // Initializing the client will create a new FD.
-    EXPECT_LT(number_of_open_fds, NumOpenFDs());
+    EXPECT_LT(number_of_open_fds, NumOpenSocketFDs());
   }
 
   // The FDs created by the QuicClients should now be closed.
-  EXPECT_EQ(number_of_open_fds, NumOpenFDs());
+  EXPECT_EQ(number_of_open_fds, NumOpenSocketFDs());
 }
 
 TEST(QuicClientTest, CreateAndCleanUpUDPSockets) {
@@ -85,22 +100,22 @@
   CryptoTestUtils::ProofVerifierForTesting().reset();
 
   EpollServer eps;
-  int number_of_open_fds = NumOpenFDs();
+  size_t number_of_open_fds = NumOpenSocketFDs();
 
   std::unique_ptr<QuicClient> client(
       CreateAndInitializeQuicClient(&eps, net::test::kTestPort));
-  EXPECT_EQ(number_of_open_fds + 1, NumOpenFDs());
+  EXPECT_EQ(number_of_open_fds + 1, NumOpenSocketFDs());
   // Create more UDP sockets.
   EXPECT_TRUE(QuicClientPeer::CreateUDPSocketAndBind(client.get()));
-  EXPECT_EQ(number_of_open_fds + 2, NumOpenFDs());
+  EXPECT_EQ(number_of_open_fds + 2, NumOpenSocketFDs());
   EXPECT_TRUE(QuicClientPeer::CreateUDPSocketAndBind(client.get()));
-  EXPECT_EQ(number_of_open_fds + 3, NumOpenFDs());
+  EXPECT_EQ(number_of_open_fds + 3, NumOpenSocketFDs());
 
   // Clean up UDP sockets.
   QuicClientPeer::CleanUpUDPSocket(client.get(), client->GetLatestFD());
-  EXPECT_EQ(number_of_open_fds + 2, NumOpenFDs());
+  EXPECT_EQ(number_of_open_fds + 2, NumOpenSocketFDs());
   QuicClientPeer::CleanUpUDPSocket(client.get(), client->GetLatestFD());
-  EXPECT_EQ(number_of_open_fds + 1, NumOpenFDs());
+  EXPECT_EQ(number_of_open_fds + 1, NumOpenSocketFDs());
 }
 
 }  // namespace
diff --git a/net/tools/quic/quic_simple_server_session_test.cc b/net/tools/quic/quic_simple_server_session_test.cc
index cc9ff32..3f4d649 100644
--- a/net/tools/quic/quic_simple_server_session_test.cc
+++ b/net/tools/quic/quic_simple_server_session_test.cc
@@ -141,7 +141,7 @@
           QuicIOVector iov,
           QuicStreamOffset offset,
           bool fin,
-          QuicReferenceCountedPointer<QuicAckListenerInterface> listern));
+          QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener));
 };
 
 class QuicSimpleServerSessionPeer {
diff --git a/net/tools/quic/quic_simple_server_stream_test.cc b/net/tools/quic/quic_simple_server_stream_test.cc
index 14210b7..72ff7c47 100644
--- a/net/tools/quic/quic_simple_server_stream_test.cc
+++ b/net/tools/quic/quic_simple_server_stream_test.cc
@@ -139,8 +139,8 @@
                       bool fin,
                       SpdyPriority priority,
                       QuicReferenceCountedPointer<QuicAckListenerInterface>
-                          ack_notifier_delegate) override {
-    return WriteHeadersMock(id, headers, fin, priority, ack_notifier_delegate);
+                          ack_listener) override {
+    return WriteHeadersMock(id, headers, fin, priority, ack_listener);
   }
   MOCK_METHOD5(
       WriteHeadersMock,
@@ -149,7 +149,7 @@
              bool fin,
              SpdyPriority priority,
              const QuicReferenceCountedPointer<QuicAckListenerInterface>&
-                 ack_notifier_delegate));
+                 ack_listener));
   MOCK_METHOD3(SendRstStream,
                void(QuicStreamId stream_id,
                     QuicRstStreamErrorCode error,
diff --git a/net/tools/quic/test_tools/quic_test_client.cc b/net/tools/quic/test_tools/quic_test_client.cc
index 697488c..aeb9e47 100644
--- a/net/tools/quic/test_tools/quic_test_client.cc
+++ b/net/tools/quic/test_tools/quic_test_client.cc
@@ -292,7 +292,7 @@
     const SpdyHeaderBlock* headers,
     StringPiece body,
     bool fin,
-    QuicReferenceCountedPointer<QuicAckListenerInterface> delegate) {
+    QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) {
   if (headers) {
     QuicClientPushPromiseIndex::TryHandle* handle;
     QuicAsyncStatus rv =
@@ -304,7 +304,7 @@
       std::unique_ptr<SpdyHeaderBlock> new_headers(
           new SpdyHeaderBlock(headers->Clone()));
       push_promise_data_to_resend_.reset(new TestClientDataToResend(
-          std::move(new_headers), body, fin, this, std::move(delegate)));
+          std::move(new_headers), body, fin, this, std::move(ack_listener)));
       return 1;
     }
   }
@@ -326,7 +326,7 @@
     ret = stream->SendRequest(std::move(spdy_headers), body, fin);
     ++num_requests_;
   } else {
-    stream->WriteOrBufferBody(body.as_string(), fin, delegate);
+    stream->WriteOrBufferBody(body.as_string(), fin, ack_listener);
     ret = body.length();
   }
   if (FLAGS_enable_quic_stateless_reject_support) {
@@ -336,7 +336,7 @@
     }
     std::unique_ptr<QuicClientBase::QuicDataToResend> data_to_resend(
         new TestClientDataToResend(std::move(new_headers), body, fin, this,
-                                   delegate));
+                                   ack_listener));
     client()->MaybeAddQuicDataToResend(std::move(data_to_resend));
   }
   return ret;
@@ -377,9 +377,9 @@
 ssize_t QuicTestClient::SendData(
     const string& data,
     bool last_data,
-    QuicReferenceCountedPointer<QuicAckListenerInterface> delegate) {
+    QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) {
   return GetOrCreateStreamAndSendRequest(nullptr, StringPiece(data), last_data,
-                                         std::move(delegate));
+                                         std::move(ack_listener));
 }
 
 bool QuicTestClient::response_complete() const {
@@ -685,16 +685,16 @@
     base::StringPiece body,
     bool fin,
     QuicTestClient* test_client,
-    QuicReferenceCountedPointer<QuicAckListenerInterface> delegate)
+    QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener)
     : QuicClient::QuicDataToResend(std::move(headers), body, fin),
       test_client_(test_client),
-      delegate_(std::move(delegate)) {}
+      ack_listener_(std::move(ack_listener)) {}
 
 QuicTestClient::TestClientDataToResend::~TestClientDataToResend() {}
 
 void QuicTestClient::TestClientDataToResend::Resend() {
   test_client_->GetOrCreateStreamAndSendRequest(headers_.get(), body_, fin_,
-                                                delegate_);
+                                                ack_listener_);
   headers_.reset();
 }
 
diff --git a/net/tools/quic/test_tools/quic_test_client.h b/net/tools/quic/test_tools/quic_test_client.h
index 10aaecb8..f35003c 100644
--- a/net/tools/quic/test_tools/quic_test_client.h
+++ b/net/tools/quic/test_tools/quic_test_client.h
@@ -116,7 +116,7 @@
   ssize_t SendData(
       const std::string& data,
       bool last_data,
-      QuicReferenceCountedPointer<QuicAckListenerInterface> delegate);
+      QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener);
 
   // Clears any outstanding state and sends a simple GET of 'uri' to the
   // server.  Returns 0 if the request failed and no bytes were written.
@@ -221,7 +221,7 @@
       const SpdyHeaderBlock* headers,
       base::StringPiece body,
       bool fin,
-      QuicReferenceCountedPointer<QuicAckListenerInterface> delegate);
+      QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener);
 
   QuicRstStreamErrorCode stream_error() { return stream_error_; }
   QuicErrorCode connection_error();
@@ -283,7 +283,7 @@
         base::StringPiece body,
         bool fin,
         QuicTestClient* test_client,
-        QuicReferenceCountedPointer<QuicAckListenerInterface> delegate);
+        QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener);
 
     ~TestClientDataToResend() override;
 
@@ -291,7 +291,7 @@
 
    protected:
     QuicTestClient* test_client_;
-    QuicReferenceCountedPointer<QuicAckListenerInterface> delegate_;
+    QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener_;
   };
 
   // Given |uri|, populates the fields in |headers| for a simple GET
diff --git a/services/catalog/catalog.cc b/services/catalog/catalog.cc
index 7985ec4a..75a2e4e4 100644
--- a/services/catalog/catalog.cc
+++ b/services/catalog/catalog.cc
@@ -115,7 +115,7 @@
 
 Catalog::Catalog(std::unique_ptr<Store> store)
     : store_(std::move(store)), weak_factory_(this) {
-  service_manager::mojom::ServiceRequest request = MakeRequest(&service_);
+  service_manager::mojom::ServiceRequest request(&service_);
   service_context_.reset(new service_manager::ServiceContext(
       base::MakeUnique<ServiceImpl>(this), std::move(request)));
 }
diff --git a/services/navigation/view_impl.cc b/services/navigation/view_impl.cc
index 83c28b6..812bb60b 100644
--- a/services/navigation/view_impl.cc
+++ b/services/navigation/view_impl.cc
@@ -148,7 +148,7 @@
                               bool* was_blocked) {
   mojom::ViewClientPtr client;
   mojom::ViewPtr view;
-  mojom::ViewRequest view_request = MakeRequest(&view);
+  mojom::ViewRequest view_request(&view);
   client_->ViewCreated(std::move(view), MakeRequest(&client),
                        disposition == WindowOpenDisposition::NEW_POPUP,
                        initial_rect, user_gesture);
diff --git a/services/service_manager/public/cpp/lib/connector_impl.cc b/services/service_manager/public/cpp/lib/connector_impl.cc
index a00b288..9d66a1cf 100644
--- a/services/service_manager/public/cpp/lib/connector_impl.cc
+++ b/services/service_manager/public/cpp/lib/connector_impl.cc
@@ -49,8 +49,7 @@
   DCHECK(params);
 
   mojom::InterfaceProviderPtr remote_interfaces;
-  mojom::InterfaceProviderRequest remote_request =
-      MakeRequest(&remote_interfaces);
+  mojom::InterfaceProviderRequest remote_request(&remote_interfaces);
   std::unique_ptr<internal::ConnectionImpl> connection(
       new internal::ConnectionImpl(params->target(),
                                    Connection::State::PENDING));
@@ -90,7 +89,7 @@
     return nullptr;
 
   mojom::ConnectorPtr connector;
-  mojom::ConnectorRequest request = MakeRequest(&connector);
+  mojom::ConnectorRequest request(&connector);
   connector_->Clone(std::move(request));
   return base::MakeUnique<ConnectorImpl>(connector.PassInterface());
 }
diff --git a/services/service_manager/service_manager.cc b/services/service_manager/service_manager.cc
index 2ca6a3a..091ce583 100644
--- a/services/service_manager/service_manager.cc
+++ b/services/service_manager/service_manager.cc
@@ -514,7 +514,7 @@
           std::move(service_process_launcher_factory)),
       weak_ptr_factory_(this) {
   mojom::ServicePtr service;
-  mojom::ServiceRequest request = mojo::MakeRequest(&service);
+  mojom::ServiceRequest request(&service);
 
   InterfaceProviderSpec spec;
   spec.provides[kCapability_ServiceManager].insert(
@@ -581,7 +581,7 @@
   params->set_target(embedder_identity);
 
   mojom::ServicePtr service;
-  mojom::ServiceRequest request = mojo::MakeRequest(&service);
+  mojom::ServiceRequest request(&service);
   Connect(std::move(params), std::move(service), nullptr);
 
   return request;
@@ -879,7 +879,7 @@
         std::move(client_process_connection));
   } else {
     // Otherwise we create a new Service pipe.
-    mojom::ServiceRequest request = MakeRequest(&service);
+    mojom::ServiceRequest request(&service);
     CHECK(!result->package_path.empty());
 
     // The catalog was unable to read a manifest for this service. We can't do
diff --git a/services/ui/gpu/gpu_main.cc b/services/ui/gpu/gpu_main.cc
index ce1c079..dc692c06a 100644
--- a/services/ui/gpu/gpu_main.cc
+++ b/services/ui/gpu/gpu_main.cc
@@ -158,8 +158,7 @@
                                  : nullptr;
 
   mojom::GpuServicePtr gpu_service;
-  mojom::GpuServiceRequest gpu_service_request =
-      mojo::MakeRequest(&gpu_service);
+  mojom::GpuServiceRequest gpu_service_request(&gpu_service);
 
   if (gpu_thread_.task_runner()->BelongsToCurrentThread()) {
     // If the DisplayCompositor creation was delayed because GpuService
diff --git a/services/ui/ws/frame_generator.cc b/services/ui/ws/frame_generator.cc
index c91684d..81cdf55 100644
--- a/services/ui/ws/frame_generator.cc
+++ b/services/ui/ws/frame_generator.cc
@@ -41,8 +41,7 @@
 void FrameGenerator::OnAcceleratedWidgetAvailable(
     gfx::AcceleratedWidget widget) {
   DCHECK_NE(gfx::kNullAcceleratedWidget, widget);
-  cc::mojom::MojoCompositorFrameSinkRequest request =
-      mojo::MakeRequest(&compositor_frame_sink_);
+  cc::mojom::MojoCompositorFrameSinkRequest request(&compositor_frame_sink_);
   root_window_->CreateDisplayCompositorFrameSink(
       widget, std::move(request), binding_.CreateInterfacePtrAndBind());
   // TODO(fsamuel): This means we're always requesting a new BeginFrame signal
diff --git a/services/ui/ws/test_utils.cc b/services/ui/ws/test_utils.cc
index e4275ac6..f11d843 100644
--- a/services/ui/ws/test_utils.cc
+++ b/services/ui/ws/test_utils.cc
@@ -511,7 +511,7 @@
   EXPECT_TRUE(wm_tree->AddWindow(FirstRootId(wm_tree), embed_window_id));
   display_->root_window()->SetBounds(root_window_bounds);
   mojom::WindowTreeClientPtr client;
-  mojom::WindowTreeClientRequest client_request = MakeRequest(&client);
+  mojom::WindowTreeClientRequest client_request(&client);
   wm_client_->Bind(std::move(client_request));
   const uint32_t embed_flags = 0;
   wm_tree->Embed(embed_window_id, std::move(client), embed_flags);
diff --git a/services/ui/ws/window_manager_state_unittest.cc b/services/ui/ws/window_manager_state_unittest.cc
index 401ae50..6a03c5d 100644
--- a/services/ui/ws/window_manager_state_unittest.cc
+++ b/services/ui/ws/window_manager_state_unittest.cc
@@ -79,7 +79,7 @@
                WindowTree** embed_tree,
                TestWindowTreeClient** embed_client_proxy) {
     mojom::WindowTreeClientPtr embed_client;
-    mojom::WindowTreeClientRequest client_request = MakeRequest(&embed_client);
+    mojom::WindowTreeClientRequest client_request(&embed_client);
     ASSERT_TRUE(
         tree->Embed(embed_window_id, std::move(embed_client), embed_flags));
     TestWindowTreeClient* client =
diff --git a/services/ui/ws/window_server.cc b/services/ui/ws/window_server.cc
index e7ef19e6..3f14290f 100644
--- a/services/ui/ws/window_server.cc
+++ b/services/ui/ws/window_server.cc
@@ -108,7 +108,7 @@
     tree->set_embedder_intercepts_events();
 
   mojom::WindowTreePtr window_tree_ptr;
-  mojom::WindowTreeRequest window_tree_request = MakeRequest(&window_tree_ptr);
+  mojom::WindowTreeRequest window_tree_request(&window_tree_ptr);
   std::unique_ptr<WindowTreeBinding> binding =
       delegate_->CreateWindowTreeBinding(
           WindowServerDelegate::BindingType::EMBED, this, tree,
diff --git a/services/ui/ws/window_tree_unittest.cc b/services/ui/ws/window_tree_unittest.cc
index fc21e53..fea549a4 100644
--- a/services/ui/ws/window_tree_unittest.cc
+++ b/services/ui/ws/window_tree_unittest.cc
@@ -222,7 +222,7 @@
   EXPECT_TRUE(wm_tree()->AddWindow(wm_root_id, embed_window_id));
   display()->root_window()->SetBounds(gfx::Rect(0, 0, 100, 100));
   mojom::WindowTreeClientPtr client;
-  mojom::WindowTreeClientRequest client_request = MakeRequest(&client);
+  mojom::WindowTreeClientRequest client_request(&client);
   wm_client()->Bind(std::move(client_request));
   const uint32_t embed_flags = 0;
   wm_tree()->Embed(embed_window_id, std::move(client), embed_flags);
diff --git a/skia/BUILD.gn b/skia/BUILD.gn
index be2084ee..da4eb2e 100644
--- a/skia/BUILD.gn
+++ b/skia/BUILD.gn
@@ -230,6 +230,7 @@
   sources += skia_core_sources
   sources += skia_effects_sources
   sources += skia_utils_sources
+  sources += skia_xps_sources
   sources += [
     "//third_party/skia/src/fonts/SkFontMgr_indirect.cpp",
     "//third_party/skia/src/fonts/SkRemotableFontMgr.cpp",
@@ -258,9 +259,6 @@
     "//third_party/skia/src/ports/SkTypeface_win_dw.cpp",
     "//third_party/skia/src/sfnt/SkOTTable_name.cpp",
     "//third_party/skia/src/sfnt/SkOTUtils.cpp",
-    "//third_party/skia/src/xps/SkDocument_XPS.cpp",
-    "//third_party/skia/src/xps/SkDocument_XPS_None.cpp",
-    "//third_party/skia/src/xps/SkXPSDevice.cpp",
   ]
 
   if (is_mac) {
diff --git a/storage/browser/BUILD.gn b/storage/browser/BUILD.gn
index d701ae0..8e91590 100644
--- a/storage/browser/BUILD.gn
+++ b/storage/browser/BUILD.gn
@@ -166,8 +166,6 @@
     "quota/quota_manager.h",
     "quota/quota_manager_proxy.cc",
     "quota/quota_manager_proxy.h",
-    "quota/quota_settings.cc",
-    "quota/quota_settings.h",
     "quota/quota_task.cc",
     "quota/quota_task.h",
     "quota/quota_temporary_storage_evictor.cc",
diff --git a/storage/browser/quota/client_usage_tracker.cc b/storage/browser/quota/client_usage_tracker.cc
index c5a17a5..c9c46f6d1 100644
--- a/storage/browser/quota/client_usage_tracker.cc
+++ b/storage/browser/quota/client_usage_tracker.cc
@@ -165,15 +165,6 @@
                                 AsWeakPtr(), origin));
 }
 
-int64_t ClientUsageTracker::GetCachedUsage() const {
-  int64_t usage = 0;
-  for (const auto& host_and_usage_map : cached_usage_by_host_) {
-    for (const auto& origin_and_usage : host_and_usage_map.second)
-      usage += origin_and_usage.second;
-  }
-  return usage;
-}
-
 void ClientUsageTracker::GetCachedHostsUsage(
     std::map<std::string, int64_t>* host_usage) const {
   DCHECK(host_usage);
diff --git a/storage/browser/quota/client_usage_tracker.h b/storage/browser/quota/client_usage_tracker.h
index 2fbe765..5b5a84b 100644
--- a/storage/browser/quota/client_usage_tracker.h
+++ b/storage/browser/quota/client_usage_tracker.h
@@ -52,7 +52,6 @@
   void GetGlobalUsage(const GlobalUsageCallback& callback);
   void GetHostUsage(const std::string& host, const UsageCallback& callback);
   void UpdateUsageCache(const GURL& origin, int64_t delta);
-  int64_t GetCachedUsage() const;
   void GetCachedHostsUsage(std::map<std::string, int64_t>* host_usage) const;
   void GetCachedOriginsUsage(std::map<GURL, int64_t>* origin_usage) const;
   void GetCachedOrigins(std::set<GURL>* origins) const;
diff --git a/storage/browser/quota/quota_manager.cc b/storage/browser/quota/quota_manager.cc
index b7e2036..44ba5f1 100644
--- a/storage/browser/quota/quota_manager.cc
+++ b/storage/browser/quota/quota_manager.cc
@@ -13,7 +13,6 @@
 #include <memory>
 #include <utility>
 
-#include "base/barrier_closure.h"
 #include "base/bind.h"
 #include "base/bind_helpers.h"
 #include "base/command_line.h"
@@ -27,7 +26,6 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/sys_info.h"
 #include "base/task_runner_util.h"
-#include "base/threading/thread_task_runner_handle.h"
 #include "base/time/time.h"
 #include "base/trace_event/trace_event.h"
 #include "net/base/url_util.h"
@@ -38,36 +36,49 @@
 #include "storage/browser/quota/usage_tracker.h"
 #include "storage/common/quota/quota_types.h"
 
+#define UMA_HISTOGRAM_MBYTES(name, sample)          \
+  UMA_HISTOGRAM_CUSTOM_COUNTS(                      \
+      (name), static_cast<int>((sample) / kMBytes), \
+      1, 10 * 1024 * 1024 /* 10TB */, 100)
+
 namespace storage {
 
 namespace {
 
 const int64_t kMBytes = 1024 * 1024;
 const int kMinutesInMilliSeconds = 60 * 1000;
-const int64_t kReportHistogramInterval = 60 * 60 * 1000;  // 1 hour
 
-#define UMA_HISTOGRAM_MBYTES(name, sample)                                     \
-  UMA_HISTOGRAM_CUSTOM_COUNTS((name), static_cast<int>((sample) / kMBytes), 1, \
-                              10 * 1024 * 1024 /* 10TB */, 100)
+const int64_t kReportHistogramInterval = 60 * 60 * 1000;  // 1 hour
+const double kTemporaryQuotaRatioToAvail = 1.0 / 3.0;  // 33%
 
 }  // namespace
 
+// Arbitrary for now, but must be reasonably small so that
+// in-memory databases can fit.
+// TODO(kinuko): Refer SysInfo::AmountOfPhysicalMemory() to determine this.
+const int64_t QuotaManager::kIncognitoDefaultQuotaLimit = 100 * kMBytes;
+
 const int64_t QuotaManager::kNoLimit = INT64_MAX;
 
+const int QuotaManager::kPerHostTemporaryPortion = 5;  // 20%
+
 // Cap size for per-host persistent quota determined by the histogram.
 // This is a bit lax value because the histogram says nothing about per-host
 // persistent storage usage and we determined by global persistent storage
 // usage that is less than 10GB for almost all users.
 const int64_t QuotaManager::kPerHostPersistentQuotaLimit = 10 * 1024 * kMBytes;
 
-// Heuristics: assuming average cloud server allows a few Gigs storage
-// on the server side and the storage needs to be shared for user data
-// and by multiple apps.
-int64_t QuotaManager::kSyncableStorageDefaultHostQuota = 500 * kMBytes;
-
 const char QuotaManager::kDatabaseName[] = "QuotaManager";
 
 const int QuotaManager::kThresholdOfErrorsToBeBlacklisted = 3;
+
+// Preserve kMinimumPreserveForSystem disk space for system book-keeping
+// when returning the quota to unlimited apps/extensions.
+// TODO(kinuko): This should be like 10% of the actual disk space.
+// For now we simply use a constant as getting the disk size needs
+// platform-dependent code. (http://crbug.com/178976)
+int64_t QuotaManager::kMinimumPreserveForSystem = 1024 * kMBytes;
+
 const int QuotaManager::kEvictionIntervalInMilliSeconds =
     30 * kMinutesInMilliSeconds;
 
@@ -78,17 +89,13 @@
 const char QuotaManager::kEvictedOriginTimeSinceAccessHistogram[] =
     "Quota.EvictedOriginTimeSinceAccess";
 
+// Heuristics: assuming average cloud server allows a few Gigs storage
+// on the server side and the storage needs to be shared for user data
+// and by multiple apps.
+int64_t QuotaManager::kSyncableStorageDefaultHostQuota = 500 * kMBytes;
+
 namespace {
 
-bool IsSupportedType(StorageType type) {
-  return type == kStorageTypeTemporary || type == kStorageTypePersistent ||
-         type == kStorageTypeSyncable;
-}
-
-bool IsSupportedIncognitoType(StorageType type) {
-  return type == kStorageTypeTemporary || type == kStorageTypePersistent;
-}
-
 void CountOriginType(const std::set<GURL>& origins,
                      SpecialStoragePolicy* policy,
                      size_t* protected_origins,
@@ -109,6 +116,17 @@
   }
 }
 
+bool SetTemporaryGlobalOverrideQuotaOnDBThread(int64_t* new_quota,
+                                               QuotaDatabase* database) {
+  DCHECK(database);
+  if (!database->SetQuotaConfigValue(
+          QuotaDatabase::kTemporaryQuotaOverrideKey, *new_quota)) {
+    *new_quota = -1;
+    return false;
+  }
+  return true;
+}
+
 bool GetPersistentHostQuotaOnDBThread(const std::string& host,
                                       int64_t* quota,
                                       QuotaDatabase* database) {
@@ -127,6 +145,17 @@
   return false;
 }
 
+bool InitializeOnDBThread(int64_t* temporary_quota_override,
+                          int64_t* desired_available_space,
+                          QuotaDatabase* database) {
+  DCHECK(database);
+  database->GetQuotaConfigValue(QuotaDatabase::kTemporaryQuotaOverrideKey,
+                                temporary_quota_override);
+  database->GetQuotaConfigValue(QuotaDatabase::kDesiredAvailableSpaceKey,
+                                desired_available_space);
+  return true;
+}
+
 bool GetLRUOriginOnDBThread(StorageType type,
                             const std::set<GURL>& exceptions,
                             SpecialStoragePolicy* policy,
@@ -175,8 +204,8 @@
   return database->SetOriginLastEvictionTime(origin, type, now);
 }
 
-bool BootstrapDatabaseOnDBThread(const std::set<GURL>* origins,
-                                 QuotaDatabase* database) {
+bool InitializeTemporaryOriginsInfoOnDBThread(const std::set<GURL>* origins,
+                                              QuotaDatabase* database) {
   DCHECK(database);
   if (database->IsOriginDatabaseBootstrapped())
     return true;
@@ -205,222 +234,277 @@
   return database->SetOriginLastModifiedTime(origin, type, modified_time);
 }
 
+int64_t CalculateTemporaryGlobalQuota(int64_t global_limited_usage,
+                                      int64_t available_space) {
+  DCHECK_GE(global_limited_usage, 0);
+  int64_t avail_space = available_space;
+  if (avail_space <
+      std::numeric_limits<int64_t>::max() - global_limited_usage) {
+    // We basically calculate the temporary quota by
+    // [available_space + space_used_for_temp] * kTempQuotaRatio,
+    // but make sure we'll have no overflow.
+    avail_space += global_limited_usage;
+  }
+  int64_t pool_size = avail_space * kTemporaryQuotaRatioToAvail;
+  UMA_HISTOGRAM_MBYTES("Quota.GlobalTemporaryPoolSize", pool_size);
+  return pool_size;
+}
+
+void DispatchTemporaryGlobalQuotaCallback(
+    const QuotaCallback& callback,
+    QuotaStatusCode status,
+    const UsageAndQuota& usage_and_quota) {
+  if (status != kQuotaStatusOk) {
+    callback.Run(status, 0);
+    return;
+  }
+
+  callback.Run(status, CalculateTemporaryGlobalQuota(
+      usage_and_quota.global_limited_usage,
+      usage_and_quota.available_disk_space));
+}
+
+int64_t CalculateQuotaWithDiskSpace(int64_t available_disk_space,
+                                    int64_t usage,
+                                    int64_t quota) {
+  if (available_disk_space < QuotaManager::kMinimumPreserveForSystem) {
+    LOG(WARNING)
+        << "Running out of disk space for profile."
+        << " QuotaManager starts forbidding further quota consumption.";
+    return usage;
+  }
+
+  if (quota < usage) {
+    // No more space; cap the quota to the current usage.
+    return usage;
+  }
+
+  available_disk_space -= QuotaManager::kMinimumPreserveForSystem;
+  if (available_disk_space < quota - usage)
+    return available_disk_space + usage;
+
+  return quota;
+}
+
+int64_t CalculateTemporaryHostQuota(int64_t host_usage,
+                                    int64_t global_quota,
+                                    int64_t global_limited_usage) {
+  DCHECK_GE(global_limited_usage, 0);
+  int64_t host_quota = global_quota / QuotaManager::kPerHostTemporaryPortion;
+  if (global_limited_usage > global_quota)
+    host_quota = std::min(host_quota, host_usage);
+  return host_quota;
+}
+
+void DispatchUsageAndQuotaForWebApps(
+    StorageType type,
+    bool is_incognito,
+    bool is_unlimited,
+    bool can_query_disk_size,
+    const QuotaManager::GetUsageAndQuotaCallback& callback,
+    QuotaStatusCode status,
+    const UsageAndQuota& usage_and_quota) {
+  if (status != kQuotaStatusOk) {
+    callback.Run(status, 0, 0);
+    return;
+  }
+
+  int64_t usage = usage_and_quota.usage;
+  int64_t quota = usage_and_quota.quota;
+
+  if (type == kStorageTypeTemporary && !is_unlimited) {
+    quota = CalculateTemporaryHostQuota(
+        usage, quota, usage_and_quota.global_limited_usage);
+  }
+
+  if (is_incognito) {
+    quota = std::min(quota, QuotaManager::kIncognitoDefaultQuotaLimit);
+    callback.Run(status, usage, quota);
+    return;
+  }
+
+  // For apps with unlimited permission or can_query_disk_size is true (and not
+  // in incognito mode).
+  // We assume we can expose the actual disk size for them and cap the quota by
+  // the available disk space.
+  if (is_unlimited || can_query_disk_size) {
+    quota = CalculateQuotaWithDiskSpace(
+        usage_and_quota.available_disk_space,
+        usage, quota);
+  }
+
+  callback.Run(status, usage, quota);
+
+  if (type == kStorageTypeTemporary && !is_unlimited)
+    UMA_HISTOGRAM_MBYTES("Quota.QuotaForOrigin", quota);
+}
+
 }  // namespace
 
-class QuotaManager::UsageAndQuotaHelper : public QuotaTask {
+UsageAndQuota::UsageAndQuota()
+    : usage(0),
+      global_limited_usage(0),
+      quota(0),
+      available_disk_space(0) {
+}
+
+UsageAndQuota::UsageAndQuota(int64_t usage,
+                             int64_t global_limited_usage,
+                             int64_t quota,
+                             int64_t available_disk_space)
+    : usage(usage),
+      global_limited_usage(global_limited_usage),
+      quota(quota),
+      available_disk_space(available_disk_space) {}
+
+class UsageAndQuotaCallbackDispatcher
+    : public QuotaTask,
+      public base::SupportsWeakPtr<UsageAndQuotaCallbackDispatcher> {
  public:
-  UsageAndQuotaHelper(QuotaManager* manager,
-                      const GURL& origin,
-                      StorageType type,
-                      bool is_unlimited,
-                      bool is_incognito,
-                      const UsageAndQuotaCallback& callback)
+  explicit UsageAndQuotaCallbackDispatcher(QuotaManager* manager)
       : QuotaTask(manager),
-        origin_(origin),
-        callback_(callback),
-        type_(type),
-        is_unlimited_(is_unlimited),
-        is_incognito_(is_incognito),
-        weak_factory_(this) {}
+        has_usage_(false),
+        has_global_limited_usage_(false),
+        has_quota_(false),
+        has_available_disk_space_(false),
+        status_(kQuotaStatusUnknown),
+        usage_and_quota_(-1, -1, -1, -1),
+        waiting_callbacks_(1) {}
 
- protected:
+  ~UsageAndQuotaCallbackDispatcher() override {}
+
+  void WaitForResults(const QuotaManager::UsageAndQuotaCallback& callback) {
+    callback_ = callback;
+    Start();
+  }
+
+  void set_usage(int64_t usage) {
+    usage_and_quota_.usage = usage;
+    has_usage_ = true;
+  }
+
+  void set_global_limited_usage(int64_t global_limited_usage) {
+    usage_and_quota_.global_limited_usage = global_limited_usage;
+    has_global_limited_usage_ = true;
+  }
+
+  void set_quota(int64_t quota) {
+    usage_and_quota_.quota = quota;
+    has_quota_ = true;
+  }
+
+  void set_available_disk_space(int64_t available_disk_space) {
+    usage_and_quota_.available_disk_space = available_disk_space;
+    has_available_disk_space_ = true;
+  }
+
+  UsageCallback GetHostUsageCallback() {
+    ++waiting_callbacks_;
+    has_usage_ = true;
+    return base::Bind(&UsageAndQuotaCallbackDispatcher::DidGetHostUsage,
+                      AsWeakPtr());
+  }
+
+  UsageCallback GetGlobalLimitedUsageCallback() {
+    ++waiting_callbacks_;
+    has_global_limited_usage_ = true;
+    return base::Bind(
+        &UsageAndQuotaCallbackDispatcher::DidGetGlobalLimitedUsage,
+        AsWeakPtr());
+  }
+
+  QuotaCallback GetQuotaCallback() {
+    ++waiting_callbacks_;
+    has_quota_ = true;
+    return base::Bind(&UsageAndQuotaCallbackDispatcher::DidGetQuota,
+                      AsWeakPtr());
+  }
+
+  QuotaCallback GetAvailableSpaceCallback() {
+    ++waiting_callbacks_;
+    has_available_disk_space_ = true;
+    return base::Bind(&UsageAndQuotaCallbackDispatcher::DidGetAvailableSpace,
+                      AsWeakPtr());
+  }
+
+ private:
+  void DidGetHostUsage(int64_t usage) {
+    if (status_ == kQuotaStatusUnknown)
+      status_ = kQuotaStatusOk;
+    usage_and_quota_.usage = usage;
+    CheckCompleted();
+  }
+
+  void DidGetGlobalLimitedUsage(int64_t limited_usage) {
+    if (status_ == kQuotaStatusUnknown)
+      status_ = kQuotaStatusOk;
+    usage_and_quota_.global_limited_usage = limited_usage;
+    CheckCompleted();
+  }
+
+  void DidGetQuota(QuotaStatusCode status, int64_t quota) {
+    if (status_ == kQuotaStatusUnknown || status_ == kQuotaStatusOk)
+      status_ = status;
+    usage_and_quota_.quota = quota;
+    CheckCompleted();
+  }
+
+  void DidGetAvailableSpace(QuotaStatusCode status, int64_t space) {
+    // crbug.com/349708
+    TRACE_EVENT0(
+        "io", "UsageAndQuotaCallbackDispatcher::DidGetAvailableSpace");
+
+    DCHECK_GE(space, 0);
+    if (status_ == kQuotaStatusUnknown || status_ == kQuotaStatusOk)
+      status_ = status;
+    usage_and_quota_.available_disk_space = space;
+    CheckCompleted();
+  }
+
   void Run() override {
-    // Start the async process of gathering the info we need.
-    // Gather 4 pieces of info before computing an answer:
-    // settings, device_storage_capacity, host_usage, and host_quota.
-    base::Closure barrier = base::BarrierClosure(
-        4, base::Bind(&UsageAndQuotaHelper::OnBarrierComplete,
-                      weak_factory_.GetWeakPtr()));
-
-    std::string host = net::GetHostOrSpecFromURL(origin_);
-
-    manager()->GetQuotaSettings(base::Bind(&UsageAndQuotaHelper::OnGotSettings,
-                                           weak_factory_.GetWeakPtr(),
-                                           barrier));
-    manager()->GetStorageCapacity(
-        base::Bind(&UsageAndQuotaHelper::OnGotCapacity,
-                   weak_factory_.GetWeakPtr(), barrier));
-    manager()->GetHostUsage(host, type_,
-                            base::Bind(&UsageAndQuotaHelper::OnGotHostUsage,
-                                       weak_factory_.GetWeakPtr(), barrier));
-
-    // Determine host_quota differently depending on type.
-    if (is_unlimited_) {
-      SetDesiredHostQuota(barrier, kQuotaStatusOk, kNoLimit);
-    } else if (type_ == kStorageTypeSyncable) {
-      SetDesiredHostQuota(barrier, kQuotaStatusOk,
-                          kSyncableStorageDefaultHostQuota);
-    } else if (type_ == kStorageTypePersistent) {
-      manager()->GetPersistentHostQuota(
-          host, base::Bind(&UsageAndQuotaHelper::SetDesiredHostQuota,
-                           weak_factory_.GetWeakPtr(), barrier));
-    } else {
-      DCHECK_EQ(kStorageTypeTemporary, type_);
-      // For temporary storge,  OnGotSettings will set the host quota.
-    }
+    // We initialize waiting_callbacks to 1 so that we won't run
+    // the completion callback until here even some of the callbacks
+    // are dispatched synchronously.
+    CheckCompleted();
   }
 
   void Aborted() override {
-    weak_factory_.InvalidateWeakPtrs();
-    callback_.Run(kQuotaErrorAbort, 0, 0);
+    callback_.Run(kQuotaErrorAbort, UsageAndQuota());
     DeleteSoon();
   }
 
   void Completed() override {
-    weak_factory_.InvalidateWeakPtrs();
+    // crbug.com/349708
+    TRACE_EVENT0("io", "UsageAndQuotaCallbackDispatcher::Completed");
 
-    // Constrain the desired |host_quota| to something that fits.
-    // If available space is too low, cap usage at current levels.
-    // If it's close to being too low, cap growth to avoid it getting too low.
-    int64_t host_quota =
-        std::min(desired_host_quota_,
-                 host_usage_ +
-                     std::max(INT64_C(0), available_space_ -
-                                              settings_.must_remain_available));
-    callback_.Run(kQuotaStatusOk, host_usage_, host_quota);
-    if (type_ == kStorageTypeTemporary && !is_incognito_ && !is_unlimited_)
-      UMA_HISTOGRAM_MBYTES("Quota.QuotaForOrigin", host_quota);
+    DCHECK(!has_usage_ || usage_and_quota_.usage >= 0);
+    DCHECK(!has_global_limited_usage_ ||
+           usage_and_quota_.global_limited_usage >= 0);
+    DCHECK(!has_quota_ || usage_and_quota_.quota >= 0);
+    DCHECK(!has_available_disk_space_ ||
+           usage_and_quota_.available_disk_space >= 0);
+
+    callback_.Run(status_, usage_and_quota_);
     DeleteSoon();
   }
 
- private:
-  QuotaManager* manager() const {
-    return static_cast<QuotaManager*>(observer());
-  }
-
-  void OnGotSettings(const base::Closure& barrier_closure,
-                     const QuotaSettings& settings) {
-    settings_ = settings;
-    barrier_closure.Run();
-    if (type_ == kStorageTypeTemporary && !is_unlimited_) {
-      SetDesiredHostQuota(barrier_closure, kQuotaStatusOk,
-                          settings.per_host_quota);
-    }
-  }
-
-  void OnGotCapacity(const base::Closure& barrier_closure,
-                     int64_t total_space,
-                     int64_t available_space) {
-    total_space_ = total_space;
-    available_space_ = available_space;
-    barrier_closure.Run();
-  }
-
-  void OnGotHostUsage(const base::Closure& barrier_closure, int64_t usage) {
-    host_usage_ = usage;
-    barrier_closure.Run();
-  }
-
-  void SetDesiredHostQuota(const base::Closure& barrier_closure,
-                           QuotaStatusCode status,
-                           int64_t quota) {
-    desired_host_quota_ = quota;
-    barrier_closure.Run();
-  }
-
-  void OnBarrierComplete() { CallCompleted(); }
-
-  GURL origin_;
-  QuotaManager::UsageAndQuotaCallback callback_;
-  StorageType type_;
-  bool is_unlimited_;
-  bool is_incognito_;
-  int64_t available_space_ = 0;
-  int64_t total_space_ = 0;
-  int64_t desired_host_quota_ = 0;
-  int64_t host_usage_ = 0;
-  QuotaSettings settings_;
-  base::WeakPtrFactory<UsageAndQuotaHelper> weak_factory_;
-  DISALLOW_COPY_AND_ASSIGN(UsageAndQuotaHelper);
-};
-
-// Helper to asychronously gather information needed at the start of an
-// eviction round.
-class QuotaManager::EvictionRoundInfoHelper : public QuotaTask {
- public:
-  EvictionRoundInfoHelper(QuotaManager* manager,
-                          const EvictionRoundInfoCallback& callback)
-      : QuotaTask(manager), callback_(callback), weak_factory_(this) {}
-
- protected:
-  void Run() override {
-    // Gather 2 pieces of info before deciding if we need to get GlobalUsage:
-    // settings and device_storage_capacity.
-    base::Closure barrier = base::BarrierClosure(
-        2, base::Bind(&EvictionRoundInfoHelper::OnBarrierComplete,
-                      weak_factory_.GetWeakPtr()));
-
-    manager()->GetQuotaSettings(
-        base::Bind(&EvictionRoundInfoHelper::OnGotSettings,
-                   weak_factory_.GetWeakPtr(), barrier));
-    manager()->GetStorageCapacity(
-        base::Bind(&EvictionRoundInfoHelper::OnGotCapacity,
-                   weak_factory_.GetWeakPtr(), barrier));
-  }
-
-  void Aborted() override {
-    weak_factory_.InvalidateWeakPtrs();
-    callback_.Run(kQuotaErrorAbort, QuotaSettings(), 0, 0, 0, false);
-    DeleteSoon();
-  }
-
-  void Completed() override {
-    weak_factory_.InvalidateWeakPtrs();
-    callback_.Run(kQuotaStatusOk, settings_, available_space_, total_space_,
-                  global_usage_, global_usage_is_complete_);
-    DeleteSoon();
-  }
-
- private:
-  QuotaManager* manager() const {
-    return static_cast<QuotaManager*>(observer());
-  }
-
-  void OnGotSettings(const base::Closure& barrier_closure,
-                     const QuotaSettings& settings) {
-    settings_ = settings;
-    barrier_closure.Run();
-  }
-
-  void OnGotCapacity(const base::Closure& barrier_closure,
-                     int64_t total_space,
-                     int64_t available_space) {
-    total_space_ = total_space;
-    available_space_ = available_space;
-    barrier_closure.Run();
-  }
-
-  void OnBarrierComplete() {
-    // Avoid computing the full current_usage when there's no pressure.
-    int64_t consumed_space = total_space_ - available_space_;
-    if (consumed_space < settings_.pool_size &&
-        available_space_ > settings_.must_remain_available) {
-      DCHECK(!global_usage_is_complete_);
-      global_usage_ =
-          manager()->GetUsageTracker(kStorageTypeTemporary)->GetCachedUsage();
+  void CheckCompleted() {
+    if (--waiting_callbacks_ <= 0)
       CallCompleted();
-      return;
-    }
-    manager()->GetGlobalUsage(
-        kStorageTypeTemporary,
-        base::Bind(&EvictionRoundInfoHelper::OnGotGlobalUsage,
-                   weak_factory_.GetWeakPtr()));
   }
 
-  void OnGotGlobalUsage(int64_t usage, int64_t unlimited_usage) {
-    global_usage_ = std::max(INT64_C(0), usage - unlimited_usage);
-    global_usage_is_complete_ = true;
-    CallCompleted();
-  }
+  // For sanity checks, they're checked only when DCHECK is on.
+  bool has_usage_;
+  bool has_global_limited_usage_;
+  bool has_quota_;
+  bool has_available_disk_space_;
 
-  EvictionRoundInfoCallback callback_;
-  QuotaSettings settings_;
-  int64_t available_space_ = 0;
-  int64_t total_space_ = 0;
-  int64_t global_usage_ = 0;
-  bool global_usage_is_complete_ = false;
-  base::WeakPtrFactory<EvictionRoundInfoHelper> weak_factory_;
-  DISALLOW_COPY_AND_ASSIGN(EvictionRoundInfoHelper);
+  QuotaStatusCode status_;
+  UsageAndQuota usage_and_quota_;
+  QuotaManager::UsageAndQuotaCallback callback_;
+  int waiting_callbacks_;
+
+  DISALLOW_COPY_AND_ASSIGN(UsageAndQuotaCallbackDispatcher);
 };
 
 class QuotaManager::GetUsageInfoTask : public QuotaTask {
@@ -782,8 +866,7 @@
     const base::FilePath& profile_path,
     const scoped_refptr<base::SingleThreadTaskRunner>& io_thread,
     const scoped_refptr<base::SequencedTaskRunner>& db_thread,
-    const scoped_refptr<SpecialStoragePolicy>& special_storage_policy,
-    const GetQuotaSettingsFunc& get_settings_function)
+    const scoped_refptr<SpecialStoragePolicy>& special_storage_policy)
     : is_incognito_(is_incognito),
       profile_path_(profile_path),
       proxy_(new QuotaManagerProxy(this, io_thread)),
@@ -791,25 +874,13 @@
       eviction_disabled_(false),
       io_thread_(io_thread),
       db_thread_(db_thread),
-      get_settings_function_(get_settings_function),
       is_getting_eviction_origin_(false),
+      temporary_quota_initialized_(false),
+      temporary_quota_override_(-1),
       special_storage_policy_(special_storage_policy),
       get_volume_info_fn_(&QuotaManager::GetVolumeInfo),
       storage_monitor_(new StorageMonitor(this)),
-      weak_factory_(this) {
-  DCHECK_EQ(settings_.refresh_interval, base::TimeDelta::Max());
-  if (!get_settings_function.is_null()) {
-    // Reset the interval to ensure we use the get_settings_function
-    // the first times settings_ is needed.
-    settings_.refresh_interval = base::TimeDelta();
-    get_settings_task_runner_ = base::ThreadTaskRunnerHandle::Get();
-  }
-}
-
-void QuotaManager::SetQuotaSettings(const QuotaSettings& settings) {
-  settings_ = settings;
-  settings_timestamp_ = base::TimeTicks::Now();
-}
+      weak_factory_(this) {}
 
 void QuotaManager::GetUsageInfo(const GetUsageInfoCallback& callback) {
   LazyInitialize();
@@ -820,28 +891,61 @@
 void QuotaManager::GetUsageAndQuotaForWebApps(
     const GURL& origin,
     StorageType type,
-    const UsageAndQuotaCallback& callback) {
-  DCHECK(origin == origin.GetOrigin());
-  if (!IsSupportedType(type) ||
-      (is_incognito_ && !IsSupportedIncognitoType(type))) {
+    const GetUsageAndQuotaCallback& callback) {
+  // TODO(pkasting): Remove ScopedTracker below once crbug.com/477117 is fixed.
+  tracked_objects::ScopedTracker tracking_profile(
+      FROM_HERE_WITH_EXPLICIT_FUNCTION(
+          "477117 QuotaManager::GetUsageAndQuotaForWebApps"));
+  if (type != kStorageTypeTemporary &&
+      type != kStorageTypePersistent &&
+      type != kStorageTypeSyncable) {
     callback.Run(kQuotaErrorNotSupported, 0, 0);
     return;
   }
+
+  DCHECK(origin == origin.GetOrigin());
   LazyInitialize();
-  UsageAndQuotaHelper* helper = new UsageAndQuotaHelper(
-      this, origin, type, IsStorageUnlimited(origin, type), is_incognito_,
-      callback);
-  helper->Start();
+
+  bool unlimited = IsStorageUnlimited(origin, type);
+  bool can_query_disk_size = CanQueryDiskSize(origin);
+
+  UsageAndQuotaCallbackDispatcher* dispatcher =
+      new UsageAndQuotaCallbackDispatcher(this);
+
+  if (unlimited) {
+    dispatcher->set_quota(kNoLimit);
+  } else {
+    if (type == kStorageTypeTemporary) {
+      GetUsageTracker(type)->GetGlobalLimitedUsage(
+          dispatcher->GetGlobalLimitedUsageCallback());
+      GetTemporaryGlobalQuota(dispatcher->GetQuotaCallback());
+    } else if (type == kStorageTypePersistent) {
+      GetPersistentHostQuota(net::GetHostOrSpecFromURL(origin),
+                             dispatcher->GetQuotaCallback());
+    } else {
+      dispatcher->set_quota(kSyncableStorageDefaultHostQuota);
+    }
+  }
+
+  DCHECK(GetUsageTracker(type));
+  GetUsageTracker(type)->GetHostUsage(net::GetHostOrSpecFromURL(origin),
+                                      dispatcher->GetHostUsageCallback());
+
+  if (!is_incognito_ && (unlimited || can_query_disk_size))
+    GetAvailableSpace(dispatcher->GetAvailableSpaceCallback());
+
+  dispatcher->WaitForResults(base::Bind(
+      &DispatchUsageAndQuotaForWebApps,
+      type, is_incognito_, unlimited, can_query_disk_size,
+      callback));
 }
 
-void QuotaManager::GetUsageAndQuota(const GURL& origin,
-                                    StorageType type,
-                                    const UsageAndQuotaCallback& callback) {
+void QuotaManager::GetUsageAndQuota(
+    const GURL& origin, StorageType type,
+    const GetUsageAndQuotaCallback& callback) {
   DCHECK(origin == origin.GetOrigin());
 
   if (IsStorageUnlimited(origin, type)) {
-    // TODO(michaeln): This seems like a non-obvious odd behavior, probably for
-    // apps/extensions, but it would be good to elimiate this special case.
     callback.Run(kQuotaStatusOk, 0, kNoLimit);
     return;
   }
@@ -887,6 +991,11 @@
   GetUsageTracker(type)->SetUsageCacheEnabled(client_id, origin, enabled);
 }
 
+void QuotaManager::SetTemporaryStorageEvictionPolicy(
+    std::unique_ptr<QuotaEvictionPolicy> policy) {
+  temporary_storage_eviction_policy_ = std::move(policy);
+}
+
 void QuotaManager::DeleteOriginData(const GURL& origin,
                                     StorageType type,
                                     int quota_client_mask,
@@ -899,6 +1008,7 @@
                                   int quota_client_mask,
                                   const StatusCallback& callback) {
   LazyInitialize();
+
   if (host.empty() || clients_.empty()) {
     callback.Run(kQuotaStatusOk);
     return;
@@ -909,6 +1019,72 @@
   deleter->Start();
 }
 
+void QuotaManager::GetAvailableSpace(const AvailableSpaceCallback& callback) {
+  if (!available_space_callbacks_.Add(callback))
+    return;
+  // crbug.com/349708
+  TRACE_EVENT0("io", "QuotaManager::GetAvailableSpace");
+
+  PostTaskAndReplyWithResult(
+      db_thread_.get(),
+      FROM_HERE,
+      base::Bind(&QuotaManager::CallGetAmountOfFreeDiskSpace,
+                 get_volume_info_fn_, profile_path_),
+      base::Bind(&QuotaManager::DidGetAvailableSpace,
+                 weak_factory_.GetWeakPtr()));
+}
+
+void QuotaManager::GetTemporaryGlobalQuota(const QuotaCallback& callback) {
+  LazyInitialize();
+  if (!temporary_quota_initialized_) {
+    db_initialization_callbacks_.Add(base::Bind(
+        &QuotaManager::GetTemporaryGlobalQuota,
+        weak_factory_.GetWeakPtr(), callback));
+    return;
+  }
+
+  if (temporary_quota_override_ > 0) {
+    callback.Run(kQuotaStatusOk, temporary_quota_override_);
+    return;
+  }
+
+  UsageAndQuotaCallbackDispatcher* dispatcher =
+      new UsageAndQuotaCallbackDispatcher(this);
+  GetUsageTracker(kStorageTypeTemporary)->
+      GetGlobalLimitedUsage(dispatcher->GetGlobalLimitedUsageCallback());
+  GetAvailableSpace(dispatcher->GetAvailableSpaceCallback());
+  dispatcher->WaitForResults(
+      base::Bind(&DispatchTemporaryGlobalQuotaCallback, callback));
+}
+
+void QuotaManager::SetTemporaryGlobalOverrideQuota(
+    int64_t new_quota,
+    const QuotaCallback& callback) {
+  LazyInitialize();
+
+  if (new_quota < 0) {
+    if (!callback.is_null())
+      callback.Run(kQuotaErrorInvalidModification, -1);
+    return;
+  }
+
+  if (db_disabled_) {
+    if (!callback.is_null())
+      callback.Run(kQuotaErrorInvalidAccess, -1);
+    return;
+  }
+
+  int64_t* new_quota_ptr = new int64_t(new_quota);
+  PostTaskAndReplyWithResultForDBThread(
+      FROM_HERE,
+      base::Bind(&SetTemporaryGlobalOverrideQuotaOnDBThread,
+                 base::Unretained(new_quota_ptr)),
+      base::Bind(&QuotaManager::DidSetTemporaryGlobalOverrideQuota,
+                 weak_factory_.GetWeakPtr(),
+                 callback,
+                 base::Owned(new_quota_ptr)));
+}
+
 void QuotaManager::GetPersistentHostQuota(const std::string& host,
                                           const QuotaCallback& callback) {
   LazyInitialize();
@@ -950,8 +1126,10 @@
     return;
   }
 
-  // Cap the requested size at the per-host quota limit.
-  new_quota = std::min(new_quota, kPerHostPersistentQuotaLimit);
+  if (kPerHostPersistentQuotaLimit < new_quota) {
+    // Cap the requested size at the per-host quota limit.
+    new_quota = kPerHostPersistentQuotaLimit;
+  }
 
   if (db_disabled_) {
     callback.Run(kQuotaErrorInvalidAccess, -1);
@@ -1111,7 +1289,7 @@
 void QuotaManager::LazyInitialize() {
   DCHECK(io_thread_->BelongsToCurrentThread());
   if (database_) {
-    // Already initialized.
+    // Initialization seems to be done already.
     return;
   }
 
@@ -1129,45 +1307,17 @@
       clients_, kStorageTypeSyncable, special_storage_policy_.get(),
       storage_monitor_.get()));
 
-  if (!is_incognito_) {
-    histogram_timer_.Start(
-        FROM_HERE, base::TimeDelta::FromMilliseconds(kReportHistogramInterval),
-        this, &QuotaManager::ReportHistogram);
-  }
-
-  base::PostTaskAndReplyWithResult(
-      db_thread_.get(), FROM_HERE,
-      base::Bind(&QuotaDatabase::IsOriginDatabaseBootstrapped,
-                 base::Unretained(database_.get())),
-      base::Bind(&QuotaManager::FinishLazyInitialize,
-                 weak_factory_.GetWeakPtr()));
-}
-
-void QuotaManager::FinishLazyInitialize(bool is_database_bootstrapped) {
-  is_database_bootstrapped_ = is_database_bootstrapped;
-  StartEviction();
-}
-
-void QuotaManager::BootstrapDatabaseForEviction(
-    const GetOriginCallback& did_get_origin_callback,
-    int64_t usage,
-    int64_t unlimited_usage) {
-  // The usage cache should be fully populated now so we can
-  // seed the database with origins we know about.
-  std::set<GURL>* origins = new std::set<GURL>;
-  temporary_usage_tracker_->GetCachedOrigins(origins);
+  int64_t* temporary_quota_override = new int64_t(-1);
+  int64_t* desired_available_space = new int64_t(-1);
   PostTaskAndReplyWithResultForDBThread(
-      FROM_HERE, base::Bind(&BootstrapDatabaseOnDBThread, base::Owned(origins)),
-      base::Bind(&QuotaManager::DidBootstrapDatabase,
-                 weak_factory_.GetWeakPtr(), did_get_origin_callback));
-}
-
-void QuotaManager::DidBootstrapDatabase(
-    const GetOriginCallback& did_get_origin_callback,
-    bool success) {
-  is_database_bootstrapped_ = success;
-  DidDatabaseWork(success);
-  GetLRUOrigin(kStorageTypeTemporary, did_get_origin_callback);
+      FROM_HERE,
+      base::Bind(&InitializeOnDBThread,
+                 base::Unretained(temporary_quota_override),
+                 base::Unretained(desired_available_space)),
+      base::Bind(&QuotaManager::DidInitialize,
+                 weak_factory_.GetWeakPtr(),
+                 base::Owned(temporary_quota_override),
+                 base::Owned(desired_available_space)));
 }
 
 void QuotaManager::RegisterClient(QuotaClient* client) {
@@ -1262,10 +1412,11 @@
 
 void QuotaManager::StartEviction() {
   DCHECK(!temporary_storage_evictor_.get());
-  if (eviction_disabled_)
-    return;
   temporary_storage_evictor_.reset(new QuotaTemporaryStorageEvictor(
       this, kEvictionIntervalInMilliSeconds));
+  if (desired_available_space_ >= 0)
+    temporary_storage_evictor_->set_min_available_disk_space_to_start_eviction(
+        desired_available_space_);
   temporary_storage_evictor_->Start();
 }
 
@@ -1451,21 +1602,26 @@
       base::Bind(&QuotaManager::DidGetEvictionOrigin,
                  weak_factory_.GetWeakPtr(), callback);
 
-  if (!is_database_bootstrapped_ && !eviction_disabled_) {
-    // Once bootstrapped, GetLRUOrigin will be called.
-    GetGlobalUsage(
-        kStorageTypeTemporary,
-        base::Bind(&QuotaManager::BootstrapDatabaseForEviction,
-                   weak_factory_.GetWeakPtr(), did_get_origin_callback));
+  if (type == kStorageTypeTemporary && temporary_storage_eviction_policy_) {
+    std::map<GURL, int64_t> usage_map;
+    // The cached origins are populated by the prior call to
+    // GetUsageAndQuotaForEviction().
+    GetUsageTracker(kStorageTypeTemporary)->GetCachedOriginsUsage(&usage_map);
+
+    temporary_storage_eviction_policy_->GetEvictionOrigin(
+        special_storage_policy_, GetEvictionOriginExceptions(extra_exceptions),
+        usage_map, global_quota, did_get_origin_callback);
+
     return;
   }
 
+  // TODO(calamity): convert LRU origin retrieval into a QuotaEvictionPolicy.
   GetLRUOrigin(type, did_get_origin_callback);
 }
 
 void QuotaManager::EvictOriginData(const GURL& origin,
                                    StorageType type,
-                                   const StatusCallback& callback) {
+                                   const EvictOriginDataCallback& callback) {
   DCHECK(io_thread_->BelongsToCurrentThread());
   DCHECK_EQ(type, kStorageTypeTemporary);
 
@@ -1478,12 +1634,47 @@
                                       weak_factory_.GetWeakPtr()));
 }
 
-void QuotaManager::GetEvictionRoundInfo(
-    const EvictionRoundInfoCallback& callback) {
+void QuotaManager::GetUsageAndQuotaForEviction(
+    const UsageAndQuotaCallback& callback) {
+  // crbug.com/349708
+  TRACE_EVENT0("io", "QuotaManager::GetUsageAndQuotaForEviction");
+
   DCHECK(io_thread_->BelongsToCurrentThread());
   LazyInitialize();
-  EvictionRoundInfoHelper* helper = new EvictionRoundInfoHelper(this, callback);
-  helper->Start();
+
+  UsageAndQuotaCallbackDispatcher* dispatcher =
+      new UsageAndQuotaCallbackDispatcher(this);
+  GetUsageTracker(kStorageTypeTemporary)
+      ->GetGlobalLimitedUsage(dispatcher->GetGlobalLimitedUsageCallback());
+  GetTemporaryGlobalQuota(dispatcher->GetQuotaCallback());
+  GetAvailableSpace(dispatcher->GetAvailableSpaceCallback());
+  dispatcher->WaitForResults(callback);
+}
+
+void QuotaManager::AsyncGetVolumeInfo(
+    const VolumeInfoCallback& callback) {
+  DCHECK(io_thread_->BelongsToCurrentThread());
+  uint64_t* available_space = new uint64_t(0);
+  uint64_t* total_space = new uint64_t(0);
+  PostTaskAndReplyWithResult(
+      db_thread_.get(),
+      FROM_HERE,
+      base::Bind(get_volume_info_fn_,
+                 profile_path_,
+                 base::Unretained(available_space),
+                 base::Unretained(total_space)),
+      base::Bind(&QuotaManager::DidGetVolumeInfo,
+                 weak_factory_.GetWeakPtr(),
+                 callback,
+                 base::Owned(available_space),
+                 base::Owned(total_space)));
+}
+
+void QuotaManager::DidGetVolumeInfo(
+    const VolumeInfoCallback& callback,
+    uint64_t* available_space, uint64_t* total_space, bool success) {
+  DCHECK(io_thread_->BelongsToCurrentThread());
+  callback.Run(success, *available_space, *total_space);
 }
 
 void QuotaManager::GetLRUOrigin(StorageType type,
@@ -1508,12 +1699,28 @@
                  base::Owned(url)));
 }
 
+void QuotaManager::DidSetTemporaryGlobalOverrideQuota(
+    const QuotaCallback& callback,
+    const int64_t* new_quota,
+    bool success) {
+  QuotaStatusCode status = kQuotaErrorInvalidAccess;
+  DidDatabaseWork(success);
+  if (success) {
+    temporary_quota_override_ = *new_quota;
+    status = kQuotaStatusOk;
+  }
+
+  if (callback.is_null())
+    return;
+
+  callback.Run(status, *new_quota);
+}
+
 void QuotaManager::DidGetPersistentHostQuota(const std::string& host,
                                              const int64_t* quota,
                                              bool success) {
   DidDatabaseWork(success);
-  persistent_host_quota_callbacks_.Run(
-      host, kQuotaStatusOk, std::min(*quota, kPerHostPersistentQuotaLimit));
+  persistent_host_quota_callbacks_.Run(host, kQuotaStatusOk, *quota);
 }
 
 void QuotaManager::DidSetPersistentHostQuota(const std::string& host,
@@ -1524,6 +1731,27 @@
   callback.Run(success ? kQuotaStatusOk : kQuotaErrorInvalidAccess, *new_quota);
 }
 
+void QuotaManager::DidInitialize(int64_t* temporary_quota_override,
+                                 int64_t* desired_available_space,
+                                 bool success) {
+  temporary_quota_override_ = *temporary_quota_override;
+  desired_available_space_ = *desired_available_space;
+  temporary_quota_initialized_ = true;
+  DidDatabaseWork(success);
+
+  if (!is_incognito_) {
+    histogram_timer_.Start(FROM_HERE,
+                           base::TimeDelta::FromMilliseconds(
+                               kReportHistogramInterval),
+                           this, &QuotaManager::ReportHistogram);
+  }
+
+  db_initialization_callbacks_.Run();
+  GetTemporaryGlobalQuota(
+      base::Bind(&QuotaManager::DidGetInitialTemporaryGlobalQuota,
+                 weak_factory_.GetWeakPtr(), base::TimeTicks::Now()));
+}
+
 void QuotaManager::DidGetLRUOrigin(const GURL* origin,
                                    bool success) {
   DidDatabaseWork(success);
@@ -1532,83 +1760,41 @@
   lru_origin_callback_.Reset();
 }
 
-namespace {
-void DidGetSettingsThreadAdapter(base::TaskRunner* task_runner,
-                                 const OptionalQuotaSettingsCallback& callback,
-                                 base::Optional<QuotaSettings> settings) {
-  task_runner->PostTask(FROM_HERE, base::Bind(callback, std::move(settings)));
-}
-}  // namespace
+void QuotaManager::DidGetInitialTemporaryGlobalQuota(
+    base::TimeTicks start_ticks,
+    QuotaStatusCode status,
+    int64_t quota_unused) {
+  UMA_HISTOGRAM_LONG_TIMES(
+      "Quota.TimeToInitializeGlobalQuota",
+      base::TimeTicks::Now() - start_ticks);
 
-void QuotaManager::GetQuotaSettings(const QuotaSettingsCallback& callback) {
-  if (base::TimeTicks::Now() - settings_timestamp_ <
-      settings_.refresh_interval) {
-    callback.Run(settings_);
-    return;
-  }
-
-  if (!settings_callbacks_.Add(callback))
+  if (eviction_disabled_)
     return;
 
-  // We invoke our clients GetQuotaSettingsFunc on the
-  // UI thread and plumb the resulting value back to this thread.
-  get_settings_task_runner_->PostTask(
+  std::set<GURL>* origins = new std::set<GURL>;
+  temporary_usage_tracker_->GetCachedOrigins(origins);
+  // This will call the StartEviction() when initial origin registration
+  // is completed.
+  PostTaskAndReplyWithResultForDBThread(
       FROM_HERE,
-      base::Bind(
-          get_settings_function_,
-          base::Bind(
-              &DidGetSettingsThreadAdapter,
-              base::RetainedRef(base::ThreadTaskRunnerHandle::Get()),
-              base::Bind(&QuotaManager::DidGetSettings,
-                         weak_factory_.GetWeakPtr(), base::TimeTicks::Now()))));
-}
-
-void QuotaManager::DidGetSettings(base::TimeTicks start_ticks,
-                                  base::Optional<QuotaSettings> settings) {
-  if (!settings) {
-    settings = settings_;
-    settings->refresh_interval = base::TimeDelta::FromMinutes(1);
-  }
-  SetQuotaSettings(*settings);
-  settings_callbacks_.Run(*settings);
-  UMA_HISTOGRAM_MBYTES("Quota.GlobalTemporaryPoolSize", settings->pool_size);
-  UMA_HISTOGRAM_LONG_TIMES("Quota.TimeToGetSettings",
-                           base::TimeTicks::Now() - start_ticks);
-  LOG_IF(WARNING, settings->pool_size == 0)
-      << "No storage quota provided in QuotaSettings.";
-}
-
-void QuotaManager::GetStorageCapacity(const StorageCapacityCallback& callback) {
-  if (!storage_capacity_callbacks_.Add(callback))
-    return;
-  if (is_incognito_) {
-    GetQuotaSettings(
-        base::Bind(&QuotaManager::ContinueIncognitoGetStorageCapacity,
-                   weak_factory_.GetWeakPtr()));
-    return;
-  }
-  base::PostTaskAndReplyWithResult(
-      db_thread_.get(), FROM_HERE,
-      base::Bind(&QuotaManager::CallGetVolumeInfo, get_volume_info_fn_,
-                 profile_path_),
-      base::Bind(&QuotaManager::DidGetStorageCapacity,
+      base::Bind(&InitializeTemporaryOriginsInfoOnDBThread,
+                 base::Owned(origins)),
+      base::Bind(&QuotaManager::DidInitializeTemporaryOriginsInfo,
                  weak_factory_.GetWeakPtr()));
 }
 
-void QuotaManager::ContinueIncognitoGetStorageCapacity(
-    const QuotaSettings& settings) {
-  int64_t current_usage =
-      GetUsageTracker(kStorageTypeTemporary)->GetCachedUsage();
-  current_usage += GetUsageTracker(kStorageTypePersistent)->GetCachedUsage();
-  int64_t available_space =
-      std::max(INT64_C(0), settings.pool_size - current_usage);
-  DidGetStorageCapacity(std::make_pair(settings.pool_size, available_space));
+void QuotaManager::DidInitializeTemporaryOriginsInfo(bool success) {
+  DidDatabaseWork(success);
+  if (success)
+    StartEviction();
 }
 
-void QuotaManager::DidGetStorageCapacity(
-    const std::pair<int64_t, int64_t>& total_and_available) {
-  storage_capacity_callbacks_.Run(total_and_available.first,
-                                  total_and_available.second);
+void QuotaManager::DidGetAvailableSpace(int64_t space) {
+  // crbug.com/349708
+  TRACE_EVENT1("io", "QuotaManager::DidGetAvailableSpace",
+               "n_callbacks", available_space_callbacks_.size());
+
+  available_space_callbacks_.Run(kQuotaStatusOk, space);
 }
 
 void QuotaManager::DidDatabaseWork(bool success) {
@@ -1638,30 +1824,41 @@
 }
 
 // static
-std::pair<int64_t, int64_t> QuotaManager::CallGetVolumeInfo(
+int64_t QuotaManager::CallGetAmountOfFreeDiskSpace(
     GetVolumeInfoFn get_volume_info_fn,
-    const base::FilePath& path) {
+    const base::FilePath& profile_path) {
   // crbug.com/349708
-  TRACE_EVENT0("io", "CallGetVolumeInfo");
-  if (!base::CreateDirectory(path)) {
-    LOG(WARNING) << "Create directory failed for path" << path.value();
-    return std::make_pair<int64_t, int64_t>(0, 0);
+  TRACE_EVENT0("io", "CallSystemGetAmountOfFreeDiskSpace");
+  if (!base::CreateDirectory(profile_path)) {
+    LOG(WARNING) << "Create directory failed for path" << profile_path.value();
+    return 0;
   }
-  std::pair<int64_t, int64_t> total_and_available = get_volume_info_fn(path);
-  if (total_and_available.first < 0 || total_and_available.second < 0) {
-    LOG(WARNING) << "Unable to get volume info: " << path.value();
-    return std::make_pair<int64_t, int64_t>(0, 0);
+  uint64_t available, total;
+  if (!get_volume_info_fn(profile_path, &available, &total)) {
+    return 0;
   }
-  UMA_HISTOGRAM_MBYTES("Quota.TotalDiskSpace", total_and_available.first);
-  UMA_HISTOGRAM_MBYTES("Quota.AvailableDiskSpace", total_and_available.second);
-  return total_and_available;
+  UMA_HISTOGRAM_MBYTES("Quota.AvailableDiskSpace", available);
+  UMA_HISTOGRAM_MBYTES("Quota.TotalDiskSpace", total);
+  return static_cast<int64_t>(available);
 }
 
-// static
-std::pair<int64_t, int64_t> QuotaManager::GetVolumeInfo(
-    const base::FilePath& path) {
-  return std::make_pair(base::SysInfo::AmountOfTotalDiskSpace(path),
-                        base::SysInfo::AmountOfFreeDiskSpace(path));
+//static
+bool QuotaManager::GetVolumeInfo(const base::FilePath& path,
+                                 uint64_t* available_space,
+                                 uint64_t* total_size) {
+  // Inspired by similar code in the base::SysInfo class.
+  base::ThreadRestrictions::AssertIOAllowed();
+
+  int64_t available = base::SysInfo::AmountOfFreeDiskSpace(path);
+  if (available < 0)
+    return false;
+  int64_t total = base::SysInfo::AmountOfTotalDiskSpace(path);
+  if (total < 0)
+    return false;
+
+  *available_space = static_cast<uint64_t>(available);
+  *total_size = static_cast<uint64_t>(total);
+  return true;
 }
 
 }  // namespace storage
diff --git a/storage/browser/quota/quota_manager.h b/storage/browser/quota/quota_manager.h
index ded960e2..a1ef11d 100644
--- a/storage/browser/quota/quota_manager.h
+++ b/storage/browser/quota/quota_manager.h
@@ -21,17 +21,17 @@
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
-#include "base/optional.h"
 #include "base/sequenced_task_runner_helpers.h"
 #include "storage/browser/quota/quota_callbacks.h"
 #include "storage/browser/quota/quota_client.h"
 #include "storage/browser/quota/quota_database.h"
-#include "storage/browser/quota/quota_settings.h"
 #include "storage/browser/quota/quota_task.h"
 #include "storage/browser/quota/special_storage_policy.h"
 #include "storage/browser/quota/storage_observer.h"
 #include "storage/browser/storage_browser_export.h"
 
+class SiteEngagementEvictionPolicyWithQuotaManagerTest;
+
 namespace base {
 class FilePath;
 class SequencedTaskRunner;
@@ -60,21 +60,44 @@
 
 struct QuotaManagerDeleter;
 
+struct STORAGE_EXPORT UsageAndQuota {
+  int64_t usage;
+  int64_t global_limited_usage;
+  int64_t quota;
+  int64_t available_disk_space;
+
+  UsageAndQuota();
+  UsageAndQuota(int64_t usage,
+                int64_t global_limited_usage,
+                int64_t quota,
+                int64_t available_disk_space);
+};
+
+// TODO(calamity): Use this in the temporary storage eviction path.
+// An interface for deciding which origin's storage should be evicted when the
+// quota is exceeded.
+class STORAGE_EXPORT QuotaEvictionPolicy {
+ public:
+  virtual ~QuotaEvictionPolicy() {}
+
+  // Returns the next origin to evict.  It might return an empty GURL when there
+  // are no evictable origins.
+  virtual void GetEvictionOrigin(
+      const scoped_refptr<SpecialStoragePolicy>& special_storage_policy,
+      const std::set<GURL>& exceptions,
+      const std::map<GURL, int64_t>& usage_map,
+      int64_t global_quota,
+      const GetOriginCallback& callback) = 0;
+};
+
 // An interface called by QuotaTemporaryStorageEvictor.
 class STORAGE_EXPORT QuotaEvictionHandler {
  public:
-  using EvictionRoundInfoCallback =
-      base::Callback<void(QuotaStatusCode status,
-                          const QuotaSettings& settings,
-                          int64_t available_space,
-                          int64_t total_space,
-                          int64_t global_usage,
-                          bool global_usage_is_complete)>;
-
-  // Called at the beginning of an eviction round to gather the info about
-  // the current settings, capacity, and usage.
-  virtual void GetEvictionRoundInfo(
-      const EvictionRoundInfoCallback& callback) = 0;
+  using EvictOriginDataCallback = StatusCallback;
+  using UsageAndQuotaCallback = base::Callback<
+      void(QuotaStatusCode status, const UsageAndQuota& usage_and_quota)>;
+  using VolumeInfoCallback = base::Callback<
+      void(bool success, uint64_t available_space, uint64_t total_space)>;
 
   // Returns next origin to evict.  It might return an empty GURL when there are
   // no evictable origins.
@@ -83,10 +106,14 @@
                                  int64_t global_quota,
                                  const GetOriginCallback& callback) = 0;
 
-  // Called to evict an origin.
-  virtual void EvictOriginData(const GURL& origin,
-                               StorageType type,
-                               const StatusCallback& callback) = 0;
+  virtual void EvictOriginData(
+      const GURL& origin,
+      StorageType type,
+      const EvictOriginDataCallback& callback) = 0;
+
+  virtual void AsyncGetVolumeInfo(const VolumeInfoCallback& callback) = 0;
+  virtual void GetUsageAndQuotaForEviction(
+      const UsageAndQuotaCallback& callback) = 0;
 
  protected:
   virtual ~QuotaEvictionHandler() {}
@@ -108,10 +135,11 @@
       public QuotaEvictionHandler,
       public base::RefCountedThreadSafe<QuotaManager, QuotaManagerDeleter> {
  public:
-  typedef base::Callback<
-      void(QuotaStatusCode, int64_t /* usage */, int64_t /* quota */)>
-      UsageAndQuotaCallback;
+  typedef base::Callback<void(QuotaStatusCode,
+                              int64_t /* usage */,
+                              int64_t /* quota */)> GetUsageAndQuotaCallback;
 
+  static const int64_t kIncognitoDefaultQuotaLimit;
   static const int64_t kNoLimit;
 
   QuotaManager(
@@ -119,11 +147,7 @@
       const base::FilePath& profile_path,
       const scoped_refptr<base::SingleThreadTaskRunner>& io_thread,
       const scoped_refptr<base::SequencedTaskRunner>& db_thread,
-      const scoped_refptr<SpecialStoragePolicy>& special_storage_policy,
-      const GetQuotaSettingsFunc& get_settings_function);
-
-  const QuotaSettings& settings() const { return settings_; }
-  void SetQuotaSettings(const QuotaSettings& settings);
+      const scoped_refptr<SpecialStoragePolicy>& special_storage_policy);
 
   // Returns a proxy object that can be used on any thread.
   QuotaManagerProxy* proxy() { return proxy_.get(); }
@@ -136,7 +160,7 @@
   virtual void GetUsageAndQuotaForWebApps(
       const GURL& origin,
       StorageType type,
-      const UsageAndQuotaCallback& callback);
+      const GetUsageAndQuotaCallback& callback);
 
   // Called by StorageClients.
   // This method is declared as virtual to allow test code to override it.
@@ -144,9 +168,10 @@
   // For UnlimitedStorage origins, this version skips usage and quota handling
   // to avoid extra query cost.
   // Do not call this method for apps/user-facing code.
-  virtual void GetUsageAndQuota(const GURL& origin,
-                                StorageType type,
-                                const UsageAndQuotaCallback& callback);
+  virtual void GetUsageAndQuota(
+      const GURL& origin,
+      StorageType type,
+      const GetUsageAndQuotaCallback& callback);
 
   // Called by clients via proxy.
   // Client storage should call this method when storage is accessed.
@@ -177,6 +202,10 @@
                             StorageType type,
                             bool enabled);
 
+  // Set the eviction policy to use when choosing an origin to evict.
+  void SetTemporaryStorageEvictionPolicy(
+      std::unique_ptr<QuotaEvictionPolicy> policy);
+
   // DeleteOriginData and DeleteHostData (surprisingly enough) delete data of a
   // particular StorageType associated with either a specific origin or set of
   // origins. Each method additionally requires a |quota_client_mask| which
@@ -194,6 +223,13 @@
                       const StatusCallback& callback);
 
   // Called by UI and internal modules.
+  void GetAvailableSpace(const AvailableSpaceCallback& callback);
+  void GetTemporaryGlobalQuota(const QuotaCallback& callback);
+
+  // Ok to call with NULL callback.
+  void SetTemporaryGlobalOverrideQuota(int64_t new_quota,
+                                       const QuotaCallback& callback);
+
   void GetPersistentHostQuota(const std::string& host,
                               const QuotaCallback& callback);
   void SetPersistentHostQuota(const std::string& host,
@@ -212,6 +248,11 @@
 
   bool IsStorageUnlimited(const GURL& origin, StorageType type) const;
 
+  bool CanQueryDiskSize(const GURL& origin) const {
+    return special_storage_policy_.get() &&
+           special_storage_policy_->CanQueryDiskSize(origin);
+  }
+
   virtual void GetOriginsModifiedSince(StorageType type,
                                        base::Time modified_since,
                                        const GetOriginsCallback& callback);
@@ -225,17 +266,26 @@
   void RemoveStorageObserverForFilter(StorageObserver* observer,
                                       const StorageObserver::Filter& filter);
 
+  // Determines the portion of the temp pool that can be
+  // utilized by a single host (ie. 5 for 20%).
+  static const int kPerHostTemporaryPortion;
+
   static const int64_t kPerHostPersistentQuotaLimit;
+
   static const char kDatabaseName[];
+
   static const int kThresholdOfErrorsToBeBlacklisted;
+
   static const int kEvictionIntervalInMilliSeconds;
+
   static const char kTimeBetweenRepeatedOriginEvictionsHistogram[];
   static const char kEvictedOriginAccessedCountHistogram[];
   static const char kEvictedOriginTimeSinceAccessHistogram[];
 
-  // Kept non-const so that test code can change the value.
+  // These are kept non-const so that test code can change the value.
   // TODO(kinuko): Make this a real const value and add a proper way to set
   // the quota for syncable storage. (http://crbug.com/155488)
+  static int64_t kMinimumPreserveForSystem;
   static int64_t kSyncableStorageDefaultHostQuota;
 
  protected:
@@ -252,12 +302,13 @@
   friend class QuotaManagerProxy;
   friend class QuotaTemporaryStorageEvictor;
   friend struct QuotaManagerDeleter;
+  friend class ::SiteEngagementEvictionPolicyWithQuotaManagerTest;
 
-  class EvictionRoundInfoHelper;
-  class UsageAndQuotaHelper;
   class GetUsageInfoTask;
+
   class OriginDataDeleter;
   class HostDataDeleter;
+
   class GetModifiedSinceHelper;
   class DumpQuotaTableHelper;
   class DumpOriginInfoTableHelper;
@@ -267,13 +318,10 @@
   typedef std::vector<QuotaTableEntry> QuotaTableEntries;
   typedef std::vector<OriginInfoTableEntry> OriginInfoTableEntries;
 
-  using QuotaSettingsCallback = base::Callback<void(const QuotaSettings&)>;
-
   // Function pointer type used to store the function which returns
   // information about the volume containing the given FilePath.
-  // The value returned is std::pair<total_space, available_space>.
-  using GetVolumeInfoFn =
-      std::pair<int64_t, int64_t> (*)(const base::FilePath&);
+  using GetVolumeInfoFn = bool(*)(const base::FilePath&,
+                                  uint64_t* available, uint64_t* total);
 
   typedef base::Callback<void(const QuotaTableEntries&)>
       DumpQuotaTableCallback;
@@ -281,36 +329,28 @@
       DumpOriginInfoTableCallback;
 
   typedef CallbackQueue<base::Closure> ClosureQueue;
+  typedef CallbackQueue<AvailableSpaceCallback, QuotaStatusCode, int64_t>
+      AvailableSpaceCallbackQueue;
   typedef CallbackQueueMap<QuotaCallback, std::string, QuotaStatusCode, int64_t>
       HostQuotaCallbackMap;
-  using QuotaSettingsCallbackQueue =
-      CallbackQueue<QuotaSettingsCallback, const QuotaSettings&>;
-
-  // The values returned total_space, available_space.
-  using StorageCapacityCallback = base::Callback<void(int64_t, int64_t)>;
-  using StorageCapacityCallbackQueue =
-      CallbackQueue<StorageCapacityCallback, int64_t, int64_t>;
 
   struct EvictionContext {
     EvictionContext();
-    ~EvictionContext();
+    virtual ~EvictionContext();
     GURL evicted_origin;
     StorageType evicted_type;
-    StatusCallback evict_origin_data_callback;
+
+    EvictOriginDataCallback evict_origin_data_callback;
   };
 
+  typedef QuotaEvictionHandler::UsageAndQuotaCallback
+      UsageAndQuotaDispatcherCallback;
+
   // This initialization method is lazily called on the IO thread
   // when the first quota manager API is called.
   // Initialize must be called after all quota clients are added to the
   // manager by RegisterStorage.
   void LazyInitialize();
-  void FinishLazyInitialize(bool is_database_bootstraped);
-  void BootstrapDatabaseForEviction(
-      const GetOriginCallback& did_get_origin_callback,
-      int64_t unused_usage,
-      int64_t unused_unlimited_usage);
-  void DidBootstrapDatabase(const GetOriginCallback& did_get_origin_callback,
-                            bool success);
 
   // Called by clients via proxy.
   // Registers a quota client to the manager.
@@ -372,11 +412,20 @@
                          const GetOriginCallback& callback) override;
   void EvictOriginData(const GURL& origin,
                        StorageType type,
-                       const StatusCallback& callback) override;
-  void GetEvictionRoundInfo(const EvictionRoundInfoCallback& callback) override;
+                       const EvictOriginDataCallback& callback) override;
+  void GetUsageAndQuotaForEviction(
+      const UsageAndQuotaCallback& callback) override;
+  void AsyncGetVolumeInfo(const VolumeInfoCallback& callback) override;
+
+  void DidGetVolumeInfo(
+      const VolumeInfoCallback& callback,
+      uint64_t* available_space, uint64_t* total_space, bool success);
 
   void GetLRUOrigin(StorageType type, const GetOriginCallback& callback);
 
+  void DidSetTemporaryGlobalOverrideQuota(const QuotaCallback& callback,
+                                          const int64_t* new_quota,
+                                          bool success);
   void DidGetPersistentHostQuota(const std::string& host,
                                  const int64_t* quota,
                                  bool success);
@@ -384,16 +433,16 @@
                                  const QuotaCallback& callback,
                                  const int64_t* new_quota,
                                  bool success);
+  void DidInitialize(int64_t* temporary_quota_override,
+                     int64_t* desired_available_space,
+                     bool success);
   void DidGetLRUOrigin(const GURL* origin,
                        bool success);
-  void GetQuotaSettings(const QuotaSettingsCallback& callback);
-  void DidGetSettings(base::TimeTicks start_ticks,
-                      base::Optional<QuotaSettings> settings);
-  void GetStorageCapacity(const StorageCapacityCallback& callback);
-  void ContinueIncognitoGetStorageCapacity(const QuotaSettings& settings);
-  void DidGetStorageCapacity(
-      const std::pair<int64_t, int64_t>& total_and_available);
-
+  void DidGetInitialTemporaryGlobalQuota(base::TimeTicks start_ticks,
+                                         QuotaStatusCode status,
+                                         int64_t quota_unused);
+  void DidInitializeTemporaryOriginsInfo(bool success);
+  void DidGetAvailableSpace(int64_t space);
   void DidDatabaseWork(bool success);
 
   void DeleteOnCorrectThread() const;
@@ -403,10 +452,12 @@
       const base::Callback<bool(QuotaDatabase*)>& task,
       const base::Callback<void(bool)>& reply);
 
-  static std::pair<int64_t, int64_t> CallGetVolumeInfo(
-      GetVolumeInfoFn get_volume_info_fn,
-      const base::FilePath& path);
-  static std::pair<int64_t, int64_t> GetVolumeInfo(const base::FilePath& path);
+  static int64_t CallGetAmountOfFreeDiskSpace(
+      GetVolumeInfoFn get_vol_info_fn,
+      const base::FilePath& profile_path);
+  static bool GetVolumeInfo(const base::FilePath& path,
+                            uint64_t* available_space,
+                            uint64_t* total_size);
 
   const bool is_incognito_;
   const base::FilePath profile_path_;
@@ -417,14 +468,6 @@
   scoped_refptr<base::SingleThreadTaskRunner> io_thread_;
   scoped_refptr<base::SequencedTaskRunner> db_thread_;
   mutable std::unique_ptr<QuotaDatabase> database_;
-  bool is_database_bootstrapped_ = false;
-
-  GetQuotaSettingsFunc get_settings_function_;
-  scoped_refptr<base::TaskRunner> get_settings_task_runner_;
-  QuotaSettings settings_;
-  base::TimeTicks settings_timestamp_;
-  QuotaSettingsCallbackQueue settings_callbacks_;
-  StorageCapacityCallbackQueue storage_capacity_callbacks_;
 
   GetOriginCallback lru_origin_callback_;
   std::set<GURL> access_notified_origins_;
@@ -439,10 +482,17 @@
 
   std::unique_ptr<QuotaTemporaryStorageEvictor> temporary_storage_evictor_;
   EvictionContext eviction_context_;
+  std::unique_ptr<QuotaEvictionPolicy> temporary_storage_eviction_policy_;
   bool is_getting_eviction_origin_;
 
+  ClosureQueue db_initialization_callbacks_;
+  AvailableSpaceCallbackQueue available_space_callbacks_;
   HostQuotaCallbackMap persistent_host_quota_callbacks_;
 
+  bool temporary_quota_initialized_;
+  int64_t temporary_quota_override_;
+  int64_t desired_available_space_;
+
   // Map from origin to count.
   std::map<GURL, int> origins_in_use_;
   // Map from origin to error count.
diff --git a/storage/browser/quota/quota_manager_proxy.cc b/storage/browser/quota/quota_manager_proxy.cc
index b67cfb9c..0c1ad0a 100644
--- a/storage/browser/quota/quota_manager_proxy.cc
+++ b/storage/browser/quota/quota_manager_proxy.cc
@@ -20,7 +20,7 @@
 
 void DidGetUsageAndQuota(
     base::SequencedTaskRunner* original_task_runner,
-    const QuotaManagerProxy::UsageAndQuotaCallback& callback,
+    const QuotaManagerProxy::GetUsageAndQuotaCallback& callback,
     QuotaStatusCode status,
     int64_t usage,
     int64_t quota) {
@@ -130,7 +130,7 @@
     base::SequencedTaskRunner* original_task_runner,
     const GURL& origin,
     StorageType type,
-    const UsageAndQuotaCallback& callback) {
+    const GetUsageAndQuotaCallback& callback) {
   if (!io_thread_->BelongsToCurrentThread()) {
     io_thread_->PostTask(
         FROM_HERE, base::Bind(&QuotaManagerProxy::GetUsageAndQuota, this,
diff --git a/storage/browser/quota/quota_manager_proxy.h b/storage/browser/quota/quota_manager_proxy.h
index 7125a6a..19a1f89d 100644
--- a/storage/browser/quota/quota_manager_proxy.h
+++ b/storage/browser/quota/quota_manager_proxy.h
@@ -34,7 +34,8 @@
 class STORAGE_EXPORT QuotaManagerProxy
     : public base::RefCountedThreadSafe<QuotaManagerProxy> {
  public:
-  typedef QuotaManager::UsageAndQuotaCallback UsageAndQuotaCallback;
+  typedef QuotaManager::GetUsageAndQuotaCallback
+      GetUsageAndQuotaCallback;
 
   virtual void RegisterClient(QuotaClient* client);
   virtual void NotifyStorageAccessed(QuotaClient::ID client_id,
@@ -51,10 +52,11 @@
                                     const GURL& origin,
                                     StorageType type,
                                     bool enabled);
-  virtual void GetUsageAndQuota(base::SequencedTaskRunner* original_task_runner,
-                                const GURL& origin,
-                                StorageType type,
-                                const UsageAndQuotaCallback& callback);
+  virtual void GetUsageAndQuota(
+      base::SequencedTaskRunner* original_task_runner,
+      const GURL& origin,
+      StorageType type,
+      const GetUsageAndQuotaCallback& callback);
 
   // This method may only be called on the IO thread.
   // It may return NULL if the manager has already been deleted.
diff --git a/storage/browser/quota/quota_settings.cc b/storage/browser/quota/quota_settings.cc
deleted file mode 100644
index 2b737098..0000000
--- a/storage/browser/quota/quota_settings.cc
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "storage/browser/quota/quota_settings.h"
-
-#include <algorithm>
-
-#include "base/metrics/histogram_macros.h"
-#include "base/sys_info.h"
-
-#define UMA_HISTOGRAM_MBYTES(name, sample)                                     \
-  UMA_HISTOGRAM_CUSTOM_COUNTS((name), static_cast<int>((sample) / kMBytes), 1, \
-                              10 * 1024 * 1024 /* 10TB */, 100)
-
-namespace storage {
-
-base::Optional<storage::QuotaSettings> CalculateNominalDynamicSettings(
-    const base::FilePath& partition_path,
-    bool is_incognito) {
-  const int64_t kMBytes = 1024 * 1024;
-
-  if (is_incognito) {
-    storage::QuotaSettings settings;
-    settings.pool_size =
-        std::min(300 * kMBytes, base::SysInfo::AmountOfPhysicalMemory() / 10);
-    settings.per_host_quota = settings.pool_size / 3;
-    settings.refresh_interval = base::TimeDelta::Max();
-    return settings;
-  }
-
-  // The fraction of the device's storage the browser is willing to
-  // use for temporary storage, this is applied after adjusting the
-  // total to take os_accomodation into account.
-  const double kTemporaryPoolSizeRatio = 1.0 / 3.0;  // 33%
-
-  // The fraction of the device's storage the browser attempts to
-  // keep free.
-  const double kMustRemainAvailableRatio = 0.1;
-
-  // Determines the portion of the temp pool that can be
-  // utilized by a single host (ie. 5 for 20%).
-  const int kPerHostTemporaryPortion = 5;
-
-  // os_accomodation is an estimate of how much storage is needed for
-  // the os and essential application code outside of the browser.
-  const int64_t kDefaultOSAccomodation =
-#if defined(OS_ANDROID)
-      1000 * kMBytes;
-#elif defined(OS_CHROMEOS)
-      1000 * kMBytes;
-#elif defined(OS_WIN) || defined(OS_LINUX) || defined(OS_MACOSX)
-      10000 * kMBytes;
-#else
-#error "Port: Need to define an OS accomodation value for unknown OS."
-#endif
-
-  storage::QuotaSettings settings;
-
-  int64_t total = base::SysInfo::AmountOfTotalDiskSpace(partition_path);
-  if (total == -1) {
-    LOG(ERROR) << "Unable to compute QuotaSettings.";
-    return base::nullopt;
-  }
-
-  // If our hardcoded OS accomodation is too large for the volume size, define
-  // the value as a fraction of the total volume size instead.
-  int64_t os_accomodation =
-      std::min(kDefaultOSAccomodation, static_cast<int64_t>(total * 0.8));
-  UMA_HISTOGRAM_MBYTES("Quota.OSAccomodationDelta",
-                       kDefaultOSAccomodation - os_accomodation);
-
-  int64_t adjusted_total = total - os_accomodation;
-  int64_t pool_size = adjusted_total * kTemporaryPoolSizeRatio;
-
-  settings.pool_size = pool_size;
-  settings.must_remain_available = total * kMustRemainAvailableRatio;
-  settings.per_host_quota = pool_size / kPerHostTemporaryPortion;
-  settings.refresh_interval = base::TimeDelta::FromSeconds(60);
-  return settings;
-}
-
-}  // namespace
diff --git a/storage/browser/quota/quota_settings.h b/storage/browser/quota/quota_settings.h
deleted file mode 100644
index e05d5530..0000000
--- a/storage/browser/quota/quota_settings.h
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef STORAGE_BROWSER_QUOTA_QUOTA_SETTINGS_H_
-#define STORAGE_BROWSER_QUOTA_QUOTA_SETTINGS_H_
-
-#include <stdint.h>
-
-#include "base/callback.h"
-#include "base/files/file_path.h"
-#include "base/optional.h"
-#include "base/time/time.h"
-#include "storage/browser/storage_browser_export.h"
-
-namespace storage {
-
-// Settings the storage lib embedder must provide to the QuotaManager.
-struct QuotaSettings {
-  QuotaSettings() = default;
-  QuotaSettings(int64_t pool_size,
-                int64_t per_host_quota,
-                int64_t must_remain_available)
-      : pool_size(pool_size),
-        per_host_quota(per_host_quota),
-        must_remain_available(must_remain_available) {}
-
-  // The target size in bytes of the shared pool of disk space the quota
-  // system allows for use by websites using HTML5 storage apis, for
-  // example an embedder may use 50% of the total volume size.
-  int64_t pool_size = 0;
-
-  // The amount in bytes of the pool an individual site may consume. The
-  // value must be less than or equal to the pool_size.
-  int64_t per_host_quota = 0;
-
-  // The amount of space that must remain available on the storage
-  // volume. As the volume approaches this limit, the quota system gets
-  // more aggressive about evicting data and disallowing new data.
-  int64_t must_remain_available = 0;
-
-  // The quota system querries the embedder for the QuataSettings,
-  // but will rate limit the frequency of the querries to no more than once
-  // per refresh interval.
-  base::TimeDelta refresh_interval = base::TimeDelta::Max();
-};
-
-// Function type used to return the settings in response to a
-// GetQuotaSettingsFunc invocation. If the embedder cannot
-// produce a settings values, base::nullopt can be returned.
-using OptionalQuotaSettingsCallback =
-    base::Callback<void(base::Optional<QuotaSettings>)>;
-
-// Function type used to query the embedder about the quota manager settings.
-// This function is invoked on the UI thread.
-using GetQuotaSettingsFunc =
-    base::Callback<void(const OptionalQuotaSettingsCallback& callback)>;
-
-// Returns settings based on the size of the volume containing the storage
-// partition and a guestimate of the size required for the OS. The refresh
-// interval is 60 seconds to accomodate changes to the size of the volume.
-// Except, in the case of incognito, the poolize and quota values are based
-// on the amount of physical memory and the rerfresh interval is max'd out.
-STORAGE_EXPORT
-base::Optional<storage::QuotaSettings> CalculateNominalDynamicSettings(
-    const base::FilePath& partition_path,
-    bool is_incognito);
-
-// Returns settings with a poolsize of zero and no per host quota.
-inline QuotaSettings GetNoQuotaSettings() {
-  return QuotaSettings();
-}
-
-// Returns settings that provide given |per_host_quota| and a total poolsize of
-// five times that.
-inline QuotaSettings GetHardCodedSettings(int64_t per_host_quota) {
-  return QuotaSettings(per_host_quota * 5, per_host_quota, per_host_quota);
-}
-
-}  // namespace storage
-
-#endif  // STORAGE_BROWSER_QUOTA_QUOTA_MANAGER_H_
diff --git a/storage/browser/quota/quota_temporary_storage_evictor.cc b/storage/browser/quota/quota_temporary_storage_evictor.cc
index 1a6c0257..6cce670 100644
--- a/storage/browser/quota/quota_temporary_storage_evictor.cc
+++ b/storage/browser/quota/quota_temporary_storage_evictor.cc
@@ -8,7 +8,6 @@
 
 #include <algorithm>
 
-#include "base/auto_reset.h"
 #include "base/bind.h"
 #include "base/metrics/histogram_macros.h"
 #include "storage/browser/quota/quota_manager.h"
@@ -30,12 +29,16 @@
 const double kUsageRatioToStartEviction = 0.7;
 const int kThresholdOfErrorsToStopEviction = 5;
 const int kHistogramReportIntervalMinutes = 60;
-
+const double kMustRemainAvailableRatio = 0.1;
+const int64_t kDefaultMustRemainAvailableSpace = 1024 * kMBytes;
 const double kDiskSpaceShortageAllowanceRatio = 0.5;
 }
 
 namespace storage {
 
+const int QuotaTemporaryStorageEvictor::
+    kMinAvailableToStartEvictionNotSpecified = -1;
+
 QuotaTemporaryStorageEvictor::EvictionRoundStatistics::EvictionRoundStatistics()
     : in_round(false),
       is_initialized(false),
@@ -49,9 +52,11 @@
 QuotaTemporaryStorageEvictor::QuotaTemporaryStorageEvictor(
     QuotaEvictionHandler* quota_eviction_handler,
     int64_t interval_ms)
-    : quota_eviction_handler_(quota_eviction_handler),
+    : min_available_to_start_eviction_(
+          kMinAvailableToStartEvictionNotSpecified),
+      quota_eviction_handler_(quota_eviction_handler),
       interval_ms_(interval_ms),
-      timer_disabled_for_testing_(false),
+      repeated_eviction_(true),
       weak_factory_(this) {
   DCHECK(quota_eviction_handler);
 }
@@ -137,8 +142,6 @@
 
 void QuotaTemporaryStorageEvictor::Start() {
   DCHECK(CalledOnValidThread());
-
-  base::AutoReset<bool> auto_reset(&timer_disabled_for_testing_, false);
   StartEvictionTimerWithDelay(0);
 
   if (histogram_timer_.IsRunning())
@@ -150,7 +153,7 @@
 }
 
 void QuotaTemporaryStorageEvictor::StartEvictionTimerWithDelay(int delay_ms) {
-  if (eviction_timer_.IsRunning() || timer_disabled_for_testing_)
+  if (eviction_timer_.IsRunning())
     return;
   eviction_timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(delay_ms),
                         this, &QuotaTemporaryStorageEvictor::ConsiderEviction);
@@ -158,49 +161,66 @@
 
 void QuotaTemporaryStorageEvictor::ConsiderEviction() {
   OnEvictionRoundStarted();
-  quota_eviction_handler_->GetEvictionRoundInfo(
-      base::Bind(&QuotaTemporaryStorageEvictor::OnGotEvictionRoundInfo,
-                 weak_factory_.GetWeakPtr()));
+
+  if (min_available_to_start_eviction_ ==
+      kMinAvailableToStartEvictionNotSpecified) {
+    quota_eviction_handler_->AsyncGetVolumeInfo(
+        base::Bind(&QuotaTemporaryStorageEvictor::OnGotVolumeInfo,
+                   weak_factory_.GetWeakPtr()));
+  } else {
+    quota_eviction_handler_->GetUsageAndQuotaForEviction(
+        base::Bind(&QuotaTemporaryStorageEvictor::OnGotUsageAndQuotaForEviction,
+                   weak_factory_.GetWeakPtr(),
+                   min_available_to_start_eviction_));
+  }
 }
 
-void QuotaTemporaryStorageEvictor::OnGotEvictionRoundInfo(
-    QuotaStatusCode status,
-    const QuotaSettings& settings,
-    int64_t available_space,
-    int64_t total_space,
-    int64_t current_usage,
-    bool current_usage_is_complete) {
-  DCHECK_GE(current_usage, 0);
+void QuotaTemporaryStorageEvictor::OnGotVolumeInfo(
+    bool success, uint64_t available_space, uint64_t total_size) {
+  // Compute how much to keep free as a function of total disk size.
+  int64_t must_remain_available_space = success ?
+      static_cast<int64_t>(total_size * kMustRemainAvailableRatio) :
+      kDefaultMustRemainAvailableSpace;
 
-  // Note: if there is no storage pressure, |current_usage|
-  // may not be fully calculated and may be 0.
+  quota_eviction_handler_->GetUsageAndQuotaForEviction(
+      base::Bind(&QuotaTemporaryStorageEvictor::OnGotUsageAndQuotaForEviction,
+                 weak_factory_.GetWeakPtr(), must_remain_available_space));
+}
+
+void QuotaTemporaryStorageEvictor::OnGotUsageAndQuotaForEviction(
+    int64_t must_remain_available_space,
+    QuotaStatusCode status,
+    const UsageAndQuota& qau) {
+  DCHECK(CalledOnValidThread());
+
+  int64_t usage = qau.global_limited_usage;
+  DCHECK_GE(usage, 0);
 
   if (status != kQuotaStatusOk)
     ++statistics_.num_errors_on_getting_usage_and_quota;
 
   int64_t usage_overage = std::max(
       static_cast<int64_t>(0),
-      current_usage - static_cast<int64_t>(settings.pool_size *
-                                           kUsageRatioToStartEviction));
-  int64_t diskspace_shortage =
-      std::max(static_cast<int64_t>(0),
-               settings.must_remain_available - available_space);
-  DCHECK(current_usage_is_complete || diskspace_shortage == 0);
+      usage - static_cast<int64_t>(qau.quota * kUsageRatioToStartEviction));
+
+  int64_t diskspace_shortage = std::max(
+      static_cast<int64_t>(0),
+      must_remain_available_space - qau.available_disk_space);
 
   // If we're using so little that freeing all of it wouldn't help,
   // don't let the low space condition cause us to delete it all.
-  if (current_usage < static_cast<int64_t>(diskspace_shortage *
-                                           kDiskSpaceShortageAllowanceRatio)) {
+  if (usage < static_cast<int64_t>(diskspace_shortage *
+                                   kDiskSpaceShortageAllowanceRatio)) {
     diskspace_shortage = 0;
   }
 
   if (!round_statistics_.is_initialized) {
     round_statistics_.usage_overage_at_round = usage_overage;
     round_statistics_.diskspace_shortage_at_round = diskspace_shortage;
-    round_statistics_.usage_on_beginning_of_round = current_usage;
+    round_statistics_.usage_on_beginning_of_round = usage;
     round_statistics_.is_initialized = true;
   }
-  round_statistics_.usage_on_end_of_round = current_usage;
+  round_statistics_.usage_on_end_of_round = usage;
 
   int64_t amount_to_evict = std::max(usage_overage, diskspace_shortage);
   if (status == kQuotaStatusOk && amount_to_evict > 0) {
@@ -208,31 +228,33 @@
     // TODO(michaeln): if the reason for eviction is low physical disk space,
     // make 'unlimited' origins subject to eviction too.
     quota_eviction_handler_->GetEvictionOrigin(
-        kStorageTypeTemporary, in_progress_eviction_origins_,
-        settings.pool_size,
+        kStorageTypeTemporary, in_progress_eviction_origins_, qau.quota,
         base::Bind(&QuotaTemporaryStorageEvictor::OnGotEvictionOrigin,
                    weak_factory_.GetWeakPtr()));
-    return;
-  }
-
-  // No action required, sleep for a while and check again later.
-  if (statistics_.num_errors_on_getting_usage_and_quota <
-      kThresholdOfErrorsToStopEviction) {
-    StartEvictionTimerWithDelay(interval_ms_);
   } else {
-    // TODO(dmikurube): Add error handling for the case status is not OK.
-    // TODO(dmikurube): Try restarting eviction after a while.
-    LOG(WARNING) << "Stopped eviction of temporary storage due to errors";
+    if (repeated_eviction_) {
+      // No action required, sleep for a while and check again later.
+      if (statistics_.num_errors_on_getting_usage_and_quota <
+          kThresholdOfErrorsToStopEviction) {
+        StartEvictionTimerWithDelay(interval_ms_);
+      } else {
+        // TODO(dmikurube): Try restarting eviction after a while.
+        LOG(WARNING) << "Stopped eviction of temporary storage due to errors "
+                        "in GetUsageAndQuotaForEviction.";
+      }
+    }
+    OnEvictionRoundFinished();
   }
 
-  OnEvictionRoundFinished();
+  // TODO(dmikurube): Add error handling for the case status != kQuotaStatusOk.
 }
 
 void QuotaTemporaryStorageEvictor::OnGotEvictionOrigin(const GURL& origin) {
   DCHECK(CalledOnValidThread());
 
   if (origin.is_empty()) {
-    StartEvictionTimerWithDelay(interval_ms_);
+    if (repeated_eviction_)
+      StartEvictionTimerWithDelay(interval_ms_);
     OnEvictionRoundFinished();
     return;
   }
@@ -262,8 +284,10 @@
     ConsiderEviction();
   } else {
     ++statistics_.num_errors_on_evicting_origin;
-    // Sleep for a while and retry again until we see too many errors.
-    StartEvictionTimerWithDelay(interval_ms_);
+    if (repeated_eviction_) {
+      // Sleep for a while and retry again until we see too many errors.
+      StartEvictionTimerWithDelay(interval_ms_);
+    }
     OnEvictionRoundFinished();
   }
 }
diff --git a/storage/browser/quota/quota_temporary_storage_evictor.h b/storage/browser/quota/quota_temporary_storage_evictor.h
index 187d3396..8039426 100644
--- a/storage/browser/quota/quota_temporary_storage_evictor.h
+++ b/storage/browser/quota/quota_temporary_storage_evictor.h
@@ -27,7 +27,7 @@
 namespace storage {
 
 class QuotaEvictionHandler;
-struct QuotaSettings;
+struct UsageAndQuota;
 
 class STORAGE_EXPORT QuotaTemporaryStorageEvictor : public base::NonThreadSafe {
  public:
@@ -78,23 +78,41 @@
   void ReportPerHourHistogram();
   void Start();
 
+  void reset_min_available_disk_space_to_start_eviction() {
+    min_available_to_start_eviction_ =
+        kMinAvailableToStartEvictionNotSpecified;
+  }
+  void set_min_available_disk_space_to_start_eviction(int64_t value) {
+    min_available_to_start_eviction_ = value;
+  }
+
  private:
   friend class content::QuotaTemporaryStorageEvictorTest;
 
   void StartEvictionTimerWithDelay(int delay_ms);
   void ConsiderEviction();
-  void OnGotEvictionRoundInfo(QuotaStatusCode status,
-                              const QuotaSettings& settings,
-                              int64_t available_space,
-                              int64_t total_space,
-                              int64_t current_usage,
-                              bool current_usage_is_complete);
+  void OnGotVolumeInfo(bool success,
+                       uint64_t available_space,
+                       uint64_t total_size);
+  void OnGotUsageAndQuotaForEviction(
+      int64_t must_remain_available_space,
+      QuotaStatusCode status,
+      const UsageAndQuota& quota_and_usage);
   void OnGotEvictionOrigin(const GURL& origin);
   void OnEvictionComplete(QuotaStatusCode status);
 
   void OnEvictionRoundStarted();
   void OnEvictionRoundFinished();
 
+  // This is only used for tests.
+  void set_repeated_eviction(bool repeated_eviction) {
+    repeated_eviction_ = repeated_eviction;
+  }
+
+  static const int kMinAvailableToStartEvictionNotSpecified;
+
+  int64_t min_available_to_start_eviction_;
+
   // Not owned; quota_eviction_handler owns us.
   QuotaEvictionHandler* quota_eviction_handler_;
 
@@ -106,7 +124,7 @@
   std::set<GURL> in_progress_eviction_origins_;
 
   int64_t interval_ms_;
-  bool timer_disabled_for_testing_;
+  bool repeated_eviction_;
 
   base::OneShotTimer eviction_timer_;
   base::RepeatingTimer histogram_timer_;
diff --git a/storage/browser/quota/special_storage_policy.h b/storage/browser/quota/special_storage_policy.h
index cac9f94..5c97806a 100644
--- a/storage/browser/quota/special_storage_policy.h
+++ b/storage/browser/quota/special_storage_policy.h
@@ -51,6 +51,10 @@
   // Durable storage is not subject to storage pressure eviction.
   virtual bool IsStorageDurable(const GURL& origin) = 0;
 
+  // Some origins (e.g. installed apps) have access to the size of the remaining
+  // disk capacity.
+  virtual bool CanQueryDiskSize(const GURL& origin) = 0;
+
   // Checks if the origin contains per-site isolated storage.
   virtual bool HasIsolatedStorage(const GURL& origin) = 0;
 
diff --git a/storage/browser/quota/usage_tracker.cc b/storage/browser/quota/usage_tracker.cc
index a29004e..041f940 100644
--- a/storage/browser/quota/usage_tracker.cc
+++ b/storage/browser/quota/usage_tracker.cc
@@ -136,13 +136,6 @@
   client_tracker->UpdateUsageCache(origin, delta);
 }
 
-int64_t UsageTracker::GetCachedUsage() const {
-  int64_t usage = 0;
-  for (const auto& client_id_and_tracker : client_tracker_map_)
-    usage += client_id_and_tracker.second->GetCachedUsage();
-  return usage;
-}
-
 void UsageTracker::GetCachedHostsUsage(
     std::map<std::string, int64_t>* host_usage) const {
   DCHECK(host_usage);
diff --git a/storage/browser/quota/usage_tracker.h b/storage/browser/quota/usage_tracker.h
index 343fab6..074b4f54 100644
--- a/storage/browser/quota/usage_tracker.h
+++ b/storage/browser/quota/usage_tracker.h
@@ -47,9 +47,8 @@
   void UpdateUsageCache(QuotaClient::ID client_id,
                         const GURL& origin,
                         int64_t delta);
-  int64_t GetCachedUsage() const;
-  void GetCachedHostsUsage(std::map<std::string, int64_t>* host_usage) const;
   void GetCachedOriginsUsage(std::map<GURL, int64_t>* origin_usage) const;
+  void GetCachedHostsUsage(std::map<std::string, int64_t>* host_usage) const;
   void GetCachedOrigins(std::set<GURL>* origins) const;
   bool IsWorking() const {
     return global_usage_callbacks_.HasCallbacks() ||
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index b3ceae7f..dd6bbd7 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -219,6 +219,7 @@
                     "forcing_flag": "enable-browser-task-scheduler",
                     "params": {
                         "RedirectHistoryService": "true",
+                        "RedirectNonUINonIOBrowserThreads": "true",
                         "RedirectSequencedWorkerPools": "true"
                     }
                 },
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index a28b140..41664cb4 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -1324,14 +1324,13 @@
 
 crbug.com/649159 imported/wpt/shadow-dom/slotchange-event.html [ Failure ]
 
-# TODO(yangguo): these tests need to be rebaselined after V8 change lands.
-crbug.com/666223 fast/workers/constructor-proto.html [ NeedsManualRebaseline ]
-crbug.com/666223 http/tests/w3c/webperf/approved/navigation-timing/html/idlharness.html [ NeedsManualRebaseline ]
-crbug.com/666223 virtual/mojo-loading/http/tests/w3c/webperf/approved/navigation-timing/html/idlharness.html [ NeedsManualRebaseline ]
-crbug.com/666223 imported/wpt/WebIDL/ecmascript-binding/es-exceptions/constructor-object.html [ NeedsManualRebaseline ]
-crbug.com/666223 imported/wpt/dom/interfaces.html [ NeedsManualRebaseline ]
-crbug.com/666223 inspector/sources/debugger-ui/watch-expressions-preserve-expansion.html [ NeedsManualRebaseline ]
-crbug.com/666223 virtual/sharedarraybuffer/fast/workers/constructor-proto.html [ NeedsManualRebaseline ]
+crbug.com/666223 fast/workers/constructor-proto.html [ NeedsRebaseline ]
+crbug.com/666223 http/tests/w3c/webperf/approved/navigation-timing/html/idlharness.html [ NeedsRebaseline ]
+crbug.com/666223 virtual/mojo-loading/http/tests/w3c/webperf/approved/navigation-timing/html/idlharness.html [ NeedsRebaseline ]
+crbug.com/666223 imported/wpt/WebIDL/ecmascript-binding/es-exceptions/constructor-object.html [ NeedsRebaseline ]
+crbug.com/666223 imported/wpt/dom/interfaces.html [ NeedsRebaseline ]
+crbug.com/666223 inspector/sources/debugger-ui/watch-expressions-preserve-expansion.html [ NeedsRebaseline ]
+crbug.com/666223 virtual/sharedarraybuffer/fast/workers/constructor-proto.html [ NeedsRebaseline ]
 
 # These are the failing tests because Chrome hasn't implemented according to the spec.
 crbug.com/645988 imported/wpt/uievents/order-of-events/focus-events/focus-manual.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/http/tests/activedomobject/media-expected.txt b/third_party/WebKit/LayoutTests/http/tests/activedomobject/media-expected.txt
index 70c2337..cf47ed7 100644
--- a/third_party/WebKit/LayoutTests/http/tests/activedomobject/media-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/activedomobject/media-expected.txt
@@ -2,8 +2,8 @@
 
 
 Before Reparenting
-PASS: window.internals.activeDOMObjectCount(document) should be '3' and is.
-PASS: window.internals.activeDOMObjectCount(iframe) should be '3' and is.
+PASS: window.internals.suspendableObjectCount(document) should be '3' and is.
+PASS: window.internals.suspendableObjectCount(iframe) should be '3' and is.
 After Reparenting
-PASS: window.internals.activeDOMObjectCount(document) should be '4' and is.
-PASS: window.internals.activeDOMObjectCount(iframe) should be '2' and is.
+PASS: window.internals.suspendableObjectCount(document) should be '4' and is.
+PASS: window.internals.suspendableObjectCount(iframe) should be '2' and is.
diff --git a/third_party/WebKit/LayoutTests/http/tests/activedomobject/media.html b/third_party/WebKit/LayoutTests/http/tests/activedomobject/media.html
index 5a5626d..76e63c1 100644
--- a/third_party/WebKit/LayoutTests/http/tests/activedomobject/media.html
+++ b/third_party/WebKit/LayoutTests/http/tests/activedomobject/media.html
@@ -10,14 +10,14 @@
         window.iframe = document.querySelector('iframe').contentDocument;
 
         log('Before Reparenting');
-        shouldBe('window.internals.activeDOMObjectCount(document)', 3);
-        shouldBe('window.internals.activeDOMObjectCount(iframe)', 3);
+        shouldBe('window.internals.suspendableObjectCount(document)', 3);
+        shouldBe('window.internals.suspendableObjectCount(iframe)', 3);
 
         document.body.appendChild(window.iframe.querySelector('video'));
 
         log('After Reparenting');
-        shouldBe('window.internals.activeDOMObjectCount(document)', 4);
-        shouldBe('window.internals.activeDOMObjectCount(iframe)', 2);
+        shouldBe('window.internals.suspendableObjectCount(document)', 4);
+        shouldBe('window.internals.suspendableObjectCount(iframe)', 2);
     }
 </script>
 </body>
diff --git a/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-lifetime-mediakeys-with-session.html b/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-lifetime-mediakeys-with-session.html
index 87c63221..6def08fd 100644
--- a/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-lifetime-mediakeys-with-session.html
+++ b/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-lifetime-mediakeys-with-session.html
@@ -22,11 +22,11 @@
                 var initDataType;
                 var initData;
                 var mediaKeys;
-                var startingActiveDOMObjectCount = window.internals.activeDOMObjectCount(document);
+                var startingSuspendableObjectCount = window.internals.suspendableObjectCount(document);
 
-                function numActiveDOMObjectsCreated()
+                function numSuspendableObjectsCreated()
                 {
-                    return window.internals.activeDOMObjectCount(document) - startingActiveDOMObjectCount;
+                    return window.internals.suspendableObjectCount(document) - startingSuspendableObjectCount;
                 }
 
                 // Create a MediaKeys object with a session.
@@ -37,27 +37,27 @@
                 }).then(function(result) {
                     mediaKeys = result;
 
-                    // Verify MediaKeys is an ActiveDOMObject.
-                    // In non-Oilpan, numActiveDOMObjectsCreate() == 1.
-                    // In Oilpan, numActiveDOMObjectsCreate() <= 4.
+                    // Verify MediaKeys is an SuspendableObject.
+                    // In non-Oilpan, numSuspendableObjectsCreate() == 1.
+                    // In Oilpan, numSuspendableObjectsCreate() <= 4.
                     // (1 MediaKeys,
                     //  1 MediaKeysInitializer and
                     //  1 MediaKeySystemAccessInitializer (navigator.requestMediaKeySystemAccess() use above),
                     //  1 MediaKeySystemAccessInitializer (isInitDataSupported() (via getSupportedInitDataType())))
-                    assert_between_inclusive(numActiveDOMObjectsCreated(), 1, 4, 'MediaKeys.create()');
+                    assert_between_inclusive(numSuspendableObjectsCreated(), 1, 4, 'MediaKeys.create()');
 
                     var mediaKeySession = mediaKeys.createSession();
                     return mediaKeySession.generateRequest(initDataType, initData);
                 }).then(function() {
                     // Should be 1 MediaKeys + 1 MediaKeySession.
-                    // In non-Oilpan, numActiveDOMObjectsCreate() == 2.
-                    // In Oilpan, numActiveDOMObjectsCreate() <= 6.
+                    // In non-Oilpan, numSuspendableObjectsCreate() == 2.
+                    // In Oilpan, numSuspendableObjectsCreate() <= 6.
                     // (1 MediaKeys,
                     //  1 MediaKeysInitializer and
                     //  2 MediaKeySystemAccessInitializer,
                     //  1 ContentDecryptionModuleResultPromise and
                     //  1 MediaKeySession).
-                    assert_between_inclusive(numActiveDOMObjectsCreated(), 2, 6, 'MediaKeys.createSession()');
+                    assert_between_inclusive(numSuspendableObjectsCreated(), 2, 6, 'MediaKeys.createSession()');
 
                     // Run gc(), should not affect MediaKeys object nor the
                     // session since we still have a reference to it.
@@ -70,7 +70,7 @@
 
                     // MediaKeys + MediaKeySessions should remain.
                     // In non-Oilpan, there is also something from createGCPromise().
-                    assert_between_inclusive(numActiveDOMObjectsCreated(), 2, 3, 'After gc()');
+                    assert_between_inclusive(numSuspendableObjectsCreated(), 2, 3, 'After gc()');
 
                     // Drop reference to the MediaKeys object and run gc()
                     // again. Object should be collected this time. Since
@@ -87,7 +87,7 @@
                 }).then(function(result) {
                     // No MediaKeySessions should remain.
                     // In non-Oilpan, there is also something from createGCPromise().
-                    assert_between_inclusive(numActiveDOMObjectsCreated(), 0, 1, 'After final gc()');
+                    assert_between_inclusive(numSuspendableObjectsCreated(), 0, 1, 'After final gc()');
 
                     test.done();
                 }).catch(function(error) {
diff --git a/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-lifetime-mediakeysession-reference.html b/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-lifetime-mediakeysession-reference.html
index a9d50d29..2736a46 100644
--- a/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-lifetime-mediakeysession-reference.html
+++ b/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-lifetime-mediakeysession-reference.html
@@ -8,7 +8,7 @@
     </head>
     <body>
         <script>
-            // Since MediaKeySession (and MediaKeys) are ActiveDOMObjects,
+            // Since MediaKeySession (and MediaKeys) are SuspendableObjects,
             // we can determine when they are garbage collected.
             // MediaKeySessions remain as long as:
             //   JavaScript has a reference to it
@@ -23,11 +23,11 @@
                 var mediaKeySession3;
                 var initDataType;
                 var initData;
-                var startingActiveDOMObjectCount = window.internals.activeDOMObjectCount(document);
+                var startingSuspendableObjectCount = window.internals.suspendableObjectCount(document);
 
-                function numActiveDOMObjectsCreated()
+                function numSuspendableObjectsCreated()
                 {
-                    return window.internals.activeDOMObjectCount(document) - startingActiveDOMObjectCount;
+                    return window.internals.suspendableObjectCount(document) - startingSuspendableObjectCount;
                 }
 
                 navigator.requestMediaKeySystemAccess('org.w3.clearkey', getSimpleConfiguration()).then(function(access) {
@@ -38,14 +38,14 @@
                     mediaKeys = result;
                     assert_equals(typeof mediaKeys.createSession, 'function');
 
-                    // Verify MediaKeys is an ActiveDOMObject.
-                    // In non-Oilpan, numActiveDOMObjectsCreate() == 1.
-                    // In Oilpan, numActiveDOMObjectsCreate() <= 4.
+                    // Verify MediaKeys is an SuspendableObject.
+                    // In non-Oilpan, numSuspendableObjectsCreate() == 1.
+                    // In Oilpan, numSuspendableObjectsCreate() <= 4.
                     // (1 MediaKeys,
                     //  1 MediaKeysInitializer and
                     //  1 MediaKeySystemAccessInitializer (navigator.requestMediaKeySystemAccess() use above),
                     //  1 MediaKeySystemAccessInitializer (isInitDataSupported() (via getSupportedInitDataType())))
-                    assert_between_inclusive(numActiveDOMObjectsCreated(), 1, 4, 'MediaKeys.create()');
+                    assert_between_inclusive(numSuspendableObjectsCreated(), 1, 4, 'MediaKeys.create()');
 
                     // Create 3 sessions.
                     mediaKeySession1 = mediaKeys.createSession();
@@ -54,14 +54,14 @@
                     assert_true(mediaKeySession1.sessionId && mediaKeySession1.sessionId.length > 0);
 
                     // Should be 1 MediaKeys + 1 MediaKeySession.
-                    // In non-Oilpan, numActiveDOMObjectsCreate() == 2.
-                    // In Oilpan, numActiveDOMObjectsCreate() <= 6.
+                    // In non-Oilpan, numSuspendableObjectsCreate() == 2.
+                    // In Oilpan, numSuspendableObjectsCreate() <= 6.
                     // (1 MediaKeys,
                     //  1 MediaKeysInitializer and
                     //  2 MediaKeySystemAccessInitializer,
                     //  1 ContentDecryptionModuleResultPromise and
                     //  1 MediaKeySession).
-                    assert_between_inclusive(numActiveDOMObjectsCreated(), 2, 6, 'MediaKeys.createSession(1)');
+                    assert_between_inclusive(numSuspendableObjectsCreated(), 2, 6, 'MediaKeys.createSession(1)');
 
                     mediaKeySession2 = mediaKeys.createSession();
                     return mediaKeySession2.generateRequest(initDataType, initData);
@@ -69,14 +69,14 @@
                     assert_true(mediaKeySession2.sessionId && mediaKeySession2.sessionId.length > 0);
 
                     // Should be 1 MediaKeys + 2 MediaKeySessions.
-                    // In non-Oilpan, numActiveDOMObjectsCreate() == 3.
-                    // In Oilpan, numActiveDOMObjectsCreate() <= 8.
+                    // In non-Oilpan, numSuspendableObjectsCreate() == 3.
+                    // In Oilpan, numSuspendableObjectsCreate() <= 8.
                     // (1 MediaKeys,
                     //  1 MediaKeysInitializer and
                     //  2 MediaKeySystemAccessInitializers,
                     //  2 ContentDecryptionModuleResultPromise and
                     //  2 MediaKeySession).
-                    assert_between_inclusive(numActiveDOMObjectsCreated(), 3, 8, 'mediaKeys.createSession(2)');
+                    assert_between_inclusive(numSuspendableObjectsCreated(), 3, 8, 'mediaKeys.createSession(2)');
 
                     mediaKeySession3 = mediaKeys.createSession();
                     return mediaKeySession3.generateRequest(initDataType, initData);
@@ -84,14 +84,14 @@
                     assert_true(mediaKeySession3.sessionId && mediaKeySession3.sessionId.length > 0);
 
                     // Should be 1 MediaKeys + 3 MediaKeySessions.
-                    // In non-Oilpan, numActiveDOMObjectsCreate() == 4.
-                    // In Oilpan, numActiveDOMObjectsCreate() <= 10.
+                    // In non-Oilpan, numSuspendableObjectsCreate() == 4.
+                    // In Oilpan, numSuspendableObjectsCreate() <= 10.
                     // (1 MediaKeys,
                     //  1 MediaKeysInitializer and
                     //  2 MediaKeySystemAccessInitializers,
                     //  3 ContentDecryptionModuleResultPromise and
                     //  3 MediaKeySession).
-                    assert_between_inclusive(numActiveDOMObjectsCreated(), 4, 10, 'mediaKeys.createSession(3)');
+                    assert_between_inclusive(numSuspendableObjectsCreated(), 4, 10, 'mediaKeys.createSession(3)');
 
                     // Run gc(). All sessions should remain as we have a
                     // reference to each one. However, running gc()
@@ -100,7 +100,7 @@
                 }).then(function(result) {
                     // Only MediaKeys + 3 MediaKeySessions should remain.
                     // In non-Oilpan, there is also something from createGCPromise().
-                    assert_between_inclusive(numActiveDOMObjectsCreated(), 4, 5, 'After gc()');
+                    assert_between_inclusive(numSuspendableObjectsCreated(), 4, 5, 'After gc()');
 
                     // Now drop references to 2 of the sessions. Even though we
                     // don't have a reference, MediaKeys is still around (and
@@ -114,7 +114,7 @@
                 }).then(function(result) {
                     // MediaKeys + 3 MediaKeySessions should remain.
                     // In non-Oilpan, there is also something from createGCPromise().
-                    assert_between_inclusive(numActiveDOMObjectsCreated(), 4, 5, 'After second gc()');
+                    assert_between_inclusive(numSuspendableObjectsCreated(), 4, 5, 'After second gc()');
 
                     // Now drop the reference to MediaKeys. It and the 2
                     // unreferenced sessions should be collected. Since
@@ -131,7 +131,7 @@
                 }).then(function(result) {
                     // Only 1 MediaKeySessions should remain.
                     // In non-Oilpan, there is also something from createGCPromise().
-                    assert_between_inclusive(numActiveDOMObjectsCreated(), 1, 2, 'After mediaKeys = null');
+                    assert_between_inclusive(numSuspendableObjectsCreated(), 1, 2, 'After mediaKeys = null');
 
                     // Drop the reference to the last session. It should get
                     // collected now since MediaKeys is gone.
@@ -140,7 +140,7 @@
                 }).then(function(result) {
                     // No MediaKeySessions should remain.
                     // In non-Oilpan, there is also something from createGCPromise().
-                    assert_between_inclusive(numActiveDOMObjectsCreated(), 0, 1, 'After final gc()');
+                    assert_between_inclusive(numSuspendableObjectsCreated(), 0, 1, 'After final gc()');
 
                     test.done();
                 }).catch(function(error) {
diff --git a/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-lifetime-mediakeysession-release-noreference.html b/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-lifetime-mediakeysession-release-noreference.html
index 38c4a2d..bff8e23 100644
--- a/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-lifetime-mediakeysession-release-noreference.html
+++ b/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-lifetime-mediakeysession-release-noreference.html
@@ -8,7 +8,7 @@
     </head>
     <body>
         <script>
-            // Since MediaKeySession (and MediaKeys) are ActiveDOMObjects,
+            // Since MediaKeySession (and MediaKeys) are SuspendableObjects,
             // we can determine when they are garbage collected.
             // MediaKeySessions remain as long as:
             //   JavaScript has a reference to it
@@ -18,11 +18,11 @@
             {
                 var initDataType;
                 var initData;
-                var startingActiveDOMObjectCount = window.internals.activeDOMObjectCount(document);
+                var startingSuspendableObjectCount = window.internals.suspendableObjectCount(document);
 
-                function numActiveDOMObjectsCreated()
+                function numSuspendableObjectsCreated()
                 {
-                    return window.internals.activeDOMObjectCount(document) - startingActiveDOMObjectCount;
+                    return window.internals.suspendableObjectCount(document) - startingSuspendableObjectCount;
                 }
 
                 // Create 2 sessions.
@@ -37,14 +37,14 @@
                 }).then(function(result) {
                     mediaKeys = result;
 
-                    // Verify MediaKeys is an ActiveDOMObject.
-                    // In non-Oilpan, numActiveDOMObjectsCreate() == 1.
-                    // In Oilpan, numActiveDOMObjectsCreate() <= 4.
+                    // Verify MediaKeys is an SuspendableObject.
+                    // In non-Oilpan, numSuspendableObjectsCreate() == 1.
+                    // In Oilpan, numSuspendableObjectsCreate() <= 4.
                     // (1 MediaKeys,
                     //  1 MediaKeysInitializer and
                     //  1 MediaKeySystemAccessInitializer (navigator.requestMediaKeySystemAccess() use above),
                     //  1 MediaKeySystemAccessInitializer (isInitDataSupported() (via getSupportedInitDataType())))
-                    assert_between_inclusive(numActiveDOMObjectsCreated(), 1, 4, 'MediaKeys.create()');
+                    assert_between_inclusive(numSuspendableObjectsCreated(), 1, 4, 'MediaKeys.create()');
 
                     mediaKeySession1 = mediaKeys.createSession();
                     return mediaKeySession1.generateRequest(initDataType, initData);
@@ -52,14 +52,14 @@
                     assert_true(mediaKeySession1.sessionId && mediaKeySession1.sessionId.length > 0);
 
                     // Should be 1 MediaKeys + 1 MediaKeySession.
-                    // In non-Oilpan, numActiveDOMObjectsCreate() == 2.
-                    // In Oilpan, numActiveDOMObjectsCreate() <= 6.
+                    // In non-Oilpan, numSuspendableObjectsCreate() == 2.
+                    // In Oilpan, numSuspendableObjectsCreate() <= 6.
                     // (1 MediaKeys,
                     //  1 MediaKeysInitializer and
                     //  2 MediaKeySystemAccessInitializer,
                     //  1 ContentDecryptionModuleResultPromise and
                     //  1 MediaKeySession).
-                    assert_between_inclusive(numActiveDOMObjectsCreated(), 2, 6, 'MediaKeys.createSession(1)');
+                    assert_between_inclusive(numSuspendableObjectsCreated(), 2, 6, 'MediaKeys.createSession(1)');
 
                     mediaKeySession2 = mediaKeys.createSession();
                     return mediaKeySession2.generateRequest(initDataType, initData);
@@ -67,14 +67,14 @@
                     assert_true(mediaKeySession2.sessionId && mediaKeySession2.sessionId.length > 0);
 
                     // Should be 1 MediaKeys + 2 MediaKeySessions.
-                    // In non-Oilpan, numActiveDOMObjectsCreate() == 3.
-                    // In Oilpan, numActiveDOMObjectsCreate() <= 8.
+                    // In non-Oilpan, numSuspendableObjectsCreate() == 3.
+                    // In Oilpan, numSuspendableObjectsCreate() <= 8.
                     // (1 MediaKeys,
                     //  1 MediaKeysInitializer and
                     //  2 MediaKeySystemAccessInitializers,
                     //  2 ContentDecryptionModuleResultPromise and
                     //  2 MediaKeySession).
-                    assert_between_inclusive(numActiveDOMObjectsCreated(), 3, 8, 'mediaKeys.createSession(2)');
+                    assert_between_inclusive(numSuspendableObjectsCreated(), 3, 8, 'mediaKeys.createSession(2)');
                 }).then(function(result) {
                     // Run gc(). All sessions should remain as we have a
                     // reference to each one.
@@ -82,7 +82,7 @@
                 }).then(function(result) {
                     // Should be just 1 MediaKeys + 2 MediaKeySessions.
                     // In non-Oilpan, there is also something from createGCPromise().
-                    assert_between_inclusive(numActiveDOMObjectsCreated(), 3, 4, 'After gc()');
+                    assert_between_inclusive(numSuspendableObjectsCreated(), 3, 4, 'After gc()');
 
                     // Close the sessions. Once the close() event is received,
                     // they should get garbage collected as there are no JS
@@ -99,7 +99,7 @@
                 }).then(function(result) {
                     // Only MediaKeys + mediaKeySession2 should remain.
                     // In non-Oilpan, there is also something from createGCPromise().
-                    assert_between_inclusive(numActiveDOMObjectsCreated(), 2, 3, 'mediaKeySession1 not collected');
+                    assert_between_inclusive(numSuspendableObjectsCreated(), 2, 3, 'mediaKeySession1 not collected');
 
                     var promise = mediaKeySession2.close();
                     mediaKeySession2 = null;
@@ -113,7 +113,7 @@
                 }).then(function(result) {
                     // Only MediaKeys should remain.
                     // In non-Oilpan, there is also something from createGCPromise().
-                    assert_between_inclusive(numActiveDOMObjectsCreated(), 1, 2, 'mediaKeySession2 not collected');
+                    assert_between_inclusive(numSuspendableObjectsCreated(), 1, 2, 'mediaKeySession2 not collected');
 
                     assert_not_equals(mediaKeys, null);
                     test.done();
diff --git a/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-lifetime-mediakeysession-release.html b/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-lifetime-mediakeysession-release.html
index 80868a2..e0bb9cb 100644
--- a/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-lifetime-mediakeysession-release.html
+++ b/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-lifetime-mediakeysession-release.html
@@ -8,7 +8,7 @@
     </head>
     <body>
         <script>
-            // Since MediaKeySession (and MediaKeys) are ActiveDOMObjects,
+            // Since MediaKeySession (and MediaKeys) are SuspendableObjects,
             // we can determine when they are garbage collected.
             // MediaKeySessions remain as long as:
             //   JavaScript has a reference to it
@@ -21,11 +21,11 @@
                 var mediaKeySession2;
                 var initDataType;
                 var initData;
-                var startingActiveDOMObjectCount = window.internals.activeDOMObjectCount(document);
+                var startingSuspendableObjectCount = window.internals.suspendableObjectCount(document);
 
-                function numActiveDOMObjectsCreated()
+                function numSuspendableObjectsCreated()
                 {
-                    return window.internals.activeDOMObjectCount(document) - startingActiveDOMObjectCount;
+                    return window.internals.suspendableObjectCount(document) - startingSuspendableObjectCount;
                 }
 
                 // Create 2 sessions.
@@ -36,40 +36,40 @@
                 }).then(function(result) {
                     mediaKeys = result;
 
-                    // Verify MediaKeys is an ActiveDOMObject.
-                    // In non-Oilpan, numActiveDOMObjectsCreate() == 1.
-                    // In Oilpan, numActiveDOMObjectsCreate() <= 4.
+                    // Verify MediaKeys is an SuspendableObject.
+                    // In non-Oilpan, numSuspendableObjectsCreate() == 1.
+                    // In Oilpan, numSuspendableObjectsCreate() <= 4.
                     // (1 MediaKeys,
                     //  1 MediaKeysInitializer and
                     //  1 MediaKeySystemAccessInitializer (navigator.requestMediaKeySystemAccess() use above),
                     //  1 MediaKeySystemAccessInitializer (isInitDataSupported() (via getSupportedInitDataType())))
-                    assert_between_inclusive(numActiveDOMObjectsCreated(), 1, 4, 'MediaKeys.create()');
+                    assert_between_inclusive(numSuspendableObjectsCreated(), 1, 4, 'MediaKeys.create()');
 
                     mediaKeySession1 = mediaKeys.createSession();
                     return mediaKeySession1.generateRequest(initDataType, initData);
                 }).then(function() {
                     // Should be 1 MediaKeys + 1 MediaKeySession.
-                    // In non-Oilpan, numActiveDOMObjectsCreate() == 2.
-                    // In Oilpan, numActiveDOMObjectsCreate() <= 6.
+                    // In non-Oilpan, numSuspendableObjectsCreate() == 2.
+                    // In Oilpan, numSuspendableObjectsCreate() <= 6.
                     // (1 MediaKeys,
                     //  1 MediaKeysInitializer,
                     //  2 MediaKeySystemAccessInitializers,
                     //  1 ContentDecryptionModuleResultPromise and
                     //  1 MediaKeySession).
-                    assert_between_inclusive(numActiveDOMObjectsCreated(), 2, 6, 'MediaKeys.createSession(1)');
+                    assert_between_inclusive(numSuspendableObjectsCreated(), 2, 6, 'MediaKeys.createSession(1)');
 
                     mediaKeySession2 = mediaKeys.createSession();
                     return mediaKeySession2.generateRequest(initDataType, initData);
                 }).then(function() {
                     // Should be 1 MediaKeys + 2 MediaKeySessions.
-                    // In non-Oilpan, numActiveDOMObjectsCreate() == 3.
-                    // In Oilpan, numActiveDOMObjectsCreate() <= 8.
+                    // In non-Oilpan, numSuspendableObjectsCreate() == 3.
+                    // In Oilpan, numSuspendableObjectsCreate() <= 8.
                     // (1 MediaKeys,
                     //  1 MediaKeysInitializer,
                     //  2 MediaKeySystemAccessInitializers,
                     //  2 ContentDecryptionModuleResultPromise and
                     //  2 MediaKeySession).
-                    assert_between_inclusive(numActiveDOMObjectsCreated(), 3, 8, 'mediaKeys.createSession(2)');
+                    assert_between_inclusive(numSuspendableObjectsCreated(), 3, 8, 'mediaKeys.createSession(2)');
 
                     // Close the sessions. Once completed, only the JS
                     // reference to them keeps them around.
@@ -81,28 +81,28 @@
                     // reference to them from JS will result in the session
                     // being garbage-collected.
                     // Should be 1 MediaKeys + 2 MediaKeySessions.
-                    // In non-Oilpan, numActiveDOMObjectsCreate() == 3.
-                    // In Oilpan, numActiveDOMObjectsCreate() <= 10.
+                    // In non-Oilpan, numSuspendableObjectsCreate() == 3.
+                    // In Oilpan, numSuspendableObjectsCreate() <= 10.
                     // (1 MediaKeys,
                     //  1 MediaKeysInitializer,
                     //  2 MediaKeySystemAccessInitializers,
                     //  4 ContentDecryptionModuleResultPromise and
                     //  2 MediaKeySession).
-                    assert_between_inclusive(numActiveDOMObjectsCreated(), 3, 10, 'after close');
+                    assert_between_inclusive(numSuspendableObjectsCreated(), 3, 10, 'after close');
 
                     mediaKeySession1 = null;
                     return createGCPromise();
                 }).then(function() {
                     // Only MediaKeys + mediaKeySession2 should remain.
                     // In non-Oilpan, there is also something from createGCPromise().
-                    assert_between_inclusive(numActiveDOMObjectsCreated(), 2, 3, 'mediaKeySession1 not collected');
+                    assert_between_inclusive(numSuspendableObjectsCreated(), 2, 3, 'mediaKeySession1 not collected');
 
                     mediaKeySession2 = null;
                     return createGCPromise();
                 }).then(function() {
                     // Only MediaKeys should remain.
                     // In non-Oilpan, there is also something from createGCPromise().
-                    assert_between_inclusive(numActiveDOMObjectsCreated(), 1, 2, 'mediaKeySession2 not collected');
+                    assert_between_inclusive(numSuspendableObjectsCreated(), 1, 2, 'mediaKeySession2 not collected');
                     test.done();
                 }).catch(function(error) {
                     forceTestFailureFromPromise(test, error);
diff --git a/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-lifetime-multiple-mediakeys.html b/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-lifetime-multiple-mediakeys.html
index 2c0ae79d..c6f3f647 100644
--- a/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-lifetime-multiple-mediakeys.html
+++ b/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-lifetime-multiple-mediakeys.html
@@ -12,11 +12,11 @@
             async_test(function(test)
             {
                 var mediaKeys;
-                var startingActiveDOMObjectCount = window.internals.activeDOMObjectCount(document);
+                var startingSuspendableObjectCount = window.internals.suspendableObjectCount(document);
 
-                function numActiveDOMObjectsCreated()
+                function numSuspendableObjectsCreated()
                 {
-                    return window.internals.activeDOMObjectCount(document) - startingActiveDOMObjectCount;
+                    return window.internals.suspendableObjectCount(document) - startingSuspendableObjectCount;
                 }
 
                 // Create a MediaKeys object. Returns a promise that resolves
@@ -34,53 +34,53 @@
                 // last one created.
                 createMediaKeys().then(function(result) {
                     // Should be 1 MediaKeys.
-                    // In non-Oilpan, numActiveDOMObjectsCreate() == 1.
-                    // In Oilpan, numActiveDOMObjectsCreated() <= 4.
+                    // In non-Oilpan, numSuspendableObjectsCreate() == 1.
+                    // In Oilpan, numSuspendableObjectsCreated() <= 4.
                     // (1 MediaKeysInitializer,
                     //  1 MediaKeySystemAccessInitializer (navigator.requestMediaKeySystemAccess() use above),
                     //  1 MediaKeySystemAccessInitializer (isInitDataSupported() (via getSupportedInitDataType())) and
                     //  1 ContentDecryptionModuleResultPromise).
-                    assert_between_inclusive(numActiveDOMObjectsCreated(), 1, 4);
+                    assert_between_inclusive(numSuspendableObjectsCreated(), 1, 4);
 
                     return createMediaKeys();
                 }).then(function(result) {
                     // Should be 2 MediaKeys.
-                    // In non-Oilpan, numActiveDOMObjectsCreate() == 2.
-                    // In Oilpan, numActiveDOMObjectsCreate() <= 8.
+                    // In non-Oilpan, numSuspendableObjectsCreate() == 2.
+                    // In Oilpan, numSuspendableObjectsCreate() <= 8.
                     // (2 MediaKeysInitializer,
                     //  4 MediaKeySystemAccessInitializer and
                     //  2 ContentDecryptionModuleResultPromise).
-                    assert_between_inclusive(numActiveDOMObjectsCreated(), 2, 8);
+                    assert_between_inclusive(numSuspendableObjectsCreated(), 2, 8);
 
                     return createMediaKeys();
                 }).then(function(result) {
                     // Should be 3 MediaKeys.
-                    // In non-Oilpan, numActiveDOMObjectsCreate() == 3.
-                    // In Oilpan, numActiveDOMObjectsCreate() <= 12.
+                    // In non-Oilpan, numSuspendableObjectsCreate() == 3.
+                    // In Oilpan, numSuspendableObjectsCreate() <= 12.
                     // (3 MediaKeysInitializer,
                     //  6 MediaKeySystemAccessInitializer and
                     //  3 ContentDecryptionModuleResultPromise).
-                    assert_between_inclusive(numActiveDOMObjectsCreated(), 3, 12);
+                    assert_between_inclusive(numSuspendableObjectsCreated(), 3, 12);
 
                     return createMediaKeys();
                 }).then(function(result) {
                     // Should be 4 MediaKeys.
-                    // In non-Oilpan, numActiveDOMObjectsCreate() == 4.
-                    // In Oilpan, numActiveDOMObjectsCreate() <= 16.
+                    // In non-Oilpan, numSuspendableObjectsCreate() == 4.
+                    // In Oilpan, numSuspendableObjectsCreate() <= 16.
                     // (4 MediaKeysInitializer,
                     //  8 MediaKeySystemAccessInitializer and
                     //  4 ContentDecryptionModuleResultPromise).
-                    assert_between_inclusive(numActiveDOMObjectsCreated(), 4, 16);
+                    assert_between_inclusive(numSuspendableObjectsCreated(), 4, 16);
 
                     return createMediaKeys();
                 }).then(function(result) {
                     // Should be 5 MediaKeys.
-                    // In non-Oilpan, numActiveDOMObjectsCreate() == 5.
-                    // In Oilpan, numActiveDOMObjectsCreate() <= 20.
+                    // In non-Oilpan, numSuspendableObjectsCreate() == 5.
+                    // In Oilpan, numSuspendableObjectsCreate() <= 20.
                     // (5 MediaKeysInitializer,
                     //  10 MediaKeySystemAccessInitializer and
                     //  5 ContentDecryptionModuleResultPromise).
-                    assert_between_inclusive(numActiveDOMObjectsCreated(), 5, 20);
+                    assert_between_inclusive(numSuspendableObjectsCreated(), 5, 20);
 
                     // |mediaKeys| refers to the most recently created MediaKeys
                     // object.
@@ -90,14 +90,14 @@
                     // collected, it needs time to process any pending events.
                     return delayToAllowEventProcessingPromise();
                 }).then(function(result) {
-                    // In non-Oilpan, numActiveDOMObjectsCreated() == 5
+                    // In non-Oilpan, numSuspendableObjectsCreated() == 5
                     // (5 MediaKeySession objects).
-                    // In Oilpan, numActiveDOMObjectsCreated() <= 23
+                    // In Oilpan, numSuspendableObjectsCreated() <= 23
                     // (5 MediaKeysInitializer,
                     //  12 MediaKeySystemAccessInitializer,
                     //  5 ContentDecryptionModuleResultPromise and
                     //  1 DOMTimer (in delayToAllowEventProcessingPromise))
-                    assert_between_inclusive(numActiveDOMObjectsCreated(), 5, 23);
+                    assert_between_inclusive(numSuspendableObjectsCreated(), 5, 23);
 
                     // As we only have a reference (|mediaKeys|) to the last
                     // created MediaKeys object, the other 4 MediaKeys objects
@@ -105,7 +105,7 @@
                     return createGCPromise();
                 }).then(function(result) {
                     // Should be 1 MediaKeys and DOMTimer.
-                    assert_less_than_equal(numActiveDOMObjectsCreated(), 2);
+                    assert_less_than_equal(numSuspendableObjectsCreated(), 2);
                     assert_equals(typeof mediaKeys.createSession, 'function');
 
                     // Release the last MediaKeys object created.
@@ -115,7 +115,7 @@
                     return createGCPromise();
                 }).then(function(result) {
                     // Should be just a DOMTimer.
-                    assert_less_than_equal(numActiveDOMObjectsCreated(), 1);
+                    assert_less_than_equal(numSuspendableObjectsCreated(), 1);
                     test.done();
                 }).catch(function(error) {
                     forceTestFailureFromPromise(test, error);
diff --git a/third_party/WebKit/Source/bindings/core/v8/ActiveDOMCallback.cpp b/third_party/WebKit/Source/bindings/core/v8/ActiveDOMCallback.cpp
index c6d1f64..977b220 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ActiveDOMCallback.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/ActiveDOMCallback.cpp
@@ -42,8 +42,7 @@
 ActiveDOMCallback::~ActiveDOMCallback() {}
 
 bool ActiveDOMCallback::canInvokeCallback() const {
-  return !m_context->activeDOMObjectsAreSuspended() &&
-         !m_context->isContextDestroyed();
+  return !m_context->isContextSuspended() && !m_context->isContextDestroyed();
 }
 
 DEFINE_TRACE(ActiveDOMCallback) {
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptPromisePropertyBase.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptPromisePropertyBase.cpp
index f5ad239e..815a3ba 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptPromisePropertyBase.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptPromisePropertyBase.cpp
@@ -17,7 +17,7 @@
 ScriptPromisePropertyBase::ScriptPromisePropertyBase(
     ExecutionContext* executionContext,
     Name name)
-    : ContextLifecycleObserver(executionContext),
+    : ContextClient(executionContext),
       m_isolate(toIsolate(executionContext)),
       m_name(name),
       m_state(Pending) {}
@@ -207,7 +207,7 @@
 }
 
 DEFINE_TRACE(ScriptPromisePropertyBase) {
-  ContextLifecycleObserver::trace(visitor);
+  ContextClient::trace(visitor);
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptPromisePropertyBase.h b/third_party/WebKit/Source/bindings/core/v8/ScriptPromisePropertyBase.h
index ef03a45..8c359827 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptPromisePropertyBase.h
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptPromisePropertyBase.h
@@ -25,7 +25,7 @@
 // TODO(yhirano): Remove NEVER_INLINE once we find the cause of crashes.
 class CORE_EXPORT ScriptPromisePropertyBase
     : public GarbageCollectedFinalized<ScriptPromisePropertyBase>,
-      public ContextLifecycleObserver {
+      public ContextClient {
   USING_GARBAGE_COLLECTED_MIXIN(ScriptPromisePropertyBase);
 
  public:
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseResolver.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseResolver.cpp
index 0c41a6a..7ef0106 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseResolver.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseResolver.cpp
@@ -72,7 +72,7 @@
 
 void ScriptPromiseResolver::resolveOrRejectImmediately() {
   DCHECK(!getExecutionContext()->isContextDestroyed());
-  DCHECK(!getExecutionContext()->activeDOMObjectsAreSuspended());
+  DCHECK(!getExecutionContext()->isContextSuspended());
   {
     InspectorInstrumentation::AsyncTask asyncTask(getExecutionContext(), this);
     if (m_state == Resolving) {
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseResolver.h b/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseResolver.h
index 48918360..201803ef 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseResolver.h
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseResolver.h
@@ -130,7 +130,7 @@
                 toV8(value, m_scriptState->context()->Global(),
                      m_scriptState->isolate()));
 
-    if (getExecutionContext()->activeDOMObjectsAreSuspended()) {
+    if (getExecutionContext()->isContextSuspended()) {
       // Retain this object until it is actually resolved or rejected.
       keepAliveWhilePending();
       return;
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptState.h b/third_party/WebKit/Source/bindings/core/v8/ScriptState.h
index fcf00ab..7da133a 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptState.h
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptState.h
@@ -123,16 +123,6 @@
     return from(info.Holder()->CreationContext());
   }
 
-  // Debugger context doesn't have associated ScriptState and when current
-  // context is debugger it should be treated as if context stack was empty.
-  static bool hasCurrentScriptState(v8::Isolate* isolate) {
-    v8::HandleScope scope(isolate);
-    v8::Local<v8::Context> context = isolate->GetCurrentContext();
-    if (context.IsEmpty())
-      return false;
-    return context != v8::Debug::GetDebugContext(isolate);
-  }
-
   static ScriptState* from(v8::Local<v8::Context> context) {
     ASSERT(!context.IsEmpty());
     ScriptState* scriptState =
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8AbstractEventListener.cpp b/third_party/WebKit/Source/bindings/core/v8/V8AbstractEventListener.cpp
index 1bc4613..6298bbf 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8AbstractEventListener.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/V8AbstractEventListener.cpp
@@ -203,7 +203,7 @@
 
 bool V8AbstractEventListener::belongsToTheCurrentWorld(
     ExecutionContext* executionContext) const {
-  if (ScriptState::hasCurrentScriptState(isolate()) &&
+  if (!isolate()->GetCurrentContext().IsEmpty() &&
       &world() == &DOMWrapperWorld::current(isolate()))
     return true;
   // If currently parsing, the parser could be accessing this listener
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.cpp b/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.cpp
index 0b0bdd52..c87a50e 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.cpp
@@ -46,9 +46,7 @@
 static V8PerIsolateData* mainThreadPerIsolateData = 0;
 
 static void beforeCallEnteredCallback(v8::Isolate* isolate) {
-  RELEASE_ASSERT(!ScriptForbiddenScope::isScriptForbidden() ||
-                 isolate->GetCurrentContext() ==
-                     v8::Debug::GetDebugContext(isolate));
+  RELEASE_ASSERT(!ScriptForbiddenScope::isScriptForbidden());
 }
 
 static void microtasksCompletedCallback(v8::Isolate* isolate) {
diff --git a/third_party/WebKit/Source/bindings/templates/callback_function.cpp.tmpl b/third_party/WebKit/Source/bindings/templates/callback_function.cpp.tmpl
index 9ef2ca6..412a9df 100644
--- a/third_party/WebKit/Source/bindings/templates/callback_function.cpp.tmpl
+++ b/third_party/WebKit/Source/bindings/templates/callback_function.cpp.tmpl
@@ -29,7 +29,7 @@
 
   ExecutionContext* context = m_scriptState->getExecutionContext();
   DCHECK(context);
-  if (context->activeDOMObjectsAreSuspended() || context->isContextDestroyed())
+  if (context->isContextSuspended() || context->isContextDestroyed())
     return false;
 
   if (m_callback.isEmpty())
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/AnyCallbackFunctionOptionalAnyArg.cpp b/third_party/WebKit/Source/bindings/tests/results/core/AnyCallbackFunctionOptionalAnyArg.cpp
index 035a160..7cce342 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/AnyCallbackFunctionOptionalAnyArg.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/AnyCallbackFunctionOptionalAnyArg.cpp
@@ -40,7 +40,7 @@
 
   ExecutionContext* context = m_scriptState->getExecutionContext();
   DCHECK(context);
-  if (context->activeDOMObjectsAreSuspended() || context->isContextDestroyed())
+  if (context->isContextSuspended() || context->isContextDestroyed())
     return false;
 
   if (m_callback.isEmpty())
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/LongCallbackFunction.cpp b/third_party/WebKit/Source/bindings/tests/results/core/LongCallbackFunction.cpp
index 7332d11..33bb9ee 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/LongCallbackFunction.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/LongCallbackFunction.cpp
@@ -39,7 +39,7 @@
 
   ExecutionContext* context = m_scriptState->getExecutionContext();
   DCHECK(context);
-  if (context->activeDOMObjectsAreSuspended() || context->isContextDestroyed())
+  if (context->isContextSuspended() || context->isContextDestroyed())
     return false;
 
   if (m_callback.isEmpty())
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/StringSequenceCallbackFunctionLongSequenceArg.cpp b/third_party/WebKit/Source/bindings/tests/results/core/StringSequenceCallbackFunctionLongSequenceArg.cpp
index f0b5ca1..1986bbe 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/StringSequenceCallbackFunctionLongSequenceArg.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/StringSequenceCallbackFunctionLongSequenceArg.cpp
@@ -39,7 +39,7 @@
 
   ExecutionContext* context = m_scriptState->getExecutionContext();
   DCHECK(context);
-  if (context->activeDOMObjectsAreSuspended() || context->isContextDestroyed())
+  if (context->isContextSuspended() || context->isContextDestroyed())
     return false;
 
   if (m_callback.isEmpty())
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/VoidCallbackFunction.cpp b/third_party/WebKit/Source/bindings/tests/results/core/VoidCallbackFunction.cpp
index 8af8e07..0ac97311 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/VoidCallbackFunction.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/VoidCallbackFunction.cpp
@@ -39,7 +39,7 @@
 
   ExecutionContext* context = m_scriptState->getExecutionContext();
   DCHECK(context);
-  if (context->activeDOMObjectsAreSuspended() || context->isContextDestroyed())
+  if (context->isContextSuspended() || context->isContextDestroyed())
     return false;
 
   if (m_callback.isEmpty())
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/VoidCallbackFunctionInterfaceArg.cpp b/third_party/WebKit/Source/bindings/tests/results/core/VoidCallbackFunctionInterfaceArg.cpp
index 31958e2..55ce233 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/VoidCallbackFunctionInterfaceArg.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/VoidCallbackFunctionInterfaceArg.cpp
@@ -40,7 +40,7 @@
 
   ExecutionContext* context = m_scriptState->getExecutionContext();
   DCHECK(context);
-  if (context->activeDOMObjectsAreSuspended() || context->isContextDestroyed())
+  if (context->isContextSuspended() || context->isContextDestroyed())
     return false;
 
   if (m_callback.isEmpty())
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/VoidCallbackFunctionTypedef.cpp b/third_party/WebKit/Source/bindings/tests/results/core/VoidCallbackFunctionTypedef.cpp
index 98d56a8..cfeb99b 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/VoidCallbackFunctionTypedef.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/VoidCallbackFunctionTypedef.cpp
@@ -39,7 +39,7 @@
 
   ExecutionContext* context = m_scriptState->getExecutionContext();
   DCHECK(context);
-  if (context->activeDOMObjectsAreSuspended() || context->isContextDestroyed())
+  if (context->isContextSuspended() || context->isContextDestroyed())
     return false;
 
   if (m_callback.isEmpty())
diff --git a/third_party/WebKit/Source/bindings/tests/results/modules/VoidCallbackFunctionModules.cpp b/third_party/WebKit/Source/bindings/tests/results/modules/VoidCallbackFunctionModules.cpp
index 892f87c..c18376a 100644
--- a/third_party/WebKit/Source/bindings/tests/results/modules/VoidCallbackFunctionModules.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/modules/VoidCallbackFunctionModules.cpp
@@ -39,7 +39,7 @@
 
   ExecutionContext* context = m_scriptState->getExecutionContext();
   DCHECK(context);
-  if (context->activeDOMObjectsAreSuspended() || context->isContextDestroyed())
+  if (context->isContextSuspended() || context->isContextDestroyed())
     return false;
 
   if (m_callback.isEmpty())
diff --git a/third_party/WebKit/Source/core/dom/ContextLifecycleNotifier.cpp b/third_party/WebKit/Source/core/dom/ContextLifecycleNotifier.cpp
index 22edb47..e9a4222 100644
--- a/third_party/WebKit/Source/core/dom/ContextLifecycleNotifier.cpp
+++ b/third_party/WebKit/Source/core/dom/ContextLifecycleNotifier.cpp
@@ -38,13 +38,13 @@
     if (observer->observerType() !=
         ContextLifecycleObserver::SuspendableObjectType)
       continue;
-    SuspendableObject* activeDOMObject =
+    SuspendableObject* suspendableObject =
         static_cast<SuspendableObject*>(observer);
 #if DCHECK_IS_ON()
-    DCHECK_EQ(activeDOMObject->getExecutionContext(), context());
-    DCHECK(activeDOMObject->suspendIfNeededCalled());
+    DCHECK_EQ(suspendableObject->getExecutionContext(), context());
+    DCHECK(suspendableObject->suspendIfNeededCalled());
 #endif
-    activeDOMObject->resume();
+    suspendableObject->resume();
   }
 }
 
@@ -54,26 +54,26 @@
     if (observer->observerType() !=
         ContextLifecycleObserver::SuspendableObjectType)
       continue;
-    SuspendableObject* activeDOMObject =
+    SuspendableObject* suspendableObject =
         static_cast<SuspendableObject*>(observer);
 #if DCHECK_IS_ON()
-    DCHECK_EQ(activeDOMObject->getExecutionContext(), context());
-    DCHECK(activeDOMObject->suspendIfNeededCalled());
+    DCHECK_EQ(suspendableObject->getExecutionContext(), context());
+    DCHECK(suspendableObject->suspendIfNeededCalled());
 #endif
-    activeDOMObject->suspend();
+    suspendableObject->suspend();
   }
 }
 
-unsigned ContextLifecycleNotifier::activeDOMObjectCount() const {
+unsigned ContextLifecycleNotifier::suspendableObjectCount() const {
   DCHECK(!isIteratingOverObservers());
-  unsigned activeDOMObjects = 0;
+  unsigned suspendableObjects = 0;
   for (ContextLifecycleObserver* observer : m_observers) {
     if (observer->observerType() !=
         ContextLifecycleObserver::SuspendableObjectType)
       continue;
-    activeDOMObjects++;
+    suspendableObjects++;
   }
-  return activeDOMObjects;
+  return suspendableObjects;
 }
 
 #if DCHECK_IS_ON()
@@ -83,9 +83,9 @@
     if (observer->observerType() !=
         ContextLifecycleObserver::SuspendableObjectType)
       continue;
-    SuspendableObject* activeDOMObject =
+    SuspendableObject* suspendableObject =
         static_cast<SuspendableObject*>(observer);
-    if (activeDOMObject == object)
+    if (suspendableObject == object)
       return true;
   }
   return false;
diff --git a/third_party/WebKit/Source/core/dom/ContextLifecycleNotifier.h b/third_party/WebKit/Source/core/dom/ContextLifecycleNotifier.h
index 4d1d775e..a0fe0c80 100644
--- a/third_party/WebKit/Source/core/dom/ContextLifecycleNotifier.h
+++ b/third_party/WebKit/Source/core/dom/ContextLifecycleNotifier.h
@@ -46,7 +46,7 @@
   void notifyResumingSuspendableObjects();
   void notifySuspendingSuspendableObjects();
 
-  unsigned activeDOMObjectCount() const;
+  unsigned suspendableObjectCount() const;
 
  protected:
   // Need a default constructor to link core and modules separately.
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp
index 196ca5c..c673093 100644
--- a/third_party/WebKit/Source/core/dom/Document.cpp
+++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -542,8 +542,7 @@
   // objects, else this new Document would have a new ExecutionContext which
   // suspended state would not match the one from the parent, and could start
   // loading resources ignoring the defersLoading flag.
-  DCHECK(!parentDocument() ||
-         !parentDocument()->activeDOMObjectsAreSuspended());
+  DCHECK(!parentDocument() || !parentDocument()->isContextSuspended());
 
 #ifndef NDEBUG
   liveDocumentSet().add(this);
diff --git a/third_party/WebKit/Source/core/dom/ExecutionContext.cpp b/third_party/WebKit/Source/core/dom/ExecutionContext.cpp
index 4d59b660..1ece34d 100644
--- a/third_party/WebKit/Source/core/dom/ExecutionContext.cpp
+++ b/third_party/WebKit/Source/core/dom/ExecutionContext.cpp
@@ -48,7 +48,7 @@
 ExecutionContext::ExecutionContext()
     : m_circularSequentialID(0),
       m_inDispatchErrorEvent(false),
-      m_activeDOMObjectsAreSuspended(false),
+      m_isContextSuspended(false),
       m_isContextDestroyed(false),
       m_windowInteractionTokens(0),
       m_referrerPolicy(ReferrerPolicyDefault) {}
@@ -56,14 +56,14 @@
 ExecutionContext::~ExecutionContext() {}
 
 void ExecutionContext::suspendSuspendableObjects() {
-  DCHECK(!m_activeDOMObjectsAreSuspended);
+  DCHECK(!m_isContextSuspended);
   notifySuspendingSuspendableObjects();
-  m_activeDOMObjectsAreSuspended = true;
+  m_isContextSuspended = true;
 }
 
 void ExecutionContext::resumeSuspendableObjects() {
-  DCHECK(m_activeDOMObjectsAreSuspended);
-  m_activeDOMObjectsAreSuspended = false;
+  DCHECK(m_isContextSuspended);
+  m_isContextSuspended = false;
   notifyResumingSuspendableObjects();
 }
 
@@ -88,7 +88,7 @@
   DCHECK(contains(object));
 #endif
   // Ensure all SuspendableObjects are suspended also newly created ones.
-  if (m_activeDOMObjectsAreSuspended)
+  if (m_isContextSuspended)
     object->suspend();
 }
 
diff --git a/third_party/WebKit/Source/core/dom/ExecutionContext.h b/third_party/WebKit/Source/core/dom/ExecutionContext.h
index 89ba2e1..470734e 100644
--- a/third_party/WebKit/Source/core/dom/ExecutionContext.h
+++ b/third_party/WebKit/Source/core/dom/ExecutionContext.h
@@ -141,9 +141,7 @@
   virtual void tasksWereSuspended() {}
   virtual void tasksWereResumed() {}
 
-  bool activeDOMObjectsAreSuspended() const {
-    return m_activeDOMObjectsAreSuspended;
-  }
+  bool isContextSuspended() const { return m_isContextSuspended; }
   bool isContextDestroyed() const { return m_isContextDestroyed; }
 
   // Called after the construction of an SuspendableObject to synchronize
@@ -200,7 +198,7 @@
   bool m_inDispatchErrorEvent;
   HeapVector<Member<ErrorEvent>> m_pendingExceptions;
 
-  bool m_activeDOMObjectsAreSuspended;
+  bool m_isContextSuspended;
   bool m_isContextDestroyed;
 
   Member<PublicURLManager> m_publicURLManager;
diff --git a/third_party/WebKit/Source/core/dom/IntersectionObserverController.cpp b/third_party/WebKit/Source/core/dom/IntersectionObserverController.cpp
index 409fb9c..68ec7e7 100644
--- a/third_party/WebKit/Source/core/dom/IntersectionObserverController.cpp
+++ b/third_party/WebKit/Source/core/dom/IntersectionObserverController.cpp
@@ -61,7 +61,7 @@
     m_pendingIntersectionObservers.clear();
     return;
   }
-  if (context->activeDOMObjectsAreSuspended()) {
+  if (context->isContextSuspended()) {
     m_callbackFiredWhileSuspended = true;
     return;
   }
diff --git a/third_party/WebKit/Source/core/dom/MutationObserver.cpp b/third_party/WebKit/Source/core/dom/MutationObserver.cpp
index 0c595bb1..9bf8da6 100644
--- a/third_party/WebKit/Source/core/dom/MutationObserver.cpp
+++ b/third_party/WebKit/Source/core/dom/MutationObserver.cpp
@@ -206,7 +206,7 @@
 
 bool MutationObserver::shouldBeSuspended() const {
   return m_callback->getExecutionContext() &&
-         m_callback->getExecutionContext()->activeDOMObjectsAreSuspended();
+         m_callback->getExecutionContext()->isContextSuspended();
 }
 
 void MutationObserver::cancelInspectorAsyncTasks() {
diff --git a/third_party/WebKit/Source/core/dom/SuspendableObject.cpp b/third_party/WebKit/Source/core/dom/SuspendableObject.cpp
index 5338ffd..e2f9b863 100644
--- a/third_party/WebKit/Source/core/dom/SuspendableObject.cpp
+++ b/third_party/WebKit/Source/core/dom/SuspendableObject.cpp
@@ -74,7 +74,7 @@
     return;
   }
 
-  if (context->activeDOMObjectsAreSuspended()) {
+  if (context->isContextSuspended()) {
     suspend();
     return;
   }
diff --git a/third_party/WebKit/Source/core/dom/SuspendableObjectTest.cpp b/third_party/WebKit/Source/core/dom/SuspendableObjectTest.cpp
index ab1fe49..5f975e2 100644
--- a/third_party/WebKit/Source/core/dom/SuspendableObjectTest.cpp
+++ b/third_party/WebKit/Source/core/dom/SuspendableObjectTest.cpp
@@ -60,50 +60,50 @@
 
   Document& srcDocument() const { return m_srcPageHolder->document(); }
   Document& destDocument() const { return m_destPageHolder->document(); }
-  MockSuspendableObject& activeDOMObject() { return *m_activeDOMObject; }
+  MockSuspendableObject& suspendableObject() { return *m_suspendableObject; }
 
  private:
   std::unique_ptr<DummyPageHolder> m_srcPageHolder;
   std::unique_ptr<DummyPageHolder> m_destPageHolder;
-  Persistent<MockSuspendableObject> m_activeDOMObject;
+  Persistent<MockSuspendableObject> m_suspendableObject;
 };
 
 SuspendableObjectTest::SuspendableObjectTest()
     : m_srcPageHolder(DummyPageHolder::create(IntSize(800, 600))),
       m_destPageHolder(DummyPageHolder::create(IntSize(800, 600))),
-      m_activeDOMObject(
+      m_suspendableObject(
           new MockSuspendableObject(&m_srcPageHolder->document())) {
-  m_activeDOMObject->suspendIfNeeded();
+  m_suspendableObject->suspendIfNeeded();
 }
 
 TEST_F(SuspendableObjectTest, NewContextObserved) {
-  unsigned initialSrcCount = srcDocument().activeDOMObjectCount();
-  unsigned initialDestCount = destDocument().activeDOMObjectCount();
+  unsigned initialSrcCount = srcDocument().suspendableObjectCount();
+  unsigned initialDestCount = destDocument().suspendableObjectCount();
 
-  EXPECT_CALL(activeDOMObject(), resume());
-  activeDOMObject().didMoveToNewExecutionContext(&destDocument());
+  EXPECT_CALL(suspendableObject(), resume());
+  suspendableObject().didMoveToNewExecutionContext(&destDocument());
 
-  EXPECT_EQ(initialSrcCount - 1, srcDocument().activeDOMObjectCount());
-  EXPECT_EQ(initialDestCount + 1, destDocument().activeDOMObjectCount());
+  EXPECT_EQ(initialSrcCount - 1, srcDocument().suspendableObjectCount());
+  EXPECT_EQ(initialDestCount + 1, destDocument().suspendableObjectCount());
 }
 
 TEST_F(SuspendableObjectTest, MoveToActiveDocument) {
-  EXPECT_CALL(activeDOMObject(), resume());
-  activeDOMObject().didMoveToNewExecutionContext(&destDocument());
+  EXPECT_CALL(suspendableObject(), resume());
+  suspendableObject().didMoveToNewExecutionContext(&destDocument());
 }
 
 TEST_F(SuspendableObjectTest, MoveToSuspendedDocument) {
   destDocument().suspendScheduledTasks();
 
-  EXPECT_CALL(activeDOMObject(), suspend());
-  activeDOMObject().didMoveToNewExecutionContext(&destDocument());
+  EXPECT_CALL(suspendableObject(), suspend());
+  suspendableObject().didMoveToNewExecutionContext(&destDocument());
 }
 
 TEST_F(SuspendableObjectTest, MoveToStoppedDocument) {
   destDocument().shutdown();
 
-  EXPECT_CALL(activeDOMObject(), contextDestroyed());
-  activeDOMObject().didMoveToNewExecutionContext(&destDocument());
+  EXPECT_CALL(suspendableObject(), contextDestroyed());
+  suspendableObject().didMoveToNewExecutionContext(&destDocument());
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/frame/DOMTimer.cpp b/third_party/WebKit/Source/core/frame/DOMTimer.cpp
index 228dcb82..2b2e2c6 100644
--- a/third_party/WebKit/Source/core/frame/DOMTimer.cpp
+++ b/third_party/WebKit/Source/core/frame/DOMTimer.cpp
@@ -135,7 +135,7 @@
   ExecutionContext* context = getExecutionContext();
   ASSERT(context);
   context->timers()->setTimerNestingLevel(m_nestingLevel);
-  ASSERT(!context->activeDOMObjectsAreSuspended());
+  DCHECK(!context->isContextSuspended());
   // Only the first execution of a multi-shot timer should get an affirmative
   // user gesture indicator.
   UserGestureIndicator gestureIndicator(m_userGestureToken.release());
diff --git a/third_party/WebKit/Source/core/frame/DeviceSingleWindowEventController.cpp b/third_party/WebKit/Source/core/frame/DeviceSingleWindowEventController.cpp
index 15d2b6d..44485d89 100644
--- a/third_party/WebKit/Source/core/frame/DeviceSingleWindowEventController.cpp
+++ b/third_party/WebKit/Source/core/frame/DeviceSingleWindowEventController.cpp
@@ -25,7 +25,7 @@
 }
 
 void DeviceSingleWindowEventController::dispatchDeviceEvent(Event* event) {
-  if (!document().domWindow() || document().activeDOMObjectsAreSuspended() ||
+  if (!document().domWindow() || document().isContextSuspended() ||
       document().isContextDestroyed())
     return;
 
diff --git a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
index d03da2e..ececc00 100644
--- a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
@@ -362,15 +362,27 @@
                                    Document& document)
     : HTMLElement(tagName, document),
       SuspendableObject(&document),
-      m_loadTimer(this, &HTMLMediaElement::loadTimerFired),
-      m_progressEventTimer(this, &HTMLMediaElement::progressEventTimerFired),
-      m_playbackProgressTimer(this,
-                              &HTMLMediaElement::playbackProgressTimerFired),
-      m_audioTracksTimer(this, &HTMLMediaElement::audioTracksTimerFired),
+      m_loadTimer(TaskRunnerHelper::get(TaskType::Unthrottled, &document),
+                  this,
+                  &HTMLMediaElement::loadTimerFired),
+      m_progressEventTimer(
+          TaskRunnerHelper::get(TaskType::Unthrottled, &document),
+          this,
+          &HTMLMediaElement::progressEventTimerFired),
+      m_playbackProgressTimer(
+          TaskRunnerHelper::get(TaskType::Unthrottled, &document),
+          this,
+          &HTMLMediaElement::playbackProgressTimerFired),
+      m_audioTracksTimer(
+          TaskRunnerHelper::get(TaskType::Unthrottled, &document),
+          this,
+          &HTMLMediaElement::audioTracksTimerFired),
       m_viewportFillDebouncerTimer(
+          TaskRunnerHelper::get(TaskType::Unthrottled, &document),
           this,
           &HTMLMediaElement::viewportFillDebouncerTimerFired),
       m_checkViewportIntersectionTimer(
+          TaskRunnerHelper::get(TaskType::Unthrottled, &document),
           this,
           &HTMLMediaElement::checkViewportIntersectionTimerFired),
       m_playedTimeRanges(),
@@ -466,6 +478,19 @@
 void HTMLMediaElement::didMoveToNewDocument(Document& oldDocument) {
   BLINK_MEDIA_LOG << "didMoveToNewDocument(" << (void*)this << ")";
 
+  m_loadTimer.moveToNewTaskRunner(
+      TaskRunnerHelper::get(TaskType::Unthrottled, &document()));
+  m_progressEventTimer.moveToNewTaskRunner(
+      TaskRunnerHelper::get(TaskType::Unthrottled, &document()));
+  m_playbackProgressTimer.moveToNewTaskRunner(
+      TaskRunnerHelper::get(TaskType::Unthrottled, &document()));
+  m_audioTracksTimer.moveToNewTaskRunner(
+      TaskRunnerHelper::get(TaskType::Unthrottled, &document()));
+  m_viewportFillDebouncerTimer.moveToNewTaskRunner(
+      TaskRunnerHelper::get(TaskType::Unthrottled, &document()));
+  m_checkViewportIntersectionTimer.moveToNewTaskRunner(
+      TaskRunnerHelper::get(TaskType::Unthrottled, &document()));
+
   m_autoplayUmaHelper->didMoveToNewDocument(oldDocument);
   // If any experiment is enabled, then we want to enable a user gesture by
   // default, otherwise the experiment does nothing.
diff --git a/third_party/WebKit/Source/core/html/HTMLMediaElement.h b/third_party/WebKit/Source/core/html/HTMLMediaElement.h
index 05de20ea..37e4ce1 100644
--- a/third_party/WebKit/Source/core/html/HTMLMediaElement.h
+++ b/third_party/WebKit/Source/core/html/HTMLMediaElement.h
@@ -553,12 +553,13 @@
 
   void viewportFillDebouncerTimerFired(TimerBase*);
 
-  UnthrottledThreadTimer<HTMLMediaElement> m_loadTimer;
-  UnthrottledThreadTimer<HTMLMediaElement> m_progressEventTimer;
-  UnthrottledThreadTimer<HTMLMediaElement> m_playbackProgressTimer;
-  UnthrottledThreadTimer<HTMLMediaElement> m_audioTracksTimer;
-  UnthrottledThreadTimer<HTMLMediaElement> m_viewportFillDebouncerTimer;
-  UnthrottledThreadTimer<HTMLMediaElement> m_checkViewportIntersectionTimer;
+  TaskRunnerTimer<HTMLMediaElement> m_loadTimer;
+  TaskRunnerTimer<HTMLMediaElement> m_progressEventTimer;
+  TaskRunnerTimer<HTMLMediaElement> m_playbackProgressTimer;
+  TaskRunnerTimer<HTMLMediaElement> m_audioTracksTimer;
+  TaskRunnerTimer<HTMLMediaElement> m_viewportFillDebouncerTimer;
+  TaskRunnerTimer<HTMLMediaElement> m_checkViewportIntersectionTimer;
+
   Member<TimeRanges> m_playedTimeRanges;
   Member<GenericEventQueue> m_asyncEventQueue;
 
diff --git a/third_party/WebKit/Source/core/layout/LayoutObject.cpp b/third_party/WebKit/Source/core/layout/LayoutObject.cpp
index 290a52f..574b9fa 100644
--- a/third_party/WebKit/Source/core/layout/LayoutObject.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutObject.cpp
@@ -3122,7 +3122,7 @@
     return false;
 
   // We will not render a new image when SuspendableObjects is suspended
-  if (document().activeDOMObjectsAreSuspended())
+  if (document().isContextSuspended())
     return false;
 
   // If we're not in a window (i.e., we're dormant from being in a background
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_length_utils.cc b/third_party/WebKit/Source/core/layout/ng/ng_length_utils.cc
index 0802881..05b2737 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_length_utils.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_length_utils.cc
@@ -5,6 +5,7 @@
 #include "core/layout/ng/ng_length_utils.h"
 
 #include "core/layout/ng/ng_constraint_space.h"
+#include "core/layout/ng/ng_constraint_space_builder.h"
 #include "core/layout/ng/ng_fragment_base.h"
 #include "core/style/ComputedStyle.h"
 #include "platform/LayoutUnit.h"
@@ -28,6 +29,11 @@
          style.logicalMaxWidth().isIntrinsic();
 }
 
+bool NeedMinAndMaxContentSizesForContentContribution(
+    const ComputedStyle& style) {
+  return NeedMinAndMaxContentSizes(style) || style.logicalWidth().isAuto();
+}
+
 LayoutUnit ResolveInlineLength(
     const NGConstraintSpace& constraint_space,
     const ComputedStyle& style,
@@ -175,6 +181,52 @@
   }
 }
 
+MinAndMaxContentSizes ComputeMinAndMaxContentContribution(
+    const ComputedStyle& style,
+    const WTF::Optional<MinAndMaxContentSizes>& min_and_max) {
+  // Synthesize a zero-sized constraint space for passing to
+  // ResolveInlineLength.
+  NGWritingMode writing_mode = FromPlatformWritingMode(style.getWritingMode());
+  NGConstraintSpaceBuilder builder(writing_mode);
+  NGConstraintSpace* space = builder.ToConstraintSpace();
+
+  MinAndMaxContentSizes computed_sizes;
+  Length inline_size = style.logicalWidth();
+  if (inline_size.isAuto()) {
+    CHECK(min_and_max.has_value());
+    NGBoxStrut border_and_padding =
+        ComputeBorders(style) + ComputePadding(*space, style);
+    computed_sizes.min_content =
+        min_and_max->min_content + border_and_padding.InlineSum();
+    computed_sizes.max_content =
+        min_and_max->max_content + border_and_padding.InlineSum();
+  } else {
+    computed_sizes.min_content = computed_sizes.max_content =
+        ResolveInlineLength(*space, style, min_and_max, inline_size,
+                            LengthResolveType::kContentSize);
+  }
+
+  Length max_length = style.logicalMaxWidth();
+  if (!max_length.isMaxSizeNone()) {
+    LayoutUnit max = ResolveInlineLength(*space, style, min_and_max, max_length,
+                                         LengthResolveType::kMaxSize);
+    computed_sizes.min_content = std::min(computed_sizes.min_content, max);
+    computed_sizes.max_content = std::min(computed_sizes.max_content, max);
+  }
+
+  LayoutUnit min =
+      ResolveInlineLength(*space, style, min_and_max, style.logicalMinWidth(),
+                          LengthResolveType::kMinSize);
+  computed_sizes.min_content = std::max(computed_sizes.min_content, min);
+  computed_sizes.max_content = std::max(computed_sizes.max_content, min);
+
+  NGBoxStrut margins =
+      ComputeMargins(*space, style, writing_mode, style.direction());
+  computed_sizes.min_content += margins.InlineSum();
+  computed_sizes.max_content += margins.InlineSum();
+  return computed_sizes;
+}
+
 LayoutUnit ComputeInlineSizeForFragment(
     const NGConstraintSpace& space,
     const ComputedStyle& style,
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_length_utils.h b/third_party/WebKit/Source/core/layout/ng/ng_length_utils.h
index 6d5eb70..9e67b62 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_length_utils.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_length_utils.h
@@ -35,6 +35,11 @@
 // MinAndMaxContentSizes struct to those functions.
 CORE_EXPORT bool NeedMinAndMaxContentSizes(const ComputedStyle&);
 
+// Like NeedMinAndMaxContentSizes, but for use when calling
+// ComputeMinAndMaxContentContribution.
+CORE_EXPORT bool NeedMinAndMaxContentSizesForContentContribution(
+    const ComputedStyle&);
+
 // Convert an inline-axis length to a layout unit using the given constraint
 // space.
 CORE_EXPORT LayoutUnit
@@ -52,6 +57,17 @@
                                           LayoutUnit content_size,
                                           LengthResolveType);
 
+// For the given style and min/max content sizes, computes the min and max
+// content contribution (https://drafts.csswg.org/css-sizing/#contributions).
+// This is similar to ComputeInlineSizeForFragment except that it does not
+// require a constraint space (percentage sizes as well as auto margins compute
+// to zero) and that an auto inline size resolves to the respective min/max
+// content size.
+// Also, the min/max contribution does include the inline margins as well.
+CORE_EXPORT MinAndMaxContentSizes ComputeMinAndMaxContentContribution(
+    const ComputedStyle&,
+    const WTF::Optional<MinAndMaxContentSizes>&);
+
 // Resolves the given length to a layout unit, constraining it by the min
 // logical width and max logical width properties from the ComputedStyle
 // object.
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_length_utils_test.cc b/third_party/WebKit/Source/core/layout/ng/ng_length_utils_test.cc
index b3a9ef8..9714710 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_length_utils_test.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_length_utils_test.cc
@@ -122,6 +122,77 @@
                                LengthResolveType::kContentSize));
 }
 
+TEST_F(NGLengthUtilsTest, testComputeContentContribution) {
+  MinAndMaxContentSizes sizes;
+  sizes.min_content = LayoutUnit(30);
+  sizes.max_content = LayoutUnit(40);
+
+  MinAndMaxContentSizes expected{LayoutUnit(), LayoutUnit()};
+  style_->setLogicalWidth(Length(30, Percent));
+  EXPECT_EQ(expected, ComputeMinAndMaxContentContribution(*style_, sizes));
+
+  style_->setLogicalWidth(Length(FillAvailable));
+  EXPECT_EQ(expected, ComputeMinAndMaxContentContribution(*style_, sizes));
+
+  expected = MinAndMaxContentSizes{LayoutUnit(150), LayoutUnit(150)};
+  style_->setLogicalWidth(Length(150, Fixed));
+  EXPECT_EQ(expected, ComputeMinAndMaxContentContribution(*style_, sizes));
+
+  expected = sizes;
+  style_->setLogicalWidth(Length(Auto));
+  EXPECT_EQ(expected, ComputeMinAndMaxContentContribution(*style_, sizes));
+
+  expected = MinAndMaxContentSizes{LayoutUnit(430), LayoutUnit(440)};
+  style_->setPaddingLeft(Length(400, Fixed));
+  EXPECT_EQ(expected, ComputeMinAndMaxContentContribution(*style_, sizes));
+
+  expected = MinAndMaxContentSizes{LayoutUnit(100), LayoutUnit(100)};
+  style_->setPaddingLeft(Length(0, Fixed));
+  style_->setLogicalWidth(Length(CalculationValue::create(
+      PixelsAndPercent(100, -10), ValueRangeNonNegative)));
+  EXPECT_EQ(expected, ComputeMinAndMaxContentContribution(*style_, sizes));
+
+  expected = MinAndMaxContentSizes{LayoutUnit(30), LayoutUnit(35)};
+  style_->setLogicalWidth(Length(Auto));
+  style_->setMaxWidth(Length(35, Fixed));
+  EXPECT_EQ(expected, ComputeMinAndMaxContentContribution(*style_, sizes));
+
+  expected = MinAndMaxContentSizes{LayoutUnit(80), LayoutUnit(80)};
+  style_->setLogicalWidth(Length(50, Fixed));
+  style_->setMinWidth(Length(80, Fixed));
+  EXPECT_EQ(expected, ComputeMinAndMaxContentContribution(*style_, sizes));
+
+  expected = MinAndMaxContentSizes{LayoutUnit(150), LayoutUnit(150)};
+  style_ = ComputedStyle::create();
+  style_->setLogicalWidth(Length(100, Fixed));
+  style_->setPaddingLeft(Length(50, Fixed));
+  EXPECT_EQ(expected, ComputeMinAndMaxContentContribution(*style_, sizes));
+
+  expected = MinAndMaxContentSizes{LayoutUnit(100), LayoutUnit(100)};
+  style_->setBoxSizing(BoxSizingBorderBox);
+  EXPECT_EQ(expected, ComputeMinAndMaxContentContribution(*style_, sizes));
+
+  // Content size should never be below zero, even with box-sizing: border-box
+  // and a large padding...
+  expected = MinAndMaxContentSizes{LayoutUnit(400), LayoutUnit(400)};
+  style_->setPaddingLeft(Length(400, Fixed));
+  EXPECT_EQ(expected, ComputeMinAndMaxContentContribution(*style_, sizes));
+
+  expected.min_content = expected.max_content =
+      sizes.min_content + LayoutUnit(400);
+  style_->setLogicalWidth(Length(MinContent));
+  EXPECT_EQ(expected, ComputeMinAndMaxContentContribution(*style_, sizes));
+  style_->setLogicalWidth(Length(100, Fixed));
+  style_->setMaxWidth(Length(MaxContent));
+  // Due to padding and box-sizing, width computes to 400px and max-width to
+  // 440px, so the result is 400.
+  expected = MinAndMaxContentSizes{LayoutUnit(400), LayoutUnit(400)};
+  EXPECT_EQ(expected, ComputeMinAndMaxContentContribution(*style_, sizes));
+  expected = MinAndMaxContentSizes{LayoutUnit(40), LayoutUnit(40)};
+  style_->setPaddingLeft(Length(0, Fixed));
+  EXPECT_EQ(expected, ComputeMinAndMaxContentContribution(*style_, sizes));
+}
+
 TEST_F(NGLengthUtilsTest, testComputeInlineSizeForFragment) {
   MinAndMaxContentSizes sizes;
   sizes.min_content = LayoutUnit(30);
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_units.cc b/third_party/WebKit/Source/core/layout/ng/ng_units.cc
index fae5e5de..1a4eec73 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_units.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_units.cc
@@ -11,6 +11,11 @@
   return std::min(max_content, std::max(min_content, available_size));
 }
 
+bool MinAndMaxContentSizes::operator==(
+    const MinAndMaxContentSizes& other) const {
+  return min_content == other.min_content && max_content == other.max_content;
+}
+
 NGPhysicalSize NGLogicalSize::ConvertToPhysical(NGWritingMode mode) const {
   return mode == kHorizontalTopBottom ? NGPhysicalSize(inline_size, block_size)
                                       : NGPhysicalSize(block_size, inline_size);
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_units.h b/third_party/WebKit/Source/core/layout/ng/ng_units.h
index ea2eec5..235bf80 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_units.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_units.h
@@ -22,8 +22,14 @@
   LayoutUnit min_content;
   LayoutUnit max_content;
   LayoutUnit ShrinkToFit(LayoutUnit available_size) const;
+  bool operator==(const MinAndMaxContentSizes& other) const;
 };
 
+inline std::ostream& operator<<(std::ostream& stream,
+                                const MinAndMaxContentSizes& value) {
+  return stream << "(" << value.min_content << ", " << value.max_content << ")";
+}
+
 struct NGLogicalSize {
   NGLogicalSize() {}
   NGLogicalSize(LayoutUnit inline_size, LayoutUnit block_size)
diff --git a/third_party/WebKit/Source/core/loader/ImageLoader.cpp b/third_party/WebKit/Source/core/loader/ImageLoader.cpp
index 3542eea7..dc36dc0 100644
--- a/third_party/WebKit/Source/core/loader/ImageLoader.cpp
+++ b/third_party/WebKit/Source/core/loader/ImageLoader.cpp
@@ -108,7 +108,7 @@
     v8::HandleScope scope(isolate);
     // If we're invoked from C++ without a V8 context on the stack, we should
     // run the microtask in the context of the element's document's main world.
-    if (ScriptState::hasCurrentScriptState(isolate)) {
+    if (!isolate->GetCurrentContext().IsEmpty()) {
       m_scriptState = ScriptState::current(isolate);
     } else {
       m_scriptState =
diff --git a/third_party/WebKit/Source/core/loader/PingLoader.cpp b/third_party/WebKit/Source/core/loader/PingLoader.cpp
index 0d85e4f..aa216f5 100644
--- a/third_party/WebKit/Source/core/loader/PingLoader.cpp
+++ b/third_party/WebKit/Source/core/loader/PingLoader.cpp
@@ -31,6 +31,7 @@
 
 #include "core/loader/PingLoader.h"
 
+#include "core/dom/ContextLifecycleObserver.h"
 #include "core/dom/DOMArrayBufferView.h"
 #include "core/dom/Document.h"
 #include "core/dom/SecurityContext.h"
@@ -187,7 +188,9 @@
 };
 
 class PingLoaderImpl : public GarbageCollectedFinalized<PingLoaderImpl>,
+                       public ContextClient,
                        private WebURLLoaderClient {
+  USING_GARBAGE_COLLECTED_MIXIN(PingLoaderImpl);
   WTF_MAKE_NONCOPYABLE(PingLoaderImpl);
 
  public:
@@ -214,7 +217,6 @@
 
   void didFailLoading(LocalFrame*);
 
-  WeakMember<LocalFrame> m_frame;
   std::unique_ptr<WebURLLoader> m_loader;
   Timer<PingLoaderImpl> m_timeout;
   String m_url;
@@ -232,7 +234,7 @@
                                const AtomicString& initiator,
                                StoredCredentials credentialsAllowed,
                                bool isBeacon)
-    : m_frame(frame),
+    : ContextClient(frame),
       m_timeout(this, &PingLoaderImpl::timeout),
       m_url(request.url()),
       m_identifier(createUniqueIdentifier()),
@@ -313,9 +315,9 @@
   if (!CrossOriginAccessControl::handleRedirect(
           m_origin, newRequest, redirectResponse, AllowStoredCredentials,
           options, errorDescription)) {
-    if (m_frame) {
-      if (m_frame->document()) {
-        m_frame->document()->addConsoleMessage(ConsoleMessage::create(
+    if (frame()) {
+      if (frame()->document()) {
+        frame()->document()->addConsoleMessage(ConsoleMessage::create(
             JSMessageSource, ErrorMessageLevel, errorDescription));
       }
     }
@@ -331,31 +333,31 @@
 }
 
 void PingLoaderImpl::didReceiveResponse(const WebURLResponse& response) {
-  if (m_frame) {
+  if (frame()) {
     TRACE_EVENT1("devtools.timeline", "ResourceFinish", "data",
                  InspectorResourceFinishEvent::data(m_identifier, 0, true));
     const ResourceResponse& resourceResponse = response.toResourceResponse();
     InspectorInstrumentation::didReceiveResourceResponse(
-        m_frame, m_identifier, 0, resourceResponse, 0);
-    didFailLoading(m_frame);
+        frame(), m_identifier, 0, resourceResponse, 0);
+    didFailLoading(frame());
   }
   dispose();
 }
 
 void PingLoaderImpl::didReceiveData(const char*, int) {
-  if (m_frame) {
+  if (frame()) {
     TRACE_EVENT1("devtools.timeline", "ResourceFinish", "data",
                  InspectorResourceFinishEvent::data(m_identifier, 0, true));
-    didFailLoading(m_frame);
+    didFailLoading(frame());
   }
   dispose();
 }
 
 void PingLoaderImpl::didFinishLoading(double, int64_t, int64_t) {
-  if (m_frame) {
+  if (frame()) {
     TRACE_EVENT1("devtools.timeline", "ResourceFinish", "data",
                  InspectorResourceFinishEvent::data(m_identifier, 0, true));
-    didFailLoading(m_frame);
+    didFailLoading(frame());
   }
   dispose();
 }
@@ -363,19 +365,19 @@
 void PingLoaderImpl::didFail(const WebURLError& resourceError,
                              int64_t,
                              int64_t) {
-  if (m_frame) {
+  if (frame()) {
     TRACE_EVENT1("devtools.timeline", "ResourceFinish", "data",
                  InspectorResourceFinishEvent::data(m_identifier, 0, true));
-    didFailLoading(m_frame);
+    didFailLoading(frame());
   }
   dispose();
 }
 
 void PingLoaderImpl::timeout(TimerBase*) {
-  if (m_frame) {
+  if (frame()) {
     TRACE_EVENT1("devtools.timeline", "ResourceFinish", "data",
                  InspectorResourceFinishEvent::data(m_identifier, 0, true));
-    didFailLoading(m_frame);
+    didFailLoading(frame());
   }
   dispose();
 }
@@ -388,7 +390,7 @@
 }
 
 DEFINE_TRACE(PingLoaderImpl) {
-  visitor->trace(m_frame);
+  ContextClient::trace(visitor);
 }
 
 void finishPingRequestInitialization(
diff --git a/third_party/WebKit/Source/core/streams/ReadableStream.js b/third_party/WebKit/Source/core/streams/ReadableStream.js
index c410099f..1586b0e 100644
--- a/third_party/WebKit/Source/core/streams/ReadableStream.js
+++ b/third_party/WebKit/Source/core/streams/ReadableStream.js
@@ -506,6 +506,7 @@
     }
 
     v8.rejectPromise(reader[_closedPromise], e);
+    v8.markPromiseAsHandled(reader[_closedPromise]);
   }
 
   function ReadableStreamClose(stream) {
@@ -588,7 +589,8 @@
         break;
       case STATE_ERRORED:
         reader[_closedPromise] = Promise_reject(stream[_storedError]);
-      break;
+        v8.markPromiseAsHandled(reader[_closedPromise]);
+        break;
     }
   }
 
@@ -608,6 +610,7 @@
     } else {
       reader[_closedPromise] = Promise_reject(new TypeError(errReleasedReaderClosedPromise));
     }
+    v8.markPromiseAsHandled(reader[_closedPromise]);
 
     reader[_ownerReadableStream][_reader] = undefined;
     reader[_ownerReadableStream] = undefined;
diff --git a/third_party/WebKit/Source/core/testing/Internals.cpp b/third_party/WebKit/Source/core/testing/Internals.cpp
index 4517fd0..1e8ba46 100644
--- a/third_party/WebKit/Source/core/testing/Internals.cpp
+++ b/third_party/WebKit/Source/core/testing/Internals.cpp
@@ -1481,9 +1481,9 @@
   overrideUserPreferredLanguages(atomicLanguages);
 }
 
-unsigned Internals::activeDOMObjectCount(Document* document) {
+unsigned Internals::suspendableObjectCount(Document* document) {
   DCHECK(document);
-  return document->activeDOMObjectCount();
+  return document->suspendableObjectCount();
 }
 
 static unsigned eventHandlerCount(
diff --git a/third_party/WebKit/Source/core/testing/Internals.h b/third_party/WebKit/Source/core/testing/Internals.h
index 72e2656..f5ac99d 100644
--- a/third_party/WebKit/Source/core/testing/Internals.h
+++ b/third_party/WebKit/Source/core/testing/Internals.h
@@ -258,7 +258,7 @@
   Vector<AtomicString> userPreferredLanguages() const;
   void setUserPreferredLanguages(const Vector<String>&);
 
-  unsigned activeDOMObjectCount(Document*);
+  unsigned suspendableObjectCount(Document*);
   unsigned wheelEventHandlerCount(Document*);
   unsigned scrollEventHandlerCount(Document*);
   unsigned touchStartOrMoveEventHandlerCount(Document*);
diff --git a/third_party/WebKit/Source/core/testing/Internals.idl b/third_party/WebKit/Source/core/testing/Internals.idl
index 0b863b7..0c056a4 100644
--- a/third_party/WebKit/Source/core/testing/Internals.idl
+++ b/third_party/WebKit/Source/core/testing/Internals.idl
@@ -145,7 +145,7 @@
     sequence<DOMString> userPreferredLanguages();
     void setUserPreferredLanguages(sequence<DOMString> languages);
 
-    unsigned long activeDOMObjectCount(Document document);
+    unsigned long suspendableObjectCount(Document document);
     unsigned long wheelEventHandlerCount(Document document);
     unsigned long scrollEventHandlerCount(Document document);
     unsigned long touchStartOrMoveEventHandlerCount(Document document);
diff --git a/third_party/WebKit/Source/core/timing/DOMWindowPerformance.cpp b/third_party/WebKit/Source/core/timing/DOMWindowPerformance.cpp
index 08ee22c..99455c94d 100644
--- a/third_party/WebKit/Source/core/timing/DOMWindowPerformance.cpp
+++ b/third_party/WebKit/Source/core/timing/DOMWindowPerformance.cpp
@@ -11,13 +11,13 @@
 namespace blink {
 
 DOMWindowPerformance::DOMWindowPerformance(LocalDOMWindow& window)
-    : DOMWindowProperty(window.frame()), m_window(&window) {}
+    : ContextClient(window.frame()), m_window(&window) {}
 
 DEFINE_TRACE(DOMWindowPerformance) {
   visitor->trace(m_window);
   visitor->trace(m_performance);
   Supplement<LocalDOMWindow>::trace(visitor);
-  DOMWindowProperty::trace(visitor);
+  ContextClient::trace(visitor);
 }
 
 // static
diff --git a/third_party/WebKit/Source/core/timing/DOMWindowPerformance.h b/third_party/WebKit/Source/core/timing/DOMWindowPerformance.h
index d68152e..b2c0d5a2 100644
--- a/third_party/WebKit/Source/core/timing/DOMWindowPerformance.h
+++ b/third_party/WebKit/Source/core/timing/DOMWindowPerformance.h
@@ -6,7 +6,7 @@
 #define DOMWindowPerformance_h
 
 #include "core/CoreExport.h"
-#include "core/frame/DOMWindowProperty.h"
+#include "core/dom/ContextLifecycleObserver.h"
 #include "platform/Supplementable.h"
 #include "platform/heap/Handle.h"
 #include "wtf/Noncopyable.h"
@@ -20,7 +20,7 @@
 class CORE_EXPORT DOMWindowPerformance final
     : public GarbageCollected<DOMWindowPerformance>,
       public Supplement<LocalDOMWindow>,
-      public DOMWindowProperty {
+      public ContextClient {
   USING_GARBAGE_COLLECTED_MIXIN(DOMWindowPerformance);
   WTF_MAKE_NONCOPYABLE(DOMWindowPerformance);
 
diff --git a/third_party/WebKit/Source/core/timing/PerformanceNavigation.cpp b/third_party/WebKit/Source/core/timing/PerformanceNavigation.cpp
index 3bcfef1..dce72f9a 100644
--- a/third_party/WebKit/Source/core/timing/PerformanceNavigation.cpp
+++ b/third_party/WebKit/Source/core/timing/PerformanceNavigation.cpp
@@ -40,7 +40,7 @@
 namespace blink {
 
 PerformanceNavigation::PerformanceNavigation(LocalFrame* frame)
-    : DOMWindowProperty(frame) {}
+    : ContextClient(frame) {}
 
 unsigned short PerformanceNavigation::type() const {
   if (!frame())
@@ -84,7 +84,7 @@
 }
 
 DEFINE_TRACE(PerformanceNavigation) {
-  DOMWindowProperty::trace(visitor);
+  ContextClient::trace(visitor);
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/timing/PerformanceNavigation.h b/third_party/WebKit/Source/core/timing/PerformanceNavigation.h
index 13bd19b..a80a76b9 100644
--- a/third_party/WebKit/Source/core/timing/PerformanceNavigation.h
+++ b/third_party/WebKit/Source/core/timing/PerformanceNavigation.h
@@ -33,7 +33,7 @@
 
 #include "bindings/core/v8/ScriptWrappable.h"
 #include "core/CoreExport.h"
-#include "core/frame/DOMWindowProperty.h"
+#include "core/dom/ContextLifecycleObserver.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
@@ -46,7 +46,7 @@
 class CORE_EXPORT PerformanceNavigation final
     : public GarbageCollected<PerformanceNavigation>,
       public ScriptWrappable,
-      public DOMWindowProperty {
+      public ContextClient {
   DEFINE_WRAPPERTYPEINFO();
   USING_GARBAGE_COLLECTED_MIXIN(PerformanceNavigation);
 
diff --git a/third_party/WebKit/Source/core/timing/PerformanceObserver.cpp b/third_party/WebKit/Source/core/timing/PerformanceObserver.cpp
index a0148f0..27c6d2ca 100644
--- a/third_party/WebKit/Source/core/timing/PerformanceObserver.cpp
+++ b/third_party/WebKit/Source/core/timing/PerformanceObserver.cpp
@@ -77,7 +77,7 @@
 }
 
 bool PerformanceObserver::shouldBeSuspended() const {
-  return m_executionContext->activeDOMObjectsAreSuspended();
+  return m_executionContext->isContextSuspended();
 }
 
 void PerformanceObserver::deliver() {
diff --git a/third_party/WebKit/Source/core/timing/PerformanceTiming.cpp b/third_party/WebKit/Source/core/timing/PerformanceTiming.cpp
index aa6fd3c..d659edee 100644
--- a/third_party/WebKit/Source/core/timing/PerformanceTiming.cpp
+++ b/third_party/WebKit/Source/core/timing/PerformanceTiming.cpp
@@ -59,7 +59,7 @@
 }
 
 PerformanceTiming::PerformanceTiming(LocalFrame* frame)
-    : DOMWindowProperty(frame) {}
+    : ContextClient(frame) {}
 
 unsigned long long PerformanceTiming::navigationStart() const {
   DocumentLoadTiming* timing = documentLoadTiming();
@@ -538,7 +538,7 @@
 }
 
 DEFINE_TRACE(PerformanceTiming) {
-  DOMWindowProperty::trace(visitor);
+  ContextClient::trace(visitor);
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/timing/PerformanceTiming.h b/third_party/WebKit/Source/core/timing/PerformanceTiming.h
index 472c94a..986f3ff 100644
--- a/third_party/WebKit/Source/core/timing/PerformanceTiming.h
+++ b/third_party/WebKit/Source/core/timing/PerformanceTiming.h
@@ -33,7 +33,7 @@
 
 #include "bindings/core/v8/ScriptWrappable.h"
 #include "core/CoreExport.h"
-#include "core/frame/DOMWindowProperty.h"
+#include "core/dom/ContextLifecycleObserver.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
@@ -53,7 +53,7 @@
 class CORE_EXPORT PerformanceTiming final
     : public GarbageCollected<PerformanceTiming>,
       public ScriptWrappable,
-      public DOMWindowProperty {
+      public ContextClient {
   DEFINE_WRAPPERTYPEINFO();
   USING_GARBAGE_COLLECTED_MIXIN(PerformanceTiming);
 
diff --git a/third_party/WebKit/Source/modules/battery/BatteryManager.cpp b/third_party/WebKit/Source/modules/battery/BatteryManager.cpp
index 09d9709..885ac95 100644
--- a/third_party/WebKit/Source/modules/battery/BatteryManager.cpp
+++ b/third_party/WebKit/Source/modules/battery/BatteryManager.cpp
@@ -70,8 +70,7 @@
 
   Document* document = toDocument(getExecutionContext());
   DCHECK(document);
-  if (document->activeDOMObjectsAreSuspended() ||
-      document->isContextDestroyed())
+  if (document->isContextSuspended() || document->isContextDestroyed())
     return;
 
   if (m_batteryStatus.charging() != oldStatus.charging())
diff --git a/third_party/WebKit/Source/modules/beacon/NavigatorBeacon.cpp b/third_party/WebKit/Source/modules/beacon/NavigatorBeacon.cpp
index 33cae5d1..74dbda3 100644
--- a/third_party/WebKit/Source/modules/beacon/NavigatorBeacon.cpp
+++ b/third_party/WebKit/Source/modules/beacon/NavigatorBeacon.cpp
@@ -21,12 +21,12 @@
 namespace blink {
 
 NavigatorBeacon::NavigatorBeacon(Navigator& navigator)
-    : DOMWindowProperty(navigator.frame()), m_transmittedBytes(0) {}
+    : ContextClient(navigator.frame()), m_transmittedBytes(0) {}
 
 NavigatorBeacon::~NavigatorBeacon() {}
 
 DEFINE_TRACE(NavigatorBeacon) {
-  DOMWindowProperty::trace(visitor);
+  ContextClient::trace(visitor);
   Supplement<Navigator>::trace(visitor);
 }
 
diff --git a/third_party/WebKit/Source/modules/beacon/NavigatorBeacon.h b/third_party/WebKit/Source/modules/beacon/NavigatorBeacon.h
index abcd58e..52b2f9c1 100644
--- a/third_party/WebKit/Source/modules/beacon/NavigatorBeacon.h
+++ b/third_party/WebKit/Source/modules/beacon/NavigatorBeacon.h
@@ -5,7 +5,7 @@
 #ifndef NavigatorBeacon_h
 #define NavigatorBeacon_h
 
-#include "core/frame/DOMWindowProperty.h"
+#include "core/dom/ContextLifecycleObserver.h"
 #include "core/frame/Navigator.h"
 #include "platform/Supplementable.h"
 #include "platform/heap/Handle.h"
@@ -18,7 +18,7 @@
 class ArrayBufferViewOrBlobOrStringOrFormData;
 
 class NavigatorBeacon final : public GarbageCollectedFinalized<NavigatorBeacon>,
-                              public DOMWindowProperty,
+                              public ContextClient,
                               public Supplement<Navigator> {
   USING_GARBAGE_COLLECTED_MIXIN(NavigatorBeacon);
 
diff --git a/third_party/WebKit/Source/modules/credentialmanager/NavigatorCredentials.cpp b/third_party/WebKit/Source/modules/credentialmanager/NavigatorCredentials.cpp
index 00c73f06..dbda6a66 100644
--- a/third_party/WebKit/Source/modules/credentialmanager/NavigatorCredentials.cpp
+++ b/third_party/WebKit/Source/modules/credentialmanager/NavigatorCredentials.cpp
@@ -13,7 +13,7 @@
 namespace blink {
 
 NavigatorCredentials::NavigatorCredentials(Navigator& navigator)
-    : DOMWindowProperty(navigator.frame()) {}
+    : ContextClient(navigator.frame()) {}
 
 NavigatorCredentials& NavigatorCredentials::from(Navigator& navigator) {
   NavigatorCredentials* supplement = static_cast<NavigatorCredentials*>(
@@ -42,7 +42,7 @@
 DEFINE_TRACE(NavigatorCredentials) {
   visitor->trace(m_credentialsContainer);
   Supplement<Navigator>::trace(visitor);
-  DOMWindowProperty::trace(visitor);
+  ContextClient::trace(visitor);
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/credentialmanager/NavigatorCredentials.h b/third_party/WebKit/Source/modules/credentialmanager/NavigatorCredentials.h
index 65516cd..e5668d1 100644
--- a/third_party/WebKit/Source/modules/credentialmanager/NavigatorCredentials.h
+++ b/third_party/WebKit/Source/modules/credentialmanager/NavigatorCredentials.h
@@ -5,7 +5,7 @@
 #ifndef NavigatorCredentials_h
 #define NavigatorCredentials_h
 
-#include "core/frame/DOMWindowProperty.h"
+#include "core/dom/ContextLifecycleObserver.h"
 #include "core/frame/Navigator.h"
 #include "platform/Supplementable.h"
 #include "platform/heap/Handle.h"
@@ -18,7 +18,7 @@
 class NavigatorCredentials final
     : public GarbageCollected<NavigatorCredentials>,
       public Supplement<Navigator>,
-      public DOMWindowProperty {
+      public ContextClient {
   USING_GARBAGE_COLLECTED_MIXIN(NavigatorCredentials);
 
  public:
diff --git a/third_party/WebKit/Source/modules/crypto/DOMWindowCrypto.cpp b/third_party/WebKit/Source/modules/crypto/DOMWindowCrypto.cpp
index 1f06297..550a00b 100644
--- a/third_party/WebKit/Source/modules/crypto/DOMWindowCrypto.cpp
+++ b/third_party/WebKit/Source/modules/crypto/DOMWindowCrypto.cpp
@@ -36,7 +36,7 @@
 namespace blink {
 
 DOMWindowCrypto::DOMWindowCrypto(LocalDOMWindow& window)
-    : DOMWindowProperty(window.frame()) {}
+    : ContextClient(window.frame()) {}
 
 const char* DOMWindowCrypto::supplementName() {
   return "DOMWindowCrypto";
@@ -65,7 +65,7 @@
 DEFINE_TRACE(DOMWindowCrypto) {
   visitor->trace(m_crypto);
   Supplement<LocalDOMWindow>::trace(visitor);
-  DOMWindowProperty::trace(visitor);
+  ContextClient::trace(visitor);
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/crypto/DOMWindowCrypto.h b/third_party/WebKit/Source/modules/crypto/DOMWindowCrypto.h
index ef26f4b..214a113 100644
--- a/third_party/WebKit/Source/modules/crypto/DOMWindowCrypto.h
+++ b/third_party/WebKit/Source/modules/crypto/DOMWindowCrypto.h
@@ -31,7 +31,7 @@
 #ifndef DOMWindowCrypto_h
 #define DOMWindowCrypto_h
 
-#include "core/frame/DOMWindowProperty.h"
+#include "core/dom/ContextLifecycleObserver.h"
 #include "platform/Supplementable.h"
 #include "platform/heap/Handle.h"
 
@@ -43,7 +43,7 @@
 
 class DOMWindowCrypto final : public GarbageCollected<DOMWindowCrypto>,
                               public Supplement<LocalDOMWindow>,
-                              public DOMWindowProperty {
+                              public ContextClient {
   USING_GARBAGE_COLLECTED_MIXIN(DOMWindowCrypto);
 
  public:
diff --git a/third_party/WebKit/Source/modules/donottrack/NavigatorDoNotTrack.cpp b/third_party/WebKit/Source/modules/donottrack/NavigatorDoNotTrack.cpp
index d5297fc..083969b 100644
--- a/third_party/WebKit/Source/modules/donottrack/NavigatorDoNotTrack.cpp
+++ b/third_party/WebKit/Source/modules/donottrack/NavigatorDoNotTrack.cpp
@@ -37,11 +37,11 @@
 namespace blink {
 
 NavigatorDoNotTrack::NavigatorDoNotTrack(LocalFrame* frame)
-    : DOMWindowProperty(frame) {}
+    : ContextClient(frame) {}
 
 DEFINE_TRACE(NavigatorDoNotTrack) {
   Supplement<Navigator>::trace(visitor);
-  DOMWindowProperty::trace(visitor);
+  ContextClient::trace(visitor);
 }
 
 const char* NavigatorDoNotTrack::supplementName() {
diff --git a/third_party/WebKit/Source/modules/donottrack/NavigatorDoNotTrack.h b/third_party/WebKit/Source/modules/donottrack/NavigatorDoNotTrack.h
index 8b10263..6fd2a17 100644
--- a/third_party/WebKit/Source/modules/donottrack/NavigatorDoNotTrack.h
+++ b/third_party/WebKit/Source/modules/donottrack/NavigatorDoNotTrack.h
@@ -31,7 +31,7 @@
 #ifndef NavigatorDoNotTrack_h
 #define NavigatorDoNotTrack_h
 
-#include "core/frame/DOMWindowProperty.h"
+#include "core/dom/ContextLifecycleObserver.h"
 #include "platform/Supplementable.h"
 #include "platform/heap/Handle.h"
 #include "wtf/text/WTFString.h"
@@ -43,7 +43,7 @@
 
 class NavigatorDoNotTrack final : public GarbageCollected<NavigatorDoNotTrack>,
                                   public Supplement<Navigator>,
-                                  public DOMWindowProperty {
+                                  public ContextClient {
   USING_GARBAGE_COLLECTED_MIXIN(NavigatorDoNotTrack);
 
  public:
diff --git a/third_party/WebKit/Source/modules/filesystem/FileSystemCallbacks.cpp b/third_party/WebKit/Source/modules/filesystem/FileSystemCallbacks.cpp
index 1a1ef6d..769aea17 100644
--- a/third_party/WebKit/Source/modules/filesystem/FileSystemCallbacks.cpp
+++ b/third_party/WebKit/Source/modules/filesystem/FileSystemCallbacks.cpp
@@ -80,7 +80,7 @@
 
 bool FileSystemCallbacksBase::shouldScheduleCallback() const {
   return !shouldBlockUntilCompletion() && m_executionContext &&
-         m_executionContext->activeDOMObjectsAreSuspended();
+         m_executionContext->isContextSuspended();
 }
 
 template <typename CB, typename CBArg>
diff --git a/third_party/WebKit/Source/modules/gamepad/NavigatorGamepad.cpp b/third_party/WebKit/Source/modules/gamepad/NavigatorGamepad.cpp
index 546499b..8b4411a 100644
--- a/third_party/WebKit/Source/modules/gamepad/NavigatorGamepad.cpp
+++ b/third_party/WebKit/Source/modules/gamepad/NavigatorGamepad.cpp
@@ -130,8 +130,7 @@
   if (!m_hasEventListener)
     return;
 
-  if (document->isContextDestroyed() ||
-      document->activeDOMObjectsAreSuspended())
+  if (document->isContextDestroyed() || document->isContextSuspended())
     return;
 
   const GamepadDispatcher::ConnectionChange& change =
diff --git a/third_party/WebKit/Source/modules/geolocation/NavigatorGeolocation.cpp b/third_party/WebKit/Source/modules/geolocation/NavigatorGeolocation.cpp
index a9526ed..e74f11a 100644
--- a/third_party/WebKit/Source/modules/geolocation/NavigatorGeolocation.cpp
+++ b/third_party/WebKit/Source/modules/geolocation/NavigatorGeolocation.cpp
@@ -31,7 +31,7 @@
 namespace blink {
 
 NavigatorGeolocation::NavigatorGeolocation(LocalFrame* frame)
-    : DOMWindowProperty(frame) {}
+    : ContextClient(frame) {}
 
 const char* NavigatorGeolocation::supplementName() {
   return "NavigatorGeolocation";
@@ -60,7 +60,7 @@
 DEFINE_TRACE(NavigatorGeolocation) {
   visitor->trace(m_geolocation);
   Supplement<Navigator>::trace(visitor);
-  DOMWindowProperty::trace(visitor);
+  ContextClient::trace(visitor);
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/geolocation/NavigatorGeolocation.h b/third_party/WebKit/Source/modules/geolocation/NavigatorGeolocation.h
index a335817..ad08716 100644
--- a/third_party/WebKit/Source/modules/geolocation/NavigatorGeolocation.h
+++ b/third_party/WebKit/Source/modules/geolocation/NavigatorGeolocation.h
@@ -20,7 +20,7 @@
 #ifndef NavigatorGeolocation_h
 #define NavigatorGeolocation_h
 
-#include "core/frame/DOMWindowProperty.h"
+#include "core/dom/ContextLifecycleObserver.h"
 #include "platform/Supplementable.h"
 #include "platform/heap/Handle.h"
 
@@ -33,7 +33,7 @@
 class NavigatorGeolocation final
     : public GarbageCollected<NavigatorGeolocation>,
       public Supplement<Navigator>,
-      public DOMWindowProperty {
+      public ContextClient {
   USING_GARBAGE_COLLECTED_MIXIN(NavigatorGeolocation);
 
  public:
diff --git a/third_party/WebKit/Source/modules/installedapp/NavigatorInstalledApp.cpp b/third_party/WebKit/Source/modules/installedapp/NavigatorInstalledApp.cpp
index a6c3869..78545b6b 100644
--- a/third_party/WebKit/Source/modules/installedapp/NavigatorInstalledApp.cpp
+++ b/third_party/WebKit/Source/modules/installedapp/NavigatorInstalledApp.cpp
@@ -23,7 +23,7 @@
 namespace blink {
 
 NavigatorInstalledApp::NavigatorInstalledApp(LocalFrame* frame)
-    : DOMWindowProperty(frame) {}
+    : ContextClient(frame) {}
 
 NavigatorInstalledApp* NavigatorInstalledApp::from(Document& document) {
   if (!document.frame() || !document.frame()->domWindow())
@@ -102,7 +102,7 @@
 
 DEFINE_TRACE(NavigatorInstalledApp) {
   Supplement<Navigator>::trace(visitor);
-  DOMWindowProperty::trace(visitor);
+  ContextClient::trace(visitor);
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/installedapp/NavigatorInstalledApp.h b/third_party/WebKit/Source/modules/installedapp/NavigatorInstalledApp.h
index 4adecbc..7a9a65ba 100644
--- a/third_party/WebKit/Source/modules/installedapp/NavigatorInstalledApp.h
+++ b/third_party/WebKit/Source/modules/installedapp/NavigatorInstalledApp.h
@@ -5,7 +5,7 @@
 #ifndef NavigatorInstalledApp_h
 #define NavigatorInstalledApp_h
 
-#include "core/frame/DOMWindowProperty.h"
+#include "core/dom/ContextLifecycleObserver.h"
 #include "platform/Supplementable.h"
 #include "platform/heap/Handle.h"
 #include "wtf/text/WTFString.h"
@@ -21,7 +21,7 @@
 class NavigatorInstalledApp final
     : public GarbageCollected<NavigatorInstalledApp>,
       public Supplement<Navigator>,
-      public DOMWindowProperty {
+      public ContextClient {
   USING_GARBAGE_COLLECTED_MIXIN(NavigatorInstalledApp);
 
  public:
diff --git a/third_party/WebKit/Source/modules/netinfo/NavigatorNetworkInformation.cpp b/third_party/WebKit/Source/modules/netinfo/NavigatorNetworkInformation.cpp
index a719286..378ad51c 100644
--- a/third_party/WebKit/Source/modules/netinfo/NavigatorNetworkInformation.cpp
+++ b/third_party/WebKit/Source/modules/netinfo/NavigatorNetworkInformation.cpp
@@ -12,7 +12,7 @@
 namespace blink {
 
 NavigatorNetworkInformation::NavigatorNetworkInformation(Navigator& navigator)
-    : DOMWindowProperty(navigator.frame()) {}
+    : ContextClient(navigator.frame()) {}
 
 NavigatorNetworkInformation& NavigatorNetworkInformation::from(
     Navigator& navigator) {
@@ -53,7 +53,7 @@
 DEFINE_TRACE(NavigatorNetworkInformation) {
   visitor->trace(m_connection);
   Supplement<Navigator>::trace(visitor);
-  DOMWindowProperty::trace(visitor);
+  ContextClient::trace(visitor);
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/netinfo/NavigatorNetworkInformation.h b/third_party/WebKit/Source/modules/netinfo/NavigatorNetworkInformation.h
index 55ca99d..c4f16e1 100644
--- a/third_party/WebKit/Source/modules/netinfo/NavigatorNetworkInformation.h
+++ b/third_party/WebKit/Source/modules/netinfo/NavigatorNetworkInformation.h
@@ -5,7 +5,7 @@
 #ifndef NavigatorNetworkInformation_h
 #define NavigatorNetworkInformation_h
 
-#include "core/frame/DOMWindowProperty.h"
+#include "core/dom/ContextLifecycleObserver.h"
 #include "platform/Supplementable.h"
 
 namespace blink {
@@ -16,7 +16,7 @@
 class NavigatorNetworkInformation final
     : public GarbageCollected<NavigatorNetworkInformation>,
       public Supplement<Navigator>,
-      public DOMWindowProperty {
+      public ContextClient {
   USING_GARBAGE_COLLECTED_MIXIN(NavigatorNetworkInformation);
 
  public:
diff --git a/third_party/WebKit/Source/modules/plugins/DOMMimeType.cpp b/third_party/WebKit/Source/modules/plugins/DOMMimeType.cpp
index 94e4238..4e339a2 100644
--- a/third_party/WebKit/Source/modules/plugins/DOMMimeType.cpp
+++ b/third_party/WebKit/Source/modules/plugins/DOMMimeType.cpp
@@ -30,12 +30,12 @@
 DOMMimeType::DOMMimeType(PassRefPtr<PluginData> pluginData,
                          LocalFrame* frame,
                          unsigned index)
-    : DOMWindowProperty(frame), m_pluginData(pluginData), m_index(index) {}
+    : ContextClient(frame), m_pluginData(pluginData), m_index(index) {}
 
 DOMMimeType::~DOMMimeType() {}
 
 DEFINE_TRACE(DOMMimeType) {
-  DOMWindowProperty::trace(visitor);
+  ContextClient::trace(visitor);
 }
 
 const String& DOMMimeType::type() const {
diff --git a/third_party/WebKit/Source/modules/plugins/DOMMimeType.h b/third_party/WebKit/Source/modules/plugins/DOMMimeType.h
index 6cb97ed..1239208 100644
--- a/third_party/WebKit/Source/modules/plugins/DOMMimeType.h
+++ b/third_party/WebKit/Source/modules/plugins/DOMMimeType.h
@@ -21,7 +21,7 @@
 #define DOMMimeType_h
 
 #include "bindings/core/v8/ScriptWrappable.h"
-#include "core/frame/DOMWindowProperty.h"
+#include "core/dom/ContextLifecycleObserver.h"
 #include "platform/heap/Handle.h"
 #include "platform/plugins/PluginData.h"
 #include "wtf/Forward.h"
@@ -34,7 +34,7 @@
 
 class DOMMimeType final : public GarbageCollectedFinalized<DOMMimeType>,
                           public ScriptWrappable,
-                          public DOMWindowProperty {
+                          public ContextClient {
   USING_GARBAGE_COLLECTED_MIXIN(DOMMimeType);
   DEFINE_WRAPPERTYPEINFO();
 
diff --git a/third_party/WebKit/Source/modules/plugins/DOMMimeTypeArray.cpp b/third_party/WebKit/Source/modules/plugins/DOMMimeTypeArray.cpp
index d9088b1..0927fe3 100644
--- a/third_party/WebKit/Source/modules/plugins/DOMMimeTypeArray.cpp
+++ b/third_party/WebKit/Source/modules/plugins/DOMMimeTypeArray.cpp
@@ -28,11 +28,10 @@
 
 namespace blink {
 
-DOMMimeTypeArray::DOMMimeTypeArray(LocalFrame* frame)
-    : DOMWindowProperty(frame) {}
+DOMMimeTypeArray::DOMMimeTypeArray(LocalFrame* frame) : ContextClient(frame) {}
 
 DEFINE_TRACE(DOMMimeTypeArray) {
-  DOMWindowProperty::trace(visitor);
+  ContextClient::trace(visitor);
 }
 
 unsigned DOMMimeTypeArray::length() const {
diff --git a/third_party/WebKit/Source/modules/plugins/DOMMimeTypeArray.h b/third_party/WebKit/Source/modules/plugins/DOMMimeTypeArray.h
index 1d42f3d..a4f4631e 100644
--- a/third_party/WebKit/Source/modules/plugins/DOMMimeTypeArray.h
+++ b/third_party/WebKit/Source/modules/plugins/DOMMimeTypeArray.h
@@ -22,7 +22,7 @@
 #define DOMMimeTypeArray_h
 
 #include "bindings/core/v8/ScriptWrappable.h"
-#include "core/frame/DOMWindowProperty.h"
+#include "core/dom/ContextLifecycleObserver.h"
 #include "modules/plugins/DOMMimeType.h"
 #include "platform/heap/Handle.h"
 #include "wtf/Forward.h"
@@ -34,7 +34,7 @@
 
 class DOMMimeTypeArray final : public GarbageCollected<DOMMimeTypeArray>,
                                public ScriptWrappable,
-                               public DOMWindowProperty {
+                               public ContextClient {
   DEFINE_WRAPPERTYPEINFO();
   USING_GARBAGE_COLLECTED_MIXIN(DOMMimeTypeArray);
 
diff --git a/third_party/WebKit/Source/modules/plugins/DOMPlugin.cpp b/third_party/WebKit/Source/modules/plugins/DOMPlugin.cpp
index 6351d4b6..6c21bf1 100644
--- a/third_party/WebKit/Source/modules/plugins/DOMPlugin.cpp
+++ b/third_party/WebKit/Source/modules/plugins/DOMPlugin.cpp
@@ -25,12 +25,12 @@
 namespace blink {
 
 DOMPlugin::DOMPlugin(PluginData* pluginData, LocalFrame* frame, unsigned index)
-    : DOMWindowProperty(frame), m_pluginData(pluginData), m_index(index) {}
+    : ContextClient(frame), m_pluginData(pluginData), m_index(index) {}
 
 DOMPlugin::~DOMPlugin() {}
 
 DEFINE_TRACE(DOMPlugin) {
-  DOMWindowProperty::trace(visitor);
+  ContextClient::trace(visitor);
 }
 
 String DOMPlugin::name() const {
diff --git a/third_party/WebKit/Source/modules/plugins/DOMPlugin.h b/third_party/WebKit/Source/modules/plugins/DOMPlugin.h
index ee07d9d..1e4347f 100644
--- a/third_party/WebKit/Source/modules/plugins/DOMPlugin.h
+++ b/third_party/WebKit/Source/modules/plugins/DOMPlugin.h
@@ -21,7 +21,7 @@
 #define DOMPlugin_h
 
 #include "bindings/core/v8/ScriptWrappable.h"
-#include "core/frame/DOMWindowProperty.h"
+#include "core/dom/ContextLifecycleObserver.h"
 #include "modules/plugins/DOMMimeType.h"
 #include "platform/heap/Handle.h"
 #include "wtf/Forward.h"
@@ -33,7 +33,7 @@
 
 class DOMPlugin final : public GarbageCollectedFinalized<DOMPlugin>,
                         public ScriptWrappable,
-                        public DOMWindowProperty {
+                        public ContextClient {
   USING_GARBAGE_COLLECTED_MIXIN(DOMPlugin);
   DEFINE_WRAPPERTYPEINFO();
 
diff --git a/third_party/WebKit/Source/modules/plugins/DOMPluginArray.cpp b/third_party/WebKit/Source/modules/plugins/DOMPluginArray.cpp
index e390dd6..8fa5d5a 100644
--- a/third_party/WebKit/Source/modules/plugins/DOMPluginArray.cpp
+++ b/third_party/WebKit/Source/modules/plugins/DOMPluginArray.cpp
@@ -28,10 +28,10 @@
 
 namespace blink {
 
-DOMPluginArray::DOMPluginArray(LocalFrame* frame) : DOMWindowProperty(frame) {}
+DOMPluginArray::DOMPluginArray(LocalFrame* frame) : ContextClient(frame) {}
 
 DEFINE_TRACE(DOMPluginArray) {
-  DOMWindowProperty::trace(visitor);
+  ContextClient::trace(visitor);
 }
 
 unsigned DOMPluginArray::length() const {
diff --git a/third_party/WebKit/Source/modules/plugins/DOMPluginArray.h b/third_party/WebKit/Source/modules/plugins/DOMPluginArray.h
index 1a0629f..a9fab1f 100644
--- a/third_party/WebKit/Source/modules/plugins/DOMPluginArray.h
+++ b/third_party/WebKit/Source/modules/plugins/DOMPluginArray.h
@@ -22,7 +22,7 @@
 #define DOMPluginArray_h
 
 #include "bindings/core/v8/ScriptWrappable.h"
-#include "core/frame/DOMWindowProperty.h"
+#include "core/dom/ContextLifecycleObserver.h"
 #include "modules/plugins/DOMPlugin.h"
 #include "platform/heap/Handle.h"
 #include "wtf/Forward.h"
@@ -34,7 +34,7 @@
 
 class DOMPluginArray final : public GarbageCollected<DOMPluginArray>,
                              public ScriptWrappable,
-                             public DOMWindowProperty {
+                             public ContextClient {
   DEFINE_WRAPPERTYPEINFO();
   USING_GARBAGE_COLLECTED_MIXIN(DOMPluginArray);
 
diff --git a/third_party/WebKit/Source/modules/plugins/NavigatorPlugins.cpp b/third_party/WebKit/Source/modules/plugins/NavigatorPlugins.cpp
index 50d538c..5a006809 100644
--- a/third_party/WebKit/Source/modules/plugins/NavigatorPlugins.cpp
+++ b/third_party/WebKit/Source/modules/plugins/NavigatorPlugins.cpp
@@ -13,7 +13,7 @@
 namespace blink {
 
 NavigatorPlugins::NavigatorPlugins(Navigator& navigator)
-    : DOMWindowProperty(navigator.frame()) {}
+    : ContextClient(navigator.frame()) {}
 
 // static
 NavigatorPlugins& NavigatorPlugins::from(Navigator& navigator) {
@@ -67,7 +67,7 @@
   visitor->trace(m_plugins);
   visitor->trace(m_mimeTypes);
   Supplement<Navigator>::trace(visitor);
-  DOMWindowProperty::trace(visitor);
+  ContextClient::trace(visitor);
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/plugins/NavigatorPlugins.h b/third_party/WebKit/Source/modules/plugins/NavigatorPlugins.h
index 5a010f692..669f8c7 100644
--- a/third_party/WebKit/Source/modules/plugins/NavigatorPlugins.h
+++ b/third_party/WebKit/Source/modules/plugins/NavigatorPlugins.h
@@ -5,7 +5,7 @@
 #ifndef NavigatorPlugins_h
 #define NavigatorPlugins_h
 
-#include "core/frame/DOMWindowProperty.h"
+#include "core/dom/ContextLifecycleObserver.h"
 #include "platform/Supplementable.h"
 
 namespace blink {
@@ -17,7 +17,7 @@
 
 class NavigatorPlugins final : public GarbageCollected<NavigatorPlugins>,
                                public Supplement<Navigator>,
-                               public DOMWindowProperty {
+                               public ContextClient {
   USING_GARBAGE_COLLECTED_MIXIN(NavigatorPlugins);
 
  public:
diff --git a/third_party/WebKit/Source/modules/presentation/Presentation.cpp b/third_party/WebKit/Source/modules/presentation/Presentation.cpp
index 8a3e16a..df41796c 100644
--- a/third_party/WebKit/Source/modules/presentation/Presentation.cpp
+++ b/third_party/WebKit/Source/modules/presentation/Presentation.cpp
@@ -13,7 +13,7 @@
 
 namespace blink {
 
-Presentation::Presentation(LocalFrame* frame) : DOMWindowProperty(frame) {}
+Presentation::Presentation(LocalFrame* frame) : ContextClient(frame) {}
 
 // static
 Presentation* Presentation::create(LocalFrame* frame) {
@@ -29,7 +29,7 @@
 DEFINE_TRACE(Presentation) {
   visitor->trace(m_defaultRequest);
   visitor->trace(m_receiver);
-  DOMWindowProperty::trace(visitor);
+  ContextClient::trace(visitor);
 }
 
 PresentationRequest* Presentation::defaultRequest() const {
diff --git a/third_party/WebKit/Source/modules/presentation/Presentation.h b/third_party/WebKit/Source/modules/presentation/Presentation.h
index 1604f522..ba064cc9 100644
--- a/third_party/WebKit/Source/modules/presentation/Presentation.h
+++ b/third_party/WebKit/Source/modules/presentation/Presentation.h
@@ -6,7 +6,7 @@
 #define Presentation_h
 
 #include "bindings/core/v8/ScriptWrappable.h"
-#include "core/frame/DOMWindowProperty.h"
+#include "core/dom/ContextLifecycleObserver.h"
 #include "platform/heap/Handle.h"
 #include "platform/heap/Heap.h"
 
@@ -22,7 +22,7 @@
 // details.
 class Presentation final : public GarbageCollected<Presentation>,
                            public ScriptWrappable,
-                           public DOMWindowProperty {
+                           public ContextClient {
   USING_GARBAGE_COLLECTED_MIXIN(Presentation);
   DEFINE_WRAPPERTYPEINFO();
 
diff --git a/third_party/WebKit/Source/modules/presentation/PresentationConnection.cpp b/third_party/WebKit/Source/modules/presentation/PresentationConnection.cpp
index 9481b5e1..67f98aace 100644
--- a/third_party/WebKit/Source/modules/presentation/PresentationConnection.cpp
+++ b/third_party/WebKit/Source/modules/presentation/PresentationConnection.cpp
@@ -150,7 +150,7 @@
 PresentationConnection::PresentationConnection(LocalFrame* frame,
                                                const String& id,
                                                const KURL& url)
-    : DOMWindowProperty(frame),
+    : ContextClient(frame),
       m_id(id),
       m_url(url),
       m_state(WebPresentationConnectionState::Connecting),
@@ -251,7 +251,7 @@
   visitor->trace(m_blobLoader);
   visitor->trace(m_messages);
   EventTargetWithInlineData::trace(visitor);
-  DOMWindowProperty::trace(visitor);
+  ContextClient::trace(visitor);
 }
 
 const AtomicString& PresentationConnection::state() const {
diff --git a/third_party/WebKit/Source/modules/presentation/PresentationConnection.h b/third_party/WebKit/Source/modules/presentation/PresentationConnection.h
index c6fa64b..2a995c3d 100644
--- a/third_party/WebKit/Source/modules/presentation/PresentationConnection.h
+++ b/third_party/WebKit/Source/modules/presentation/PresentationConnection.h
@@ -5,10 +5,10 @@
 #ifndef PresentationConnection_h
 #define PresentationConnection_h
 
+#include "core/dom/ContextLifecycleObserver.h"
 #include "core/events/EventTarget.h"
 #include "core/fileapi/Blob.h"
 #include "core/fileapi/FileError.h"
-#include "core/frame/DOMWindowProperty.h"
 #include "platform/heap/Handle.h"
 #include "platform/weborigin/KURL.h"
 #include "public/platform/modules/presentation/WebPresentationConnectionClient.h"
@@ -28,7 +28,7 @@
 class PresentationRequest;
 
 class PresentationConnection final : public EventTargetWithInlineData,
-                                     public DOMWindowProperty {
+                                     public ContextClient {
   USING_GARBAGE_COLLECTED_MIXIN(PresentationConnection);
   DEFINE_WRAPPERTYPEINFO();
 
diff --git a/third_party/WebKit/Source/modules/presentation/PresentationReceiver.cpp b/third_party/WebKit/Source/modules/presentation/PresentationReceiver.cpp
index 7a75368..9d22bcd 100644
--- a/third_party/WebKit/Source/modules/presentation/PresentationReceiver.cpp
+++ b/third_party/WebKit/Source/modules/presentation/PresentationReceiver.cpp
@@ -18,7 +18,7 @@
 
 PresentationReceiver::PresentationReceiver(LocalFrame* frame,
                                            WebPresentationClient* client)
-    : DOMWindowProperty(frame) {
+    : ContextClient(frame) {
   m_connectionList = new PresentationConnectionList(frame->document());
 
   if (client)
@@ -68,6 +68,7 @@
 DEFINE_TRACE(PresentationReceiver) {
   visitor->trace(m_connectionList);
   visitor->trace(m_connectionListProperty);
-  DOMWindowProperty::trace(visitor);
+  ContextClient::trace(visitor);
 }
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/presentation/PresentationReceiver.h b/third_party/WebKit/Source/modules/presentation/PresentationReceiver.h
index 0ff8eb1..c4d3c2c 100644
--- a/third_party/WebKit/Source/modules/presentation/PresentationReceiver.h
+++ b/third_party/WebKit/Source/modules/presentation/PresentationReceiver.h
@@ -8,8 +8,8 @@
 #include "bindings/core/v8/ScriptPromise.h"
 #include "bindings/core/v8/ScriptPromiseProperty.h"
 #include "bindings/core/v8/ScriptWrappable.h"
+#include "core/dom/ContextLifecycleObserver.h"
 #include "core/dom/DOMException.h"
-#include "core/frame/DOMWindowProperty.h"
 #include "modules/ModulesExport.h"
 #include "platform/heap/Handle.h"
 #include "platform/heap/Heap.h"
@@ -27,7 +27,7 @@
 class MODULES_EXPORT PresentationReceiver final
     : public GarbageCollectedFinalized<PresentationReceiver>,
       public ScriptWrappable,
-      public DOMWindowProperty,
+      public ContextClient,
       public WebPresentationReceiver {
   USING_GARBAGE_COLLECTED_MIXIN(PresentationReceiver);
   DEFINE_WRAPPERTYPEINFO();
diff --git a/third_party/WebKit/Source/modules/quota/DOMWindowQuota.cpp b/third_party/WebKit/Source/modules/quota/DOMWindowQuota.cpp
index cd5143e..edd1b46d 100644
--- a/third_party/WebKit/Source/modules/quota/DOMWindowQuota.cpp
+++ b/third_party/WebKit/Source/modules/quota/DOMWindowQuota.cpp
@@ -38,7 +38,7 @@
 namespace blink {
 
 DOMWindowQuota::DOMWindowQuota(LocalDOMWindow& window)
-    : DOMWindowProperty(window.frame()) {}
+    : ContextClient(window.frame()) {}
 
 const char* DOMWindowQuota::supplementName() {
   return "DOMWindowQuota";
@@ -69,7 +69,7 @@
 DEFINE_TRACE(DOMWindowQuota) {
   visitor->trace(m_storageInfo);
   Supplement<LocalDOMWindow>::trace(visitor);
-  DOMWindowProperty::trace(visitor);
+  ContextClient::trace(visitor);
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/quota/DOMWindowQuota.h b/third_party/WebKit/Source/modules/quota/DOMWindowQuota.h
index cf9f56c..4fbab18 100644
--- a/third_party/WebKit/Source/modules/quota/DOMWindowQuota.h
+++ b/third_party/WebKit/Source/modules/quota/DOMWindowQuota.h
@@ -31,7 +31,7 @@
 #ifndef DOMWindowQuota_h
 #define DOMWindowQuota_h
 
-#include "core/frame/DOMWindowProperty.h"
+#include "core/dom/ContextLifecycleObserver.h"
 #include "platform/Supplementable.h"
 #include "platform/heap/Handle.h"
 
@@ -43,7 +43,7 @@
 
 class DOMWindowQuota final : public GarbageCollected<DOMWindowQuota>,
                              public Supplement<LocalDOMWindow>,
-                             public DOMWindowProperty {
+                             public ContextClient {
   USING_GARBAGE_COLLECTED_MIXIN(DOMWindowQuota);
 
  public:
diff --git a/third_party/WebKit/Source/modules/quota/NavigatorStorageQuota.cpp b/third_party/WebKit/Source/modules/quota/NavigatorStorageQuota.cpp
index 87789fa..77f5b5a 100644
--- a/third_party/WebKit/Source/modules/quota/NavigatorStorageQuota.cpp
+++ b/third_party/WebKit/Source/modules/quota/NavigatorStorageQuota.cpp
@@ -38,7 +38,7 @@
 namespace blink {
 
 NavigatorStorageQuota::NavigatorStorageQuota(LocalFrame* frame)
-    : DOMWindowProperty(frame) {}
+    : ContextClient(frame) {}
 
 const char* NavigatorStorageQuota::supplementName() {
   return "NavigatorStorageQuota";
@@ -104,7 +104,7 @@
   visitor->trace(m_persistentStorage);
   visitor->trace(m_storageManager);
   Supplement<Navigator>::trace(visitor);
-  DOMWindowProperty::trace(visitor);
+  ContextClient::trace(visitor);
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/quota/NavigatorStorageQuota.h b/third_party/WebKit/Source/modules/quota/NavigatorStorageQuota.h
index 4ed60a5..c2c201e 100644
--- a/third_party/WebKit/Source/modules/quota/NavigatorStorageQuota.h
+++ b/third_party/WebKit/Source/modules/quota/NavigatorStorageQuota.h
@@ -31,7 +31,7 @@
 #ifndef NavigatorStorageQuota_h
 #define NavigatorStorageQuota_h
 
-#include "core/frame/DOMWindowProperty.h"
+#include "core/dom/ContextLifecycleObserver.h"
 #include "modules/quota/DeprecatedStorageQuota.h"
 #include "platform/Supplementable.h"
 #include "platform/heap/Handle.h"
@@ -46,7 +46,7 @@
 class NavigatorStorageQuota final
     : public GarbageCollected<NavigatorStorageQuota>,
       public Supplement<Navigator>,
-      public DOMWindowProperty {
+      public ContextClient {
   USING_GARBAGE_COLLECTED_MIXIN(NavigatorStorageQuota);
 
  public:
diff --git a/third_party/WebKit/Source/modules/screen_orientation/ScreenOrientation.cpp b/third_party/WebKit/Source/modules/screen_orientation/ScreenOrientation.cpp
index 937f9dbf..895f7ea 100644
--- a/third_party/WebKit/Source/modules/screen_orientation/ScreenOrientation.cpp
+++ b/third_party/WebKit/Source/modules/screen_orientation/ScreenOrientation.cpp
@@ -115,9 +115,7 @@
 }
 
 ScreenOrientation::ScreenOrientation(LocalFrame* frame)
-    : DOMWindowProperty(frame),
-      m_type(WebScreenOrientationUndefined),
-      m_angle(0) {}
+    : ContextClient(frame), m_type(WebScreenOrientationUndefined), m_angle(0) {}
 
 ScreenOrientation::~ScreenOrientation() {}
 
@@ -191,7 +189,7 @@
 
 DEFINE_TRACE(ScreenOrientation) {
   EventTargetWithInlineData::trace(visitor);
-  DOMWindowProperty::trace(visitor);
+  ContextClient::trace(visitor);
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/screen_orientation/ScreenOrientation.h b/third_party/WebKit/Source/modules/screen_orientation/ScreenOrientation.h
index 9d24694..5a80789 100644
--- a/third_party/WebKit/Source/modules/screen_orientation/ScreenOrientation.h
+++ b/third_party/WebKit/Source/modules/screen_orientation/ScreenOrientation.h
@@ -6,8 +6,8 @@
 #define ScreenOrientation_h
 
 #include "bindings/core/v8/ScriptWrappable.h"
+#include "core/dom/ContextLifecycleObserver.h"
 #include "core/events/EventTarget.h"
-#include "core/frame/DOMWindowProperty.h"
 #include "platform/heap/Handle.h"
 #include "public/platform/modules/screen_orientation/WebScreenOrientationType.h"
 #include "wtf/text/AtomicString.h"
@@ -22,7 +22,7 @@
 class ScreenOrientationControllerImpl;
 
 class ScreenOrientation final : public EventTargetWithInlineData,
-                                public DOMWindowProperty {
+                                public ContextClient {
   DEFINE_WRAPPERTYPEINFO();
   USING_GARBAGE_COLLECTED_MIXIN(ScreenOrientation);
 
diff --git a/third_party/WebKit/Source/modules/speech/DOMWindowSpeechSynthesis.cpp b/third_party/WebKit/Source/modules/speech/DOMWindowSpeechSynthesis.cpp
index 5ef27d37..b992182e 100644
--- a/third_party/WebKit/Source/modules/speech/DOMWindowSpeechSynthesis.cpp
+++ b/third_party/WebKit/Source/modules/speech/DOMWindowSpeechSynthesis.cpp
@@ -37,7 +37,7 @@
 namespace blink {
 
 DOMWindowSpeechSynthesis::DOMWindowSpeechSynthesis(LocalDOMWindow& window)
-    : DOMWindowProperty(window.frame()) {}
+    : ContextClient(window.frame()) {}
 
 const char* DOMWindowSpeechSynthesis::supplementName() {
   return "DOMWindowSpeechSynthesis";
@@ -71,7 +71,7 @@
 DEFINE_TRACE(DOMWindowSpeechSynthesis) {
   visitor->trace(m_speechSynthesis);
   Supplement<LocalDOMWindow>::trace(visitor);
-  DOMWindowProperty::trace(visitor);
+  ContextClient::trace(visitor);
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/speech/DOMWindowSpeechSynthesis.h b/third_party/WebKit/Source/modules/speech/DOMWindowSpeechSynthesis.h
index 1039f8c5..a52811b 100644
--- a/third_party/WebKit/Source/modules/speech/DOMWindowSpeechSynthesis.h
+++ b/third_party/WebKit/Source/modules/speech/DOMWindowSpeechSynthesis.h
@@ -26,7 +26,7 @@
 #ifndef DOMWindowSpeechSynthesis_h
 #define DOMWindowSpeechSynthesis_h
 
-#include "core/frame/DOMWindowProperty.h"
+#include "core/dom/ContextLifecycleObserver.h"
 #include "modules/ModulesExport.h"
 #include "modules/speech/SpeechSynthesis.h"
 #include "platform/Supplementable.h"
@@ -39,7 +39,7 @@
 class MODULES_EXPORT DOMWindowSpeechSynthesis final
     : public GarbageCollected<DOMWindowSpeechSynthesis>,
       public Supplement<LocalDOMWindow>,
-      public DOMWindowProperty {
+      public ContextClient {
   USING_GARBAGE_COLLECTED_MIXIN(DOMWindowSpeechSynthesis);
 
  public:
diff --git a/third_party/WebKit/Source/modules/storage/DOMWindowStorage.cpp b/third_party/WebKit/Source/modules/storage/DOMWindowStorage.cpp
index 111e9a6..b323e46 100644
--- a/third_party/WebKit/Source/modules/storage/DOMWindowStorage.cpp
+++ b/third_party/WebKit/Source/modules/storage/DOMWindowStorage.cpp
@@ -18,14 +18,14 @@
 namespace blink {
 
 DOMWindowStorage::DOMWindowStorage(LocalDOMWindow& window)
-    : DOMWindowProperty(window.frame()), m_window(&window) {}
+    : ContextClient(window.frame()), m_window(&window) {}
 
 DEFINE_TRACE(DOMWindowStorage) {
   visitor->trace(m_window);
   visitor->trace(m_sessionStorage);
   visitor->trace(m_localStorage);
   Supplement<LocalDOMWindow>::trace(visitor);
-  DOMWindowProperty::trace(visitor);
+  ContextClient::trace(visitor);
 }
 
 // static
diff --git a/third_party/WebKit/Source/modules/storage/DOMWindowStorage.h b/third_party/WebKit/Source/modules/storage/DOMWindowStorage.h
index 6bd5769..f97faf3 100644
--- a/third_party/WebKit/Source/modules/storage/DOMWindowStorage.h
+++ b/third_party/WebKit/Source/modules/storage/DOMWindowStorage.h
@@ -5,7 +5,7 @@
 #ifndef DOMWindowStorage_h
 #define DOMWindowStorage_h
 
-#include "core/frame/DOMWindowProperty.h"
+#include "core/dom/ContextLifecycleObserver.h"
 #include "platform/Supplementable.h"
 #include "platform/heap/Handle.h"
 
@@ -18,7 +18,7 @@
 
 class DOMWindowStorage final : public GarbageCollected<DOMWindowStorage>,
                                public Supplement<LocalDOMWindow>,
-                               public DOMWindowProperty {
+                               public ContextClient {
   USING_GARBAGE_COLLECTED_MIXIN(DOMWindowStorage);
 
  public:
diff --git a/third_party/WebKit/Source/modules/storage/Storage.cpp b/third_party/WebKit/Source/modules/storage/Storage.cpp
index 4c13799..7b79121d 100644
--- a/third_party/WebKit/Source/modules/storage/Storage.cpp
+++ b/third_party/WebKit/Source/modules/storage/Storage.cpp
@@ -36,7 +36,7 @@
 }
 
 Storage::Storage(LocalFrame* frame, StorageArea* storageArea)
-    : DOMWindowProperty(frame), m_storageArea(storageArea) {
+    : ContextClient(frame), m_storageArea(storageArea) {
   DCHECK(frame);
   DCHECK(m_storageArea);
 }
@@ -102,7 +102,7 @@
 
 DEFINE_TRACE(Storage) {
   visitor->trace(m_storageArea);
-  DOMWindowProperty::trace(visitor);
+  ContextClient::trace(visitor);
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/storage/Storage.h b/third_party/WebKit/Source/modules/storage/Storage.h
index 90b0467e..e3b5278 100644
--- a/third_party/WebKit/Source/modules/storage/Storage.h
+++ b/third_party/WebKit/Source/modules/storage/Storage.h
@@ -28,7 +28,7 @@
 
 #include "bindings/core/v8/ScriptWrappable.h"
 #include "bindings/core/v8/V8Binding.h"
-#include "core/frame/DOMWindowProperty.h"
+#include "core/dom/ContextLifecycleObserver.h"
 #include "modules/storage/StorageArea.h"
 #include "platform/heap/Handle.h"
 #include "wtf/Forward.h"
@@ -41,7 +41,7 @@
 
 class Storage final : public GarbageCollected<Storage>,
                       public ScriptWrappable,
-                      public DOMWindowProperty {
+                      public ContextClient {
   DEFINE_WRAPPERTYPEINFO();
   USING_GARBAGE_COLLECTED_MIXIN(Storage);
 
diff --git a/third_party/WebKit/Source/modules/vr/NavigatorVR.cpp b/third_party/WebKit/Source/modules/vr/NavigatorVR.cpp
index 1dfdcf8a..77a2f29 100644
--- a/third_party/WebKit/Source/modules/vr/NavigatorVR.cpp
+++ b/third_party/WebKit/Source/modules/vr/NavigatorVR.cpp
@@ -90,12 +90,12 @@
   visitor->trace(m_controller);
 
   Supplement<Navigator>::trace(visitor);
-  DOMWindowProperty::trace(visitor);
+  ContextClient::trace(visitor);
   PageVisibilityObserver::trace(visitor);
 }
 
 NavigatorVR::NavigatorVR(LocalFrame* frame)
-    : DOMWindowProperty(frame), PageVisibilityObserver(frame->page()) {
+    : ContextClient(frame), PageVisibilityObserver(frame->page()) {
   frame->domWindow()->registerEventListenerObserver(this);
 }
 
diff --git a/third_party/WebKit/Source/modules/vr/NavigatorVR.h b/third_party/WebKit/Source/modules/vr/NavigatorVR.h
index a88a304..65f7fba 100644
--- a/third_party/WebKit/Source/modules/vr/NavigatorVR.h
+++ b/third_party/WebKit/Source/modules/vr/NavigatorVR.h
@@ -6,7 +6,7 @@
 #define NavigatorVR_h
 
 #include "bindings/core/v8/ScriptPromise.h"
-#include "core/frame/DOMWindowProperty.h"
+#include "core/dom/ContextLifecycleObserver.h"
 #include "core/frame/LocalDOMWindow.h"
 #include "core/page/PageVisibilityObserver.h"
 #include "modules/ModulesExport.h"
@@ -26,7 +26,7 @@
 class MODULES_EXPORT NavigatorVR final
     : public GarbageCollectedFinalized<NavigatorVR>,
       public Supplement<Navigator>,
-      public DOMWindowProperty,
+      public ContextClient,
       public PageVisibilityObserver,
       public LocalDOMWindow::EventListenerObserver {
   USING_GARBAGE_COLLECTED_MIXIN(NavigatorVR);
diff --git a/third_party/WebKit/Source/modules/webmidi/NavigatorWebMIDI.cpp b/third_party/WebKit/Source/modules/webmidi/NavigatorWebMIDI.cpp
index b592f40..90a04e6c 100644
--- a/third_party/WebKit/Source/modules/webmidi/NavigatorWebMIDI.cpp
+++ b/third_party/WebKit/Source/modules/webmidi/NavigatorWebMIDI.cpp
@@ -42,12 +42,11 @@
 
 namespace blink {
 
-NavigatorWebMIDI::NavigatorWebMIDI(LocalFrame* frame)
-    : DOMWindowProperty(frame) {}
+NavigatorWebMIDI::NavigatorWebMIDI(LocalFrame* frame) : ContextClient(frame) {}
 
 DEFINE_TRACE(NavigatorWebMIDI) {
   Supplement<Navigator>::trace(visitor);
-  DOMWindowProperty::trace(visitor);
+  ContextClient::trace(visitor);
 }
 
 const char* NavigatorWebMIDI::supplementName() {
diff --git a/third_party/WebKit/Source/modules/webmidi/NavigatorWebMIDI.h b/third_party/WebKit/Source/modules/webmidi/NavigatorWebMIDI.h
index 00c239e5..cc1a1d8 100644
--- a/third_party/WebKit/Source/modules/webmidi/NavigatorWebMIDI.h
+++ b/third_party/WebKit/Source/modules/webmidi/NavigatorWebMIDI.h
@@ -32,7 +32,7 @@
 #define NavigatorWebMIDI_h
 
 #include "bindings/core/v8/ScriptPromise.h"
-#include "core/frame/DOMWindowProperty.h"
+#include "core/dom/ContextLifecycleObserver.h"
 #include "modules/webmidi/MIDIOptions.h"
 #include "platform/Supplementable.h"
 #include "platform/heap/Handle.h"
@@ -43,7 +43,7 @@
 
 class NavigatorWebMIDI final : public GarbageCollected<NavigatorWebMIDI>,
                                public Supplement<Navigator>,
-                               public DOMWindowProperty {
+                               public ContextClient {
   USING_GARBAGE_COLLECTED_MIXIN(NavigatorWebMIDI);
 
  public:
diff --git a/third_party/WebKit/Source/platform/Timer.h b/third_party/WebKit/Source/platform/Timer.h
index 884adb9..1af4cfc 100644
--- a/third_party/WebKit/Source/platform/Timer.h
+++ b/third_party/WebKit/Source/platform/Timer.h
@@ -181,6 +181,8 @@
 // This subclass of Timer posts its tasks on the current thread's default task
 // runner.  Tasks posted on there are not throttled when the tab is in the
 // background.
+//
+// DEPRECATED: Use TaskRunnerHelper::get with TaskType::Unthrottled.
 template <typename TimerFiredClass>
 class UnthrottledThreadTimer : public TaskRunnerTimer<TimerFiredClass> {
  public:
diff --git a/third_party/WebKit/Source/web/SuspendableScriptExecutor.cpp b/third_party/WebKit/Source/web/SuspendableScriptExecutor.cpp
index 6145f8a..4fe999f 100644
--- a/third_party/WebKit/Source/web/SuspendableScriptExecutor.cpp
+++ b/third_party/WebKit/Source/web/SuspendableScriptExecutor.cpp
@@ -198,7 +198,7 @@
 void SuspendableScriptExecutor::run() {
   ExecutionContext* context = getExecutionContext();
   DCHECK(context);
-  if (!context->activeDOMObjectsAreSuspended()) {
+  if (!context->isContextSuspended()) {
     suspendIfNeeded();
     executeAndDestroySelf();
     return;
diff --git a/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp b/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp
index 5660cd4..56be05ae 100644
--- a/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp
+++ b/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp
@@ -662,14 +662,13 @@
 
 WebPluginContainerImpl::WebPluginContainerImpl(HTMLPlugInElement* element,
                                                WebPlugin* webPlugin)
-    : DOMWindowProperty(element->document().frame()),
+    : ContextClient(element->document().frame()),
       m_element(element),
       m_webPlugin(webPlugin),
       m_webLayer(nullptr),
       m_touchEventRequestType(TouchEventRequestTypeNone),
       m_wantsWheelEvents(false),
-      m_isDisposed(false) {
-}
+      m_isDisposed(false) {}
 
 WebPluginContainerImpl::~WebPluginContainerImpl() {
   // The plugin container must have been disposed of by now.
@@ -696,7 +695,7 @@
 
 DEFINE_TRACE(WebPluginContainerImpl) {
   visitor->trace(m_element);
-  DOMWindowProperty::trace(visitor);
+  ContextClient::trace(visitor);
   PluginView::trace(visitor);
 }
 
diff --git a/third_party/WebKit/Source/web/WebPluginContainerImpl.h b/third_party/WebKit/Source/web/WebPluginContainerImpl.h
index 631ab11..a67de1a 100644
--- a/third_party/WebKit/Source/web/WebPluginContainerImpl.h
+++ b/third_party/WebKit/Source/web/WebPluginContainerImpl.h
@@ -32,7 +32,7 @@
 #ifndef WebPluginContainerImpl_h
 #define WebPluginContainerImpl_h
 
-#include "core/frame/DOMWindowProperty.h"
+#include "core/dom/ContextLifecycleObserver.h"
 #include "core/plugins/PluginView.h"
 #include "platform/Widget.h"
 #include "public/web/WebPluginContainer.h"
@@ -62,7 +62,7 @@
 class WEB_EXPORT WebPluginContainerImpl final
     : public PluginView,
       NON_EXPORTED_BASE(public WebPluginContainer),
-      public DOMWindowProperty {
+      public ContextClient {
   USING_GARBAGE_COLLECTED_MIXIN(WebPluginContainerImpl);
   USING_PRE_FINALIZER(WebPluginContainerImpl, dispose);
 
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 7eb08c64..efdd7bdb 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -51425,16 +51425,6 @@
   <summary>Number of unlimited origins using temporary storage.</summary>
 </histogram>
 
-<histogram name="Quota.OSAccomodationDelta" units="MB">
-  <owner>michaeln@chromium.org</owner>
-  <summary>
-    If our hardcoded OS accomodation is too large for the volume size, we define
-    the value as a fraction of the total volume size instead. The
-    OSAccomodationDelta is the difference between the hardcoded and computed
-    values.
-  </summary>
-</histogram>
-
 <histogram name="Quota.QuotaForOrigin" units="MB">
   <owner>michaeln@chromium.org</owner>
   <summary>
@@ -51470,18 +51460,7 @@
   <summary>Time spent to an eviction round.</summary>
 </histogram>
 
-<histogram name="Quota.TimeToGetSettings" units="ms">
-  <owner>michaeln@chromium.org</owner>
-  <summary>
-    Time spent querying the embedder for the settings values. Logged at
-    irregular intervals as the values are refreshed.
-  </summary>
-</histogram>
-
 <histogram name="Quota.TimeToInitializeGlobalQuota" units="ms">
-  <obsolete>
-    Removed November 2016
-  </obsolete>
   <owner>michaeln@chromium.org</owner>
   <summary>
     Time spent initializing the global quota. Logged when the storage
diff --git a/ui/views_content_client/DEPS b/ui/views_content_client/DEPS
index 5be0a24..7f82ac5 100644
--- a/ui/views_content_client/DEPS
+++ b/ui/views_content_client/DEPS
@@ -1,7 +1,6 @@
 include_rules = [
   "+content/public",
   "+content/shell",
-  "+storage/browser/quota",
   "+ui/aura",
   "+ui/base",
   "+ui/display",
diff --git a/ui/views_content_client/views_content_browser_client.cc b/ui/views_content_client/views_content_browser_client.cc
index f8c5a854..29b6dec 100644
--- a/ui/views_content_client/views_content_browser_client.cc
+++ b/ui/views_content_client/views_content_browser_client.cc
@@ -4,10 +4,6 @@
 
 #include "ui/views_content_client/views_content_browser_client.h"
 
-#include "content/public/browser/browser_context.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/storage_partition.h"
-#include "storage/browser/quota/quota_settings.h"
 #include "ui/views_content_client/views_content_client_main_parts.h"
 
 namespace ui {
@@ -28,15 +24,4 @@
   return views_content_main_parts_;
 }
 
-void ViewsContentBrowserClient::GetQuotaSettings(
-    content::BrowserContext* context,
-    content::StoragePartition* partition,
-    const storage::OptionalQuotaSettingsCallback& callback) {
-  content::BrowserThread::PostTaskAndReplyWithResult(
-      content::BrowserThread::FILE, FROM_HERE,
-      base::Bind(&storage::CalculateNominalDynamicSettings,
-                 partition->GetPath(), context->IsOffTheRecord()),
-      callback);
-}
-
 }  // namespace ui
diff --git a/ui/views_content_client/views_content_browser_client.h b/ui/views_content_client/views_content_browser_client.h
index 017ae63..408fb8a 100644
--- a/ui/views_content_client/views_content_browser_client.h
+++ b/ui/views_content_client/views_content_browser_client.h
@@ -22,10 +22,6 @@
   // content::ContentBrowserClient:
   content::BrowserMainParts* CreateBrowserMainParts(
       const content::MainFunctionParams& parameters) override;
-  void GetQuotaSettings(
-      content::BrowserContext* context,
-      content::StoragePartition* partition,
-      const storage::OptionalQuotaSettingsCallback& callback) override;
 
  private:
   ViewsContentClientMainParts* views_content_main_parts_;