diff --git a/DEPS b/DEPS
index 6468b7d0..29f96e2 100644
--- a/DEPS
+++ b/DEPS
@@ -40,7 +40,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': '96cf2065f356ff93722953aa6a9d665fc377c40b',
+  'skia_revision': 'dabe8acb7f89806dc6808d3ce913dc3d190c7e81',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
@@ -64,7 +64,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
-  'pdfium_revision': '8c1a66b6c55dfce51b6b2c2c5de479b97b9792ed',
+  'pdfium_revision': '2b63ae28236f71e4df9c26b66cfca2905ceec512',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling openmax_dl
   # and whatever else without interference from each other.
diff --git a/ash/common/wm/panels/panel_layout_manager.cc b/ash/common/wm/panels/panel_layout_manager.cc
index 4fe8a1b..cd016d6 100644
--- a/ash/common/wm/panels/panel_layout_manager.cc
+++ b/ash/common/wm/panels/panel_layout_manager.cc
@@ -22,9 +22,13 @@
 #include "ash/root_window_controller.h"
 #include "ash/shell.h"
 #include "ash/wm/window_properties.h"
+#include "ash/wm/window_state_aura.h"
+#include "ash/wm/window_util.h"
 #include "base/auto_reset.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "third_party/skia/include/core/SkPath.h"
+#include "ui/aura/client/window_parenting_client.h"
+#include "ui/aura/window_delegate.h"
 #include "ui/compositor/scoped_layer_animation_settings.h"
 #include "ui/gfx/canvas.h"
 #include "ui/gfx/geometry/rect.h"
@@ -33,6 +37,8 @@
 #include "ui/views/widget/widget.h"
 #include "ui/wm/public/activation_client.h"
 
+using aura::Window;
+
 namespace ash {
 namespace {
 
@@ -270,7 +276,8 @@
   return static_cast<PanelLayoutManager*>(
       window->GetRootWindow()
           ->GetChildByShellWindowId(kShellWindowId_PanelContainer)
-          ->GetLayoutManager());
+          ->aura_window()
+          ->layout_manager());
 }
 
 void PanelLayoutManager::Shutdown() {
@@ -337,72 +344,70 @@
   Relayout();
 }
 
-void PanelLayoutManager::OnWindowAddedToLayout(WmWindow* child) {
-  if (child->GetType() == ui::wm::WINDOW_TYPE_POPUP)
+void PanelLayoutManager::OnWindowAddedToLayout(Window* child) {
+  if (child->type() == ui::wm::WINDOW_TYPE_POPUP)
     return;
   if (in_add_window_)
     return;
   base::AutoReset<bool> auto_reset_in_add_window(&in_add_window_, true);
-  if (!child->aura_window()->GetProperty(kPanelAttachedKey)) {
+  if (!child->GetProperty(kPanelAttachedKey)) {
     // This should only happen when a window is added to panel container as a
     // result of bounds change from within the application during a drag.
     // If so we have already stopped the drag and should reparent the panel
     // back to appropriate container and ignore it.
     // TODO(varkha): Updating bounds during a drag can cause problems and a more
     // general solution is needed. See http://crbug.com/251813 .
-    aura::Window* old_parent = child->aura_window()->parent();
-    child->SetParentUsingContext(child,
-                                 child->GetRootWindow()->GetBoundsInScreen());
-    wm::ReparentTransientChildrenOfChild(child->aura_window(), old_parent,
-                                         child->aura_window()->parent());
-    DCHECK(child->GetParent()->GetShellWindowId() !=
-           kShellWindowId_PanelContainer);
+    Window* old_parent = child->parent();
+    aura::client::ParentWindowWithContext(
+        child, child, child->GetRootWindow()->GetBoundsInScreen());
+    wm::ReparentTransientChildrenOfChild(child, old_parent, child->parent());
+    DCHECK(child->parent()->id() != kShellWindowId_PanelContainer);
     return;
   }
   PanelInfo panel_info;
-  panel_info.window = child;
+  panel_info.window = WmWindow::Get(child);
   panel_info.callout_widget = new PanelCalloutWidget(panel_container_);
-  panel_info.slide_in = child != dragged_panel_;
+  panel_info.slide_in = WmWindow::Get(child) != dragged_panel_;
   panel_windows_.push_back(panel_info);
-  child->aura_window()->AddObserver(this);
-  child->GetWindowState()->AddObserver(this);
+  child->AddObserver(this);
+  wm::GetWindowState(child)->AddObserver(this);
   Relayout();
 }
 
-void PanelLayoutManager::OnWillRemoveWindowFromLayout(WmWindow* child) {}
+void PanelLayoutManager::OnWillRemoveWindowFromLayout(Window* child) {}
 
-void PanelLayoutManager::OnWindowRemovedFromLayout(WmWindow* child) {
-  if (child->GetType() == ui::wm::WINDOW_TYPE_POPUP)
+void PanelLayoutManager::OnWindowRemovedFromLayout(Window* child) {
+  if (child->type() == ui::wm::WINDOW_TYPE_POPUP)
     return;
 
-  PanelList::iterator found =
-      std::find(panel_windows_.begin(), panel_windows_.end(), child);
+  PanelList::iterator found = std::find(
+      panel_windows_.begin(), panel_windows_.end(), WmWindow::Get(child));
   if (found != panel_windows_.end()) {
     delete found->callout_widget;
     panel_windows_.erase(found);
   }
   if (restore_windows_on_shelf_visible_)
-    restore_windows_on_shelf_visible_->Remove(child->aura_window());
-  child->aura_window()->RemoveObserver(this);
-  child->GetWindowState()->RemoveObserver(this);
+    restore_windows_on_shelf_visible_->Remove(child);
+  child->RemoveObserver(this);
+  wm::GetWindowState(child)->RemoveObserver(this);
 
-  if (dragged_panel_ == child)
+  if (dragged_panel_ == WmWindow::Get(child))
     dragged_panel_ = nullptr;
 
-  if (last_active_panel_ == child)
+  if (last_active_panel_ == WmWindow::Get(child))
     last_active_panel_ = nullptr;
 
   Relayout();
 }
 
-void PanelLayoutManager::OnChildWindowVisibilityChanged(WmWindow* child,
+void PanelLayoutManager::OnChildWindowVisibilityChanged(Window* child,
                                                         bool visible) {
   if (visible)
-    child->GetWindowState()->Restore();
+    wm::GetWindowState(child)->Restore();
   Relayout();
 }
 
-void PanelLayoutManager::SetChildBounds(WmWindow* child,
+void PanelLayoutManager::SetChildBounds(Window* child,
                                         const gfx::Rect& requested_bounds) {
   gfx::Rect bounds(requested_bounds);
   const gfx::Rect& max_bounds = panel_container_->GetRootWindow()->GetBounds();
@@ -414,7 +419,7 @@
     bounds.set_height(max_height);
 
   // Reposition dragged panel in the panel order.
-  if (dragged_panel_ == child) {
+  if (dragged_panel_ == WmWindow::Get(child)) {
     PanelList::iterator dragged_panel_iter =
         std::find(panel_windows_.begin(), panel_windows_.end(), dragged_panel_);
     DCHECK(dragged_panel_iter != panel_windows_.end());
@@ -432,13 +437,14 @@
     }
   }
   // Respect the minimum size of the window.
-  if (child->HasNonClientArea()) {
-    const gfx::Size min_size = child->GetMinimumSize();
+  if (child->delegate()) {
+    const gfx::Size min_size = child->delegate()->GetMinimumSize();
     bounds.set_width(std::max(min_size.width(), bounds.width()));
     bounds.set_height(std::max(min_size.height(), bounds.height()));
   }
 
-  child->SetBoundsDirect(bounds);
+  SetChildBoundsDirect(child, bounds);
+  wm::SnapWindowToPixelBoundary(child);
   Relayout();
 }
 
diff --git a/ash/common/wm/panels/panel_layout_manager.h b/ash/common/wm/panels/panel_layout_manager.h
index 307ca5c..df7a258 100644
--- a/ash/common/wm/panels/panel_layout_manager.h
+++ b/ash/common/wm/panels/panel_layout_manager.h
@@ -13,12 +13,12 @@
 #include "ash/common/shell_observer.h"
 #include "ash/common/wm/window_state_observer.h"
 #include "ash/common/wm_display_observer.h"
-#include "ash/common/wm_layout_manager.h"
 #include "ash/root_window_controller.h"
 #include "base/compiler_specific.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "base/scoped_observer.h"
+#include "ui/aura/layout_manager.h"
 #include "ui/aura/window_observer.h"
 #include "ui/aura/window_tracker.h"
 #include "ui/keyboard/keyboard_controller.h"
@@ -51,7 +51,7 @@
 // panel_container->SetLayoutManager(new PanelLayoutManager(panel_container));
 
 class ASH_EXPORT PanelLayoutManager
-    : public WmLayoutManager,
+    : public aura::LayoutManager,
       public wm::WindowStateObserver,
       public aura::client::ActivationChangeObserver,
       public WmDisplayObserver,
@@ -84,39 +84,40 @@
   WmShelf* shelf() { return shelf_; }
   void SetShelf(WmShelf* shelf);
 
-  // Overridden from WmLayoutManager
+  // WmLayoutManager:
   void OnWindowResized() override;
-  void OnWindowAddedToLayout(WmWindow* child) override;
-  void OnWillRemoveWindowFromLayout(WmWindow* child) override;
-  void OnWindowRemovedFromLayout(WmWindow* child) override;
-  void OnChildWindowVisibilityChanged(WmWindow* child, bool visibile) override;
-  void SetChildBounds(WmWindow* child,
+  void OnWindowAddedToLayout(aura::Window* child) override;
+  void OnWillRemoveWindowFromLayout(aura::Window* child) override;
+  void OnWindowRemovedFromLayout(aura::Window* child) override;
+  void OnChildWindowVisibilityChanged(aura::Window* child,
+                                      bool visibile) override;
+  void SetChildBounds(aura::Window* child,
                       const gfx::Rect& requested_bounds) override;
 
-  // Overridden from ShellObserver:
+  // ShellObserver:
   void OnOverviewModeEnded() override;
   void OnShelfAlignmentChanged(WmWindow* root_window) override;
   void OnVirtualKeyboardStateChanged(bool activated,
                                      WmWindow* root_window) override;
 
-  // Overridden from aura::WindowObserver
+  // aura::WindowObserver
   void OnWindowPropertyChanged(aura::Window* window,
                                const void* key,
                                intptr_t old) override;
 
-  // Overridden from wm::WindowStateObserver
+  // wm::WindowStateObserver:
   void OnPostWindowStateTypeChange(wm::WindowState* window_state,
                                    wm::WindowStateType old_type) override;
 
-  // Overridden from aura::client::ActivationChangeObserver
+  // aura::client::ActivationChangeObserver:
   void OnWindowActivated(ActivationReason reason,
                          aura::Window* gained_active,
                          aura::Window* lost_active) override;
 
-  // Overridden from WindowTreeHostManager::Observer
+  // WindowTreeHostManager::Observer:
   void OnDisplayConfigurationChanged() override;
 
-  // Overridden from WmShelfObserver
+  // WmShelfObserver:
   void WillChangeVisibilityState(ShelfVisibilityState new_state) override;
   void OnShelfIconPositionsChanged() override;
 
diff --git a/ash/common/wm/wm_snap_to_pixel_layout_manager.cc b/ash/common/wm/wm_snap_to_pixel_layout_manager.cc
index 79afc89..7a604f1 100644
--- a/ash/common/wm/wm_snap_to_pixel_layout_manager.cc
+++ b/ash/common/wm/wm_snap_to_pixel_layout_manager.cc
@@ -24,7 +24,7 @@
         child->GetShellWindowId() > kShellWindowId_Max)  // not a container
       continue;
     if (child->aura_window()->GetProperty(kSnapChildrenToPixelBoundary)) {
-      if (!child->GetLayoutManager())
+      if (!child->GetLayoutManager() && !child->aura_window()->layout_manager())
         child->SetLayoutManager(base::MakeUnique<WmSnapToPixelLayoutManager>());
     } else {
       InstallOnContainers(child);
diff --git a/ash/mus/window_manager_unittest.cc b/ash/mus/window_manager_unittest.cc
index 90d3bc0..4fb7e82 100644
--- a/ash/mus/window_manager_unittest.cc
+++ b/ash/mus/window_manager_unittest.cc
@@ -91,7 +91,8 @@
 
   // Connect to mus and create a new top level window. The request goes to
   // |ash|, but is async.
-  aura::WindowTreeClient client(connector(), &window_tree_delegate);
+  aura::WindowTreeClient client(connector(), &window_tree_delegate, nullptr,
+                                nullptr, nullptr, false);
   client.ConnectViaWindowTreeFactory();
   aura::test::EnvTestHelper().SetWindowTreeClient(&client);
   std::map<std::string, std::vector<uint8_t>> properties;
@@ -110,7 +111,8 @@
   auto tree_client_request = MakeRequest(&tree_client);
   client.Embed(child_window, std::move(tree_client), 0u, base::Bind(&OnEmbed));
   aura::WindowTreeClient child_client(connector(), &window_tree_delegate,
-                                      nullptr, std::move(tree_client_request));
+                                      nullptr, std::move(tree_client_request),
+                                      nullptr, false);
   window_tree_delegate.WaitForEmbed();
   ASSERT_TRUE(!child_client.GetRoots().empty());
   window_tree_delegate.DestroyWindowTreeHost();
diff --git a/ash/root_window_controller.cc b/ash/root_window_controller.cc
index 1ba82de..a55579a 100644
--- a/ash/root_window_controller.cc
+++ b/ash/root_window_controller.cc
@@ -865,7 +865,7 @@
   // Create Panel layout manager
   WmWindow* wm_panel_container = GetWmContainer(kShellWindowId_PanelContainer);
   panel_layout_manager_ = new PanelLayoutManager(wm_panel_container);
-  wm_panel_container->SetLayoutManager(base::WrapUnique(panel_layout_manager_));
+  wm_panel_container->aura_window()->SetLayoutManager(panel_layout_manager_);
 
   wm::WmSnapToPixelLayoutManager::InstallOnContainers(root);
 
diff --git a/ash/test/wm_window_test_api.h b/ash/test/wm_window_test_api.h
index 33bd1a18..bf48107 100644
--- a/ash/test/wm_window_test_api.h
+++ b/ash/test/wm_window_test_api.h
@@ -27,18 +27,12 @@
     DISALLOW_COPY_AND_ASSIGN(GlobalMinimumSizeLock);
   };
 
-  explicit WmWindowTestApi(WmWindow* window) : window_(window) {}
+  WmWindowTestApi() {}
   ~WmWindowTestApi() {}
 
-  void set_use_empty_minimum_size(bool value) {
-    window_->use_empty_minimum_size_for_testing_ = true;
-  }
-
  private:
   static void SetDefaultUseEmptyMinimumSizeForTesting(bool value);
 
-  WmWindow* window_;
-
   DISALLOW_COPY_AND_ASSIGN(WmWindowTestApi);
 };
 
diff --git a/build/android/gradle/android.jinja b/build/android/gradle/android.jinja
index 197f98f..4f4a5d5 100644
--- a/build/android/gradle/android.jinja
+++ b/build/android/gradle/android.jinja
@@ -9,14 +9,12 @@
 {% for path in variables.java_dirs %}
                 "{{ path }}",
 {% endfor %}
-            ]
-{% if variables.java_excludes %}
-            java.filter.exclude(
-{% for path in variables.java_excludes %}
+{% if variables.java_files %}
+{% for path in variables.java_files %}
                 "{{ path }}",
 {% endfor %}
-            )
 {% endif %}
+            ]
             jniLibs.srcDirs = [
 {% for path in variables.jni_libs %}
                 "{{ path }}",
diff --git a/build/android/gradle/generate_gradle.py b/build/android/gradle/generate_gradle.py
index ec50a24..c4e8665 100755
--- a/build/android/gradle/generate_gradle.py
+++ b/build/android/gradle/generate_gradle.py
@@ -7,7 +7,6 @@
 
 import argparse
 import codecs
-import glob
 import logging
 import os
 import re
@@ -259,9 +258,9 @@
     java_files = []
     for entry in self._GetEntries(root_entry):
       java_files += entry.JavaFiles()
-    java_dirs, excludes = _ComputeJavaSourceDirsAndExcludes(
+    java_dirs, single_files = _ComputeJavaSourceDirsAndFiles(
         constants.GetOutDirectory(), java_files)
-    return java_dirs, excludes
+    return java_dirs, single_files
 
   def _GenCustomManifest(self, entry):
     """Returns the path to the generated AndroidManifest.xml.
@@ -333,11 +332,11 @@
     # TODO(agrieve): Add an option to use interface jars and see if that speeds
     # things up at all.
     variables = {}
-    java_dirs, excludes = self._GenJavaDirs(root_entry)
+    java_dirs, java_files = self._GenJavaDirs(root_entry)
     java_dirs.sort()
     variables['java_dirs'] = self._Relativize(root_entry, java_dirs)
     variables['java_dirs'].append(_SRCJARS_SUBDIR)
-    variables['java_excludes'] = excludes
+    variables['java_files'] = self._Relativize(root_entry, java_files)
     variables['jni_libs'] = self._Relativize(
         root_entry, set(self._GenJniLibs(root_entry)))
     variables['prebuilts'] = [
@@ -388,42 +387,18 @@
   return found_roots
 
 
-def _ComputeExcludeFilters(wanted_files, unwanted_files, parent_dir):
-  """Returns exclude patters to exclude unwanted files but keep wanted files.
-
-  - Shortens exclude list by globbing if possible.
-  - Exclude patterns are relative paths from the parent directory.
-  """
-  excludes = []
-  files_to_include = set(wanted_files)
-  files_to_exclude = set(unwanted_files)
-  while files_to_exclude:
-    unwanted_file = files_to_exclude.pop()
-    target_exclude = os.path.join(
-        os.path.dirname(unwanted_file), '*.java')
-    found_files = set(glob.glob(target_exclude))
-    valid_files = found_files & files_to_include
-    if valid_files:
-      excludes.append(os.path.relpath(unwanted_file, parent_dir))
-    else:
-      excludes.append(os.path.relpath(target_exclude, parent_dir))
-      files_to_exclude -= found_files
-  return excludes
-
-
-def _ComputeJavaSourceDirsAndExcludes(output_dir, java_files):
-  """Computes the list of java source directories and exclude patterns.
+def _ComputeJavaSourceDirsAndFiles(output_dir, java_files):
+  """Computes the list of java source directories and single files.
 
   1. Computes the root java source directories from the list of files.
-  2. Compute exclude patterns that exclude all extra files only.
-  3. Returns the list of java source directories and exclude patterns.
+  2. Compute single files that are not included in full directories.
+  3. Returns the list of java source directories and single files.
   """
   java_dirs = []
-  excludes = []
+  single_files = set()
   if java_files:
     java_files = _RebasePath(java_files)
     computed_dirs = _ComputeJavaSourceDirs(java_files)
-    java_dirs = computed_dirs.keys()
     all_found_java_files = set()
 
     for directory, files in computed_dirs.iteritems():
@@ -431,19 +406,20 @@
       all_found_java_files.update(found_java_files)
       unwanted_java_files = set(found_java_files) - set(files)
       if unwanted_java_files:
-        logging.debug('Directory requires excludes: %s', directory)
-        excludes.extend(
-            _ComputeExcludeFilters(files, unwanted_java_files, directory))
+        logging.debug('Directory requires single files: %s', directory)
+        single_files.update(files)
+      else:
+        java_dirs.append(directory)
 
     missing_java_files = set(java_files) - all_found_java_files
     # Warn only about non-generated files that are missing.
     missing_java_files = [p for p in missing_java_files
                           if not p.startswith(output_dir)]
     if missing_java_files:
-      logging.warning(
+      logging.error(
           'Some java files were not found: %s', missing_java_files)
 
-  return java_dirs, excludes
+  return java_dirs, list(single_files)
 
 
 def _CreateRelativeSymlink(target_path, link_path):
@@ -519,6 +495,8 @@
       _RebasePath(os.path.join(build_vars['android_sdk_build_tools'],
                                'source.properties')))
   variables['build_tools_version'] = source_properties['Pkg.Revision']
+  # TODO(wnwen): Remove this line once http://crbug.com/688263 is fixed.
+  variables['build_tools_version'] = '25.0.0'
   variables['compile_sdk_version'] = (
       'android-%s' % build_vars['android_sdk_version'])
   variables['main'] = generator.Generate(entry)
@@ -738,7 +716,7 @@
     _ExtractZips(generator.project_dir, zip_tuples)
 
   logging.warning('Project created! (%d subprojects)', len(project_entries))
-  logging.warning('Generated projects work best with Android Studio 2.2')
+  logging.warning('Generated projects are targeting Android Studio 2.3')
   logging.warning('For more tips: https://chromium.googlesource.com/chromium'
                   '/src.git/+/master/docs/android_studio.md')
 
diff --git a/build/android/gradle/root.jinja b/build/android/gradle/root.jinja
index 52f0eda..d3730e7 100644
--- a/build/android/gradle/root.jinja
+++ b/build/android/gradle/root.jinja
@@ -8,6 +8,6 @@
         jcenter()
     }
     dependencies {
-        classpath "com.android.tools.build:gradle:2.2.3"
+        classpath "com.android.tools.build:gradle:2.3.0"
     }
 }
diff --git a/build/sanitizers/tsan_suppressions.cc b/build/sanitizers/tsan_suppressions.cc
index e26ed0b5..d9753ef8 100644
--- a/build/sanitizers/tsan_suppressions.cc
+++ b/build/sanitizers/tsan_suppressions.cc
@@ -120,12 +120,6 @@
 // http://crbug.com/272095
 "race:base::g_top_manager\n"
 
-// http://crbug.com/280466
-"race:content::WebRtcAudioCapturer::SetCapturerSource\n"
-
-// http://crbug.com/285242
-"race:media::PulseAudioOutputStream::SetVolume\n"
-
 // http://crbug.com/308590
 "race:CustomThreadWatcher::~CustomThreadWatcher\n"
 
@@ -172,22 +166,12 @@
 "race:content::"
     "RendererWebKitPlatformSupportImpl::~RendererWebKitPlatformSupportImpl\n"
 
-// http://crbug.com/345618
-"race:WebCore::AudioDestinationNode::render\n"
-
-// http://crbug.com/345624
-"race:media::DataSource::set_host\n"
-
 // http://crbug.com/347534
 "race:v8::internal::V8::TearDown\n"
 
 // http://crbug.com/347538
 "race:sctp_timer_start\n"
 
-// http://crbug.com/347548
-"race:cricket::WebRtcVideoMediaChannel::MaybeResetVieSendCodec\n"
-"race:cricket::WebRtcVideoMediaChannel::SetSendCodec\n"
-
 // http://crbug.com/347553
 "race:blink::WebString::reset\n"
 
@@ -230,10 +214,6 @@
 // http://crbug.com/490856
 "deadlock:content::TracingControllerImpl::SetEnabledOnFileThread\n"
 
-// http://crbug.com/417193
-// Suppressing both AudioContext.{cpp,h}.
-"race:modules/webaudio/AudioContext\n"
-
 // https://code.google.com/p/skia/issues/detail?id=3294
 "race:SkBaseMutex::acquire\n"
 
@@ -259,9 +239,6 @@
 // http://crbug.com/633145
 "race:third_party/libjpeg_turbo/simd/jsimd_x86_64.c\n"
 
-// http://crbug.com/638583
-"race:webrtc/modules/audio_processing/aec/aec_rdft.cc\n"
-
 // http://crbug.com/587199
 "race:base::TimerTest_OneShotTimer_CustomTaskRunner_Test::TestBody\n"
 
diff --git a/cc/output/overlay_strategy_single_on_top.cc b/cc/output/overlay_strategy_single_on_top.cc
index 8ce4c6a3..f55a435 100644
--- a/cc/output/overlay_strategy_single_on_top.cc
+++ b/cc/output/overlay_strategy_single_on_top.cc
@@ -25,13 +25,27 @@
     OverlayCandidateList* candidate_list,
     std::vector<gfx::Rect>* content_bounds) {
   QuadList* quad_list = &render_pass->quad_list;
+  // Build a list of candidates with the associated quad.
+  OverlayCandidate best_candidate;
+  QuadList::Iterator best_quad_it = quad_list->end();
   for (auto it = quad_list->begin(); it != quad_list->end(); ++it) {
     OverlayCandidate candidate;
     if (OverlayCandidate::FromDrawQuad(resource_provider, *it, &candidate) &&
-        TryOverlay(quad_list, candidate_list, candidate, it)) {
-      return true;
+        // TODO(dcastagna): Remove this once drm platform supports transforms.
+        candidate.transform == gfx::OVERLAY_TRANSFORM_NONE &&
+        !OverlayCandidate::IsOccluded(candidate, quad_list->cbegin(), it)) {
+      if (candidate.display_rect.size().GetArea() >
+          best_candidate.display_rect.size().GetArea()) {
+        best_candidate = candidate;
+        best_quad_it = it;
+      }
     }
   }
+  if (best_quad_it == quad_list->end())
+    return false;
+
+  if (TryOverlay(quad_list, candidate_list, best_candidate, best_quad_it))
+    return true;
 
   return false;
 }
@@ -41,15 +55,6 @@
     OverlayCandidateList* candidate_list,
     const OverlayCandidate& candidate,
     QuadList::Iterator candidate_iterator) {
-  // Reject transformed overlays.
-  // TODO(dcastagna): Remove this once drm platform supports transforms.
-  if (candidate.transform != gfx::OVERLAY_TRANSFORM_NONE)
-    return false;
-  // Check that no prior quads overlap it.
-  if (OverlayCandidate::IsOccluded(candidate, quad_list->cbegin(),
-                                   candidate_iterator))
-    return false;
-
   // Add the overlay.
   OverlayCandidateList new_candidate_list = *candidate_list;
   new_candidate_list.push_back(candidate);
diff --git a/cc/output/overlay_unittest.cc b/cc/output/overlay_unittest.cc
index 2e1dffa..a02bb2af 100644
--- a/cc/output/overlay_unittest.cc
+++ b/cc/output/overlay_unittest.cc
@@ -79,12 +79,13 @@
 
 class SingleOverlayValidator : public OverlayCandidateValidator {
  public:
-  SingleOverlayValidator() : expected_rect_(kOverlayRect) {}
+  SingleOverlayValidator() : expected_rects_(1, gfx::RectF(kOverlayRect)) {}
 
   void GetStrategies(OverlayProcessor::StrategyList* strategies) override {
     strategies->push_back(base::MakeUnique<OverlayStrategySingleOnTop>(this));
     strategies->push_back(base::MakeUnique<OverlayStrategyUnderlay>(this));
   }
+
   bool AllowCALayerOverlays() override { return false; }
   bool AllowDCLayerOverlays() override { return false; }
   void CheckOverlaySupport(OverlayCandidateList* surfaces) override {
@@ -95,25 +96,34 @@
 
     OverlayCandidate& candidate = surfaces->back();
     EXPECT_TRUE(!candidate.use_output_surface_for_resource);
-    EXPECT_NEAR(expected_rect_.x(), candidate.display_rect.x(), 0.01f);
-    EXPECT_NEAR(expected_rect_.y(), candidate.display_rect.y(), 0.01f);
-    EXPECT_NEAR(expected_rect_.width(), candidate.display_rect.width(), 0.01f);
-    EXPECT_NEAR(expected_rect_.height(), candidate.display_rect.height(),
-                0.01f);
-
-    EXPECT_FLOAT_RECT_EQ(BoundingRect(kUVTopLeft, kUVBottomRight),
-                         candidate.uv_rect);
-    if (!candidate.clip_rect.IsEmpty()) {
-      EXPECT_EQ(true, candidate.is_clipped);
-      EXPECT_EQ(kOverlayClipRect, candidate.clip_rect);
+    for (const auto& r : expected_rects_) {
+      const float kAbsoluteError = 0.01f;
+      if (std::abs(r.x() - candidate.display_rect.x()) <= kAbsoluteError &&
+          std::abs(r.y() - candidate.display_rect.y()) <= kAbsoluteError &&
+          std::abs(r.width() - candidate.display_rect.width()) <=
+              kAbsoluteError &&
+          std::abs(r.height() - candidate.display_rect.height()) <=
+              kAbsoluteError) {
+        EXPECT_FLOAT_RECT_EQ(BoundingRect(kUVTopLeft, kUVBottomRight),
+                             candidate.uv_rect);
+        if (!candidate.clip_rect.IsEmpty()) {
+          EXPECT_EQ(true, candidate.is_clipped);
+          EXPECT_EQ(kOverlayClipRect, candidate.clip_rect);
+        }
+        candidate.overlay_handled = true;
+        return;
+      }
     }
-    candidate.overlay_handled = true;
+    // We should find one rect in expected_rects_that matches candidate.
+    EXPECT_TRUE(false);
   }
 
-  void SetExpectedRect(const gfx::RectF& rect) { expected_rect_ = rect; }
+  void AddExpectedRect(const gfx::RectF& rect) {
+    expected_rects_.push_back(rect);
+  }
 
  private:
-  gfx::RectF expected_rect_;
+  std::vector<gfx::RectF> expected_rects_;
 };
 
 class CALayerValidator : public OverlayCandidateValidator {
@@ -671,6 +681,49 @@
   EXPECT_EQ(original_resource_id, candidate_list.back().resource_id);
 }
 
+TEST_F(SingleOverlayOnTopTest, PrioritizeBiggerOne) {
+  std::unique_ptr<RenderPass> pass = CreateRenderPass();
+  // Add a small quad.
+  const auto kSmallCandidateRect = gfx::Rect(0, 0, 16, 16);
+  CreateCandidateQuadAt(resource_provider_.get(),
+                        pass->shared_quad_state_list.back(), pass.get(),
+                        kSmallCandidateRect);
+  output_surface_->GetOverlayCandidateValidator()->AddExpectedRect(
+      gfx::RectF(kSmallCandidateRect));
+
+  // Add a bigger quad below the previous one, but not occluded.
+  const auto kBigCandidateRect = gfx::Rect(20, 20, 32, 32);
+  TextureDrawQuad* quad_big = CreateCandidateQuadAt(
+      resource_provider_.get(), pass->shared_quad_state_list.back(), pass.get(),
+      kBigCandidateRect);
+  output_surface_->GetOverlayCandidateValidator()->AddExpectedRect(
+      gfx::RectF(kBigCandidateRect));
+
+  unsigned resource_big = quad_big->resource_id();
+
+  // Add something behind it.
+  CreateFullscreenOpaqueQuad(resource_provider_.get(),
+                             pass->shared_quad_state_list.back(), pass.get());
+
+  // Check for potential candidates.
+  OverlayCandidateList candidate_list;
+  RenderPassFilterList render_pass_filters;
+  RenderPassFilterList render_pass_background_filters;
+  overlay_processor_->ProcessForOverlays(
+      resource_provider_.get(), pass.get(), render_pass_filters,
+      render_pass_background_filters, &candidate_list, nullptr, nullptr,
+      &damage_rect_, &content_bounds_);
+  ASSERT_EQ(1U, candidate_list.size());
+
+  RenderPass* main_pass = pass.get();
+  // Check that one quad is gone.
+  EXPECT_EQ(2U, main_pass->quad_list.size());
+  // Check that we have only one overlay.
+  EXPECT_EQ(1U, candidate_list.size());
+  // Check that the right resource id (bigger quad) got extracted.
+  EXPECT_EQ(resource_big, candidate_list.front().resource_id);
+}
+
 TEST_F(SingleOverlayOnTopTest, DamageRect) {
   std::unique_ptr<RenderPass> pass = CreateRenderPass();
   CreateFullscreenCandidateQuad(resource_provider_.get(),
@@ -1029,7 +1082,7 @@
 }
 
 TEST_F(SingleOverlayOnTopTest, AllowNotTopIfNotOccluded) {
-  output_surface_->GetOverlayCandidateValidator()->SetExpectedRect(
+  output_surface_->GetOverlayCandidateValidator()->AddExpectedRect(
       gfx::RectF(kOverlayBottomRightRect));
 
   std::unique_ptr<RenderPass> pass = CreateRenderPass();
@@ -1052,7 +1105,7 @@
 }
 
 TEST_F(SingleOverlayOnTopTest, AllowTransparentOnTop) {
-  output_surface_->GetOverlayCandidateValidator()->SetExpectedRect(
+  output_surface_->GetOverlayCandidateValidator()->AddExpectedRect(
       gfx::RectF(kOverlayBottomRightRect));
 
   std::unique_ptr<RenderPass> pass = CreateRenderPass();
@@ -1076,7 +1129,7 @@
 }
 
 TEST_F(SingleOverlayOnTopTest, AllowTransparentColorOnTop) {
-  output_surface_->GetOverlayCandidateValidator()->SetExpectedRect(
+  output_surface_->GetOverlayCandidateValidator()->AddExpectedRect(
       gfx::RectF(kOverlayBottomRightRect));
 
   std::unique_ptr<RenderPass> pass = CreateRenderPass();
@@ -1218,7 +1271,7 @@
 }
 
 TEST_F(UnderlayTest, OverlayLayerUnderMainLayer) {
-  output_surface_->GetOverlayCandidateValidator()->SetExpectedRect(
+  output_surface_->GetOverlayCandidateValidator()->AddExpectedRect(
       gfx::RectF(kOverlayBottomRightRect));
 
   std::unique_ptr<RenderPass> pass = CreateRenderPass();
@@ -1318,7 +1371,7 @@
 TEST_F(UnderlayTest, DamageNotSubtractedForNonIdenticalConsecutiveUnderlays) {
   gfx::Rect overlay_rects[] = {kOverlayBottomRightRect, kOverlayRect};
   for (int i = 0; i < 2; ++i) {
-    output_surface_->GetOverlayCandidateValidator()->SetExpectedRect(
+    output_surface_->GetOverlayCandidateValidator()->AddExpectedRect(
         gfx::RectF(overlay_rects[i]));
 
     std::unique_ptr<RenderPass> pass = CreateRenderPass();
@@ -1366,7 +1419,7 @@
 }
 
 TEST_F(UnderlayTest, DamageSubtractedWhenQuadsAboveDontOverlap) {
-  output_surface_->GetOverlayCandidateValidator()->SetExpectedRect(
+  output_surface_->GetOverlayCandidateValidator()->AddExpectedRect(
       gfx::RectF(kOverlayBottomRightRect));
 
   for (int i = 0; i < 2; ++i) {
@@ -1429,7 +1482,7 @@
 }
 
 TEST_F(UnderlayCastTest, BlackOutsideOverlayContentBounds) {
-  output_surface_->GetOverlayCandidateValidator()->SetExpectedRect(
+  output_surface_->GetOverlayCandidateValidator()->AddExpectedRect(
       gfx::RectF(kOverlayBottomRightRect));
 
   const gfx::Rect kLeftSide(0, 0, 128, 256);
@@ -1507,7 +1560,7 @@
   // Check rounding behaviour on overlay quads.  Be conservative (content
   // potentially visible on boundary).
   const gfx::Rect overlay_rect(1, 1, 8, 8);
-  output_surface_->GetOverlayCandidateValidator()->SetExpectedRect(
+  output_surface_->GetOverlayCandidateValidator()->AddExpectedRect(
       gfx::RectF(1.5f, 1.5f, 8, 8));
 
   gfx::Transform transform;
@@ -1538,7 +1591,7 @@
   // rect).
   gfx::Rect overlay_rect = kOverlayRect;
   overlay_rect.Inset(0, 0, 1, 1);
-  output_surface_->GetOverlayCandidateValidator()->SetExpectedRect(
+  output_surface_->GetOverlayCandidateValidator()->AddExpectedRect(
       gfx::RectF(0.5f, 0.5f, 255, 255));
 
   gfx::Transform transform;
@@ -1912,7 +1965,7 @@
   bool use_validator = true;
   Init(use_validator);
   renderer_->set_expect_overlays(true);
-  output_surface_->GetOverlayCandidateValidator()->SetExpectedRect(
+  output_surface_->GetOverlayCandidateValidator()->AddExpectedRect(
       gfx::RectF(kOverlayBottomRightRect));
 
   gfx::Size viewport_size(16, 16);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
index 8a5a25f..cabf212d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
@@ -824,7 +824,7 @@
         FeatureUtilities.setIsInMultiWindowMode(
                 MultiWindowUtils.getInstance().isInMultiWindowMode(this));
 
-        VideoPersister.getInstance().stopPersist(this);
+        VideoPersister.getInstance().stopIfPersisted(this);
     }
 
     @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/VideoPersister.java b/chrome/android/java/src/org/chromium/chrome/browser/media/VideoPersister.java
index 09e79621..c0a7828 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/media/VideoPersister.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/media/VideoPersister.java
@@ -7,6 +7,7 @@
 import org.chromium.base.ThreadUtils;
 import org.chromium.chrome.browser.AppHooks;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.tab.Tab;
 
 /**
  * Utilities for persisting fullscreen video on Chrome exit.
@@ -27,6 +28,21 @@
         return sInstance;
     }
 
-    public void attemptPersist(ChromeActivity activity) { }
-    public void stopPersist(ChromeActivity activity) { }
+    /**
+     * If this method returns true, a tab should not toggle fullscreen. Calling this method queues
+     * a fullscreen toggle at an appropriate later time.
+     */
+    public boolean shouldDelayFullscreenModeChange(Tab tab, boolean fullscreen) {
+        return false;
+    }
+
+    /**
+     * This method will persist a video if possible.
+     */
+    public void attemptPersist(ChromeActivity activity) {}
+
+    /**
+     * If the video has been persisted, perform cleanup.
+     */
+    public void stopIfPersisted(ChromeActivity activity) {}
 }
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 c833e89..baf1a596 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
@@ -304,7 +304,11 @@
         final TextView searchBoxTextView = (TextView) mSearchBoxView
                 .findViewById(R.id.search_box_text);
 
-        if (!ChromeFeatureList.isEnabled(ChromeFeatureList.NTP_SHOW_GOOGLE_G_IN_OMNIBOX)) {
+        boolean isTablet = DeviceFormFactor.isTablet(getContext());
+
+        // If the Google G should not be shown then clear it because it is shown by default in xml.
+        if (isTablet
+                || !ChromeFeatureList.isEnabled(ChromeFeatureList.NTP_SHOW_GOOGLE_G_IN_OMNIBOX)) {
             searchBoxTextView.setCompoundDrawablePadding(0);
 
             // Not using the relative version of this call because we only want to clear
@@ -313,7 +317,7 @@
         }
 
         String hintText = getResources().getString(R.string.search_or_type_url);
-        if (!DeviceFormFactor.isTablet(getContext()) || mManager.isFakeOmniboxTextEnabledTablet()) {
+        if (!isTablet || mManager.isFakeOmniboxTextEnabledTablet()) {
             searchBoxTextView.setHint(hintText);
         } else {
             searchBoxTextView.setContentDescription(hintText);
@@ -519,7 +523,8 @@
         if (hasLogo == mSearchProviderHasLogo && mInitialized) return;
         mSearchProviderHasLogo = hasLogo;
         boolean showLogo = mSearchProviderHasLogo
-                && !ChromeFeatureList.isEnabled(ChromeFeatureList.NTP_CONDENSED_LAYOUT);
+                && (DeviceFormFactor.isTablet(getContext())
+                           || !ChromeFeatureList.isEnabled(ChromeFeatureList.NTP_CONDENSED_LAYOUT));
 
         // Set a bit more top padding on the tile grid if there is no logo.
         int paddingTop = getResources().getDimensionPixelSize(showLogo
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
index da0941d..1f8767d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
@@ -2452,6 +2452,21 @@
     }
 
     /**
+     * Toggles fullscreen mode and notifies all observers.
+     * @param enableFullscreen Whether fullscreen should be enabled.
+     */
+    public void toggleFullscreenMode(boolean enableFullscreen) {
+        if (mFullscreenManager != null) {
+            mFullscreenManager.setPersistentFullscreenMode(enableFullscreen);
+        }
+
+        RewindableIterator<TabObserver> observers = getTabObservers();
+        while (observers.hasNext()) {
+            observers.next().onToggleFullscreenMode(this, enableFullscreen);
+        }
+    }
+
+    /**
      * Called when offset values related with fullscreen functionality has been changed by the
      * compositor.
      * @param topControlsOffsetY The Y offset of the top controls in physical pixels.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsDelegateAndroid.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsDelegateAndroid.java
index 837ccba..faecfb4f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsDelegateAndroid.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsDelegateAndroid.java
@@ -31,6 +31,7 @@
 import org.chromium.chrome.browser.findinpage.FindNotificationDetails;
 import org.chromium.chrome.browser.fullscreen.FullscreenManager;
 import org.chromium.chrome.browser.media.MediaCaptureNotificationService;
+import org.chromium.chrome.browser.media.VideoPersister;
 import org.chromium.chrome.browser.policy.PolicyAuditor;
 import org.chromium.chrome.browser.policy.PolicyAuditor.AuditEvent;
 import org.chromium.chrome.browser.tabmodel.TabCreatorManager.TabCreator;
@@ -214,13 +215,8 @@
 
     @Override
     public void toggleFullscreenModeForTab(boolean enableFullscreen) {
-        if (mTab.getFullscreenManager() != null) {
-            mTab.getFullscreenManager().setPersistentFullscreenMode(enableFullscreen);
-        }
-
-        RewindableIterator<TabObserver> observers = mTab.getTabObservers();
-        while (observers.hasNext()) {
-            observers.next().onToggleFullscreenMode(mTab, enableFullscreen);
+        if (!VideoPersister.getInstance().shouldDelayFullscreenModeChange(mTab, enableFullscreen)) {
+            mTab.toggleFullscreenMode(enableFullscreen);
         }
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java
index c0801f5..3f7d2328 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java
@@ -102,7 +102,7 @@
         WebappInfo newWebappInfo = createWebappInfo(intent);
         if (newWebappInfo == null) {
             Log.e(TAG, "Failed to parse new Intent: " + intent);
-            finish();
+            ApiCompatibilityUtils.finishAndRemoveTask(this);
         } else if (!TextUtils.equals(mWebappInfo.id(), newWebappInfo.id())) {
             mWebappInfo = newWebappInfo;
             resetSavedInstanceState();
@@ -165,7 +165,10 @@
 
     @Override
     public void finishNativeInitialization() {
-        if (!mWebappInfo.isInitialized()) finish();
+        if (!mWebappInfo.isInitialized()) {
+            ApiCompatibilityUtils.finishAndRemoveTask(this);
+            return;
+        }
         super.finishNativeInitialization();
         initializeUI(getSavedInstanceState());
         mIsInitialized = true;
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd
index 2d783596..504da7a 100644
--- a/chrome/android/java/strings/android_chrome_strings.grd
+++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -2093,13 +2093,13 @@
         <ph name="BEGIN_LINK">&lt;link&gt;</ph>Learn more<ph name="END_LINK">&lt;/link&gt;</ph> about suggested content
       </message>
       <message name="IDS_NTP_ALL_DISMISSED_BODY_TEXT_MORNING" desc="Body text shown in the morning on the New Tab Page when all suggested content has been dismissed.">
-        More articles will appear soon. Enjoy your morning.
+        More articles will appear soon. Enjoy your morning!
       </message>
       <message name="IDS_NTP_ALL_DISMISSED_BODY_TEXT_AFTERNOON" desc="Body text shown in the afternoon on the New Tab Page when all suggested content has been dismissed.">
-        More articles will appear soon. Enjoy your afternoon.
+        More articles will appear soon. Enjoy your afternoon!
       </message>
       <message name="IDS_NTP_ALL_DISMISSED_BODY_TEXT_EVENING" desc="Body text shown in the evening on the New Tab Page when all suggested content has been dismissed.">
-        More articles will appear soon. Enjoy your evening.
+        More articles will appear soon. Enjoy your evening!
       </message>
       <message name="IDS_NTP_ALL_DISMISSED_REFRESH" desc="Text label for button to refresh the New Tab Page when all suggested content has been dismissed. [CHAR-LIMIT=20]">
         Refresh
diff --git a/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkServiceConnectionManager.java b/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkServiceConnectionManager.java
index a2bcd65..2ef8453 100644
--- a/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkServiceConnectionManager.java
+++ b/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkServiceConnectionManager.java
@@ -144,6 +144,10 @@
      * @param webApkPackage WebAPK package for the service to disconnect from.
      */
     public void disconnect(final Context appContext, String webApkPackage) {
+        if (webApkPackage == null) {
+            return;
+        }
+
         final Connection connection = mConnections.remove(webApkPackage);
         if (connection == null) {
             return;
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 9202721..e6850d4 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -6471,6 +6471,12 @@
         <message name="IDS_FLAGS_MAC_VIEWS_NATIVE_APP_WINDOWS_DESCRIPTION" desc="Description of flag to enable or disable toolkit-views Chrome App windows on Mac.">
           Controls whether to use Toolkit-Views based Chrome App windows.
         </message>
+        <message name="IDS_FLAGS_MAC_VIEWS_TASK_MANAGER_NAME" desc="Name of the flag to enable or disable the toolkit-views Task Manager on Mac.">
+          Toolkit-Views Task Manager.
+        </message>
+        <message name="IDS_FLAGS_MAC_VIEWS_TASK_MANAGER_DESCRIPTION" desc="Description of the flag to enable or disable the toolkit-views Task Manager on Mac.">
+          Controls whether to use the Toolkit-Views based Task Manager.
+        </message>
         <message name="IDS_FLAGS_APP_WINDOW_CYCLING_NAME" desc="Name of the flag to enable or disable custom Cmd+` App window cycling on Mac.">
           Custom Window Cycling for Chrome Apps.
         </message>
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 877cbac..88f243a 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -1650,6 +1650,9 @@
      IDS_FLAGS_MAC_VIEWS_NATIVE_APP_WINDOWS_DESCRIPTION, kOsMac,
      ENABLE_DISABLE_VALUE_TYPE(switches::kEnableMacViewsNativeAppWindows,
                                switches::kDisableMacViewsNativeAppWindows)},
+    {"mac-views-task-manager", IDS_FLAGS_MAC_VIEWS_TASK_MANAGER_NAME,
+     IDS_FLAGS_MAC_VIEWS_TASK_MANAGER_DESCRIPTION, kOsMac,
+     FEATURE_VALUE_TYPE(features::kViewsTaskManager)},
     {"app-window-cycling", IDS_FLAGS_APP_WINDOW_CYCLING_NAME,
      IDS_FLAGS_APP_WINDOW_CYCLING_DESCRIPTION, kOsMac,
      ENABLE_DISABLE_VALUE_TYPE(switches::kEnableAppWindowCycling,
diff --git a/chrome/browser/ui/cocoa/task_manager_mac.mm b/chrome/browser/ui/cocoa/task_manager_mac.mm
index 178681ab..47d67577 100644
--- a/chrome/browser/ui/cocoa/task_manager_mac.mm
+++ b/chrome/browser/ui/cocoa/task_manager_mac.mm
@@ -9,6 +9,7 @@
 #include <algorithm>
 #include <vector>
 
+#include "base/feature_list.h"
 #include "base/mac/bundle_locations.h"
 #include "base/macros.h"
 #include "base/strings/sys_string_conversions.h"
@@ -19,6 +20,7 @@
 #include "chrome/browser/ui/browser_dialogs.h"
 #import "chrome/browser/ui/cocoa/window_size_autosaver.h"
 #include "chrome/browser/ui/task_manager/task_manager_columns.h"
+#include "chrome/common/chrome_features.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/prefs/pref_service.h"
@@ -35,6 +37,10 @@
   return [NSString stringWithFormat:@"%d", id];
 }
 
+bool ShouldUseViewsTaskManager() {
+  return base::FeatureList::IsEnabled(features::kViewsTaskManager);
+}
+
 }  // namespace
 
 @interface TaskManagerWindowController (Private)
@@ -639,10 +645,14 @@
 
 // Declared in browser_dialogs.h.
 task_manager::TaskManagerTableModel* ShowTaskManager(Browser* browser) {
+  if (ShouldUseViewsTaskManager())
+    return chrome::ShowTaskManagerViews(browser);
   return task_manager::TaskManagerMac::Show();
 }
 
 void HideTaskManager() {
+  if (ShouldUseViewsTaskManager())
+    return chrome::HideTaskManagerViews();
   task_manager::TaskManagerMac::Hide();
 }
 
diff --git a/chrome/browser/ui/views/payments/credit_card_editor_view_controller.cc b/chrome/browser/ui/views/payments/credit_card_editor_view_controller.cc
index f3c9034..afff0949 100644
--- a/chrome/browser/ui/views/payments/credit_card_editor_view_controller.cc
+++ b/chrome/browser/ui/views/payments/credit_card_editor_view_controller.cc
@@ -190,7 +190,7 @@
     return false;
 
   // Add the card (will not add a duplicate).
-  request()->GetPersonalDataManager()->AddCreditCard(credit_card);
+  request()->state()->GetPersonalDataManager()->AddCreditCard(credit_card);
 
   return true;
 }
diff --git a/chrome/browser/ui/views/payments/order_summary_view_controller.cc b/chrome/browser/ui/views/payments/order_summary_view_controller.cc
index 47b61d71..d8b1a9c 100644
--- a/chrome/browser/ui/views/payments/order_summary_view_controller.cc
+++ b/chrome/browser/ui/views/payments/order_summary_view_controller.cc
@@ -118,7 +118,7 @@
         CreateLineItemView(
             base::UTF8ToUTF16(
                 request()->spec()->details().display_items[i]->label),
-            request()->GetFormattedCurrencyAmount(
+            request()->spec()->GetFormattedCurrencyAmount(
                 request()->spec()->details().display_items[i]->amount->value),
             false, view_id)
             .release());
@@ -127,7 +127,7 @@
   base::string16 total_label_value = l10n_util::GetStringFUTF16(
       IDS_PAYMENT_REQUEST_ORDER_SUMMARY_SHEET_TOTAL_FORMAT,
       base::UTF8ToUTF16(request()->spec()->details().total->amount->currency),
-      request()->GetFormattedCurrencyAmount(
+      request()->spec()->GetFormattedCurrencyAmount(
           request()->spec()->details().total->amount->value));
 
   content_view->AddChildView(
diff --git a/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc b/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
index 384a00b..031f804a 100644
--- a/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
+++ b/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
@@ -352,8 +352,9 @@
         new views::Label(base::ASCIIToUTF16(items[i]->label)));
 
     item_amounts_layout->StartRow(0, 0);
-    item_amounts_layout->AddView(new views::Label(
-        request()->GetFormattedCurrencyAmount(items[i]->amount->value)));
+    item_amounts_layout->AddView(
+        new views::Label(request()->spec()->GetFormattedCurrencyAmount(
+            items[i]->amount->value)));
   }
 
   int hidden_item_count = items.size() - kMaxNumberOfItemsShown;
@@ -382,8 +383,8 @@
       CreateBoldLabel(
           l10n_util::GetStringFUTF16(
               IDS_PAYMENT_REQUEST_ORDER_SUMMARY_SHEET_TOTAL_FORMAT,
-              base::UTF8ToUTF16(request()->GetFormattedCurrencyCode()),
-              request()->GetFormattedCurrencyAmount(
+              base::UTF8ToUTF16(request()->spec()->GetFormattedCurrencyCode()),
+              request()->spec()->GetFormattedCurrencyAmount(
                   request()->spec()->details().total->amount->value)))
           .release());
 
@@ -408,7 +409,7 @@
 
   return profile ? payments::GetShippingAddressLabel(
                        AddressStyleType::SUMMARY,
-                       request()->GetApplicationLocale(), *profile)
+                       request()->state()->GetApplicationLocale(), *profile)
                  : base::MakeUnique<views::Label>(base::string16());
 }
 
@@ -484,15 +485,15 @@
 
 std::unique_ptr<views::View>
 PaymentSheetViewController::CreateContactInfoSectionContent() {
-  auto* profile = request()->state()->selected_contact_profile();
-
-  return profile
-             ? payments::GetContactInfoLabel(
-                   AddressStyleType::SUMMARY, request()->GetApplicationLocale(),
-                   *profile, request()->spec()->request_payer_name(),
-                   request()->spec()->request_payer_phone(),
-                   request()->spec()->request_payer_email())
-             : base::MakeUnique<views::Label>(base::string16());
+  autofill::AutofillProfile* profile =
+      request()->state()->selected_contact_profile();
+  return profile ? payments::GetContactInfoLabel(
+                       AddressStyleType::SUMMARY,
+                       request()->state()->GetApplicationLocale(), *profile,
+                       request()->spec()->request_payer_name(),
+                       request()->spec()->request_payer_phone(),
+                       request()->spec()->request_payer_email())
+                 : base::MakeUnique<views::Label>(base::string16());
 }
 
 // Creates the Contact Info row, which contains a "Contact info" label; the
@@ -521,9 +522,10 @@
   payments::mojom::PaymentShippingOption* selected_option =
       request()->state()->selected_shipping_option();
   std::unique_ptr<views::View> option_label = CreateShippingOptionLabel(
-      selected_option, selected_option ? request()->GetFormattedCurrencyAmount(
-                                             selected_option->amount->value)
-                                       : base::ASCIIToUTF16(""));
+      selected_option, selected_option
+                           ? request()->spec()->GetFormattedCurrencyAmount(
+                                 selected_option->amount->value)
+                           : base::ASCIIToUTF16(""));
   std::unique_ptr<views::Button> section = CreatePaymentSheetRow(
       this,
       GetShippingOptionSectionString(
diff --git a/chrome/browser/ui/views/payments/profile_list_view_controller.cc b/chrome/browser/ui/views/payments/profile_list_view_controller.cc
index 931635c..ba95e87 100644
--- a/chrome/browser/ui/views/payments/profile_list_view_controller.cc
+++ b/chrome/browser/ui/views/payments/profile_list_view_controller.cc
@@ -94,7 +94,8 @@
   std::unique_ptr<views::View> GetLabel(
       autofill::AutofillProfile* profile) override {
     return GetShippingAddressLabel(AddressStyleType::DETAILED,
-                                   request()->GetApplicationLocale(), *profile);
+                                   request()->state()->GetApplicationLocale(),
+                                   *profile);
   }
 
   std::vector<autofill::AutofillProfile*> GetProfiles() override {
@@ -121,11 +122,11 @@
   // ProfileListViewController:
   std::unique_ptr<views::View> GetLabel(
       autofill::AutofillProfile* profile) override {
-    return GetContactInfoLabel(AddressStyleType::DETAILED,
-                               request()->GetApplicationLocale(), *profile,
-                               request()->spec()->request_payer_name(),
-                               request()->spec()->request_payer_phone(),
-                               request()->spec()->request_payer_email());
+    return GetContactInfoLabel(
+        AddressStyleType::DETAILED, request()->state()->GetApplicationLocale(),
+        *profile, request()->spec()->request_payer_name(),
+        request()->spec()->request_payer_phone(),
+        request()->spec()->request_payer_email());
   }
 
   std::vector<autofill::AutofillProfile*> GetProfiles() override {
diff --git a/chrome/browser/ui/views/payments/shipping_option_view_controller.cc b/chrome/browser/ui/views/payments/shipping_option_view_controller.cc
index ad68373..78c2b16 100644
--- a/chrome/browser/ui/views/payments/shipping_option_view_controller.cc
+++ b/chrome/browser/ui/views/payments/shipping_option_view_controller.cc
@@ -6,6 +6,7 @@
 
 #include "chrome/browser/ui/views/payments/payment_request_views_util.h"
 #include "components/payments/content/payment_request.h"
+#include "components/payments/content/payment_request_spec.h"
 
 namespace payments {
 
@@ -25,8 +26,8 @@
   // payments::PaymentRequestItemList::Item:
   std::unique_ptr<views::View> CreateItemView() override {
     return CreateShippingOptionLabel(
-        shipping_option_,
-        request()->GetFormattedCurrencyAmount(shipping_option_->amount->value));
+        shipping_option_, request()->spec()->GetFormattedCurrencyAmount(
+                              shipping_option_->amount->value));
   }
 
   void SelectedStateChanged() override {}
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc
index 77a675b..786a279 100644
--- a/chrome/common/chrome_features.cc
+++ b/chrome/common/chrome_features.cc
@@ -21,6 +21,10 @@
 // Enables Javascript execution via AppleScript.
 const base::Feature kAppleScriptExecuteJavaScript{
     "AppleScriptExecuteJavaScript", base::FEATURE_ENABLED_BY_DEFAULT};
+
+// Use the Toolkit-Views Task Manager window.
+const base::Feature kViewsTaskManager{"ViewsTaskManager",
+                                      base::FEATURE_DISABLED_BY_DEFAULT};
 #endif  // defined(OS_MACOSX)
 
 #if defined(OS_CHROMEOS)
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h
index 71efa21e..f44f462 100644
--- a/chrome/common/chrome_features.h
+++ b/chrome/common/chrome_features.h
@@ -24,6 +24,7 @@
 
 #if defined(OS_MACOSX)
 extern const base::Feature kAppleScriptExecuteJavaScript;
+extern const base::Feature kViewsTaskManager;
 #endif  // defined(OS_MACOSX)
 
 #if defined(OS_CHROMEOS)
diff --git a/components/cronet/android/api.txt b/components/cronet/android/api.txt
index ca10e4ff..a646d96 100644
--- a/components/cronet/android/api.txt
+++ b/components/cronet/android/api.txt
@@ -2,6 +2,7 @@
 
 public class org.chromium.net.ApiVersion {
   public static java.lang.String getCronetVersionWithLastChange();
+  public static int getMaximumAvailableApiLevel();
   public static int getApiLevel();
   public static java.lang.String getCronetVersion();
   public static java.lang.String getLastChange();
diff --git a/components/cronet/android/api/src/org/chromium/net/ApiVersion.template b/components/cronet/android/api/src/org/chromium/net/ApiVersion.template
index ca8114cb..4c32f80 100644
--- a/components/cronet/android/api/src/org/chromium/net/ApiVersion.template
+++ b/components/cronet/android/api/src/org/chromium/net/ApiVersion.template
@@ -11,6 +11,16 @@
 public class ApiVersion {
     private static final String CRONET_VERSION = "@MAJOR@.@MINOR@.@BUILD@.@PATCH@";
     private static final int API_LEVEL = @API_LEVEL@;
+    /**
+     * The minimum API level of implementations that are compatible with this API.
+     * The last API level which broke backwards API compatibility. In other words, the
+     * Cronet API that this class is part of won't work with Cronet implementations that implement
+     * API levels less than this value. That is if
+     * ImplVersion.getApiLevel() < ApiVersion.getApiLevel(), then the Cronet implementation
+     * providing ImplVersion cannot be used with the Cronet API providing ApiVersion; if they are
+     * used together various unexpected Errors, like AbstractMethodError, may result.
+     */
+    private static final int MIN_COMPATIBLE_API_LEVEL = 3;
     private static final String LAST_CHANGE = "@LASTCHANGE@";
 
     /**
@@ -22,10 +32,27 @@
         return CRONET_VERSION + "@" + LAST_CHANGE.substring(0, 8);
     }
 
-    public static int getApiLevel() {
+    /**
+     * Returns API level of the API linked into the application. This is the maximum API
+     * level the application can use, even if the application is run with a newer implementation.
+     */
+    public static int getMaximumAvailableApiLevel() {
         return API_LEVEL;
     }
 
+    /**
+     * The minimum API level of implementations that are compatible with this API.
+     * Returns the last API level which broke backwards API compatibility. In other words, the
+     * Cronet API that this class is part of won't work with Cronet implementations that implement
+     * API levels less than this value. That is if
+     * ImplVersion.getApiLevel() < ApiVersion.getApiLevel(), then the Cronet implementation
+     * providing ImplVersion cannot be used with the Cronet API providing ApiVersion; if they are
+     * used together various unexpected Errors, like AbstractMethodError, may result.
+     */
+    public static int getApiLevel() {
+        return MIN_COMPATIBLE_API_LEVEL;
+    }
+
     public static String getCronetVersion() {
         return CRONET_VERSION;
     }
diff --git a/components/cronet/android/api_version.txt b/components/cronet/android/api_version.txt
index e440e5c..bf0d87a 100644
--- a/components/cronet/android/api_version.txt
+++ b/components/cronet/android/api_version.txt
@@ -1 +1 @@
-3
\ No newline at end of file
+4
\ No newline at end of file
diff --git a/components/favicon/ios/web_favicon_driver.mm b/components/favicon/ios/web_favicon_driver.mm
index 47011b0..500a5f4 100644
--- a/components/favicon/ios/web_favicon_driver.mm
+++ b/components/favicon/ios/web_favicon_driver.mm
@@ -77,8 +77,8 @@
 
   image_fetcher::IOSImageDataFetcherCallback local_callback =
       ^(NSData* data, const image_fetcher::RequestMetadata& metadata) {
-        if (metadata.response_code ==
-            image_fetcher::ImageDataFetcher::RESPONSE_CODE_INVALID)
+        if (metadata.http_response_code ==
+            image_fetcher::RequestMetadata::RESPONSE_CODE_INVALID)
           return;
 
         std::vector<SkBitmap> frames;
@@ -89,7 +89,7 @@
             sizes.push_back(gfx::Size(frame.width(), frame.height()));
           }
         }
-        callback.Run(local_download_id, metadata.response_code, local_url,
+        callback.Run(local_download_id, metadata.http_response_code, local_url,
                      frames, sizes);
       };
   image_fetcher_.FetchImageDataWebpDecoded(url, local_callback);
diff --git a/components/image_fetcher/image_data_fetcher.cc b/components/image_fetcher/image_data_fetcher.cc
index 204fa95d..f066673 100644
--- a/components/image_fetcher/image_data_fetcher.cc
+++ b/components/image_fetcher/image_data_fetcher.cc
@@ -8,7 +8,6 @@
 #include "net/http/http_response_headers.h"
 #include "net/http/http_status_code.h"
 #include "net/url_request/url_fetcher.h"
-#include "net/url_request/url_request.h"
 #include "net/url_request/url_request_context_getter.h"
 #include "net/url_request/url_request_status.h"
 #include "url/gurl.h"
@@ -82,12 +81,12 @@
   bool success = source->GetStatus().status() == net::URLRequestStatus::SUCCESS;
 
   RequestMetadata metadata;
-  metadata.response_code = RESPONSE_CODE_INVALID;
   if (success && source->GetResponseHeaders()) {
     source->GetResponseHeaders()->GetMimeType(&metadata.mime_type);
-    metadata.response_code = source->GetResponseHeaders()->response_code();
-    success &= (metadata.response_code == net::HTTP_OK);
+    metadata.http_response_code = source->GetResponseHeaders()->response_code();
+    success &= (metadata.http_response_code == net::HTTP_OK);
   }
+  metadata.from_http_cache = source->WasCached();
 
   std::string image_data;
   if (success) {
diff --git a/components/image_fetcher/image_data_fetcher.h b/components/image_fetcher/image_data_fetcher.h
index d05ec3d..fbf544f 100644
--- a/components/image_fetcher/image_data_fetcher.h
+++ b/components/image_fetcher/image_data_fetcher.h
@@ -14,7 +14,6 @@
 #include "base/memory/ref_counted.h"
 #include "components/data_use_measurement/core/data_use_user_data.h"
 #include "components/image_fetcher/request_metadata.h"
-#include "net/url_request/url_fetcher.h"
 #include "net/url_request/url_fetcher_delegate.h"
 #include "net/url_request/url_request.h"
 #include "url/gurl.h"
@@ -28,11 +27,6 @@
 
 class ImageDataFetcher : public net::URLFetcherDelegate {
  public:
-  // Impossible http response code. Used to signal that no http response code
-  // was received.
-  enum ResponseCode {
-    RESPONSE_CODE_INVALID = net::URLFetcher::RESPONSE_CODE_INVALID
-  };
 
   // Callback with the |image_data|. If an error prevented a http response,
   // |request_metadata.response_code| will be RESPONSE_CODE_INVALID.
diff --git a/components/image_fetcher/image_data_fetcher_unittest.cc b/components/image_fetcher/image_data_fetcher_unittest.cc
index 15039781..e8d240f 100644
--- a/components/image_fetcher/image_data_fetcher_unittest.cc
+++ b/components/image_fetcher/image_data_fetcher_unittest.cc
@@ -65,7 +65,7 @@
 
   RequestMetadata expected_metadata;
   expected_metadata.mime_type = std::string("image/png");
-  expected_metadata.response_code = net::HTTP_OK;
+  expected_metadata.http_response_code = net::HTTP_OK;
   EXPECT_CALL(*this, OnImageDataFetched(std::string(kURLResponseData),
                                         expected_metadata));
 
@@ -90,6 +90,40 @@
   test_url_fetcher->delegate()->OnURLFetchComplete(test_url_fetcher);
 }
 
+TEST_F(ImageDataFetcherTest, FetchImageData_FromCache) {
+  image_data_fetcher_.FetchImageData(
+      GURL(kImageURL), base::Bind(&ImageDataFetcherTest::OnImageDataFetched,
+                                  base::Unretained(this)));
+
+  RequestMetadata expected_metadata;
+  expected_metadata.mime_type = std::string("image/png");
+  expected_metadata.http_response_code = net::HTTP_OK;
+  expected_metadata.from_http_cache = true;
+  EXPECT_CALL(*this, OnImageDataFetched(std::string(kURLResponseData),
+                                        expected_metadata));
+
+  // Get and configure the TestURLFetcher.
+  net::TestURLFetcher* test_url_fetcher = fetcher_factory_.GetFetcherByID(0);
+  ASSERT_NE(nullptr, test_url_fetcher);
+  test_url_fetcher->set_status(
+      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, net::OK));
+  test_url_fetcher->SetResponseString(kURLResponseData);
+  test_url_fetcher->set_response_code(net::HTTP_OK);
+  test_url_fetcher->set_was_cached(true);
+
+  std::string raw_header =
+      "HTTP/1.1 200 OK\n"
+      "Content-type: image/png\n\n";
+  std::replace(raw_header.begin(), raw_header.end(), '\n', '\0');
+  scoped_refptr<net::HttpResponseHeaders> headers(
+      new net::HttpResponseHeaders(raw_header));
+
+  test_url_fetcher->set_response_headers(headers);
+
+  // Call the URLFetcher delegate to continue the test.
+  test_url_fetcher->delegate()->OnURLFetchComplete(test_url_fetcher);
+}
+
 TEST_F(ImageDataFetcherTest, FetchImageData_NotFound) {
   image_data_fetcher_.FetchImageData(
       GURL(kImageURL), base::Bind(&ImageDataFetcherTest::OnImageDataFetched,
@@ -97,7 +131,7 @@
 
   RequestMetadata expected_metadata;
   expected_metadata.mime_type = std::string("image/png");
-  expected_metadata.response_code = net::HTTP_NOT_FOUND;
+  expected_metadata.http_response_code = net::HTTP_NOT_FOUND;
   // For 404, expect an empty result even though correct image data is sent.
   EXPECT_CALL(*this, OnImageDataFetched(std::string(), expected_metadata));
 
@@ -128,7 +162,7 @@
                  base::Unretained(this)));
 
   RequestMetadata expected_metadata;
-  expected_metadata.response_code = net::URLFetcher::RESPONSE_CODE_INVALID;
+  expected_metadata.http_response_code = net::URLFetcher::RESPONSE_CODE_INVALID;
   EXPECT_CALL(
       *this, OnImageDataFetchedFailedRequest(std::string(), expected_metadata));
 
diff --git a/components/image_fetcher/request_metadata.cc b/components/image_fetcher/request_metadata.cc
index 172dc5c..51748cdba 100644
--- a/components/image_fetcher/request_metadata.cc
+++ b/components/image_fetcher/request_metadata.cc
@@ -6,9 +6,13 @@
 
 namespace image_fetcher {
 
+RequestMetadata::RequestMetadata()
+    : http_response_code(RESPONSE_CODE_INVALID), from_http_cache(false) {}
+
 bool operator==(const RequestMetadata& lhs, const RequestMetadata& rhs) {
   return lhs.mime_type == rhs.mime_type &&
-         lhs.response_code == rhs.response_code;
+         lhs.http_response_code == rhs.http_response_code &&
+         lhs.from_http_cache == rhs.from_http_cache;
 }
 
 bool operator!=(const RequestMetadata& lhs, const RequestMetadata& rhs) {
diff --git a/components/image_fetcher/request_metadata.h b/components/image_fetcher/request_metadata.h
index 6b41e2d..03963ee 100644
--- a/components/image_fetcher/request_metadata.h
+++ b/components/image_fetcher/request_metadata.h
@@ -7,13 +7,23 @@
 
 #include <string>
 
+#include "net/url_request/url_fetcher.h"
+
 namespace image_fetcher {
 
 // Metadata for a URL request.
 struct RequestMetadata {
+  // Impossible http response code. Used to signal that no http response code
+  // was received.
+  enum ResponseCode {
+    RESPONSE_CODE_INVALID = net::URLFetcher::RESPONSE_CODE_INVALID
+  };
+
+  RequestMetadata();
+
   std::string mime_type;
-  // HTTP response code.
-  int response_code;
+  int http_response_code;
+  bool from_http_cache;
 };
 
 bool operator==(const RequestMetadata& lhs, const RequestMetadata& rhs);
diff --git a/components/image_fetcher/request_metadata_unittest.cc b/components/image_fetcher/request_metadata_unittest.cc
index ba87ba0..bfda964 100644
--- a/components/image_fetcher/request_metadata_unittest.cc
+++ b/components/image_fetcher/request_metadata_unittest.cc
@@ -13,8 +13,10 @@
   RequestMetadata lhs;
   rhs.mime_type = "testMimeType";
   lhs.mime_type = "testMimeType";
-  rhs.response_code = 1;
-  lhs.response_code = 1;
+  rhs.http_response_code = 1;
+  lhs.http_response_code = 1;
+  rhs.from_http_cache = true;
+  lhs.from_http_cache = true;
 
   EXPECT_EQ(rhs, lhs);
 }
@@ -24,16 +26,22 @@
   RequestMetadata lhs;
   rhs.mime_type = "testMimeType";
   lhs.mime_type = "testMimeType";
-  rhs.response_code = 1;
-  lhs.response_code = 1;
+  rhs.http_response_code = 1;
+  lhs.http_response_code = 1;
+  rhs.from_http_cache = true;
+  lhs.from_http_cache = true;
 
   lhs.mime_type = "testOtherMimeType";
   EXPECT_NE(rhs, lhs);
   lhs.mime_type = "testMimeType";
 
-  lhs.response_code = 2;
+  lhs.http_response_code = 2;
   EXPECT_NE(rhs, lhs);
-  lhs.response_code = 1;
+  lhs.http_response_code = 1;
+
+  lhs.from_http_cache = false;
+  EXPECT_NE(rhs, lhs);
+  lhs.from_http_cache = true;
 }
 
 }  // namespace image_fetcher
diff --git a/components/infobars/core/BUILD.gn b/components/infobars/core/BUILD.gn
index 4b5bf24..103e359 100644
--- a/components/infobars/core/BUILD.gn
+++ b/components/infobars/core/BUILD.gn
@@ -34,6 +34,7 @@
     "//base",
     "//ui/base",
     "//ui/gfx",
+    "//ui/gfx/animation",
     "//ui/strings",
     "//url",
   ]
diff --git a/components/payments/content/payment_request.cc b/components/payments/content/payment_request.cc
index 89a424f4..310cc5ac 100644
--- a/components/payments/content/payment_request.cc
+++ b/components/payments/content/payment_request.cc
@@ -7,10 +7,8 @@
 #include <utility>
 
 #include "base/memory/ptr_util.h"
-#include "components/autofill/core/browser/personal_data_manager.h"
 #include "components/payments/content/payment_details_validation.h"
 #include "components/payments/content/payment_request_web_contents_manager.h"
-#include "components/payments/core/currency_formatter.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/web_contents.h"
 
@@ -50,8 +48,11 @@
   }
   client_ = std::move(client);
   spec_ = base::MakeUnique<PaymentRequestSpec>(
-      std::move(options), std::move(details), std::move(method_data), this);
-  state_ = base::MakeUnique<PaymentRequestState>(spec_.get(), this);
+      std::move(options), std::move(details), std::move(method_data), this,
+      delegate_->GetApplicationLocale());
+  state_ = base::MakeUnique<PaymentRequestState>(
+      spec_.get(), this, delegate_->GetApplicationLocale(),
+      delegate_->GetPersonalDataManager());
 }
 
 void PaymentRequest::Show() {
@@ -91,14 +92,6 @@
   OnConnectionTerminated();
 }
 
-const std::string& PaymentRequest::GetApplicationLocale() {
-  return delegate_->GetApplicationLocale();
-}
-
-autofill::PersonalDataManager* PaymentRequest::GetPersonalDataManager() {
-  return delegate_->GetPersonalDataManager();
-}
-
 void PaymentRequest::OnPaymentResponseAvailable(
     mojom::PaymentResponsePtr response) {
   client_->OnPaymentResponse(std::move(response));
@@ -137,31 +130,4 @@
   state_->GeneratePaymentResponse();
 }
 
-CurrencyFormatter* PaymentRequest::GetOrCreateCurrencyFormatter(
-    const std::string& currency_code,
-    const std::string& currency_system,
-    const std::string& locale_name) {
-  if (!currency_formatter_) {
-    currency_formatter_.reset(
-        new CurrencyFormatter(currency_code, currency_system, locale_name));
-  }
-  return currency_formatter_.get();
-}
-
-base::string16 PaymentRequest::GetFormattedCurrencyAmount(
-    const std::string& amount) {
-  CurrencyFormatter* formatter = GetOrCreateCurrencyFormatter(
-      spec_->details().total->amount->currency,
-      spec_->details().total->amount->currency_system, GetApplicationLocale());
-  return formatter->Format(amount);
-}
-
-std::string PaymentRequest::GetFormattedCurrencyCode() {
-  CurrencyFormatter* formatter = GetOrCreateCurrencyFormatter(
-      spec_->details().total->amount->currency,
-      spec_->details().total->amount->currency_system, GetApplicationLocale());
-
-  return formatter->formatted_currency_code();
-}
-
 }  // namespace payments
diff --git a/components/payments/content/payment_request.h b/components/payments/content/payment_request.h
index ca56c8e6..b9753dbb4 100644
--- a/components/payments/content/payment_request.h
+++ b/components/payments/content/payment_request.h
@@ -6,7 +6,6 @@
 #define COMPONENTS_PAYMENTS_CONTENT_PAYMENT_REQUEST_H_
 
 #include <memory>
-#include <string>
 #include <vector>
 
 #include "base/macros.h"
@@ -17,17 +16,12 @@
 #include "mojo/public/cpp/bindings/binding.h"
 #include "mojo/public/cpp/bindings/interface_request.h"
 
-namespace autofill {
-class PersonalDataManager;
-}
-
 namespace content {
 class WebContents;
 }
 
 namespace payments {
 
-class CurrencyFormatter;
 class PaymentRequestWebContentsManager;
 
 // This class manages the interaction between the renderer (through the
@@ -61,8 +55,6 @@
   void OnInvalidSpecProvided() override;
 
   // PaymentRequestState::Delegate:
-  const std::string& GetApplicationLocale() override;
-  autofill::PersonalDataManager* GetPersonalDataManager() override;
   void OnPaymentResponseAvailable(mojom::PaymentResponsePtr response) override;
 
   // Called when the user explicitely cancelled the flow. Will send a message
@@ -79,23 +71,6 @@
   // Called when the user clicks on the "Pay" button.
   void Pay();
 
-  // Returns the CurrencyFormatter instance for this PaymentRequest.
-  // |locale_name| should be the result of the browser's GetApplicationLocale().
-  // Note: Having multiple currencies per PaymentRequest is not supported; hence
-  // the CurrencyFormatter is cached here.
-  CurrencyFormatter* GetOrCreateCurrencyFormatter(
-      const std::string& currency_code,
-      const std::string& currency_system,
-      const std::string& locale_name);
-
-  // Uses CurrencyFormatter to format |amount| with the currency symbol for this
-  // request's currency.
-  base::string16 GetFormattedCurrencyAmount(const std::string& amount);
-
-  // Uses CurrencyFormatter to get the formatted currency code for this
-  // request's currency.
-  std::string GetFormattedCurrencyCode();
-
   content::WebContents* web_contents() { return web_contents_; }
 
   PaymentRequestSpec* spec() { return spec_.get(); }
@@ -108,7 +83,6 @@
   PaymentRequestWebContentsManager* manager_;
   mojo::Binding<mojom::PaymentRequest> binding_;
   mojom::PaymentRequestClientPtr client_;
-  std::unique_ptr<CurrencyFormatter> currency_formatter_;
 
   std::unique_ptr<PaymentRequestSpec> spec_;
   std::unique_ptr<PaymentRequestState> state_;
diff --git a/components/payments/content/payment_request_spec.cc b/components/payments/content/payment_request_spec.cc
index 7509a76..3d321120 100644
--- a/components/payments/content/payment_request_spec.cc
+++ b/components/payments/content/payment_request_spec.cc
@@ -19,8 +19,11 @@
     mojom::PaymentOptionsPtr options,
     mojom::PaymentDetailsPtr details,
     std::vector<mojom::PaymentMethodDataPtr> method_data,
-    Observer* observer)
-    : options_(std::move(options)), details_(std::move(details)) {
+    Observer* observer,
+    const std::string& app_locale)
+    : options_(std::move(options)),
+      details_(std::move(details)),
+      app_locale_(app_locale) {
   if (observer)
     AddObserver(observer);
   PopulateValidatedMethodData(method_data);
@@ -36,6 +39,22 @@
   observers_.RemoveObserver(observer);
 }
 
+base::string16 PaymentRequestSpec::GetFormattedCurrencyAmount(
+    const std::string& amount) {
+  CurrencyFormatter* formatter = GetOrCreateCurrencyFormatter(
+      details_->total->amount->currency,
+      details_->total->amount->currency_system, app_locale_);
+  return formatter->Format(amount);
+}
+
+std::string PaymentRequestSpec::GetFormattedCurrencyCode() {
+  CurrencyFormatter* formatter = GetOrCreateCurrencyFormatter(
+      details_->total->amount->currency,
+      details_->total->amount->currency_system, app_locale_);
+
+  return formatter->formatted_currency_code();
+}
+
 void PaymentRequestSpec::PopulateValidatedMethodData(
     const std::vector<mojom::PaymentMethodDataPtr>& method_data) {
   if (method_data.empty()) {
@@ -112,4 +131,15 @@
     observer.OnInvalidSpecProvided();
 }
 
+CurrencyFormatter* PaymentRequestSpec::GetOrCreateCurrencyFormatter(
+    const std::string& currency_code,
+    const std::string& currency_system,
+    const std::string& locale_name) {
+  if (!currency_formatter_) {
+    currency_formatter_.reset(
+        new CurrencyFormatter(currency_code, currency_system, locale_name));
+  }
+  return currency_formatter_.get();
+}
+
 }  // namespace payments
diff --git a/components/payments/content/payment_request_spec.h b/components/payments/content/payment_request_spec.h
index dbefd2b..d205a1b 100644
--- a/components/payments/content/payment_request_spec.h
+++ b/components/payments/content/payment_request_spec.h
@@ -11,6 +11,7 @@
 #include "base/macros.h"
 #include "base/observer_list.h"
 #include "components/payments/content/payment_request.mojom.h"
+#include "components/payments/core/currency_formatter.h"
 
 namespace payments {
 
@@ -33,7 +34,8 @@
   PaymentRequestSpec(mojom::PaymentOptionsPtr options,
                      mojom::PaymentDetailsPtr details,
                      std::vector<mojom::PaymentMethodDataPtr> method_data,
-                     PaymentRequestSpec::Observer* observer);
+                     PaymentRequestSpec::Observer* observer,
+                     const std::string& app_locale);
   ~PaymentRequestSpec();
 
   void AddObserver(Observer* observer);
@@ -48,6 +50,16 @@
     return supported_card_networks_;
   }
 
+  // Uses CurrencyFormatter to format |amount| with the currency symbol for this
+  // request's currency. Will use currency of the "total" display item, because
+  // all items are supposed to have the same currency in a given request.
+  base::string16 GetFormattedCurrencyAmount(const std::string& amount);
+
+  // Uses CurrencyFormatter to get the formatted currency code for this
+  // request's currency. Will use currency of the "total" display item, because
+  // all items are supposed to have the same currency in a given request.
+  std::string GetFormattedCurrencyCode();
+
   const mojom::PaymentDetails& details() const { return *details_.get(); }
   const mojom::PaymentOptions& options() const { return *options_.get(); }
 
@@ -59,8 +71,19 @@
   // Will notify all observers that the spec is invalid.
   void NotifyOnInvalidSpecProvided();
 
+  // Returns the CurrencyFormatter instance for this PaymentRequest.
+  // |locale_name| should be the result of the browser's GetApplicationLocale().
+  // Note: Having multiple currencies per PaymentRequest is not supported; hence
+  // the CurrencyFormatter is cached here.
+  CurrencyFormatter* GetOrCreateCurrencyFormatter(
+      const std::string& currency_code,
+      const std::string& currency_system,
+      const std::string& locale_name);
+
   mojom::PaymentOptionsPtr options_;
   mojom::PaymentDetailsPtr details_;
+  const std::string app_locale_;
+  std::unique_ptr<CurrencyFormatter> currency_formatter_;
 
   // A list of supported basic card networks, in order that they were specified
   // by the merchant.
diff --git a/components/payments/content/payment_request_spec_unittest.cc b/components/payments/content/payment_request_spec_unittest.cc
index b1230e9e..0c4de2b 100644
--- a/components/payments/content/payment_request_spec_unittest.cc
+++ b/components/payments/content/payment_request_spec_unittest.cc
@@ -23,8 +23,8 @@
 
   void RecreateSpecWithMethodData(
       std::vector<payments::mojom::PaymentMethodDataPtr> method_data) {
-    spec_ = base::MakeUnique<PaymentRequestSpec>(nullptr, nullptr,
-                                                 std::move(method_data), this);
+    spec_ = base::MakeUnique<PaymentRequestSpec>(
+        nullptr, nullptr, std::move(method_data), this, "en-US");
   }
 
   PaymentRequestSpec* spec() { return spec_.get(); }
diff --git a/components/payments/content/payment_request_state.cc b/components/payments/content/payment_request_state.cc
index 9c0c9253c..e37422a 100644
--- a/components/payments/content/payment_request_state.cc
+++ b/components/payments/content/payment_request_state.cc
@@ -7,6 +7,7 @@
 #include "components/autofill/core/browser/autofill_data_util.h"
 #include "components/autofill/core/browser/autofill_profile.h"
 #include "components/autofill/core/browser/credit_card.h"
+#include "components/autofill/core/browser/personal_data_manager.h"
 #include "components/payments/content/payment_request_spec.h"
 #include "components/payments/core/autofill_payment_instrument.h"
 
@@ -17,11 +18,16 @@
 static const char* const kBasicCardMethodName = "basic-card";
 }  // namespace
 
-PaymentRequestState::PaymentRequestState(PaymentRequestSpec* spec,
-                                         Delegate* delegate)
+PaymentRequestState::PaymentRequestState(
+    PaymentRequestSpec* spec,
+    Delegate* delegate,
+    const std::string& app_locale,
+    autofill::PersonalDataManager* personal_data_manager)
     : is_ready_to_pay_(false),
+      app_locale_(app_locale),
       spec_(spec),
       delegate_(delegate),
+      personal_data_manager_(personal_data_manager),
       selected_shipping_profile_(nullptr),
       selected_contact_profile_(nullptr),
       selected_credit_card_(nullptr),
@@ -59,7 +65,7 @@
   // not necessarily basic-card.
   selected_payment_instrument_.reset(new AutofillPaymentInstrument(
       kBasicCardMethodName, *selected_credit_card_, shipping_profiles_,
-      delegate_->GetApplicationLocale()));
+      app_locale_));
   // Fetch the instrument details, will call back into
   // PaymentRequest::OnInstrumentsDetailsReady.
   selected_payment_instrument_->InvokePaymentApp(this);
@@ -82,12 +88,17 @@
   UpdateIsReadyToPayAndNotifyObservers();
 }
 
+const std::string& PaymentRequestState::GetApplicationLocale() {
+  return app_locale_;
+}
+
+autofill::PersonalDataManager* PaymentRequestState::GetPersonalDataManager() {
+  return personal_data_manager_;
+}
+
 void PaymentRequestState::PopulateProfileCache() {
-  autofill::PersonalDataManager* personal_data_manager =
-      delegate_->GetPersonalDataManager();
-  DCHECK(personal_data_manager);
   std::vector<autofill::AutofillProfile*> profiles =
-      personal_data_manager->GetProfilesToSuggest();
+      personal_data_manager_->GetProfilesToSuggest();
 
   // PaymentRequest may outlive the Profiles returned by the Data Manager.
   // Thus, we store copies, and return a vector of pointers to these copies
@@ -103,7 +114,7 @@
   }
 
   const std::vector<autofill::CreditCard*>& cards =
-      personal_data_manager->GetCreditCardsToSuggest();
+      personal_data_manager_->GetCreditCardsToSuggest();
   for (autofill::CreditCard* card : cards) {
     card_cache_.push_back(base::MakeUnique<autofill::CreditCard>(*card));
     credit_cards_.push_back(card_cache_.back().get());
@@ -162,11 +173,10 @@
     return false;
 
   // TODO(mathp): Make an encompassing class to validate contact info.
-  const std::string& app_locale = delegate_->GetApplicationLocale();
   if (spec_->request_payer_name() &&
       (selected_contact_profile_ == nullptr ||
        selected_contact_profile_
-           ->GetInfo(autofill::AutofillType(autofill::NAME_FULL), app_locale)
+           ->GetInfo(autofill::AutofillType(autofill::NAME_FULL), app_locale_)
            .empty())) {
     return false;
   }
@@ -174,7 +184,7 @@
       (selected_contact_profile_ == nullptr ||
        selected_contact_profile_
            ->GetInfo(autofill::AutofillType(autofill::EMAIL_ADDRESS),
-                     app_locale)
+                     app_locale_)
            .empty())) {
     return false;
   }
@@ -182,7 +192,7 @@
       (selected_contact_profile_ == nullptr ||
        selected_contact_profile_
            ->GetInfo(autofill::AutofillType(autofill::PHONE_HOME_WHOLE_NUMBER),
-                     app_locale)
+                     app_locale_)
            .empty())) {
     return false;
   }
diff --git a/components/payments/content/payment_request_state.h b/components/payments/content/payment_request_state.h
index 536ec8d5..1363690 100644
--- a/components/payments/content/payment_request_state.h
+++ b/components/payments/content/payment_request_state.h
@@ -7,13 +7,13 @@
 
 #include "base/macros.h"
 #include "base/observer_list.h"
-#include "components/autofill/core/browser/personal_data_manager.h"
 #include "components/payments/content/payment_request.mojom.h"
 #include "components/payments/core/payment_instrument.h"
 
 namespace autofill {
 class AutofillProfile;
 class CreditCard;
+class PersonalDataManager;
 }  // namespace autofill
 
 namespace payments {
@@ -40,9 +40,6 @@
 
   class Delegate {
    public:
-    virtual const std::string& GetApplicationLocale() = 0;
-    // Used to get the user's data.
-    virtual autofill::PersonalDataManager* GetPersonalDataManager() = 0;
     // Called when the PaymentResponse is available.
     virtual void OnPaymentResponseAvailable(
         mojom::PaymentResponsePtr response) = 0;
@@ -51,7 +48,10 @@
     virtual ~Delegate() {}
   };
 
-  PaymentRequestState(PaymentRequestSpec* spec, Delegate* delegate);
+  PaymentRequestState(PaymentRequestSpec* spec,
+                      Delegate* delegate,
+                      const std::string& app_locale,
+                      autofill::PersonalDataManager* personal_data_manager);
   ~PaymentRequestState() override;
 
   void AddObserver(Observer* observer);
@@ -106,6 +106,9 @@
 
   bool is_ready_to_pay() { return is_ready_to_pay_; }
 
+  const std::string& GetApplicationLocale();
+  autofill::PersonalDataManager* GetPersonalDataManager();
+
  private:
   // Fetches the Autofill Profiles for this user from the PersonalDataManager,
   // and stores copies of them, owned by this PaymentRequestState, in
@@ -138,9 +141,12 @@
 
   bool is_ready_to_pay_;
 
+  const std::string app_locale_;
+
   // Not owned. Never null. Both outlive this object.
   PaymentRequestSpec* spec_;
   Delegate* delegate_;
+  autofill::PersonalDataManager* personal_data_manager_;
 
   autofill::AutofillProfile* selected_shipping_profile_;
   autofill::AutofillProfile* selected_contact_profile_;
diff --git a/components/payments/content/payment_request_state_unittest.cc b/components/payments/content/payment_request_state_unittest.cc
index 2af1af0..be56d1f 100644
--- a/components/payments/content/payment_request_state_unittest.cc
+++ b/components/payments/content/payment_request_state_unittest.cc
@@ -23,7 +23,6 @@
  protected:
   PaymentRequestStateTest()
       : num_on_selected_information_changed_called_(0),
-        locale_("en-US"),
         address_(autofill::test::GetFullProfile()),
         credit_card_(autofill::test::GetCreditCard()) {
     test_personal_data_manager_.AddTestingProfile(&address_);
@@ -38,10 +37,6 @@
   }
 
   // PaymentRequestState::Delegate:
-  const std::string& GetApplicationLocale() override { return locale_; };
-  autofill::PersonalDataManager* GetPersonalDataManager() override {
-    return &test_personal_data_manager_;
-  }
   void OnPaymentResponseAvailable(mojom::PaymentResponsePtr response) override {
     payment_response_ = std::move(response);
   };
@@ -52,9 +47,10 @@
       std::vector<mojom::PaymentMethodDataPtr> method_data) {
     // The spec will be based on the |options| and |details| passed in.
     spec_ = base::MakeUnique<PaymentRequestSpec>(
-        std::move(options), std::move(details), std::move(method_data),
-        nullptr);
-    state_ = base::MakeUnique<PaymentRequestState>(spec_.get(), this);
+        std::move(options), std::move(details), std::move(method_data), nullptr,
+        "en-US");
+    state_ = base::MakeUnique<PaymentRequestState>(
+        spec_.get(), this, "en-US", &test_personal_data_manager_);
     state_->AddObserver(this);
   }
 
@@ -96,7 +92,6 @@
   std::unique_ptr<PaymentRequestState> state_;
   std::unique_ptr<PaymentRequestSpec> spec_;
   int num_on_selected_information_changed_called_;
-  std::string locale_;
   mojom::PaymentResponsePtr payment_response_;
   autofill::TestPersonalDataManager test_personal_data_manager_;
 
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index 9ecbeea..3bd6eb0 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -146,6 +146,7 @@
     "//ui/events:gesture_detection",
     "//ui/events/blink",
     "//ui/gfx",
+    "//ui/gfx/animation",
     "//ui/gfx/geometry",
     "//ui/gfx/geometry/mojo",
     "//ui/gl",
diff --git a/content/renderer/media/media_stream_video_source.cc b/content/renderer/media/media_stream_video_source.cc
index 3c962ff0..41fa5e8 100644
--- a/content/renderer/media/media_stream_video_source.cc
+++ b/content/renderer/media/media_stream_video_source.cc
@@ -582,6 +582,13 @@
       track_adapter_->AddTrack(track.track, track.frame_callback, max_width,
                                max_height, min_aspect_ratio, max_aspect_ratio,
                                max_frame_rate);
+      // Calculate resulting frame size if the source delivers frames
+      // according to the current format. Note: Format may change later.
+      gfx::Size desired_size;
+      VideoTrackAdapter::CalculateTargetSize(
+          current_format_.frame_size, gfx::Size(max_width, max_height),
+          min_aspect_ratio, max_aspect_ratio, &desired_size);
+      track.track->SetTargetSize(desired_size.width(), desired_size.height());
     }
 
     DVLOG(3) << "FinalizeAddTrack() result " << result;
diff --git a/content/renderer/media/media_stream_video_track.cc b/content/renderer/media/media_stream_video_track.cc
index 599018f61..0f366f5 100644
--- a/content/renderer/media/media_stream_video_track.cc
+++ b/content/renderer/media/media_stream_video_track.cc
@@ -302,18 +302,15 @@
 
 void MediaStreamVideoTrack::getSettings(
     blink::WebMediaStreamTrack::Settings& settings) {
-  // TODO(hta): Extract the real value.
-  settings.deviceId = blink::WebString("video device ID");
-  if (!source_)
-    return;
-
   const media::VideoCaptureFormat* format = source_->GetCurrentFormat();
   if (format) {
     settings.frameRate = format->frame_rate;
-    settings.width = format->frame_size.width();
-    settings.height = format->frame_size.height();
     settings.videoKind = GetVideoKindForFormat(*format);
   }
+  if (width_ && height_) {
+    settings.width = width_;
+    settings.height = height_;
+  }
   switch (source_->device_info().device.video_facing) {
     case media::MEDIA_VIDEO_FACING_NONE:
       settings.facingMode = blink::WebMediaStreamTrack::FacingMode::None;
diff --git a/content/renderer/media/media_stream_video_track.h b/content/renderer/media/media_stream_video_track.h
index 364a64e7..72ead10c 100644
--- a/content/renderer/media/media_stream_video_track.h
+++ b/content/renderer/media/media_stream_video_track.h
@@ -61,6 +61,13 @@
 
   const blink::WebMediaConstraints& constraints() const { return constraints_; }
 
+  // Setting information about the track size.
+  // Called from MediaStreamVideoSource at track initialization.
+  void SetTargetSize(int width, int height) {
+    width_ = width;
+    height_ = height;
+  }
+
  private:
   // MediaStreamVideoSink is a friend to allow it to call AddSink() and
   // RemoveSink().
@@ -95,6 +102,10 @@
   // This is used for tracking if all connected video sinks are secure.
   SecureDisplayLinkTracker<MediaStreamVideoSink> secure_tracker_;
 
+  // Remembering our desired video size.
+  int width_ = 0;
+  int height_ = 0;
+
   DISALLOW_COPY_AND_ASSIGN(MediaStreamVideoTrack);
 };
 
diff --git a/content/renderer/media/video_track_adapter.cc b/content/renderer/media/video_track_adapter.cc
index b80f6b6..8171c52c 100644
--- a/content/renderer/media/video_track_adapter.cc
+++ b/content/renderer/media/video_track_adapter.cc
@@ -223,42 +223,11 @@
     return;
   }
   scoped_refptr<media::VideoFrame> video_frame(frame);
-  const double input_ratio =
-      static_cast<double>(frame->natural_size().width()) /
-      frame->natural_size().height();
 
-  // If |frame| has larger width or height than requested, or the aspect ratio
-  // does not match the requested, we want to create a wrapped version of this
-  // frame with a size that fulfills the constraints.
-  if (frame->natural_size().width() > max_frame_size_.width() ||
-      frame->natural_size().height() > max_frame_size_.height() ||
-      input_ratio > max_aspect_ratio_ ||
-      input_ratio < min_aspect_ratio_) {
-    int desired_width = std::min(max_frame_size_.width(),
-                                 frame->natural_size().width());
-    int desired_height = std::min(max_frame_size_.height(),
-                                  frame->natural_size().height());
-
-    const double resulting_ratio =
-        static_cast<double>(desired_width) / desired_height;
-    // Make sure |min_aspect_ratio_| < |requested_ratio| < |max_aspect_ratio_|.
-    const double requested_ratio = std::max(
-        std::min(resulting_ratio, max_aspect_ratio_), min_aspect_ratio_);
-
-    if (resulting_ratio < requested_ratio) {
-      desired_height = static_cast<int>((desired_height * resulting_ratio) /
-                                        requested_ratio);
-      // Make sure we scale to an even height to avoid rounding errors
-      desired_height = (desired_height + 1) & ~1;
-    } else if (resulting_ratio > requested_ratio) {
-      desired_width = static_cast<int>((desired_width * requested_ratio) /
-                                       resulting_ratio);
-      // Make sure we scale to an even width to avoid rounding errors.
-      desired_width = (desired_width + 1) & ~1;
-    }
-
-    const gfx::Size desired_size(desired_width, desired_height);
-
+  gfx::Size desired_size;
+  CalculateTargetSize(frame->natural_size(), max_frame_size_, min_aspect_ratio_,
+                      max_aspect_ratio_, &desired_size);
+  if (desired_size != frame->natural_size()) {
     // Get the largest centered rectangle with the same aspect ratio of
     // |desired_size| that fits entirely inside of |frame->visible_rect()|.
     // This will be the rect we need to crop the original frame to.
@@ -448,6 +417,48 @@
       FROM_HERE, base::Bind(&VideoTrackAdapter::StopFrameMonitoringOnIO, this));
 }
 
+// static
+void VideoTrackAdapter::CalculateTargetSize(const gfx::Size& input_size,
+                                            const gfx::Size& max_frame_size,
+                                            double min_aspect_ratio,
+                                            double max_aspect_ratio,
+                                            gfx::Size* desired_size) {
+  // If |frame| has larger width or height than requested, or the aspect ratio
+  // does not match the requested, we want to create a wrapped version of this
+  // frame with a size that fulfills the constraints.
+  const double input_ratio =
+      static_cast<double>(input_size.width()) / input_size.height();
+
+  if (input_size.width() > max_frame_size.width() ||
+      input_size.height() > max_frame_size.height() ||
+      input_ratio > max_aspect_ratio || input_ratio < min_aspect_ratio) {
+    int desired_width = std::min(max_frame_size.width(), input_size.width());
+    int desired_height = std::min(max_frame_size.height(), input_size.height());
+
+    const double resulting_ratio =
+        static_cast<double>(desired_width) / desired_height;
+    // Make sure |min_aspect_ratio| < |requested_ratio| < |max_aspect_ratio|.
+    const double requested_ratio =
+        std::max(std::min(resulting_ratio, max_aspect_ratio), min_aspect_ratio);
+
+    if (resulting_ratio < requested_ratio) {
+      desired_height = static_cast<int>((desired_height * resulting_ratio) /
+                                        requested_ratio);
+      // Make sure we scale to an even height to avoid rounding errors
+      desired_height = (desired_height + 1) & ~1;
+    } else if (resulting_ratio > requested_ratio) {
+      desired_width =
+          static_cast<int>((desired_width * requested_ratio) / resulting_ratio);
+      // Make sure we scale to an even width to avoid rounding errors.
+      desired_width = (desired_width + 1) & ~1;
+    }
+
+    *desired_size = gfx::Size(desired_width, desired_height);
+  } else {
+    *desired_size = input_size;
+  }
+}
+
 void VideoTrackAdapter::StartFrameMonitoringOnIO(
     const OnMutedCallback& on_muted_callback,
     double source_frame_rate) {
diff --git a/content/renderer/media/video_track_adapter.h b/content/renderer/media/video_track_adapter.h
index ddd73ef..340bf86 100644
--- a/content/renderer/media/video_track_adapter.h
+++ b/content/renderer/media/video_track_adapter.h
@@ -65,6 +65,12 @@
                             const OnMutedCallback& on_muted_callback);
   void StopFrameMonitoring();
 
+  static void CalculateTargetSize(const gfx::Size& input_size,
+                                  const gfx::Size& max_frame_size,
+                                  double min_aspect_ratio,
+                                  double max_aspect_ratio,
+                                  gfx::Size* desired_size);
+
  private:
   virtual ~VideoTrackAdapter();
   friend class base::RefCountedThreadSafe<VideoTrackAdapter>;
diff --git a/docs/android_studio.md b/docs/android_studio.md
index 900f090..cefa544 100644
--- a/docs/android_studio.md
+++ b/docs/android_studio.md
@@ -120,7 +120,8 @@
 
 ### What works
 
-* Tested with Android Studio v2.2.
+* Tested with Android Studio v2.3.
+    * If you get an error about build tools version 25.0.0, install it manually.
 * Java editing and gradle compile works.
 * Instrumentation tests included as androidTest.
 * Symlinks to existing .so files in jniLibs (doesn't generate them).
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd
index f0fd75a..74ce181 100644
--- a/ios/chrome/app/strings/ios_strings.grd
+++ b/ios/chrome/app/strings/ios_strings.grd
@@ -1033,7 +1033,7 @@
         Edit
       </message>
       <message name="IDS_IOS_READING_LIST_EMPTY_MESSAGE" desc="Message to explain to the user how to add entries to the reading list" meaning="[Length: unlimited]">
-        Your reading list is available offline. To add a page to your reading list, tap<ph name="SHARE_OPENING_ICON">SHARE_OPENING_ICON<ex>Menu > Share > Read Later</ex></ph>.
+        Your reading list is available offline. To add a page to your reading list, tap <ph name="SHARE_OPENING_ICON">SHARE_OPENING_ICON<ex>Menu > Share > Read Later</ex></ph>.
       </message>
       <message name="IDS_IOS_READING_LIST_MARK_ALL_BUTTON" desc="Label of the button to suggest options to mark all reading list entries read or unread [Length: 25em]" meaning="Display options letting the user mark all the entries as read or as unread. [Length: 25em]">
         Mark All…
diff --git a/ios/chrome/browser/content_suggestions/content_suggestions_mediator.mm b/ios/chrome/browser/content_suggestions/content_suggestions_mediator.mm
index 6ba0cfd0899..0ef1796f 100644
--- a/ios/chrome/browser/content_suggestions/content_suggestions_mediator.mm
+++ b/ios/chrome/browser/content_suggestions/content_suggestions_mediator.mm
@@ -25,6 +25,20 @@
 
 namespace {
 
+// TODO(crbug.com/701275): Once base::BindBlock supports the move semantics,
+// remove this wrapper.
+// Wraps a callback taking a const ref to a callback taking an object.
+void BindWrapper(
+    base::Callback<void(ntp_snippets::Status status_code,
+                        const std::vector<ntp_snippets::ContentSuggestion>&
+                            suggestions)> callback,
+    ntp_snippets::Status status_code,
+    std::vector<ntp_snippets::ContentSuggestion> suggestions) {
+  if (callback) {
+    callback.Run(status_code, suggestions);
+  }
+}
+
 // Returns the Type for this |category|.
 ContentSuggestionType TypeForCategory(ntp_snippets::Category category) {
   // For now, only Article is a relevant type.
@@ -112,10 +126,12 @@
                         ContentSuggestionsSectionInformation*>*
         sectionInformationByCategory;
 
-// Converts the data in |category| to ContentSuggestion and adds them to the
-// |contentArray| if the category is available.
-- (void)addContentInCategory:(ntp_snippets::Category&)category
-                     toArray:(NSMutableArray<ContentSuggestion*>*)contentArray;
+// Converts the |suggestions| from |category| to ContentSuggestion and adds them
+// to the |contentArray|  if the category is available.
+- (void)addSuggestions:
+            (const std::vector<ntp_snippets::ContentSuggestion>&)suggestions
+          fromCategory:(ntp_snippets::Category&)category
+               toArray:(NSMutableArray<ContentSuggestion*>*)contentArray;
 
 // Adds the section information for |category| in
 // self.sectionInformationByCategory.
@@ -164,7 +180,9 @@
       self.contentService->GetCategories();
   NSMutableArray<ContentSuggestion*>* dataHolders = [NSMutableArray array];
   for (auto& category : categories) {
-    [self addContentInCategory:category toArray:dataHolders];
+    const std::vector<ntp_snippets::ContentSuggestion>& suggestions =
+        self.contentService->GetSuggestionsForCategory(category);
+    [self addSuggestions:suggestions fromCategory:category toArray:dataHolders];
   }
   return dataHolders;
 }
@@ -174,15 +192,49 @@
   ntp_snippets::Category category =
       [[self categoryWrapperForSectionInfo:sectionInfo] category];
 
-  NSMutableArray* suggestions = [NSMutableArray array];
-  [self addContentInCategory:category toArray:suggestions];
-  return suggestions;
+  NSMutableArray* convertedSuggestions = [NSMutableArray array];
+  const std::vector<ntp_snippets::ContentSuggestion>& suggestions =
+      self.contentService->GetSuggestionsForCategory(category);
+  [self addSuggestions:suggestions
+          fromCategory:category
+               toArray:convertedSuggestions];
+  return convertedSuggestions;
 }
 
 - (id<ContentSuggestionsImageFetcher>)imageFetcher {
   return self;
 }
 
+- (void)fetchMoreSuggestionsKnowing:
+            (NSArray<ContentSuggestionIdentifier*>*)knownSuggestions
+                    fromSectionInfo:
+                        (ContentSuggestionsSectionInformation*)sectionInfo
+                           callback:(MoreSuggestionsFetched)callback {
+  std::set<std::string> known_suggestion_ids;
+  for (ContentSuggestionIdentifier* identifier in knownSuggestions) {
+    if (identifier.sectionInfo != sectionInfo)
+      continue;
+    known_suggestion_ids.insert(identifier.IDInSection);
+  }
+
+  ContentSuggestionsCategoryWrapper* wrapper =
+      [self categoryWrapperForSectionInfo:sectionInfo];
+
+  __weak ContentSuggestionsMediator* weakSelf = self;
+  ntp_snippets::FetchDoneCallback serviceCallback = base::Bind(
+      &BindWrapper,
+      base::BindBlockArc(^void(
+          ntp_snippets::Status status,
+          const std::vector<ntp_snippets::ContentSuggestion>& suggestions) {
+        [weakSelf didFetchMoreSuggestions:suggestions
+                           withStatusCode:status
+                                 callback:callback];
+      }));
+
+  self.contentService->Fetch([wrapper category], known_suggestion_ids,
+                             serviceCallback);
+}
+
 #pragma mark - ContentSuggestionsServiceObserver
 
 - (void)contentSuggestionsService:
@@ -252,25 +304,26 @@
 
 #pragma mark - Private
 
-- (void)addContentInCategory:(ntp_snippets::Category&)category
-                     toArray:(NSMutableArray<ContentSuggestion*>*)contentArray {
+- (void)addSuggestions:
+            (const std::vector<ntp_snippets::ContentSuggestion>&)suggestions
+          fromCategory:(ntp_snippets::Category&)category
+               toArray:(NSMutableArray<ContentSuggestion*>*)contentArray {
   if (self.contentService->GetCategoryStatus(category) !=
       ntp_snippets::CategoryStatus::AVAILABLE) {
     return;
   }
+
   ContentSuggestionsCategoryWrapper* categoryWrapper =
       [ContentSuggestionsCategoryWrapper wrapperWithCategory:category];
   if (!self.sectionInformationByCategory[categoryWrapper]) {
     [self addSectionInformationForCategory:category];
   }
 
-  const std::vector<ntp_snippets::ContentSuggestion>& suggestions =
-      self.contentService->GetSuggestionsForCategory(category);
-
   for (auto& contentSuggestion : suggestions) {
     ContentSuggestion* suggestion = ConvertContentSuggestion(contentSuggestion);
 
     suggestion.type = TypeForCategory(category);
+
     suggestion.suggestionIdentifier.sectionInfo =
         self.sectionInformationByCategory[categoryWrapper];
 
@@ -295,4 +348,21 @@
       firstObject];
 }
 
+// If the |statusCode| is a success and |suggestions| is not empty, runs the
+// |callback| with the |suggestions| converted to Objective-C.
+- (void)didFetchMoreSuggestions:
+            (const std::vector<ntp_snippets::ContentSuggestion>&)suggestions
+                 withStatusCode:(ntp_snippets::Status)statusCode
+                       callback:(MoreSuggestionsFetched)callback {
+  if (statusCode.IsSuccess() && !suggestions.empty() && callback) {
+    NSMutableArray<ContentSuggestion*>* contentSuggestions =
+        [NSMutableArray array];
+    ntp_snippets::Category category = suggestions[0].id().category();
+    [self addSuggestions:suggestions
+            fromCategory:category
+                 toArray:contentSuggestions];
+    callback(contentSuggestions);
+  }
+}
+
 @end
diff --git a/ios/chrome/browser/context_menu/context_menu_egtest.mm b/ios/chrome/browser/context_menu/context_menu_egtest.mm
index 993ebfb..3e021534 100644
--- a/ios/chrome/browser/context_menu/context_menu_egtest.mm
+++ b/ios/chrome/browser/context_menu/context_menu_egtest.mm
@@ -189,7 +189,9 @@
 // Tests "Open in New Tab" on context menu  on a link that requires scrolling
 // on the page to verify that context menu can be properly triggered in the
 // current screen view.
-- (void)testContextMenuOpenInNewTabFromTallPage {
+// TODO(crbug.com/701104): This test is flaky because sometimes it doesn't
+// scroll down far enough for the link to be visible.
+- (void)FLAKY_testContextMenuOpenInNewTabFromTallPage {
   // Set up test simple http server.
   std::map<GURL, std::string> responses;
   GURL initialURL =
diff --git a/ios/chrome/browser/tabs/tab.mm b/ios/chrome/browser/tabs/tab.mm
index d48ffed..96c7d6b 100644
--- a/ios/chrome/browser/tabs/tab.mm
+++ b/ios/chrome/browser/tabs/tab.mm
@@ -1176,11 +1176,6 @@
   // Reset association with the webController.
   [self.webController setDelegate:nil];
 
-  webStateImpl_->ClearTransientContentView();
-  // Terminate the network activity before notifying the parent model, because
-  // the parent model may initiate the request context destruction.
-  [self terminateNetworkActivity];
-
   // Cancel any queued dialogs.
   [self.dialogDelegate cancelDialogForTab:self];
 
@@ -1195,14 +1190,20 @@
   // delegate should be torn down after |-didCloseTab:| so components triggered
   // by tab closure can use the content facade, and it should be deleted before
   // the web controller since the web controller owns the facade's backing
-  // objects.
+  // objects. |parentTabModel_| is reset after calling |-didCloseTab:| to
+  // prevent propagating WebState notifications that happen during WebState
+  // destruction.
   // TODO(crbug.com/546222): Fix the need for this; TabModel should be
   // responsible for making the lifetime of Tab sane, rather than allowing Tab
   // to drive its own destruction.
   base::scoped_nsobject<Tab> kungFuDeathGrip([self retain]);
   [parentTabModel_ didCloseTab:self];  // Inform parent of tab closure.
+  parentTabModel_ = nil;
 
+  // Destroy the WebState but first stop listening to WebState events (as |self|
+  // is in no state to respond to the notifications if |webStateImpl_| is null).
   LegacyTabHelper::RemoveFromWebState(self.webState);
+  webStateObserver_.reset();
   webStateImpl_.reset();
 }
 
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm
index 32bc6f7e..6a4a637 100644
--- a/ios/chrome/browser/ui/browser_view_controller.mm
+++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -609,6 +609,8 @@
 - (void)showToolsMenuPopup;
 // Add all delegates to the provided |tab|.
 - (void)installDelegatesForTab:(Tab*)tab;
+// Remove delegates from the provided |tab|.
+- (void)uninstallDelegatesForTab:(Tab*)tab;
 // Closes the current tab, with animation if applicable.
 - (void)closeCurrentTab;
 // Shows the menu to initiate sharing |data|.
@@ -2111,9 +2113,7 @@
 }
 
 - (void)installDelegatesForTab:(Tab*)tab {
-  // We don't unregister any of this delegation.
-  // TODO(crbug.com/375577): Unregister these delegates correctly on BVC
-  // deallocation.
+  // Unregistration happens when the Tab is removed from the TabModel.
   tab.dialogDelegate = self;
   tab.snapshotOverlayProvider = self;
   tab.passKitDialogProvider = self;
@@ -2131,10 +2131,27 @@
   StoreKitTabHelper* tabHelper = StoreKitTabHelper::FromWebState(tab.webState);
   if (tabHelper)
     tabHelper->SetLauncher(self);
-  // Delegate will remove itself on destruction.
   tab.webState->SetDelegate(_webStateDelegate.get());
 }
 
+- (void)uninstallDelegatesForTab:(Tab*)tab {
+  tab.dialogDelegate = nil;
+  tab.snapshotOverlayProvider = nil;
+  tab.passKitDialogProvider = nil;
+  tab.fullScreenControllerDelegate = nil;
+  if (!IsIPadIdiom()) {
+    tab.overscrollActionsControllerDelegate = nil;
+  }
+  tab.tabHeadersDelegate = nil;
+  tab.tabSnapshottingDelegate = nil;
+  tab.webController.nativeProvider = nil;
+  tab.webController.swipeRecognizerProvider = nil;
+  StoreKitTabHelper* tabHelper = StoreKitTabHelper::FromWebState(tab.webState);
+  if (tabHelper)
+    tabHelper->SetLauncher(nil);
+  tab.webState->SetDelegate(nullptr);
+}
+
 // Called when a tab is selected in the model. Make any required view changes.
 // The notification will not be sent when the tab is already the selected tab.
 - (void)tabSelected:(Tab*)tab {
@@ -4554,10 +4571,21 @@
   }
 }
 
+// Observer method, tab replaced.
+- (void)tabModel:(TabModel*)model
+    didReplaceTab:(Tab*)oldTab
+          withTab:(Tab*)newTab
+          atIndex:(NSUInteger)index {
+  [self uninstallDelegatesForTab:oldTab];
+  [self installDelegatesForTab:newTab];
+}
+
 // A tab has been removed, remove its views from display if necessary.
 - (void)tabModel:(TabModel*)model
     didRemoveTab:(Tab*)tab
          atIndex:(NSUInteger)index {
+  [self uninstallDelegatesForTab:tab];
+
   // Remove stored native controllers for the tab.
   [_nativeControllersForTabIDs removeObjectForKey:tab.tabId];
 
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.h b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.h
index f1c79f6..6661d09 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.h
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.h
@@ -34,6 +34,17 @@
 // Returns the ContentSuggestionType associated with this item.
 - (ContentSuggestionType)contentSuggestionTypeForItem:(CollectionViewItem*)item;
 
+// Adds the sections for the |suggestions| to the model and returns their
+// indices.
+- (NSIndexSet*)addSectionsForSuggestionsToModel:
+    (NSArray<ContentSuggestion*>*)suggestions;
+
+// Adds the |suggestions| to the model and returns their index paths.
+// The caller must ensure the corresponding sections have been added to the
+// model.
+- (NSArray<NSIndexPath*>*)addSuggestionsToModel:
+    (NSArray<ContentSuggestion*>*)suggestions;
+
 @end
 
 #endif  // IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CONTENT_SUGGESTIONS_COLLECTION_UPDATER_H_
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.mm
index 9bce876..83866cc 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.mm
@@ -87,13 +87,6 @@
     NSMutableDictionary<NSNumber*, ContentSuggestionsSectionInformation*>*
         sectionInfoBySectionIdentifier;
 
-// Adds a new section if needed and returns the section identifier.
-- (NSInteger)addSectionIfNeeded:
-    (ContentSuggestionsSectionInformation*)sectionInformation;
-// Resets the models, removing the current CollectionViewItem and the
-// SectionInfo.
-- (void)resetModels;
-
 @end
 
 @implementation ContentSuggestionsCollectionUpdater
@@ -135,7 +128,8 @@
     return;
   }
 
-  [self addSuggestions:[self.dataSource suggestionsForSection:sectionInfo]];
+  [self.collectionViewController
+      addSuggestions:[self.dataSource suggestionsForSection:sectionInfo]];
 }
 
 - (void)clearSuggestion:(ContentSuggestionIdentifier*)suggestionIdentifier {
@@ -170,7 +164,8 @@
 
 - (void)reloadAllData {
   [self resetModels];
-  [self addSuggestions:[self.dataSource allSuggestions]];
+  [self.collectionViewController
+      addSuggestions:[self.dataSource allSuggestions]];
 }
 
 - (void)clearSection:(ContentSuggestionsSectionInformation*)sectionInfo {
@@ -196,6 +191,64 @@
   return ContentSuggestionTypeForItemType(item.type);
 }
 
+- (NSArray<NSIndexPath*>*)addSuggestionsToModel:
+    (NSArray<ContentSuggestion*>*)suggestions {
+  if (suggestions.count == 0) {
+    return [NSArray array];
+  }
+
+  CollectionViewModel* model =
+      self.collectionViewController.collectionViewModel;
+
+  NSMutableArray<NSIndexPath*>* indexPaths = [NSMutableArray array];
+  for (ContentSuggestion* suggestion in suggestions) {
+    NSInteger sectionIdentifier =
+        SectionIdentifierForInfo(suggestion.suggestionIdentifier.sectionInfo);
+
+    ContentSuggestionsArticleItem* articleItem =
+        [[ContentSuggestionsArticleItem alloc]
+            initWithType:ItemTypeForContentSuggestionType(suggestion.type)
+                   title:suggestion.title
+                subtitle:suggestion.text
+                delegate:self
+                     url:suggestion.url];
+
+    articleItem.publisher = suggestion.publisher;
+    articleItem.publishDate = suggestion.publishDate;
+
+    articleItem.suggestionIdentifier = suggestion.suggestionIdentifier;
+
+    NSInteger section = [model sectionForSectionIdentifier:sectionIdentifier];
+    NSInteger itemNumber = [model numberOfItemsInSection:section];
+    [model addItem:articleItem toSectionWithIdentifier:sectionIdentifier];
+
+    [indexPaths
+        addObject:[NSIndexPath indexPathForItem:itemNumber inSection:section]];
+  }
+
+  return indexPaths;
+}
+
+- (NSIndexSet*)addSectionsForSuggestionsToModel:
+    (NSArray<ContentSuggestion*>*)suggestions {
+  NSMutableIndexSet* indexSet = [NSMutableIndexSet indexSet];
+
+  CollectionViewModel* model =
+      self.collectionViewController.collectionViewModel;
+  for (ContentSuggestion* suggestion in suggestions) {
+    ContentSuggestionsSectionInformation* sectionInfo =
+        suggestion.suggestionIdentifier.sectionInfo;
+    NSInteger sectionIdentifier = SectionIdentifierForInfo(sectionInfo);
+
+    if (![model hasSectionForSectionIdentifier:sectionIdentifier]) {
+      [model addSectionWithIdentifier:sectionIdentifier];
+      self.sectionInfoBySectionIdentifier[@(sectionIdentifier)] = sectionInfo;
+      [indexSet addIndex:[model sectionForSectionIdentifier:sectionIdentifier]];
+    }
+  }
+  return indexSet;
+}
+
 #pragma mark - ContentSuggestionsArticleItemDelegate
 
 - (void)loadImageForArticleItem:(ContentSuggestionsArticleItem*)articleItem {
@@ -228,55 +281,8 @@
 
 #pragma mark - Private methods
 
-// Add the |suggestions| to the model and reload the data.
-- (void)addSuggestions:(NSArray<ContentSuggestion*>*)suggestions {
-  if (suggestions.count == 0) {
-    return;
-  }
-
-  CollectionViewModel* model =
-      self.collectionViewController.collectionViewModel;
-
-  for (ContentSuggestion* suggestion in suggestions) {
-    NSInteger sectionIdentifier =
-        [self addSectionIfNeeded:suggestion.suggestionIdentifier.sectionInfo];
-    ContentSuggestionsArticleItem* articleItem =
-        [[ContentSuggestionsArticleItem alloc]
-            initWithType:ItemTypeForContentSuggestionType(suggestion.type)
-                   title:suggestion.title
-                subtitle:suggestion.text
-                delegate:self
-                     url:suggestion.url];
-
-    articleItem.publisher = suggestion.publisher;
-    articleItem.publishDate = suggestion.publishDate;
-
-    articleItem.suggestionIdentifier = suggestion.suggestionIdentifier;
-
-    [model addItem:articleItem toSectionWithIdentifier:sectionIdentifier];
-  }
-
-  if ([self.collectionViewController isViewLoaded]) {
-    [self.collectionViewController.collectionView reloadData];
-  }
-}
-
-- (NSInteger)addSectionIfNeeded:
-    (ContentSuggestionsSectionInformation*)sectionInformation {
-  NSInteger sectionIdentifier = SectionIdentifierForInfo(sectionInformation);
-
-  CollectionViewModel* model =
-      self.collectionViewController.collectionViewModel;
-  if (![model hasSectionForSectionIdentifier:sectionIdentifier]) {
-    [model addSectionWithIdentifier:sectionIdentifier];
-    self.sectionInfoBySectionIdentifier[@(sectionIdentifier)] =
-        sectionInformation;
-    [self.sectionInfoBySectionIdentifier setObject:sectionInformation
-                                            forKey:@(sectionIdentifier)];
-  }
-  return sectionIdentifier;
-}
-
+// Resets the models, removing the current CollectionViewItem and the
+// SectionInfo.
 - (void)resetModels {
   [self.collectionViewController loadModel];
   self.sectionInfoBySectionIdentifier = [[NSMutableDictionary alloc] init];
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_data_source.h b/ios/chrome/browser/ui/content_suggestions/content_suggestions_data_source.h
index fc7a26e..3758b553 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_data_source.h
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_data_source.h
@@ -6,10 +6,14 @@
 #define IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CONTENT_SUGGESTIONS_DATA_SOURCE_H_
 
 @class ContentSuggestion;
+@class ContentSuggestionIdentifier;
 @class ContentSuggestionsSectionInformation;
 @protocol ContentSuggestionsDataSink;
 @protocol ContentSuggestionsImageFetcher;
 
+// Typedef for a block taking the fetched suggestions as parameter.
+typedef void (^MoreSuggestionsFetched)(NSArray<ContentSuggestion*>* _Nonnull);
+
 // DataSource for the content suggestions. Provides the suggestions data in a
 // format compatible with Objective-C.
 @protocol ContentSuggestionsDataSource
@@ -28,6 +32,16 @@
 // Returns an image updater for the suggestions provided by this data source.
 - (nullable id<ContentSuggestionsImageFetcher>)imageFetcher;
 
+// Fetches additional content. All the |knownSuggestions| must come from the
+// same |sectionInfo|. If the fetch was completed, the given |callback| is
+// called with the new content.
+- (void)fetchMoreSuggestionsKnowing:
+            (nullable NSArray<ContentSuggestionIdentifier*>*)knownSuggestions
+                    fromSectionInfo:
+                        (nonnull ContentSuggestionsSectionInformation*)
+                            sectionInfo
+                           callback:(nullable MoreSuggestionsFetched)callback;
+
 @end
 
 #endif  // IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CONTENT_SUGGESTIONS_DATA_SOURCE_H_
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.h b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.h
index ed6415f..7b11cb3 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.h
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.h
@@ -11,6 +11,7 @@
 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_expandable_item.h"
 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_favicon_item.h"
 
+@class ContentSuggestion;
 @protocol ContentSuggestionsCommands;
 @protocol ContentSuggestionsDataSource;
 @protocol ContentSuggestionIdentification;
@@ -39,6 +40,8 @@
 - (void)dismissEntryAtIndexPath:(NSIndexPath*)indexPath;
 // Removes the |section|.
 - (void)dismissSection:(NSInteger)section;
+// Adds the |suggestions| to the collection and its model.
+- (void)addSuggestions:(NSArray<ContentSuggestion*>*)suggestions;
 
 @end
 
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm
index fc613715..a7a7fa6 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm
@@ -89,6 +89,26 @@
       }];
 }
 
+- (void)addSuggestions:(NSArray<ContentSuggestion*>*)suggestions {
+  if (suggestions.count == 0) {
+    return;
+  }
+
+  [self.collectionView performBatchUpdates:^{
+    NSIndexSet* addedSections =
+        [self.collectionUpdater addSectionsForSuggestionsToModel:suggestions];
+    [self.collectionView insertSections:addedSections];
+  }
+                                completion:nil];
+
+  [self.collectionView performBatchUpdates:^{
+    NSArray<NSIndexPath*>* addedItems =
+        [self.collectionUpdater addSuggestionsToModel:suggestions];
+    [self.collectionView insertItemsAtIndexPaths:addedItems];
+  }
+                                completion:nil];
+}
+
 #pragma mark - UIViewController
 
 - (void)viewDidLoad {
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_empty_collection_background.mm b/ios/chrome/browser/ui/reading_list/reading_list_empty_collection_background.mm
index d3eaca49..4c8ac93 100644
--- a/ios/chrome/browser/ui/reading_list/reading_list_empty_collection_background.mm
+++ b/ios/chrome/browser/ui/reading_list/reading_list_empty_collection_background.mm
@@ -29,11 +29,13 @@
 // Background view constants.
 const CGFloat kTextImageSpacing = 10;
 const CGFloat kTextHorizontalMinimumMargin = 32;
-const CGFloat kTextMaximalWidth = 270;
+const CGFloat kTextMaximalWidth = 255;
 const CGFloat kImageWidth = 60;
 const CGFloat kImageHeight = 44;
 const CGFloat kFontSize = 16;
-const CGFloat kIconSize = 24;
+const CGFloat kIconHeight = 24;
+const CGFloat kToolbarMenuWidth = 18;
+const CGFloat kShareMenuWidth = 24;
 const CGFloat kLineHeight = 24;
 const CGFloat kPercentageFromTopForPosition = 0.4;
 
@@ -48,8 +50,8 @@
 - (void)attachIconNamed:(NSString*)iconName
                toString:(NSMutableAttributedString*)instructionString
               withCaret:(NSMutableAttributedString*)caret
-       spaceBeforeCaret:(BOOL)spaceBeforeCaret
                  offset:(CGFloat)iconOffset
+                  width:(CGFloat)icondWidth
         imageAttributes:(NSDictionary*)attributes;
 // Sets the constraints for this view, positionning the |imageView| in the X
 // center and at 40% of the top. The |label| is positionned below.
@@ -87,7 +89,7 @@
     };
 
     // Offset to vertically center the icons.
-    CGFloat iconOffset = (textFont.xHeight - kIconSize) / 2.0;
+    CGFloat iconOffset = (textFont.xHeight - kIconHeight) / 2.0;
 
     UIFont* instructionFont = [fontLoader boldFontOfSize:kFontSize];
     NSDictionary* instructionAttributes = @{
@@ -114,30 +116,30 @@
       // If the device has a compact display the share menu is accessed from the
       // toolbar menu. If it is expanded, the share menu is directly accessible.
       [self attachIconNamed:kToolbarMenuIcon
-                    toString:instructionString
-                   withCaret:caret
-            spaceBeforeCaret:NO
-                      offset:iconOffset
-             imageAttributes:textAttributes];
+                   toString:instructionString
+                  withCaret:caret
+                     offset:iconOffset
+                      width:kToolbarMenuWidth
+            imageAttributes:textAttributes];
 
       accessibilityInstructionString = [[accessibilityInstructionString
           stringByAppendingString:l10n_util::GetNSString(
                                       IDS_IOS_TOOLBAR_SETTINGS)]
           stringByAppendingString:@", "];
+
+      // Add a space before the share icon.
+      [instructionString
+          appendAttributedString:[[NSAttributedString alloc]
+                                     initWithString:@" "
+                                         attributes:instructionAttributes]];
     }
 
-    // Add a space before the share icon.
-    [instructionString
-        appendAttributedString:[[NSAttributedString alloc]
-                                   initWithString:@" "
-                                       attributes:instructionAttributes]];
-
     [self attachIconNamed:kShareMenuIcon
-                  toString:instructionString
-                 withCaret:caret
-          spaceBeforeCaret:YES
-                    offset:iconOffset
-           imageAttributes:textAttributes];
+                 toString:instructionString
+                withCaret:caret
+                   offset:iconOffset
+                    width:kShareMenuWidth
+          imageAttributes:textAttributes];
 
     accessibilityInstructionString = [[accessibilityInstructionString
         stringByAppendingString:l10n_util::GetNSString(
@@ -186,8 +188,8 @@
 - (void)attachIconNamed:(NSString*)iconName
                toString:(NSMutableAttributedString*)instructionString
               withCaret:(NSMutableAttributedString*)caret
-       spaceBeforeCaret:(BOOL)spaceBeforeCaret
                  offset:(CGFloat)iconOffset
+                  width:(CGFloat)iconWidth
         imageAttributes:(NSDictionary*)attributes {
   // Add a zero width space to set the attributes for the image.
   [instructionString appendAttributedString:[[NSAttributedString alloc]
@@ -197,16 +199,14 @@
   NSTextAttachment* toolbarIcon = [[NSTextAttachment alloc] init];
   toolbarIcon.image = [[UIImage imageNamed:iconName]
       imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
-  toolbarIcon.bounds = CGRectMake(0, iconOffset, kIconSize, kIconSize);
+  toolbarIcon.bounds = CGRectMake(0, iconOffset, iconWidth, kIconHeight);
   [instructionString
       appendAttributedString:[NSAttributedString
                                  attributedStringWithAttachment:toolbarIcon]];
 
-  if (spaceBeforeCaret) {
     [instructionString appendAttributedString:[[NSAttributedString alloc]
                                                   initWithString:@" "
                                                       attributes:attributes]];
-  }
 
   [instructionString appendAttributedString:caret];
 }
diff --git a/ios/chrome/browser/ui/reading_list/resources/reading_list_toolbar_icon.png b/ios/chrome/browser/ui/reading_list/resources/reading_list_toolbar_icon.png
index 567394d..175aa31 100644
--- a/ios/chrome/browser/ui/reading_list/resources/reading_list_toolbar_icon.png
+++ b/ios/chrome/browser/ui/reading_list/resources/reading_list_toolbar_icon.png
Binary files differ
diff --git a/ios/chrome/browser/ui/reading_list/resources/reading_list_toolbar_icon@2x.png b/ios/chrome/browser/ui/reading_list/resources/reading_list_toolbar_icon@2x.png
index c8bf225c..60bc239f 100644
--- a/ios/chrome/browser/ui/reading_list/resources/reading_list_toolbar_icon@2x.png
+++ b/ios/chrome/browser/ui/reading_list/resources/reading_list_toolbar_icon@2x.png
Binary files differ
diff --git a/ios/chrome/browser/ui/reading_list/resources/reading_list_toolbar_icon@3x.png b/ios/chrome/browser/ui/reading_list/resources/reading_list_toolbar_icon@3x.png
index e030c011..1f6925d51 100644
--- a/ios/chrome/browser/ui/reading_list/resources/reading_list_toolbar_icon@3x.png
+++ b/ios/chrome/browser/ui/reading_list/resources/reading_list_toolbar_icon@3x.png
Binary files differ
diff --git a/ios/chrome/browser/ui/settings/utils/BUILD.gn b/ios/chrome/browser/ui/settings/utils/BUILD.gn
index c8754f8d..3700356 100644
--- a/ios/chrome/browser/ui/settings/utils/BUILD.gn
+++ b/ios/chrome/browser/ui/settings/utils/BUILD.gn
@@ -16,9 +16,6 @@
     "//components/content_settings/core/browser",
     "//components/content_settings/core/common",
     "//components/prefs",
-    "//ios/chrome/browser/ui",
-    "//ios/public/provider/chrome/browser",
-    "//ios/public/provider/chrome/browser/signin",
   ]
 }
 
diff --git a/ios/showcase/core/resources/Icon-120.png b/ios/showcase/core/resources/Icon-120.png
index 433df7265..d54ac65 100644
--- a/ios/showcase/core/resources/Icon-120.png
+++ b/ios/showcase/core/resources/Icon-120.png
Binary files differ
diff --git a/ios/showcase/core/resources/Icon-152.png b/ios/showcase/core/resources/Icon-152.png
index 0a3e5d0..71eb0df 100644
--- a/ios/showcase/core/resources/Icon-152.png
+++ b/ios/showcase/core/resources/Icon-152.png
Binary files differ
diff --git a/ios/showcase/core/resources/Icon-167.png b/ios/showcase/core/resources/Icon-167.png
index 7c51f33c..f466a018 100644
--- a/ios/showcase/core/resources/Icon-167.png
+++ b/ios/showcase/core/resources/Icon-167.png
Binary files differ
diff --git a/ios/showcase/core/resources/Icon-180.png b/ios/showcase/core/resources/Icon-180.png
index ca6ccc4..ae2125bd 100644
--- a/ios/showcase/core/resources/Icon-180.png
+++ b/ios/showcase/core/resources/Icon-180.png
Binary files differ
diff --git a/ios/showcase/core/resources/Icon-29.png b/ios/showcase/core/resources/Icon-29.png
index f5730bc8..a473a563 100644
--- a/ios/showcase/core/resources/Icon-29.png
+++ b/ios/showcase/core/resources/Icon-29.png
Binary files differ
diff --git a/ios/showcase/core/resources/Icon-58.png b/ios/showcase/core/resources/Icon-58.png
index 94de16e..5e2bae3 100644
--- a/ios/showcase/core/resources/Icon-58.png
+++ b/ios/showcase/core/resources/Icon-58.png
Binary files differ
diff --git a/ios/showcase/core/resources/Icon-76.png b/ios/showcase/core/resources/Icon-76.png
index 199cf8f..7b7b4fa 100644
--- a/ios/showcase/core/resources/Icon-76.png
+++ b/ios/showcase/core/resources/Icon-76.png
Binary files differ
diff --git a/ios/showcase/core/resources/Icon-80.png b/ios/showcase/core/resources/Icon-80.png
index 9b27743..530d2a6 100644
--- a/ios/showcase/core/resources/Icon-80.png
+++ b/ios/showcase/core/resources/Icon-80.png
Binary files differ
diff --git a/ios/showcase/core/resources/Icon-87.png b/ios/showcase/core/resources/Icon-87.png
index 5dc0a08..9f4ab561 100644
--- a/ios/showcase/core/resources/Icon-87.png
+++ b/ios/showcase/core/resources/Icon-87.png
Binary files differ
diff --git a/ios/web/web_state/ui/crw_web_controller_unittest.mm b/ios/web/web_state/ui/crw_web_controller_unittest.mm
index b41327ea..ebc5dd1 100644
--- a/ios/web/web_state/ui/crw_web_controller_unittest.mm
+++ b/ios/web/web_state/ui/crw_web_controller_unittest.mm
@@ -54,27 +54,6 @@
                           previousURL:(const GURL&)previousURL;
 @end
 
-// Used to mock CRWWebDelegate methods with C++ params.
-@interface MockInteractionLoader : OCMockComplexTypeHelper
-@end
-
-@implementation MockInteractionLoader
-
-typedef BOOL (^openExternalURLBlockType)(const GURL&);
-
-- (BOOL)openExternalURL:(const GURL&)url {
-  return static_cast<openExternalURLBlockType>([self blockForSelector:_cmd])(
-      url);
-}
-
-- (BOOL)webController:(CRWWebController*)webController
-        shouldOpenURL:(const GURL&)URL
-      mainDocumentURL:(const GURL&)mainDocumentURL
-          linkClicked:(BOOL)linkClicked {
-  return YES;
-}
-@end
-
 @interface CountingObserver : NSObject<CRWWebControllerObserver>
 
 @property(nonatomic, readonly) int pageLoadedCount;
@@ -134,55 +113,38 @@
   });
 }
 
-// Test fixture for testing CRWWebController. Stubs out web view and
-// child CRWWebController.
+// Test fixture for testing CRWWebController. Stubs out web view.
 class CRWWebControllerTest : public web::WebTestWithWebController {
  protected:
   void SetUp() override {
     web::WebTestWithWebController::SetUp();
-    mockWebView_.reset(CreateMockWebView());
-    mockScrollView_.reset([[UIScrollView alloc] init]);
-    [[[mockWebView_ stub] andReturn:mockScrollView_.get()] scrollView];
+    mock_web_view_.reset([CreateMockWebView() retain]);
+    scroll_view_.reset([[UIScrollView alloc] init]);
+    [[[mock_web_view_ stub] andReturn:scroll_view_.get()] scrollView];
 
-    id originalMockDelegate =
-        [OCMockObject niceMockForProtocol:@protocol(CRWWebDelegate)];
-    mockDelegate_.reset([[MockInteractionLoader alloc]
-        initWithRepresentedObject:originalMockDelegate]);
-    [web_controller() setDelegate:mockDelegate_];
     base::scoped_nsobject<TestWebViewContentView> webViewContentView(
-        [[TestWebViewContentView alloc] initWithMockWebView:mockWebView_
-                                                 scrollView:mockScrollView_]);
+        [[TestWebViewContentView alloc] initWithMockWebView:mock_web_view_
+                                                 scrollView:scroll_view_]);
     [web_controller() injectWebViewContentView:webViewContentView];
-
-    NavigationManagerImpl& navigationManager =
-        [web_controller() webStateImpl]->GetNavigationManagerImpl();
-    navigationManager.InitializeSession(NO);
-    navigationManager.AddPendingItem(
-        GURL("http://www.google.com/?q=foo#bar"), web::Referrer(),
-        ui::PAGE_TRANSITION_TYPED,
-        web::NavigationInitiationType::USER_INITIATED);
   }
 
   void TearDown() override {
-    EXPECT_OCMOCK_VERIFY(mockDelegate_);
-    EXPECT_OCMOCK_VERIFY(mockChildWebController_);
-    EXPECT_OCMOCK_VERIFY(mockWebView_);
+    EXPECT_OCMOCK_VERIFY(mock_web_view_);
     [web_controller() resetInjectedWebViewContentView];
-    [web_controller() setDelegate:nil];
     web::WebTestWithWebController::TearDown();
   }
 
   // The value for web view OCMock objects to expect for |-setFrame:|.
-  CGRect ExpectedWebViewFrame() const {
-    CGSize containerViewSize = [UIScreen mainScreen].bounds.size;
-    containerViewSize.height -=
+  CGRect GetExpectedWebViewFrame() const {
+    CGSize container_view_size = [UIScreen mainScreen].bounds.size;
+    container_view_size.height -=
         CGRectGetHeight([UIApplication sharedApplication].statusBarFrame);
-    return {CGPointZero, containerViewSize};
+    return {CGPointZero, container_view_size};
   }
 
   // Creates WebView mock.
   UIView* CreateMockWebView() {
-    id result = [[OCMockObject mockForClass:[WKWebView class]] retain];
+    id result = [OCMockObject mockForClass:[WKWebView class]];
 
     if (base::ios::IsRunningOnIOS10OrLater()) {
       [[result stub] serverTrust];
@@ -194,95 +156,80 @@
     [[[result stub] andReturn:[NSURL URLWithString:@(kTestURLString)]] URL];
     [[result stub] setNavigationDelegate:OCMOCK_ANY];
     [[result stub] setUIDelegate:OCMOCK_ANY];
-    [[result stub] setFrame:ExpectedWebViewFrame()];
+    [[result stub] setFrame:GetExpectedWebViewFrame()];
     [[result stub] addObserver:web_controller()
                     forKeyPath:OCMOCK_ANY
                        options:0
                        context:nullptr];
-    [[result stub] addObserver:OCMOCK_ANY
-                    forKeyPath:@"scrollView.backgroundColor"
-                       options:0
-                       context:nullptr];
-
     [[result stub] removeObserver:web_controller() forKeyPath:OCMOCK_ANY];
-    [[result stub] removeObserver:OCMOCK_ANY
-                       forKeyPath:@"scrollView.backgroundColor"];
 
     return result;
   }
 
-  base::scoped_nsobject<UIScrollView> mockScrollView_;
-  base::scoped_nsobject<id> mockWebView_;
-  base::scoped_nsobject<id> mockDelegate_;
-  base::scoped_nsobject<id> mockChildWebController_;
+  base::scoped_nsobject<UIScrollView> scroll_view_;
+  base::scoped_nsobject<id> mock_web_view_;
 };
 
 #define MAKE_URL(url_string) GURL([url_string UTF8String])
 
 TEST_F(CRWWebControllerTest, UrlForHistoryNavigation) {
-  NSArray* urlsNoFragments = @[
-    @"http://one.com",
-    @"http://two.com/",
-    @"http://three.com/bar",
-    @"http://four.com/bar/",
-    @"five",
-    @"/six",
-    @"/seven/",
-    @""
+  NSArray* urls_without_fragments = @[
+    @"http://one.com", @"http://two.com/", @"http://three.com/bar",
+    @"http://four.com/bar/", @"five", @"/six", @"/seven/", @""
   ];
 
   NSArray* fragments = @[ @"#", @"#bar" ];
-  NSMutableArray* urlsWithFragments = [NSMutableArray array];
-  for (NSString* url in urlsNoFragments) {
+  NSMutableArray* urls_with_fragments = [NSMutableArray array];
+  for (NSString* url in urls_without_fragments) {
     for (NSString* fragment in fragments) {
-      [urlsWithFragments addObject:[url stringByAppendingString:fragment]];
+      [urls_with_fragments addObject:[url stringByAppendingString:fragment]];
     }
   }
 
   GURL previous_url;
-  web::NavigationItemImpl toItem;
+  web::NavigationItemImpl to_item;
 
   // No start fragment: the end url is never changed.
-  for (NSString* start in urlsNoFragments) {
-    for (NSString* end in urlsWithFragments) {
+  for (NSString* start in urls_without_fragments) {
+    for (NSString* end in urls_with_fragments) {
       previous_url = MAKE_URL(start);
-      toItem.SetURL(MAKE_URL(end));
+      to_item.SetURL(MAKE_URL(end));
       EXPECT_EQ(MAKE_URL(end),
-                [web_controller() URLForHistoryNavigationToItem:&toItem
+                [web_controller() URLForHistoryNavigationToItem:&to_item
                                                     previousURL:previous_url]);
     }
   }
   // Both contain fragments: the end url is never changed.
-  for (NSString* start in urlsWithFragments) {
-    for (NSString* end in urlsWithFragments) {
+  for (NSString* start in urls_with_fragments) {
+    for (NSString* end in urls_with_fragments) {
       previous_url = MAKE_URL(start);
-      toItem.SetURL(MAKE_URL(end));
+      to_item.SetURL(MAKE_URL(end));
       EXPECT_EQ(MAKE_URL(end),
-                [web_controller() URLForHistoryNavigationToItem:&toItem
+                [web_controller() URLForHistoryNavigationToItem:&to_item
                                                     previousURL:previous_url]);
     }
   }
-  for (unsigned start_index = 0; start_index < [urlsWithFragments count];
+  for (unsigned start_index = 0; start_index < urls_with_fragments.count;
        ++start_index) {
-    NSString* start = urlsWithFragments[start_index];
-    for (unsigned end_index = 0; end_index < [urlsNoFragments count];
+    NSString* start = urls_with_fragments[start_index];
+    for (unsigned end_index = 0; end_index < urls_without_fragments.count;
          ++end_index) {
-      NSString* end = urlsNoFragments[end_index];
+      NSString* end = urls_without_fragments[end_index];
       previous_url = MAKE_URL(start);
       if (start_index / 2 != end_index) {
         // The URLs have nothing in common, they are left untouched.
-        toItem.SetURL(MAKE_URL(end));
+        to_item.SetURL(MAKE_URL(end));
         EXPECT_EQ(
             MAKE_URL(end),
-            [web_controller() URLForHistoryNavigationToItem:&toItem
+            [web_controller() URLForHistoryNavigationToItem:&to_item
                                                 previousURL:previous_url]);
       } else {
         // Start contains a fragment and matches end: An empty fragment is
         // added.
-        toItem.SetURL(MAKE_URL(end));
+        to_item.SetURL(MAKE_URL(end));
         EXPECT_EQ(
             MAKE_URL([end stringByAppendingString:@"#"]),
-            [web_controller() URLForHistoryNavigationToItem:&toItem
+            [web_controller() URLForHistoryNavigationToItem:&to_item
                                                 previousURL:previous_url]);
       }
     }
@@ -311,16 +258,12 @@
                         web::kNSErrorPeerCertificateChainKey : chain,
                         web::kNSErrorFailingURLKey : net::NSURLWithGURL(url),
                       }];
-  CRWWebControllerContainerView* containerView =
-      static_cast<CRWWebControllerContainerView*>([web_controller() view]);
-  WKWebView* webView =
-      static_cast<WKWebView*>(containerView.webViewContentView.webView);
   base::scoped_nsobject<NSObject> navigation([[NSObject alloc] init]);
   [static_cast<id<WKNavigationDelegate>>(web_controller())
-                            webView:webView
+                            webView:mock_web_view_
       didStartProvisionalNavigation:static_cast<WKNavigation*>(navigation)];
   [static_cast<id<WKNavigationDelegate>>(web_controller())
-                           webView:webView
+                           webView:mock_web_view_
       didFailProvisionalNavigation:static_cast<WKNavigation*>(navigation)
                          withError:error];
 
@@ -718,24 +661,28 @@
 }
 
 TEST_F(CRWWebControllerTest, WebUrlWithTrustLevel) {
-  [[[mockWebView_ stub] andReturn:[NSURL URLWithString:@(kTestURLString)]] URL];
-  [[[mockWebView_ stub] andReturnBool:NO] hasOnlySecureContent];
-  [[[mockWebView_ stub] andReturn:@""] title];
+  [web_controller() webStateImpl]->GetNavigationManagerImpl().AddPendingItem(
+      GURL("http://chromium.test"), web::Referrer(), ui::PAGE_TRANSITION_TYPED,
+      web::NavigationInitiationType::USER_INITIATED);
+
+  [[[mock_web_view_ stub] andReturnBool:NO] hasOnlySecureContent];
+  [[[mock_web_view_ stub] andReturn:@""] title];
 
   // Stub out the injection process.
-  [[mockWebView_ stub] evaluateJavaScript:OCMOCK_ANY
-                        completionHandler:OCMOCK_ANY];
+  [[mock_web_view_ stub] evaluateJavaScript:OCMOCK_ANY
+                          completionHandler:OCMOCK_ANY];
 
   // Simulate registering load request to avoid failing page load simulation.
   [web_controller() simulateLoadRequestWithURL:GURL(kTestURLString)];
   // Simulate a page load to trigger a URL update.
-  [static_cast<id<WKNavigationDelegate>>(web_controller()) webView:mockWebView_
-                                               didCommitNavigation:nil];
+  [static_cast<id<WKNavigationDelegate>>(web_controller())
+                  webView:mock_web_view_
+      didCommitNavigation:nil];
 
   web::URLVerificationTrustLevel trust_level = web::kNone;
-  GURL gurl = [web_controller() currentURLWithTrustLevel:&trust_level];
+  GURL url = [web_controller() currentURLWithTrustLevel:&trust_level];
 
-  EXPECT_EQ(gurl, GURL(kTestURLString));
+  EXPECT_EQ(GURL(kTestURLString), url);
   EXPECT_EQ(web::kAbsolute, trust_level);
 }
 
diff --git a/services/ui/ws/window_manager_client_unittest.cc b/services/ui/ws/window_manager_client_unittest.cc
index 075b70b2..02a59a7 100644
--- a/services/ui/ws/window_manager_client_unittest.cc
+++ b/services/ui/ws/window_manager_client_unittest.cc
@@ -711,7 +711,8 @@
 TEST_F(WindowServerTest, EstablishConnectionViaFactory) {
   EstablishConnectionViaFactoryDelegate delegate(window_manager());
   set_window_manager_delegate(&delegate);
-  aura::WindowTreeClient second_client(connector(), this);
+  aura::WindowTreeClient second_client(connector(), this, nullptr, nullptr,
+                                       nullptr, false);
   second_client.ConnectViaWindowTreeFactory();
   aura::WindowTreeHostMus window_tree_host_in_second_client(&second_client);
   window_tree_host_in_second_client.InitHost();
@@ -739,7 +740,8 @@
   // of the first window and then add it.
   EstablishConnectionViaFactoryDelegate delegate(window_manager());
   set_window_manager_delegate(&delegate);
-  aura::WindowTreeClient second_client(connector(), this);
+  aura::WindowTreeClient second_client(connector(), this, nullptr, nullptr,
+                                       nullptr, false);
   second_client.ConnectViaWindowTreeFactory();
   aura::WindowTreeHostMus window_tree_host_in_second_client(&second_client);
   window_tree_host_in_second_client.InitHost();
diff --git a/services/ui/ws/window_server_test_base.cc b/services/ui/ws/window_server_test_base.cc
index 492bad0..4cfacda 100644
--- a/services/ui/ws/window_server_test_base.cc
+++ b/services/ui/ws/window_server_test_base.cc
@@ -271,8 +271,10 @@
 void WindowServerTestBase::Create(
     const service_manager::Identity& remote_identity,
     mojom::WindowTreeClientRequest request) {
+  const bool create_discardable_memory = false;
   window_tree_clients_.push_back(base::MakeUnique<aura::WindowTreeClient>(
-      connector(), this, nullptr, std::move(request)));
+      connector(), this, nullptr, std::move(request), nullptr,
+      create_discardable_memory));
 }
 
 bool WindowServerTestBase::DeleteWindowTreeHost(
diff --git a/testing/buildbot/chromium.perf.fyi.json b/testing/buildbot/chromium.perf.fyi.json
index 6f9d31b..41142a4 100644
--- a/testing/buildbot/chromium.perf.fyi.json
+++ b/testing/buildbot/chromium.perf.fyi.json
@@ -11003,6 +11003,63 @@
           "hard_timeout": 7200,
           "io_timeout": 3600
         }
+      },
+      {
+        "args": [
+          "webrtc.webrtc_smoothness_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.webrtc_smoothness_tbmv2",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "webrtc.webrtc_smoothness_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.webrtc_smoothness_tbmv2.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
       }
     ]
   },
@@ -22122,6 +22179,63 @@
           "hard_timeout": 7200,
           "io_timeout": 3600
         }
+      },
+      {
+        "args": [
+          "webrtc.webrtc_smoothness_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.webrtc_smoothness_tbmv2",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build155-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "webrtc.webrtc_smoothness_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.webrtc_smoothness_tbmv2.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build155-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
       }
     ]
   },
@@ -33127,6 +33241,63 @@
           "hard_timeout": 7200,
           "io_timeout": 3600
         }
+      },
+      {
+        "args": [
+          "webrtc.webrtc_smoothness_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.webrtc_smoothness_tbmv2",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "1002:9874",
+              "id": "build219-b4",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "webrtc.webrtc_smoothness_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.webrtc_smoothness_tbmv2.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "1002:9874",
+              "id": "build219-b4",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
       }
     ]
   }
diff --git a/testing/buildbot/chromium.perf.json b/testing/buildbot/chromium.perf.json
index 3b63567..2dccb0a 100644
--- a/testing/buildbot/chromium.perf.json
+++ b/testing/buildbot/chromium.perf.json
@@ -11127,6 +11127,63 @@
           "hard_timeout": 7200,
           "io_timeout": 3600
         }
+      },
+      {
+        "args": [
+          "webrtc.webrtc_smoothness_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.webrtc_smoothness_tbmv2",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "102b:0534",
+              "id": "build148-m1",
+              "os": "Ubuntu-14.04",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "webrtc.webrtc_smoothness_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.webrtc_smoothness_tbmv2.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "102b:0534",
+              "id": "build148-m1",
+              "os": "Ubuntu-14.04",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
       }
     ]
   },
@@ -22151,6 +22208,63 @@
           "hard_timeout": 7200,
           "io_timeout": 3600
         }
+      },
+      {
+        "args": [
+          "webrtc.webrtc_smoothness_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.webrtc_smoothness_tbmv2",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:0166",
+              "id": "build102-b1",
+              "os": "Mac-10.11",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "webrtc.webrtc_smoothness_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.webrtc_smoothness_tbmv2.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:0166",
+              "id": "build102-b1",
+              "os": "Mac-10.11",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
       }
     ]
   },
@@ -33156,6 +33270,63 @@
           "hard_timeout": 7200,
           "io_timeout": 3600
         }
+      },
+      {
+        "args": [
+          "webrtc.webrtc_smoothness_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.webrtc_smoothness_tbmv2",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:0a2e",
+              "id": "build158-m1",
+              "os": "Mac-10.12",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "webrtc.webrtc_smoothness_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.webrtc_smoothness_tbmv2.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:0a2e",
+              "id": "build158-m1",
+              "os": "Mac-10.12",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
       }
     ]
   },
@@ -44161,6 +44332,63 @@
           "hard_timeout": 7200,
           "io_timeout": 3600
         }
+      },
+      {
+        "args": [
+          "webrtc.webrtc_smoothness_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.webrtc_smoothness_tbmv2",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:1626",
+              "id": "build123-b1",
+              "os": "Mac-10.11",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "webrtc.webrtc_smoothness_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.webrtc_smoothness_tbmv2.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:1626",
+              "id": "build123-b1",
+              "os": "Mac-10.11",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
       }
     ]
   },
@@ -55166,6 +55394,63 @@
           "hard_timeout": 7200,
           "io_timeout": 3600
         }
+      },
+      {
+        "args": [
+          "webrtc.webrtc_smoothness_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.webrtc_smoothness_tbmv2",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:0a26",
+              "id": "build24-b1",
+              "os": "Mac-10.12",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "webrtc.webrtc_smoothness_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.webrtc_smoothness_tbmv2.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:0a26",
+              "id": "build24-b1",
+              "os": "Mac-10.12",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
       }
     ]
   },
@@ -66171,6 +66456,63 @@
           "hard_timeout": 7200,
           "io_timeout": 3600
         }
+      },
+      {
+        "args": [
+          "webrtc.webrtc_smoothness_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.webrtc_smoothness_tbmv2",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "1002:6821",
+              "id": "build128-b1",
+              "os": "Mac-10.11",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "webrtc.webrtc_smoothness_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.webrtc_smoothness_tbmv2.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "1002:6821",
+              "id": "build128-b1",
+              "os": "Mac-10.11",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
       }
     ]
   },
@@ -77176,6 +77518,63 @@
           "hard_timeout": 7200,
           "io_timeout": 3600
         }
+      },
+      {
+        "args": [
+          "webrtc.webrtc_smoothness_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.webrtc_smoothness_tbmv2",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:0d26",
+              "id": "build4-b1",
+              "os": "Mac-10.11",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "webrtc.webrtc_smoothness_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.webrtc_smoothness_tbmv2.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:0d26",
+              "id": "build4-b1",
+              "os": "Mac-10.11",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
       }
     ]
   },
@@ -88181,6 +88580,63 @@
           "hard_timeout": 7200,
           "io_timeout": 3600
         }
+      },
+      {
+        "args": [
+          "webrtc.webrtc_smoothness_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.webrtc_smoothness_tbmv2",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:1616",
+              "id": "build117-b1",
+              "os": "Windows-10-10240",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "webrtc.webrtc_smoothness_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.webrtc_smoothness_tbmv2.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:1616",
+              "id": "build117-b1",
+              "os": "Windows-10-10240",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
       }
     ]
   },
@@ -99205,6 +99661,63 @@
           "hard_timeout": 7200,
           "io_timeout": 3600
         }
+      },
+      {
+        "args": [
+          "webrtc.webrtc_smoothness_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.webrtc_smoothness_tbmv2",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "102b:0534",
+              "id": "build132-m1",
+              "os": "Windows-10-10240",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "webrtc.webrtc_smoothness_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.webrtc_smoothness_tbmv2.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "102b:0534",
+              "id": "build132-m1",
+              "os": "Windows-10-10240",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
       }
     ]
   },
@@ -110286,6 +110799,63 @@
           "hard_timeout": 7200,
           "io_timeout": 3600
         }
+      },
+      {
+        "args": [
+          "webrtc.webrtc_smoothness_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.webrtc_smoothness_tbmv2",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "1002:6613",
+              "id": "build101-m1",
+              "os": "Windows-2008ServerR2-SP1",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "webrtc.webrtc_smoothness_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.webrtc_smoothness_tbmv2.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "1002:6613",
+              "id": "build101-m1",
+              "os": "Windows-2008ServerR2-SP1",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
       }
     ]
   },
@@ -121348,6 +121918,63 @@
           "hard_timeout": 7200,
           "io_timeout": 3600
         }
+      },
+      {
+        "args": [
+          "webrtc.webrtc_smoothness_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.webrtc_smoothness_tbmv2",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:041a",
+              "id": "build164-m1",
+              "os": "Windows-2008ServerR2-SP1",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "webrtc.webrtc_smoothness_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.webrtc_smoothness_tbmv2.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:041a",
+              "id": "build164-m1",
+              "os": "Windows-2008ServerR2-SP1",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
       }
     ]
   },
@@ -132429,6 +133056,63 @@
           "hard_timeout": 7200,
           "io_timeout": 3600
         }
+      },
+      {
+        "args": [
+          "webrtc.webrtc_smoothness_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.webrtc_smoothness_tbmv2",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:104a",
+              "id": "build92-m1",
+              "os": "Windows-2008ServerR2-SP1",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "webrtc.webrtc_smoothness_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.webrtc_smoothness_tbmv2.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:104a",
+              "id": "build92-m1",
+              "os": "Windows-2008ServerR2-SP1",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
       }
     ]
   },
@@ -143491,6 +144175,63 @@
           "hard_timeout": 7200,
           "io_timeout": 3600
         }
+      },
+      {
+        "args": [
+          "webrtc.webrtc_smoothness_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.webrtc_smoothness_tbmv2",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "102b:0532",
+              "id": "build185-m1",
+              "os": "Windows-2008ServerR2-SP1",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "webrtc.webrtc_smoothness_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.webrtc_smoothness_tbmv2.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "102b:0532",
+              "id": "build185-m1",
+              "os": "Windows-2008ServerR2-SP1",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
       }
     ]
   },
@@ -154534,6 +155275,63 @@
           "hard_timeout": 7200,
           "io_timeout": 3600
         }
+      },
+      {
+        "args": [
+          "webrtc.webrtc_smoothness_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.webrtc_smoothness_tbmv2",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "102b:0532",
+              "id": "build138-m1",
+              "os": "Windows-2008ServerR2-SP1",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "webrtc.webrtc_smoothness_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.webrtc_smoothness_tbmv2.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "102b:0532",
+              "id": "build138-m1",
+              "os": "Windows-2008ServerR2-SP1",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
       }
     ]
   },
@@ -165596,6 +166394,63 @@
           "hard_timeout": 7200,
           "io_timeout": 3600
         }
+      },
+      {
+        "args": [
+          "webrtc.webrtc_smoothness_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.webrtc_smoothness_tbmv2",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "102b:0532",
+              "id": "build143-m1",
+              "os": "Windows-2012ServerR2-SP0",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "webrtc.webrtc_smoothness_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.webrtc_smoothness_tbmv2.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "102b:0532",
+              "id": "build143-m1",
+              "os": "Windows-2012ServerR2-SP0",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
       }
     ]
   },
@@ -176601,6 +177456,63 @@
           "hard_timeout": 7200,
           "io_timeout": 3600
         }
+      },
+      {
+        "args": [
+          "webrtc.webrtc_smoothness_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.webrtc_smoothness_tbmv2",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:161e",
+              "id": "build30-b1",
+              "os": "Windows-10-10240",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "webrtc.webrtc_smoothness_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.webrtc_smoothness_tbmv2.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:161e",
+              "id": "build30-b1",
+              "os": "Windows-10-10240",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
       }
     ]
   }
diff --git a/third_party/WebKit/LayoutTests/LeakExpectations b/third_party/WebKit/LayoutTests/LeakExpectations
index 3dc29fe0..5b775b2 100644
--- a/third_party/WebKit/LayoutTests/LeakExpectations
+++ b/third_party/WebKit/LayoutTests/LeakExpectations
@@ -25,6 +25,7 @@
 
 # FIXME: The below tests fails when the leak detector is disabled.
 crbug.com/366029 compositing/fixed-body-background-positioned.html [ Failure Pass ]
+crbug.com/366029 virtual/disable-spinvalidation/compositing/fixed-body-background-positioned.html [ Failure Pass ]
 
 # FIXME: The below tests crashes when the leak detector is run on debug builds
 crbug.com/366043 [ Debug ] fast/history/history-traversal-is-asynchronous.html [ Crash ]
diff --git a/third_party/WebKit/LayoutTests/SlowTests b/third_party/WebKit/LayoutTests/SlowTests
index 4485b557..a47077a1 100644
--- a/third_party/WebKit/LayoutTests/SlowTests
+++ b/third_party/WebKit/LayoutTests/SlowTests
@@ -14,6 +14,8 @@
 crbug.com/24182 editing/selection/modify_move/move-by-word-visually-multi-line.html [ Slow ]
 crbug.com/24182 compositing/culling/filter-occlusion-blur-large.html [ Slow ]
 crbug.com/24182 compositing/video-frame-size-change.html [ Slow ]
+crbug.com/24182 virtual/disable-spinvalidation/compositing/culling/filter-occlusion-blur-large.html [ Slow ]
+crbug.com/24182 virtual/disable-spinvalidation/compositing/video-frame-size-change.html [ Slow ]
 crbug.com/24182 css3/filters/effect-reference-hidpi-hw.html [ Slow ]
 crbug.com/24182 css3/filters/filter-change-repaint-composited.html [ Slow ]
 crbug.com/24182 editing/selection/caret-at-bidi-boundary.html [ Slow ]
@@ -302,6 +304,7 @@
 crbug.com/528419 inspector/elements/styles-2/pseudo-elements.html [ Slow ]
 
 crbug.com/529345 [ Win10 ] paint/masks/fieldset-mask.html [ Slow ]
+crbug.com/529345 [ Win10 ] virtual/disable-spinvalidation/paint/masks/fieldset-mask.html [ Slow ]
 crbug.com/552556 [ Win Linux ] virtual/threaded/fast/scroll-behavior/overflow-scroll-root-frame-animates.html [ Slow ]
 crbug.com/552556 [ Win Linux ] virtual/threaded/fast/scroll-behavior/overflow-scroll-animates.html [ Slow ]
 crbug.com/570656 [ Mac ] fast/writing-mode/Kusa-Makura-background-canvas.html [ Slow ]
@@ -354,6 +357,7 @@
 crbug.com/614910 virtual/gpu-rasterization/images/color-profile-filter.html [ Slow ]
 
 crbug.com/623798 paint/images/animated-gif-last-frame-crash.html [ Slow ]
+crbug.com/623798 virtual/disable-spinvalidation/paint/images/animated-gif-last-frame-crash.html [ Slow ]
 
 crbug.com/606649 fast/dom/gc-dom-tree-lifetime.html [ Slow ]
 
@@ -367,6 +371,8 @@
 # bots running tests on real hardware or maybe when using SwiftShader.
 crbug.com/646528 compositing/lots-of-img-layers.html [ Slow ]
 crbug.com/646528 compositing/lots-of-img-layers-with-opacity.html [ Slow ]
+crbug.com/646528 virtual/disable-spinvalidation/compositing/lots-of-img-layers.html [ Slow ]
+crbug.com/646528 virtual/disable-spinvalidation/compositing/lots-of-img-layers-with-opacity.html [ Slow ]
 
 # IDB Observer tests require multiple browsing contexts/workers interacting with
 # IndexedDB, which can be slow.
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 33b333c..e2cf74f 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -50,25 +50,10 @@
 # --- End SPV2 Tests ---
 
 crbug.com/309675 compositing/gestures/gesture-tapHighlight-simple-longPress.html [ Failure ]
-
-# TODO(schenney) For some reason these tests are failing to get correct baselines with rebaseline-cl.
-# They may be flaky or it may be something else. Investigate and rebaseline manually or with the bot.
-crbug.com/349985 [ Win Linux ] fast/css/background-clip-values.html [ Failure ]
-crbug.com/349985 [ Win Linux ] compositing/scrollbars/custom-composited-different-track-parts.html [ Failure ]
-crbug.com/349985 [ Mac ] fast/table/backgr_border-table-column-group.html [ Failure ]
-crbug.com/349985 [ Mac ] fast/table/backgr_simple-table.html [ Failure ]
-crbug.com/349985 [ Mac ] fast/table/backgr_position-table-cell-collapsed-border.html [ Failure ]
-crbug.com/349985 [ Mac ] fast/table/backgr_border-table-collapsed-border.html [ Failure ]
-crbug.com/349985 [ Mac ] fast/table/backgr_simple-table-collapsed-border.html [ Failure ]
-crbug.com/349985 [ Win ] fast/table/backgr_position-table-row-collapsed-border.html [ Failure ]
-crbug.com/349985 [ Win ] fast/table/backgr_border-table-row-collapsed-border.html [ Failure ]
-crbug.com/349985 [ Win ] fast/table/backgr_simple-table-row-collapsed-border.html [ Failure ]
-crbug.com/349985 [ Win ] fast/table/backgr_simple-table-cell-collapsed-border.html [ Failure ]
-crbug.com/349985 [ Win ] fast/table/backgr_simple-table-cell.html [ Failure ]
-crbug.com/349985 [ Win ] fast/table/backgr_simple-table-column-group.html [ Failure ]
-crbug.com/349985 [ Win ] fast/table/backgr_position-table-column-group-collapsed-border.html [ Failure ]
+crbug.com/309675 virtual/disable-spinvalidation/compositing/gestures/gesture-tapHighlight-simple-longPress.html [ Failure ]
 
 crbug.com/504613 crbug.com/524248 paint/images/image-backgrounds-not-antialiased.html [ Skip ]
+crbug.com/504613 crbug.com/524248 virtual/disable-spinvalidation/paint/images/image-backgrounds-not-antialiased.html [ Skip ]
 
 crbug.com/517449 [ Android ] images/optimize-contrast-image.html [ Failure ]
 
@@ -81,6 +66,7 @@
 crbug.com/549742 [ Linux Mac Win ] virtual/gpu/fast/canvas/canvas-drawImage-video-imageSmoothingEnabled.html [ Failure ]
 
 crbug.com/591500 [ Win10 ] compositing/squashing/squashing-print.html [ Failure ]
+crbug.com/591500 [ Win10 ] virtual/disable-spinvalidation/compositing/squashing/squashing-print.html [ Failure ]
 
 crbug.com/602110 hittesting/border-hittest-with-image-fallback.html [ Failure ]
 
@@ -131,6 +117,7 @@
 crbug.com/683339 virtual/disable-spinvalidation/paint/invalidation/paged-with-overflowing-block-rl.html [ Failure ]
 
 crbug.com/646010 paint/selection/text-selection-newline-rtl-double-linebreak.html [ Failure ]
+crbug.com/646010 virtual/disable-spinvalidation/paint/selection/text-selection-newline-rtl-double-linebreak.html [ Failure ]
 crbug.com/646015 paint/invalidation/hover-invalidation-table.html [ Failure ]
 crbug.com/646015 virtual/disable-spinvalidation/paint/invalidation/hover-invalidation-table.html [ Failure ]
 crbug.com/646016 paint/invalidation/selected-replaced.html [ Failure ]
@@ -151,9 +138,11 @@
 
 # Added 2016-12-14
 crbug.com/674396 [ Win ] compositing/reflections/nested-reflection-transition.html [ Pass Failure ]
+crbug.com/674396 [ Win ] virtual/disable-spinvalidation/compositing/reflections/nested-reflection-transition.html [ Pass Failure ]
 
 # Added 2016-12-15
 crbug.com/674468 [ Trusty ] compositing/reflections/nested-reflection-transition.html [ Pass Failure ]
+crbug.com/674468 [ Trusty ] virtual/disable-spinvalidation/compositing/reflections/nested-reflection-transition.html [ Pass Failure ]
 
 # Added 2016-12-16
 crbug.com/674858 [ Linux ] virtual/threaded/printing/offscreencanvas-2d-printing.html [ Pass Failure Crash ]
@@ -162,10 +151,14 @@
 # Added 2017-02-20
 crbug.com/693510 compositing/reflections/nested-reflection-anchor-point.html [ Failure Pass ]
 crbug.com/693510 compositing/reflections/nested-reflection-animated.html [ Failure Pass ]
+crbug.com/693510 virtual/disable-spinvalidation/compositing/reflections/nested-reflection-anchor-point.html [ Failure Pass ]
+crbug.com/693510 virtual/disable-spinvalidation/compositing/reflections/nested-reflection-animated.html [ Failure Pass ]
 
 crbug.com/667045 paint/invalidation/table/composited-cell-collapsed-border-add-anonymous.html [ Crash ]
 crbug.com/667045 virtual/disable-spinvalidation/paint/invalidation/table/composited-cell-collapsed-border-add-anonymous.html [ Crash ]
 
+crbug.com/701800 [ Win7 ] virtual/disable-spinvalidation/compositing/perpendicular-layer-sorting.html [ Pass Failure ]
+
 # ====== Paint team owned tests to here ======
 
 # ====== LayoutNG-only failures from here ======
@@ -1801,6 +1794,7 @@
 crbug.com/487344 paint/invalidation/video-paint-invalidation.html [ Failure ]
 crbug.com/487344 virtual/disable-spinvalidation/paint/invalidation/video-paint-invalidation.html [ Failure ]
 crbug.com/487344 [ Win ] compositing/video/video-controls-layer-creation.html [ Pass Failure ]
+crbug.com/487344 [ Win ] virtual/disable-spinvalidation/compositing/video/video-controls-layer-creation.html [ Pass Failure ]
 crbug.com/487344 fast/hidpi/video-controls-in-hidpi.html [ Failure ]
 crbug.com/487344 fast/layers/video-layer.html [ Failure ]
 crbug.com/487344 media/audio-controls-rendering.html [ Failure ]
@@ -2264,7 +2258,6 @@
 crbug.com/626703 external/wpt/streams/readable-streams/cancel.html [ Failure Timeout ]
 crbug.com/626703 external/wpt/streams/readable-streams/garbage-collection.html [ Failure Timeout ]
 crbug.com/626703 external/wpt/streams/readable-streams/general.html [ Failure Timeout ]
-crbug.com/626703 external/wpt/streams/readable-streams/tee.html [ Failure Timeout ]
 crbug.com/626703 external/wpt/streams/readable-streams/templated.html [ Failure Timeout ]
 crbug.com/626703 external/wpt/html/webappapis/idle-callbacks/callback-exception.html [ Timeout ]
 crbug.com/626703 external/wpt/html/webappapis/idle-callbacks/callback-iframe.html [ Timeout ]
@@ -2497,10 +2490,8 @@
 crbug.com/697971 [ Mac10.12 ] fast/table/append-cells2.html [ Failure ]
 crbug.com/697971 [ Mac10.12 ] fast/table/backgr_border-table-cell-collapsed-border.html [ Failure ]
 crbug.com/697971 [ Mac10.12 ] fast/table/backgr_border-table-cell.html [ Failure ]
-# crbug.com/697971 [ Mac10.12 ] fast/table/backgr_border-table-collapsed-border.html [ Failure ]
 crbug.com/697971 [ Mac10.12 ] fast/table/backgr_border-table-column-collapsed-border.html [ Failure ]
 crbug.com/697971 [ Mac10.12 ] fast/table/backgr_border-table-column-group-collapsed-border.html [ Failure ]
-# crbug.com/697971 [ Mac10.12 ] fast/table/backgr_border-table-column-group.html [ Failure ]
 crbug.com/697971 [ Mac10.12 ] fast/table/backgr_border-table-column.html [ Failure ]
 crbug.com/697971 [ Mac10.12 ] fast/table/backgr_border-table-quirks-collapsed-border.html [ Failure ]
 crbug.com/697971 [ Mac10.12 ] fast/table/backgr_border-table-quirks.html [ Failure ]
@@ -2510,7 +2501,6 @@
 crbug.com/697971 [ Mac10.12 ] fast/table/backgr_border-table.html [ Failure ]
 crbug.com/697971 [ Mac10.12 ] fast/table/backgr_layers-hide-collapsed-border.html [ Failure ]
 crbug.com/697971 [ Mac10.12 ] fast/table/backgr_layers-hide.html [ Failure ]
-# crbug.com/697971 [ Mac10.12 ] fast/table/backgr_position-table-cell-collapsed-border.html [ Failure ]
 crbug.com/697971 [ Mac10.12 ] fast/table/backgr_position-table-cell.html [ Failure ]
 crbug.com/697971 [ Mac10.12 ] fast/table/backgr_position-table-collapsed-border.html [ Failure ]
 crbug.com/697971 [ Mac10.12 ] fast/table/backgr_position-table-column-collapsed-border.html [ Failure ]
@@ -2523,7 +2513,6 @@
 crbug.com/697971 [ Mac10.12 ] fast/table/backgr_position-table.html [ Failure ]
 crbug.com/697971 [ Mac10.12 ] fast/table/backgr_simple-table-cell-collapsed-border.html [ Failure ]
 crbug.com/697971 [ Mac10.12 ] fast/table/backgr_simple-table-cell.html [ Failure ]
-# crbug.com/697971 [ Mac10.12 ] fast/table/backgr_simple-table-collapsed-border.html [ Failure ]
 crbug.com/697971 [ Mac10.12 ] fast/table/backgr_simple-table-column-collapsed-border.html [ Failure ]
 crbug.com/697971 [ Mac10.12 ] fast/table/backgr_simple-table-column-group-collapsed-border.html [ Failure ]
 crbug.com/697971 [ Mac10.12 ] fast/table/backgr_simple-table-column-group.html [ Failure ]
@@ -2619,14 +2608,20 @@
 crbug.com/697971 [ Mac10.12 ] svg/zoom/page/zoom-background-images.html [ Failure ]
 crbug.com/697971 [ Mac10.12 ] transforms/2d/zoom-menulist.html [ Failure ]
 crbug.com/697971 [ Mac10.12 ] transforms/svg-vs-css.xhtml [ Failure ]
+crbug.com/697971 [ Mac10.12 ] virtual/disable-spinvalidation/compositing/overflow/border-radius-styles-with-composited-child.html [ Failure ]
+crbug.com/697971 [ Mac10.12 ] virtual/disable-spinvalidation/compositing/overflow/do-not-paint-outline-into-composited-scrolling-contents.html [ Failure ]
+crbug.com/697971 [ Mac10.12 ] virtual/disable-spinvalidation/compositing/overflow/theme-affects-visual-overflow.html [ Failure ]
+crbug.com/697971 [ Mac10.12 ] virtual/disable-spinvalidation/compositing/overflow/update-widget-positions-on-nested-frames-and-scrollers.html [ Failure ]
 crbug.com/697971 [ Mac10.12 ] virtual/disable-spinvalidation/paint/invalidation/button-checkbox-click-method-repaint.html [ Failure ]
 crbug.com/697971 [ Mac10.12 ] virtual/disable-spinvalidation/paint/invalidation/caret-invalidation-in-overflow-scroll.html [ Failure ]
 crbug.com/697971 [ Mac10.12 ] virtual/disable-spinvalidation/paint/invalidation/forms/button-reset-focus-by-mouse-then-keydown.html [ Failure ]
 crbug.com/697971 [ Mac10.12 ] virtual/disable-spinvalidation/paint/invalidation/forms/submit-focus-by-mouse-then-keydown.html [ Failure ]
 crbug.com/697971 [ Mac10.12 ] virtual/disable-spinvalidation/paint/invalidation/resize-iframe-text.html [ Failure ]
-crbug.com/697971 [ Mac10.12 ] virtual/disable-spinvalidation/paint/invalidation/search-field-cancel.html [ Failure ]
 crbug.com/697971 [ Mac10.12 ] virtual/disable-spinvalidation/paint/invalidation/subtree-root-skipped.html [ Failure ]
 crbug.com/697971 [ Mac10.12 ] virtual/disable-spinvalidation/paint/invalidation/textarea-caret.html [ Failure ]
+crbug.com/697971 [ Mac10.12 ] virtual/disable-spinvalidation/paint/selection/text-selection-inline-block-rtl.html [ Failure ]
+crbug.com/697971 [ Mac10.12 ] virtual/disable-spinvalidation/paint/selection/text-selection-inline-block.html [ Failure ]
+crbug.com/697971 [ Mac10.12 ] virtual/disable-spinvalidation/paint/spellmarkers/document-markers-zoom-150.html [ Failure ]
 crbug.com/697971 [ Mac10.12 ] virtual/gpu-rasterization/images/12-55.html [ Failure ]
 crbug.com/697971 [ Mac10.12 ] virtual/gpu-rasterization/images/182.html [ Failure ]
 crbug.com/697971 [ Mac10.12 ] virtual/gpu-rasterization/images/2-dht.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/VirtualTestSuites b/third_party/WebKit/LayoutTests/VirtualTestSuites
index ee2cf64..bacc904 100644
--- a/third_party/WebKit/LayoutTests/VirtualTestSuites
+++ b/third_party/WebKit/LayoutTests/VirtualTestSuites
@@ -105,7 +105,12 @@
   },
   {
     "prefix": "disable-spinvalidation",
-    "base": "paint/invalidation",
+    "base": "compositing",
+    "args": ["--disable-slimming-paint-invalidation"]
+  },
+  {
+    "prefix": "disable-spinvalidation",
+    "base": "paint",
     "args": ["--disable-slimming-paint-invalidation"]
   },
   {
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
index df0ae6e..1c8f015a 100644
--- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
+++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
@@ -11535,6 +11535,11 @@
      {}
     ]
    ],
+   "html/browsers/windows/browsing-context-expected.txt": [
+    [
+     {}
+    ]
+   ],
    "html/browsers/windows/browsing-context-names/001-1.html": [
     [
      {}
@@ -18580,7 +18585,7 @@
      {}
     ]
    ],
-   "html/webappapis/scripting/events/event-handler-processing-algorithm-expected.txt": [
+   "html/webappapis/scripting/events/event-handler-processing-algorithm-error/window-synthetic-event-expected.txt": [
     [
      {}
     ]
@@ -19020,6 +19025,11 @@
      {}
     ]
    ],
+   "infrastructure/failing-test-expected.txt": [
+    [
+     {}
+    ]
+   ],
    "infrastructure/reftest-wait-ref.html": [
     [
      {}
@@ -19045,6 +19055,36 @@
      {}
     ]
    ],
+   "longtask-timing/longtask-attributes-expected.txt": [
+    [
+     {}
+    ]
+   ],
+   "longtask-timing/longtask-in-childiframe-expected.txt": [
+    [
+     {}
+    ]
+   ],
+   "longtask-timing/longtask-in-externalscript-expected.txt": [
+    [
+     {}
+    ]
+   ],
+   "longtask-timing/longtask-in-parentiframe-expected.txt": [
+    [
+     {}
+    ]
+   ],
+   "longtask-timing/longtask-in-raf-expected.txt": [
+    [
+     {}
+    ]
+   ],
+   "longtask-timing/longtask-in-sibling-iframe-expected.txt": [
+    [
+     {}
+    ]
+   ],
    "longtask-timing/resources/makelongtask.js": [
     [
      {}
@@ -20005,12 +20045,22 @@
      {}
     ]
    ],
-   "pointerevents/README.md": [
+   "orientation-event/devicemotionevent-init-expected.txt": [
     [
      {}
     ]
    ],
-   "pointerevents/compat/pointerevent_touch-action_two-finger_interaction-manual-expected.txt": [
+   "orientation-event/horizontal-surface-manual-expected.txt": [
+    [
+     {}
+    ]
+   ],
+   "orientation-event/idlharness-expected.txt": [
+    [
+     {}
+    ]
+   ],
+   "pointerevents/README.md": [
     [
      {}
     ]
@@ -22915,6 +22965,21 @@
      {}
     ]
    ],
+   "service-workers/service-worker/claim-fetch.https-expected.txt": [
+    [
+     {}
+    ]
+   ],
+   "service-workers/service-worker/clients-matchall-exact-controller.https-expected.txt": [
+    [
+     {}
+    ]
+   ],
+   "service-workers/service-worker/clients-matchall.https-expected.txt": [
+    [
+     {}
+    ]
+   ],
    "service-workers/service-worker/controller-on-disconnect.https-expected.txt": [
     [
      {}
@@ -24845,6 +24910,11 @@
      {}
     ]
    ],
+   "web-animations/interfaces/AnimationEffectTiming/easing-expected.txt": [
+    [
+     {}
+    ]
+   ],
    "web-animations/interfaces/AnimationEffectTiming/getComputedStyle-expected.txt": [
     [
      {}
@@ -25155,6 +25225,11 @@
      {}
     ]
    ],
+   "webstorage/storage_string_conversion-expected.txt": [
+    [
+     {}
+    ]
+   ],
    "webvr/idlharness-expected.txt": [
     [
      {}
@@ -25210,6 +25285,11 @@
      {}
     ]
    ],
+   "webvtt/api/interfaces-expected.txt": [
+    [
+     {}
+    ]
+   ],
    "webvtt/interfaces-expected.txt": [
     [
      {}
@@ -57654,7 +57734,7 @@
    "support"
   ],
   "./check_stability.py": [
-   "929a459294fca2be3f2728043390cd5076db669a",
+   "777e9cbda11e9aa5bb4888668d82e9e51db2c4ea",
    "support"
   ],
   "./ci_built_diff.sh": [
@@ -62322,7 +62402,7 @@
    "testharness"
   ],
   "dom/nodes/Document-createElement-namespace-expected.txt": [
-   "e8445bd71bc05b8034f7fa8738e48c2419fbe93d",
+   "75074db7b6e2c38e9b07bf690798a717257e9eb8",
    "support"
   ],
   "dom/nodes/Document-createElement-namespace-tests/bare_mathml.html": [
@@ -65250,7 +65330,7 @@
    "support"
   ],
   "html/browsers/browsing-the-web/history-traversal/browsing_context_name_cross_origin-expected.txt": [
-   "9762c240f4c9c44cdb9d71d2d9d07c9866b61af4",
+   "4b15b4ee5d7c705987e1ac9570d950b79df5f508",
    "support"
   ],
   "html/browsers/browsing-the-web/history-traversal/browsing_context_name_cross_origin.html": [
@@ -67037,6 +67117,10 @@
    "aecd2f28b5bd6301c51d535a4b1068a10b497899",
    "support"
   ],
+  "html/browsers/windows/browsing-context-expected.txt": [
+   "1c8adae8b27e8310be0ac7a26cd586b685df001e",
+   "support"
+  ],
   "html/browsers/windows/browsing-context-names/001-1.html": [
    "7f9396d2baeeafd98832c7fe5a0a1474fc358e98",
    "support"
@@ -75806,7 +75890,7 @@
    "testharness"
   ],
   "html/semantics/tabular-data/the-table-element/tHead-expected.txt": [
-   "ed6d21ded3010a5fddbe6a5a09a4ea9a1f117e71",
+   "d3372ded99c871806b94cd8e6e0b3f01f49f257b",
    "support"
   ],
   "html/semantics/tabular-data/the-table-element/tHead.html": [
@@ -76837,6 +76921,10 @@
    "23db12066d01404453425499bbc1c85e293375cc",
    "testharness"
   ],
+  "html/webappapis/scripting/events/event-handler-processing-algorithm-error/window-synthetic-event-expected.txt": [
+   "f28915679bf718c5e71d2f36cb0de26c04275564",
+   "support"
+  ],
   "html/webappapis/scripting/events/event-handler-processing-algorithm-error/window-synthetic-event.html": [
    "a779db7beb4c5f52bde9131b7648b6efab2f8000",
    "testharness"
@@ -76857,10 +76945,6 @@
    "cdc54d4667e9f7d0774fdf64050d561affb14480",
    "testharness"
   ],
-  "html/webappapis/scripting/events/event-handler-processing-algorithm-expected.txt": [
-   "10cb96228545b28542eb4cac2f7075feed63dfa5",
-   "support"
-  ],
   "html/webappapis/scripting/events/event-handler-processing-algorithm-manual.html": [
    "3ae38e063225a1e5c39c620f5499fb39843e0550",
    "manual"
@@ -77505,6 +77589,10 @@
    "4e33f8928d27bd64a96d72c32de08ebd483ab888",
    "support"
   ],
+  "infrastructure/failing-test-expected.txt": [
+   "936079eb1760f752fca0b0af39eecaf59d233c90",
+   "support"
+  ],
   "infrastructure/failing-test.html": [
    "c832afb4826fd43d2fcc4f5e3fd6a773a6ee35f0",
    "testharness"
@@ -77518,7 +77606,7 @@
    "reftest"
   ],
   "innerText/getter-expected.txt": [
-   "11c121b0354c9017afdc58b1ad97134411142cbc",
+   "5c1decdefb4d44188bdc9c5974758d88740ff6a5",
    "support"
   ],
   "innerText/getter-tests.js": [
@@ -77530,7 +77618,7 @@
    "testharness"
   ],
   "innerText/setter-expected.txt": [
-   "5330e9d6db01f7e4bbb2a99345f1be683251c815",
+   "5822d895ed54fa3d7420aba16c6ca9b40070494c",
    "support"
   ],
   "innerText/setter-tests.js": [
@@ -77545,6 +77633,10 @@
    "cd25518dd402033694667ccd1982fd3b85faa412",
    "testharness"
   ],
+  "longtask-timing/longtask-attributes-expected.txt": [
+   "dae6a99683bdbae412208af8848a5c70a8e29bb2",
+   "support"
+  ],
   "longtask-timing/longtask-attributes.html": [
    "a88bd658adcb9ef3dcbfa803397910e531bc864b",
    "testharness"
@@ -77553,18 +77645,34 @@
    "646324580798ab727e31db4c47b919bb9df6e6a9",
    "testharness"
   ],
+  "longtask-timing/longtask-in-childiframe-expected.txt": [
+   "c52c650677cbc916cf8b6c045fd80a7737943a74",
+   "support"
+  ],
   "longtask-timing/longtask-in-childiframe.html": [
    "74f235096580d329eb0cc2d2c682857c2b6f2c6d",
    "testharness"
   ],
+  "longtask-timing/longtask-in-externalscript-expected.txt": [
+   "dae6a99683bdbae412208af8848a5c70a8e29bb2",
+   "support"
+  ],
   "longtask-timing/longtask-in-externalscript.html": [
    "74329829a0248b8e81443f78b998bf97ac60e965",
    "testharness"
   ],
+  "longtask-timing/longtask-in-parentiframe-expected.txt": [
+   "b3c1614ad49351b564649391c06fbaa933b28164",
+   "support"
+  ],
   "longtask-timing/longtask-in-parentiframe.html": [
    "4732540c350dcfed013f07af0590c5de04aacc2a",
    "testharness"
   ],
+  "longtask-timing/longtask-in-raf-expected.txt": [
+   "dae6a99683bdbae412208af8848a5c70a8e29bb2",
+   "support"
+  ],
   "longtask-timing/longtask-in-raf.html": [
    "e5a058a841e039e1d8f7b5f8b24d48937aad038b",
    "testharness"
@@ -77573,6 +77681,10 @@
    "64085903b907b37077013d42747e3aaa8cf2b86e",
    "testharness"
   ],
+  "longtask-timing/longtask-in-sibling-iframe-expected.txt": [
+   "5f0c8a77a42abe159b591583ecee1e04af7454b1",
+   "support"
+  ],
   "longtask-timing/longtask-in-sibling-iframe.html": [
    "d08d6f2ddf39615cc3dad7c65a01a29c9411a2a9",
    "testharness"
@@ -79697,6 +79809,10 @@
    "c7d89bf7a3119dbfe9a581f82b5ac43ff6645a64",
    "testharness"
   ],
+  "orientation-event/devicemotionevent-init-expected.txt": [
+   "c60b8873f1c46e419b88ddc2fe46ef19bdc90c60",
+   "support"
+  ],
   "orientation-event/devicemotionevent-init.html": [
    "fab191bbebab21f696fefc0ad9e8110b99855eee",
    "testharness"
@@ -79713,10 +79829,18 @@
    "e291465a89d97156f518e12e1bf65e6ab8091ce7",
    "manual"
   ],
+  "orientation-event/horizontal-surface-manual-expected.txt": [
+   "fe79c9395f6423d0263cd4bc45b7ac18cdf38413",
+   "support"
+  ],
   "orientation-event/horizontal-surface-manual.html": [
    "ef54a144013c5eb07a1c5742d8239e741a2a18dc",
    "manual"
   ],
+  "orientation-event/idlharness-expected.txt": [
+   "adc83b19e793491b1c6ea0fd8b46cd9f32e592fc",
+   "support"
+  ],
   "orientation-event/idlharness.html": [
    "d23bfd2d59820008a8783e73e5e349a762dd8b64",
    "testharness"
@@ -79781,10 +79905,6 @@
    "91a8bd86357b0d96ba3ab8f08f88c28436de484c",
    "support"
   ],
-  "pointerevents/compat/pointerevent_touch-action_two-finger_interaction-manual-expected.txt": [
-   "c042d299f01622588c89152939840e23be0c613f",
-   "support"
-  ],
   "pointerevents/compat/pointerevent_touch-action_two-finger_interaction-manual.html": [
    "cba44e2dd2a3c54106bfecc6cdd407643e2ba995",
    "manual"
@@ -88085,6 +88205,10 @@
    "96ffb6f3376a5fa73abd405e123d019d8cac694d",
    "testharness"
   ],
+  "service-workers/service-worker/claim-fetch.https-expected.txt": [
+   "3e8688f2e8a82a93770a06f99fcece6d09e4e118",
+   "support"
+  ],
   "service-workers/service-worker/claim-fetch.https.html": [
    "adec77bbeec2ec9ea7da3aba94375bc92e1b4f6f",
    "testharness"
@@ -88113,6 +88237,10 @@
    "aaca38d0ad5e6a03775632fcef1657dd40753ae0",
    "testharness"
   ],
+  "service-workers/service-worker/clients-matchall-exact-controller.https-expected.txt": [
+   "8363bdc904d31be5e60e62b705789e17c16ef98a",
+   "support"
+  ],
   "service-workers/service-worker/clients-matchall-exact-controller.https.html": [
    "231ce3ee744eeb670e00ee3a670ba361d5ca0707",
    "testharness"
@@ -88125,6 +88253,10 @@
    "b2617b7dce0dce64c1a354a3dc07c67f1fa0adf2",
    "testharness"
   ],
+  "service-workers/service-worker/clients-matchall.https-expected.txt": [
+   "ed5ad6b895c98878acf49cfd5c512a643b35724c",
+   "support"
+  ],
   "service-workers/service-worker/clients-matchall.https.html": [
    "ac873d343a0c9d0af058f84d7e8db2809825c64c",
    "testharness"
@@ -90422,11 +90554,11 @@
    "support"
   ],
   "streams/writable-streams/aborting-expected.txt": [
-   "79d55e510d5da8a2440c93a7b1c9d3a0e75114ae",
+   "84e08dacc259de6782a334f9b26b202c54ac8f97",
    "support"
   ],
   "streams/writable-streams/aborting.dedicatedworker-expected.txt": [
-   "79d55e510d5da8a2440c93a7b1c9d3a0e75114ae",
+   "84e08dacc259de6782a334f9b26b202c54ac8f97",
    "support"
   ],
   "streams/writable-streams/aborting.dedicatedworker.html": [
@@ -90438,11 +90570,11 @@
    "testharness"
   ],
   "streams/writable-streams/aborting.js": [
-   "f6edf8933a360f06d399bc17672a464e147310f6",
+   "cabcfe5be9a294a2d249743da2e819a1e9d730d3",
    "support"
   ],
   "streams/writable-streams/aborting.serviceworker.https-expected.txt": [
-   "4e6d368665753be3203254eb6d468c56ef4e0349",
+   "7842749164cd9c2ffdbc8e9571d364d8726e04bf",
    "support"
   ],
   "streams/writable-streams/aborting.serviceworker.https.html": [
@@ -90450,7 +90582,7 @@
    "testharness"
   ],
   "streams/writable-streams/aborting.sharedworker-expected.txt": [
-   "79d55e510d5da8a2440c93a7b1c9d3a0e75114ae",
+   "84e08dacc259de6782a334f9b26b202c54ac8f97",
    "support"
   ],
   "streams/writable-streams/aborting.sharedworker.html": [
@@ -90650,7 +90782,7 @@
    "testharness"
   ],
   "streams/writable-streams/general.js": [
-   "22131ed892a5b38321a49bd7ba1e8b2dca780e7e",
+   "7a6fb1ccd2f77edc2077ec127716d3d2edcf8475",
    "support"
   ],
   "streams/writable-streams/general.serviceworker.https.html": [
@@ -91434,7 +91566,7 @@
    "testharness"
   ],
   "web-animations/interfaces/Animatable/animate-expected.txt": [
-   "171f7cc3ce026fb9be6fc86cfca92a27387ceb00",
+   "e9d5ab88a0bbaeac9aab961be02cdf6e522cfe34",
    "support"
   ],
   "web-animations/interfaces/Animatable/animate.html": [
@@ -91533,6 +91665,10 @@
    "54858f64784c74a3d112e559fb765a1dbb9ba279",
    "testharness"
   ],
+  "web-animations/interfaces/AnimationEffectTiming/easing-expected.txt": [
+   "cd3accf90f53fd604760d8451216437b42edbb0a",
+   "support"
+  ],
   "web-animations/interfaces/AnimationEffectTiming/easing.html": [
    "a4b8b1c715795d5e66c0e32c2415a2e8fb587147",
    "testharness"
@@ -92214,7 +92350,7 @@
    "testharness"
   ],
   "webrtc/rtcpeerconnection/rtcpeerconnection-constructor-expected.txt": [
-   "ae19b2abd560bd378b5a4dc0afde8763fd09cdc2",
+   "f11720c8bedc9befad6c67d989b5e5dae8f62ec5",
    "support"
   ],
   "webrtc/rtcpeerconnection/rtcpeerconnection-constructor.html": [
@@ -92489,6 +92625,10 @@
    "74fb62c4369f7929bb9387d8fadb1341e30eb90f",
    "testharness"
   ],
+  "webstorage/storage_string_conversion-expected.txt": [
+   "c0b3a51a27cbd52e962ef1dcdb905433f844a45f",
+   "support"
+  ],
   "webstorage/storage_string_conversion.html": [
    "33c748773a518af29ea2ef8cbbc859fe988fb88a",
    "testharness"
@@ -92522,7 +92662,7 @@
    "testharness"
   ],
   "webvtt/api/VTTCue/getCueAsHTML-expected.txt": [
-   "1ad453df49e45ff18cd6a6681ecad254f18c10ee",
+   "4adc8860251f5e0afe9d7778c1bcb4578101f3ee",
    "support"
   ],
   "webvtt/api/VTTCue/getCueAsHTML.html": [
@@ -92625,6 +92765,10 @@
    "103a481c365bea3c1d6494f9fc3f3b6bf70ed580",
    "testharness"
   ],
+  "webvtt/api/interfaces-expected.txt": [
+   "ae4ac09131979fe00e079bea72219691626dac16",
+   "support"
+  ],
   "webvtt/api/interfaces.html": [
    "dbff06876d1a0db46505423b9c1d919c2188b7a9",
    "testharness"
diff --git a/third_party/WebKit/LayoutTests/external/wpt/check_stability.py b/third_party/WebKit/LayoutTests/external/wpt/check_stability.py
index 8398dbe..ba0d888 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/check_stability.py
+++ b/third_party/WebKit/LayoutTests/external/wpt/check_stability.py
@@ -584,7 +584,7 @@
     s = s.replace('\t', u'\\t')
     s = s.replace('\n', u'\\n')
     s = s.replace('\r', u'\\r')
-    s = s.replace('`',  u'\\`')
+    s = s.replace('`',  u'')
     return s
 
 
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/aborting-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/aborting-expected.txt
index fd1b4a7..629e9d5 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/aborting-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/aborting-expected.txt
@@ -33,5 +33,7 @@
 PASS controller.error(), writer.abort() while there is an in-flight write, and then finish the write 
 PASS releaseLock() while aborting should reject the original closed promise 
 PASS releaseLock() during delayed async abort() should create a new rejected closed promise 
+FAIL abort() should be rejected with the error passed to controller.error() during pending write() promise_test: Unhandled rejection with value: object "TypeError: Cannot error a errored writable stream"
+FAIL abort() should be rejected with the error passed to controller.error() during pending close() promise_test: Unhandled rejection with value: object "TypeError: Cannot error a errored writable stream"
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/aborting.dedicatedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/aborting.dedicatedworker-expected.txt
index fd1b4a7..629e9d5 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/aborting.dedicatedworker-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/aborting.dedicatedworker-expected.txt
@@ -33,5 +33,7 @@
 PASS controller.error(), writer.abort() while there is an in-flight write, and then finish the write 
 PASS releaseLock() while aborting should reject the original closed promise 
 PASS releaseLock() during delayed async abort() should create a new rejected closed promise 
+FAIL abort() should be rejected with the error passed to controller.error() during pending write() promise_test: Unhandled rejection with value: object "TypeError: Cannot error a errored writable stream"
+FAIL abort() should be rejected with the error passed to controller.error() during pending close() promise_test: Unhandled rejection with value: object "TypeError: Cannot error a errored writable stream"
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/aborting.js b/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/aborting.js
index 6b2f86e..05dabb86 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/aborting.js
+++ b/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/aborting.js
@@ -890,4 +890,52 @@
   });
 }, 'releaseLock() during delayed async abort() should create a new rejected closed promise');
 
+promise_test(t => {
+  let writeReject;
+  let controller;
+  const ws = new WritableStream({
+    write(chunk, c) {
+      controller = c;
+      return new Promise((resolve, reject) => {
+        writeReject = reject;
+      });
+    }
+  });
+  const writer = ws.getWriter();
+  return writer.ready.then(() => {
+    const writePromise = writer.write('a');
+    const abortPromise = writer.abort();
+    controller.error(error1);
+    writeReject(error2);
+    return Promise.all([
+      promise_rejects(t, error2, writePromise, 'write() should reject with error2'),
+      promise_rejects(t, error1, abortPromise, 'abort() should reject with error1')
+    ]);
+  });
+}, 'abort() should be rejected with the error passed to controller.error() during pending write()');
+
+promise_test(t => {
+  let closeReject;
+  let controller;
+  const ws = new WritableStream({
+    close(c) {
+      controller = c;
+      return new Promise((resolve, reject) => {
+        closeReject = reject;
+      });
+    }
+  });
+  const writer = ws.getWriter();
+  return writer.ready.then(() => {
+    const closePromise = writer.close();
+    const abortPromise = writer.abort();
+    controller.error(error1);
+    closeReject(error2);
+    return Promise.all([
+      promise_rejects(t, error2, closePromise, 'close() should reject with error2'),
+      promise_rejects(t, error1, abortPromise, 'abort() should reject with error1')
+    ]);
+  });
+}, 'abort() should be rejected with the error passed to controller.error() during pending close()');
+
 done();
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/aborting.serviceworker.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/aborting.serviceworker.https-expected.txt
index ad1c7fb1..d3b6b90 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/aborting.serviceworker.https-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/aborting.serviceworker.https-expected.txt
@@ -34,5 +34,7 @@
 PASS controller.error(), writer.abort() while there is an in-flight write, and then finish the write 
 PASS releaseLock() while aborting should reject the original closed promise 
 PASS releaseLock() during delayed async abort() should create a new rejected closed promise 
+FAIL abort() should be rejected with the error passed to controller.error() during pending write() promise_test: Unhandled rejection with value: object "TypeError: Cannot error a errored writable stream"
+FAIL abort() should be rejected with the error passed to controller.error() during pending close() promise_test: Unhandled rejection with value: object "TypeError: Cannot error a errored writable stream"
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/aborting.sharedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/aborting.sharedworker-expected.txt
index fd1b4a7..629e9d5 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/aborting.sharedworker-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/aborting.sharedworker-expected.txt
@@ -33,5 +33,7 @@
 PASS controller.error(), writer.abort() while there is an in-flight write, and then finish the write 
 PASS releaseLock() while aborting should reject the original closed promise 
 PASS releaseLock() during delayed async abort() should create a new rejected closed promise 
+FAIL abort() should be rejected with the error passed to controller.error() during pending write() promise_test: Unhandled rejection with value: object "TypeError: Cannot error a errored writable stream"
+FAIL abort() should be rejected with the error passed to controller.error() during pending close() promise_test: Unhandled rejection with value: object "TypeError: Cannot error a errored writable stream"
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/general-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/general-expected.txt
new file mode 100644
index 0000000..1300dad5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/general-expected.txt
@@ -0,0 +1,17 @@
+This is a testharness.js-based test.
+PASS desiredSize on a released writer 
+PASS desiredSize initial value 
+PASS desiredSize on a writer for a closed stream 
+PASS desiredSize on a writer for an errored stream 
+PASS ws.getWriter() on a closing WritableStream 
+PASS ws.getWriter() on a closed WritableStream 
+PASS ws.getWriter() on an aborted WritableStream 
+PASS ws.getWriter() on an errored WritableStream 
+PASS closed and ready on a released writer 
+PASS WritableStream should call underlying sink methods as methods 
+PASS methods should not not have .apply() or .call() called 
+PASS WritableStream's strategy.size should not be called as a method 
+PASS redundant releaseLock() is no-op 
+FAIL ready promise should fire before closed on releaseLock assert_array_equals: ready promise should fire before closed promise property 0, expected "ready" but got "closed"
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/general.dedicatedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/general.dedicatedworker-expected.txt
new file mode 100644
index 0000000..1300dad5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/general.dedicatedworker-expected.txt
@@ -0,0 +1,17 @@
+This is a testharness.js-based test.
+PASS desiredSize on a released writer 
+PASS desiredSize initial value 
+PASS desiredSize on a writer for a closed stream 
+PASS desiredSize on a writer for an errored stream 
+PASS ws.getWriter() on a closing WritableStream 
+PASS ws.getWriter() on a closed WritableStream 
+PASS ws.getWriter() on an aborted WritableStream 
+PASS ws.getWriter() on an errored WritableStream 
+PASS closed and ready on a released writer 
+PASS WritableStream should call underlying sink methods as methods 
+PASS methods should not not have .apply() or .call() called 
+PASS WritableStream's strategy.size should not be called as a method 
+PASS redundant releaseLock() is no-op 
+FAIL ready promise should fire before closed on releaseLock assert_array_equals: ready promise should fire before closed promise property 0, expected "ready" but got "closed"
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/general.js b/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/general.js
index bb48859e..0e773ce 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/general.js
+++ b/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/general.js
@@ -226,4 +226,25 @@
   return writer2.ready;
 }, 'redundant releaseLock() is no-op');
 
+promise_test(t => {
+  const events = [];
+  const ws = new WritableStream();
+  const writer = ws.getWriter();
+  return writer.ready.then(() => {
+    // Force the ready promise back to a pending state.
+    const writerPromise = writer.write('dummy');
+    const readyPromise = writer.ready.catch(() => events.push('ready'));
+    const closedPromise = writer.closed.catch(() => events.push('closed'));
+    writer.releaseLock();
+    return Promise.all([readyPromise, closedPromise]).then(() => {
+      assert_array_equals(events, ['ready', 'closed'], 'ready promise should fire before closed promise');
+      // Stop the writer promise hanging around after the test has finished.
+      return Promise.all([
+        writerPromise,
+        ws.abort()
+      ]);
+    });
+  });
+}, 'ready promise should fire before closed on releaseLock');
+
 done();
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/general.serviceworker.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/general.serviceworker.https-expected.txt
new file mode 100644
index 0000000..e24e760d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/general.serviceworker.https-expected.txt
@@ -0,0 +1,18 @@
+This is a testharness.js-based test.
+PASS Service worker test setup 
+PASS desiredSize on a released writer 
+PASS desiredSize initial value 
+PASS desiredSize on a writer for a closed stream 
+PASS desiredSize on a writer for an errored stream 
+PASS ws.getWriter() on a closing WritableStream 
+PASS ws.getWriter() on a closed WritableStream 
+PASS ws.getWriter() on an aborted WritableStream 
+PASS ws.getWriter() on an errored WritableStream 
+PASS closed and ready on a released writer 
+PASS WritableStream should call underlying sink methods as methods 
+PASS methods should not not have .apply() or .call() called 
+PASS WritableStream's strategy.size should not be called as a method 
+PASS redundant releaseLock() is no-op 
+FAIL ready promise should fire before closed on releaseLock assert_array_equals: ready promise should fire before closed promise property 0, expected "ready" but got "closed"
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/general.sharedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/general.sharedworker-expected.txt
new file mode 100644
index 0000000..1300dad5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/general.sharedworker-expected.txt
@@ -0,0 +1,17 @@
+This is a testharness.js-based test.
+PASS desiredSize on a released writer 
+PASS desiredSize initial value 
+PASS desiredSize on a writer for a closed stream 
+PASS desiredSize on a writer for an errored stream 
+PASS ws.getWriter() on a closing WritableStream 
+PASS ws.getWriter() on a closed WritableStream 
+PASS ws.getWriter() on an aborted WritableStream 
+PASS ws.getWriter() on an errored WritableStream 
+PASS closed and ready on a released writer 
+PASS WritableStream should call underlying sink methods as methods 
+PASS methods should not not have .apply() or .call() called 
+PASS WritableStream's strategy.size should not be called as a method 
+PASS redundant releaseLock() is no-op 
+FAIL ready promise should fire before closed on releaseLock assert_array_equals: ready promise should fire before closed promise property 0, expected "ready" but got "closed"
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamTrack-getSettings.html b/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamTrack-getSettings.html
index 7401a32..e0cf760 100644
--- a/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamTrack-getSettings.html
+++ b/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamTrack-getSettings.html
@@ -46,6 +46,38 @@
 }, 'A video track returns the expected variables');
 
 promise_test(function() {
+  track1 = null;
+  track2 = null;
+  return navigator.mediaDevices.getUserMedia({video: true})
+      .then(function(s1) {
+    track1 = s1.getVideoTracks()[0];
+    settings1 = track1.getSettings();
+    // We ask for the second track to have half the width of the first one,
+    // but the same source.
+    // This should cause a scaling factor to be applied.
+    constraints2 = {deviceId: settings1.deviceId,
+                    width: { max: settings1.width / 2 }};
+        console.log(JSON.stringify(constraints2));
+    return navigator.mediaDevices.getUserMedia({video: constraints2});
+  })
+      .then(function(s) {
+        track2 = s.getVideoTracks()[0];
+        console.log(JSON.stringify(track2.getConstraints()));
+    settings = track2.getSettings();
+    settings1 = track1.getSettings();
+    // This test does not work in blink_tests due to limitations in mocking.
+    // The Web-Platform-Test that does the same thing passes when run
+    // in a browser.
+    // TODO(hta): Add constraints to the mock media stream registry.
+    // crbug.com/617152
+    // assert_equals(settings.deviceId, settings1.deviceId);
+    // assert_equals(settings.width, settings1.width / 2,
+    //              'widths are not 2x different: ' +
+    //              JSON.stringify(settings) + ' ' + JSON.stringify(settings1));
+  });
+}, 'Two video tracks with the same source but different scaling are different');
+
+promise_test(function() {
   return navigator.mediaDevices.getUserMedia({audio: true, video: true})
     .then(function(s) {
       videoSettings = s.getVideoTracks()[0].getSettings();
diff --git a/third_party/WebKit/LayoutTests/http/tests/sendbeacon/beacon-allowance-limit.html b/third_party/WebKit/LayoutTests/http/tests/sendbeacon/beacon-allowance-limit.html
new file mode 100644
index 0000000..095c322c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/sendbeacon/beacon-allowance-limit.html
@@ -0,0 +1,17 @@
+<!DOCTYPE HTML>
+<script src="/js-test-resources/testharness.js"></script>
+<script src="/js-test-resources/testharnessreport.js"></script>
+<script>
+test(() => {
+  // Note: the limit used must be same as Settings#maxBeaconTransmission.
+  // First beacon request should go through, but with a zero allowance for
+  // any subsequent requests. Which must fail.
+  let payload = new Uint8Array(64 * 1024);
+  let result = navigator.sendBeacon("resources/blank.txt", payload);
+  assert_true(result);
+  result = navigator.sendBeacon("resources/blank.txt", payload);
+  assert_false(result);
+}, "navigator.sendBeacon() with a payload size greater than " +
+   "remaining transfer allowance should fail.");
+</script>
+</html>
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/paint/selection/text-selection-newline-mixed-ltr-rtl-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/paint/selection/text-selection-newline-mixed-ltr-rtl-expected.png
new file mode 100644
index 0000000..5060e32
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/paint/selection/text-selection-newline-mixed-ltr-rtl-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/paint/selection/text-selection-newline-mixed-ltr-rtl-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/paint/selection/text-selection-newline-mixed-ltr-rtl-expected.txt
new file mode 100644
index 0000000..b0717317
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/paint/selection/text-selection-newline-mixed-ltr-rtl-expected.txt
@@ -0,0 +1,17 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x136
+  LayoutBlockFlow {HTML} at (0,0) size 800x136
+    LayoutBlockFlow {BODY} at (8,16) size 784x112
+      LayoutBlockFlow {P} at (0,0) size 784x20
+        LayoutText {#text} at (0,0) size 339x19
+          text run at (0,0) width 339: "Passes if there are no overpainted selection highlights."
+      LayoutBlockFlow (anonymous) at (0,36) size 784x76
+        LayoutInline {SPAN} at (0,0) size 189x73
+          LayoutText {#text} at (0,1) size 189x73
+            text run at (0,1) width 96: "text"
+            text run at (96,1) width 93 RTL: "\x{645}\x{62A}\x{646}:"
+        LayoutText {#text} at (0,0) size 0x0
+        LayoutText {#text} at (0,0) size 0x0
+selection start: position 5 of child 0 {#text} of child 2 {SPAN} of body
+selection end:   position 13 of child 0 {#text} of child 2 {SPAN} of body
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/disable-spinvalidation/compositing/gestures/gesture-tapHighlight-pixel-rotated-div-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/disable-spinvalidation/compositing/gestures/gesture-tapHighlight-pixel-rotated-div-expected.png
new file mode 100644
index 0000000..94fef2a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/disable-spinvalidation/compositing/gestures/gesture-tapHighlight-pixel-rotated-div-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/disable-spinvalidation/compositing/gestures/gesture-tapHighlight-pixel-rotated-link-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/disable-spinvalidation/compositing/gestures/gesture-tapHighlight-pixel-rotated-link-expected.png
new file mode 100644
index 0000000..7e37300
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/disable-spinvalidation/compositing/gestures/gesture-tapHighlight-pixel-rotated-link-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/disable-spinvalidation/compositing/gestures/gesture-tapHighlight-pixel-transparent-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/disable-spinvalidation/compositing/gestures/gesture-tapHighlight-pixel-transparent-expected.png
new file mode 100644
index 0000000..0cea47d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/disable-spinvalidation/compositing/gestures/gesture-tapHighlight-pixel-transparent-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/disable-spinvalidation/paint/invalidation/search-field-cancel-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/disable-spinvalidation/paint/invalidation/search-field-cancel-expected.txt
new file mode 100644
index 0000000..8c243ca
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/disable-spinvalidation/paint/invalidation/search-field-cancel-expected.txt
@@ -0,0 +1,41 @@
+{
+  "layers": [
+    {
+      "name": "LayoutView #document",
+      "bounds": [800, 600],
+      "contentsOpaque": true,
+      "drawsContent": true,
+      "paintInvalidations": [
+        {
+          "object": "LayoutBlockFlow DIV id='inner-editor'",
+          "rect": [12, 45, 113, 13],
+          "reason": "forced by layout"
+        },
+        {
+          "object": "LayoutText #text",
+          "rect": [12, 45, 51, 13],
+          "reason": "layoutObject insertion"
+        }
+      ]
+    }
+  ],
+  "objectPaintInvalidations": [
+    {
+      "object": "LayoutBlockFlow DIV id='inner-editor'",
+      "reason": "forced by layout"
+    },
+    {
+      "object": "RootInlineBox",
+      "reason": "forced by layout"
+    },
+    {
+      "object": "LayoutText #text",
+      "reason": "layoutObject insertion"
+    },
+    {
+      "object": "InlineTextBox 'some text'",
+      "reason": "layoutObject insertion"
+    }
+  ]
+}
+
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-collapsed-border-expected.png
deleted file mode 100644
index afb73ba..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-collapsed-border-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-column-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-column-group-expected.png
index 15c85d1..fa79dfb 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-column-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-column-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-cell-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-cell-collapsed-border-expected.png
index f5c1554e..a218e62 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-cell-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-cell-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-collapsed-border-expected.png
index 98abc7b..6e978cb 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-expected.png
index f7c5b4d..6aa6f72c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/disable-spinvalidation/paint/invalidation/search-field-cancel-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/disable-spinvalidation/paint/invalidation/search-field-cancel-expected.txt
new file mode 100644
index 0000000..8c243ca
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/disable-spinvalidation/paint/invalidation/search-field-cancel-expected.txt
@@ -0,0 +1,41 @@
+{
+  "layers": [
+    {
+      "name": "LayoutView #document",
+      "bounds": [800, 600],
+      "contentsOpaque": true,
+      "drawsContent": true,
+      "paintInvalidations": [
+        {
+          "object": "LayoutBlockFlow DIV id='inner-editor'",
+          "rect": [12, 45, 113, 13],
+          "reason": "forced by layout"
+        },
+        {
+          "object": "LayoutText #text",
+          "rect": [12, 45, 51, 13],
+          "reason": "layoutObject insertion"
+        }
+      ]
+    }
+  ],
+  "objectPaintInvalidations": [
+    {
+      "object": "LayoutBlockFlow DIV id='inner-editor'",
+      "reason": "forced by layout"
+    },
+    {
+      "object": "RootInlineBox",
+      "reason": "forced by layout"
+    },
+    {
+      "object": "LayoutText #text",
+      "reason": "layoutObject insertion"
+    },
+    {
+      "object": "InlineTextBox 'some text'",
+      "reason": "layoutObject insertion"
+    }
+  ]
+}
+
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-collapsed-border-expected.png
index 02d2b110..1a5c415 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-column-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-column-group-expected.png
index 65acf813..d428607 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-column-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-column-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-cell-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-cell-collapsed-border-expected.png
index a9b0063..0beed695 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-cell-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-cell-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-collapsed-border-expected.png
index 186b07b..e3f767dc 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/compositing/gestures/gesture-tapHighlight-pixel-rotated-div-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/compositing/gestures/gesture-tapHighlight-pixel-rotated-div-expected.png
new file mode 100644
index 0000000..75f290f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/compositing/gestures/gesture-tapHighlight-pixel-rotated-div-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/compositing/gestures/gesture-tapHighlight-pixel-rotated-link-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/compositing/gestures/gesture-tapHighlight-pixel-rotated-link-expected.png
new file mode 100644
index 0000000..46bb1ca1
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/compositing/gestures/gesture-tapHighlight-pixel-rotated-link-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/compositing/gestures/gesture-tapHighlight-pixel-transparent-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/compositing/gestures/gesture-tapHighlight-pixel-transparent-expected.png
new file mode 100644
index 0000000..a7f6587d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/compositing/gestures/gesture-tapHighlight-pixel-transparent-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/compositing/gestures/gesture-tapHighlight-skew-matrix-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/compositing/gestures/gesture-tapHighlight-skew-matrix-expected.png
new file mode 100644
index 0000000..8a9e6c7
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/compositing/gestures/gesture-tapHighlight-skew-matrix-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/compositing/gestures/gesture-tapHighlight-with-box-shadow-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/compositing/gestures/gesture-tapHighlight-with-box-shadow-expected.png
new file mode 100644
index 0000000..e2a4f44
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/compositing/gestures/gesture-tapHighlight-with-box-shadow-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/compositing/gestures/gesture-tapHighlight-with-squashing-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/compositing/gestures/gesture-tapHighlight-with-squashing-expected.png
new file mode 100644
index 0000000..b8c2c24
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/compositing/gestures/gesture-tapHighlight-with-squashing-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/paint/invalidation/search-field-cancel-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/paint/invalidation/search-field-cancel-expected.txt
index 8c243ca..49e1ed89 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/paint/invalidation/search-field-cancel-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/paint/invalidation/search-field-cancel-expected.txt
@@ -13,7 +13,7 @@
         },
         {
           "object": "LayoutText #text",
-          "rect": [12, 45, 51, 13],
+          "rect": [12, 45, 52, 13],
           "reason": "layoutObject insertion"
         }
       ]
diff --git a/third_party/WebKit/LayoutTests/platform/win/compositing/scrollbars/custom-composited-different-track-parts-expected.png b/third_party/WebKit/LayoutTests/platform/win/compositing/scrollbars/custom-composited-different-track-parts-expected.png
deleted file mode 100644
index 4eb4245..0000000
--- a/third_party/WebKit/LayoutTests/platform/win/compositing/scrollbars/custom-composited-different-track-parts-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/css/background-clip-values-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/css/background-clip-values-expected.png
deleted file mode 100644
index 05547a2..0000000
--- a/third_party/WebKit/LayoutTests/platform/win/fast/css/background-clip-values-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-row-collapsed-border-expected.png
index 11e6d9a..f0b6d48 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-row-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-column-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-column-group-collapsed-border-expected.png
index 4e07c4b..8fe9464a 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-column-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-column-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-row-collapsed-border-expected.png
index 8f65c1c7..b49ab749 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-row-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-cell-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
index 889e629..fa893272 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-cell-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-cell-expected.png
index a2135e93..6f9ce97 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-cell-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-cell-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-column-group-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-column-group-expected.png
index f877418..b778535 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-column-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-column-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-row-collapsed-border-expected.png
index 50a00482..81c3607 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-row-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/disable-spinvalidation/compositing/scrollbars/custom-composited-different-track-parts-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/disable-spinvalidation/compositing/scrollbars/custom-composited-different-track-parts-expected.png
new file mode 100644
index 0000000..2c7f7e5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/disable-spinvalidation/compositing/scrollbars/custom-composited-different-track-parts-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_border-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_border-table-row-collapsed-border-expected.png
index 7bc73f87..27039c2 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_border-table-row-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_border-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_position-table-column-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_position-table-column-group-collapsed-border-expected.png
index 4fb0511..04afec3 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_position-table-column-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_position-table-column-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_position-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_position-table-row-collapsed-border-expected.png
index d84a97c..de8baef 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_position-table-row-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_position-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-cell-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
index 960a6a74..a97284ba 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-cell-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-cell-expected.png
index bd22490..704c21ef 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-cell-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-cell-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-column-group-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-column-group-expected.png
index 0d70719..81789e24 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-column-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-column-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-row-collapsed-border-expected.png
index 1e7508f..bc609fd 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-row-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/disable-spinvalidation/compositing/README.txt b/third_party/WebKit/LayoutTests/virtual/disable-spinvalidation/compositing/README.txt
new file mode 100644
index 0000000..edc3930e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/virtual/disable-spinvalidation/compositing/README.txt
@@ -0,0 +1 @@
+# This suite runs the tests in compositing/ with --disable-slimming-paint-invalidation.
diff --git a/third_party/WebKit/LayoutTests/virtual/disable-spinvalidation/compositing/squashing/squash-transform-repainting-child-expected.txt b/third_party/WebKit/LayoutTests/virtual/disable-spinvalidation/compositing/squashing/squash-transform-repainting-child-expected.txt
new file mode 100644
index 0000000..a5e7976c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/virtual/disable-spinvalidation/compositing/squashing/squash-transform-repainting-child-expected.txt
@@ -0,0 +1,165 @@
+CASE 1, original layer tree
+{
+  "layers": [
+    {
+      "name": "LayoutView #document",
+      "bounds": [800, 600],
+      "contentsOpaque": true,
+      "drawsContent": true
+    },
+    {
+      "name": "LayoutBlockFlow (positioned) DIV class='composited box behind'",
+      "position": [100, 100],
+      "bounds": [100, 100],
+      "contentsOpaque": true,
+      "drawsContent": true,
+      "backgroundColor": "#0000FF"
+    },
+    {
+      "name": "Squashing Containment Layer",
+      "shouldFlattenTransform": false
+    },
+    {
+      "name": "LayoutBlockFlow (positioned) DIV class='box middle'",
+      "position": [20, 20],
+      "bounds": [100, 100],
+      "contentsOpaque": true,
+      "drawsContent": true,
+      "backgroundColor": "#00FF00",
+      "transform": [
+        [0.707106781186548, 0.707106781186548, 0, 0],
+        [-0.707106781186548, 0.707106781186548, 0, 0],
+        [0, 0, 1, 0],
+        [0, 0, 0, 1]
+      ]
+    },
+    {
+      "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box top')",
+      "position": [180, 180],
+      "bounds": [100, 100],
+      "drawsContent": true
+    }
+  ]
+}
+CASE 2, hovering over the outer div
+{
+  "layers": [
+    {
+      "name": "LayoutView #document",
+      "bounds": [800, 600],
+      "contentsOpaque": true,
+      "drawsContent": true
+    },
+    {
+      "name": "LayoutBlockFlow (positioned) DIV class='composited box behind'",
+      "position": [100, 100],
+      "bounds": [100, 100],
+      "contentsOpaque": true,
+      "drawsContent": true,
+      "backgroundColor": "#0000FF"
+    },
+    {
+      "name": "Squashing Containment Layer",
+      "shouldFlattenTransform": false
+    },
+    {
+      "name": "LayoutBlockFlow (positioned) DIV class='box middle'",
+      "position": [20, 20],
+      "bounds": [100, 100],
+      "contentsOpaque": true,
+      "drawsContent": true,
+      "backgroundColor": "#008000",
+      "transform": [
+        [0.707106781186548, 0.707106781186548, 0, 0],
+        [-0.707106781186548, 0.707106781186548, 0, 0],
+        [0, 0, 1, 0],
+        [0, 0, 0, 1]
+      ],
+      "paintInvalidations": [
+        {
+          "object": "LayoutBlockFlow (positioned) DIV class='box middle'",
+          "rect": [0, 0, 100, 100],
+          "reason": "style change"
+        }
+      ]
+    },
+    {
+      "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box top')",
+      "position": [180, 180],
+      "bounds": [100, 100],
+      "drawsContent": true
+    }
+  ],
+  "objectPaintInvalidations": [
+    {
+      "object": "LayoutBlockFlow (positioned) DIV class='box middle'",
+      "reason": "style change"
+    }
+  ]
+}
+CASE 3, hovering over the inner div
+{
+  "layers": [
+    {
+      "name": "LayoutView #document",
+      "bounds": [800, 600],
+      "contentsOpaque": true,
+      "drawsContent": true
+    },
+    {
+      "name": "LayoutBlockFlow (positioned) DIV class='composited box behind'",
+      "position": [100, 100],
+      "bounds": [100, 100],
+      "contentsOpaque": true,
+      "drawsContent": true,
+      "backgroundColor": "#0000FF"
+    },
+    {
+      "name": "Squashing Containment Layer",
+      "shouldFlattenTransform": false
+    },
+    {
+      "name": "LayoutBlockFlow (positioned) DIV class='box middle'",
+      "position": [20, 20],
+      "bounds": [100, 100],
+      "contentsOpaque": true,
+      "drawsContent": true,
+      "backgroundColor": "#008000",
+      "transform": [
+        [0.707106781186548, 0.707106781186548, 0, 0],
+        [-0.707106781186548, 0.707106781186548, 0, 0],
+        [0, 0, 1, 0],
+        [0, 0, 0, 1]
+      ],
+      "paintInvalidations": [
+        {
+          "object": "LayoutBlockFlow (positioned) DIV class='box middle'",
+          "rect": [0, 0, 100, 100],
+          "reason": "style change"
+        },
+        {
+          "object": "LayoutBlockFlow (positioned) DIV class='smallbox'",
+          "rect": [20, 25, 50, 50],
+          "reason": "style change"
+        }
+      ]
+    },
+    {
+      "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box top')",
+      "position": [180, 180],
+      "bounds": [100, 100],
+      "drawsContent": true
+    }
+  ],
+  "objectPaintInvalidations": [
+    {
+      "object": "LayoutBlockFlow (positioned) DIV class='box middle'",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutBlockFlow (positioned) DIV class='smallbox'",
+      "reason": "style change"
+    }
+  ]
+}
+
diff --git a/third_party/WebKit/LayoutTests/virtual/disable-spinvalidation/compositing/squashing/squash-transform-repainting-transformed-child-expected.txt b/third_party/WebKit/LayoutTests/virtual/disable-spinvalidation/compositing/squashing/squash-transform-repainting-transformed-child-expected.txt
new file mode 100644
index 0000000..d2a68910
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/virtual/disable-spinvalidation/compositing/squashing/squash-transform-repainting-transformed-child-expected.txt
@@ -0,0 +1,165 @@
+CASE 1, original layer tree
+{
+  "layers": [
+    {
+      "name": "LayoutView #document",
+      "bounds": [800, 600],
+      "contentsOpaque": true,
+      "drawsContent": true
+    },
+    {
+      "name": "LayoutBlockFlow (positioned) DIV class='composited box behind'",
+      "position": [100, 100],
+      "bounds": [100, 100],
+      "contentsOpaque": true,
+      "drawsContent": true,
+      "backgroundColor": "#0000FF"
+    },
+    {
+      "name": "Squashing Containment Layer",
+      "shouldFlattenTransform": false
+    },
+    {
+      "name": "LayoutBlockFlow (positioned) DIV class='box middle'",
+      "position": [20, 20],
+      "bounds": [100, 100],
+      "contentsOpaque": true,
+      "drawsContent": true,
+      "backgroundColor": "#00FF00",
+      "transform": [
+        [0.927183854566787, 0.374606593415912, 0, 0],
+        [-0.374606593415912, 0.927183854566787, 0, 0],
+        [0, 0, 1, 0],
+        [0, 0, 0, 1]
+      ]
+    },
+    {
+      "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box top')",
+      "position": [180, 180],
+      "bounds": [100, 100],
+      "drawsContent": true
+    }
+  ]
+}
+CASE 2, hovering over the outer div
+{
+  "layers": [
+    {
+      "name": "LayoutView #document",
+      "bounds": [800, 600],
+      "contentsOpaque": true,
+      "drawsContent": true
+    },
+    {
+      "name": "LayoutBlockFlow (positioned) DIV class='composited box behind'",
+      "position": [100, 100],
+      "bounds": [100, 100],
+      "contentsOpaque": true,
+      "drawsContent": true,
+      "backgroundColor": "#0000FF"
+    },
+    {
+      "name": "Squashing Containment Layer",
+      "shouldFlattenTransform": false
+    },
+    {
+      "name": "LayoutBlockFlow (positioned) DIV class='box middle'",
+      "position": [20, 20],
+      "bounds": [100, 100],
+      "contentsOpaque": true,
+      "drawsContent": true,
+      "backgroundColor": "#008000",
+      "transform": [
+        [0.927183854566787, 0.374606593415912, 0, 0],
+        [-0.374606593415912, 0.927183854566787, 0, 0],
+        [0, 0, 1, 0],
+        [0, 0, 0, 1]
+      ],
+      "paintInvalidations": [
+        {
+          "object": "LayoutBlockFlow (positioned) DIV class='box middle'",
+          "rect": [0, 0, 100, 100],
+          "reason": "style change"
+        }
+      ]
+    },
+    {
+      "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box top')",
+      "position": [180, 180],
+      "bounds": [100, 100],
+      "drawsContent": true
+    }
+  ],
+  "objectPaintInvalidations": [
+    {
+      "object": "LayoutBlockFlow (positioned) DIV class='box middle'",
+      "reason": "style change"
+    }
+  ]
+}
+CASE 3, hovering over the inner div
+{
+  "layers": [
+    {
+      "name": "LayoutView #document",
+      "bounds": [800, 600],
+      "contentsOpaque": true,
+      "drawsContent": true
+    },
+    {
+      "name": "LayoutBlockFlow (positioned) DIV class='composited box behind'",
+      "position": [100, 100],
+      "bounds": [100, 100],
+      "contentsOpaque": true,
+      "drawsContent": true,
+      "backgroundColor": "#0000FF"
+    },
+    {
+      "name": "Squashing Containment Layer",
+      "shouldFlattenTransform": false
+    },
+    {
+      "name": "LayoutBlockFlow (positioned) DIV class='box middle'",
+      "position": [20, 20],
+      "bounds": [100, 100],
+      "contentsOpaque": true,
+      "drawsContent": true,
+      "backgroundColor": "#008000",
+      "transform": [
+        [0.927183854566787, 0.374606593415912, 0, 0],
+        [-0.374606593415912, 0.927183854566787, 0, 0],
+        [0, 0, 1, 0],
+        [0, 0, 0, 1]
+      ],
+      "paintInvalidations": [
+        {
+          "object": "LayoutBlockFlow (positioned) DIV class='box middle'",
+          "rect": [0, 0, 100, 100],
+          "reason": "style change"
+        },
+        {
+          "object": "LayoutBlockFlow (positioned) DIV class='smallbox'",
+          "rect": [12, 17, 66, 66],
+          "reason": "style change"
+        }
+      ]
+    },
+    {
+      "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box top')",
+      "position": [180, 180],
+      "bounds": [100, 100],
+      "drawsContent": true
+    }
+  ],
+  "objectPaintInvalidations": [
+    {
+      "object": "LayoutBlockFlow (positioned) DIV class='box middle'",
+      "reason": "style change"
+    },
+    {
+      "object": "LayoutBlockFlow (positioned) DIV class='smallbox'",
+      "reason": "style change"
+    }
+  ]
+}
+
diff --git a/third_party/WebKit/LayoutTests/virtual/disable-spinvalidation/paint/README.txt b/third_party/WebKit/LayoutTests/virtual/disable-spinvalidation/paint/README.txt
new file mode 100644
index 0000000..4304347b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/virtual/disable-spinvalidation/paint/README.txt
@@ -0,0 +1 @@
+# This suite runs the tests in paint/ with --disable-slimming-paint-invalidation.
diff --git a/third_party/WebKit/LayoutTests/virtual/disable-spinvalidation/paint/invalidation/README.txt b/third_party/WebKit/LayoutTests/virtual/disable-spinvalidation/paint/invalidation/README.txt
deleted file mode 100644
index fb466fe..0000000
--- a/third_party/WebKit/LayoutTests/virtual/disable-spinvalidation/paint/invalidation/README.txt
+++ /dev/null
@@ -1 +0,0 @@
-# This suite runs the tests in paint/invalidation with experimental features disabled.
diff --git a/third_party/WebKit/Source/bindings/core/v8/RejectedPromises.cpp b/third_party/WebKit/Source/bindings/core/v8/RejectedPromises.cpp
index 87fcf6e..e5bb615 100644
--- a/third_party/WebKit/Source/bindings/core/v8/RejectedPromises.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/RejectedPromises.cpp
@@ -204,7 +204,7 @@
   // by processQueue().
   for (auto it = m_queue.begin(); it != m_queue.end(); ++it) {
     if (!(*it)->isCollected() && (*it)->hasPromise(data.GetPromise())) {
-      m_queue.remove(it);
+      m_queue.erase(it);
       return;
     }
   }
diff --git a/third_party/WebKit/Source/core/core_idl_files.gni b/third_party/WebKit/Source/core/core_idl_files.gni
index 1a0633a..cf04f09 100644
--- a/third_party/WebKit/Source/core/core_idl_files.gni
+++ b/third_party/WebKit/Source/core/core_idl_files.gni
@@ -473,10 +473,10 @@
                     "events/NavigatorEvents.idl",
                     "fileapi/URLFileAPI.idl",
                     "frame/NavigatorCPU.idl",
+                    "frame/NavigatorCookies.idl",
                     "frame/NavigatorID.idl",
                     "frame/NavigatorLanguage.idl",
                     "frame/NavigatorOnLine.idl",
-                    "frame/NavigatorStorageUtils.idl",
                     "frame/WindowBase64.idl",
                     "frame/WindowEventHandlers.idl",
                     "frame/WindowTimers.idl",
diff --git a/third_party/WebKit/Source/core/css/resolver/SharedStyleFinder.cpp b/third_party/WebKit/Source/core/css/resolver/SharedStyleFinder.cpp
index df7e4ede..8ecb8159 100644
--- a/third_party/WebKit/Source/core/css/resolver/SharedStyleFinder.cpp
+++ b/third_party/WebKit/Source/core/css/resolver/SharedStyleFinder.cpp
@@ -355,7 +355,7 @@
       continue;
     if (it != styleSharingList.begin()) {
       // Move the element to the front of the LRU
-      styleSharingList.remove(it);
+      styleSharingList.erase(it);
       styleSharingList.prepend(&candidate);
     }
     return &candidate;
diff --git a/third_party/WebKit/Source/core/dom/ScriptRunner.cpp b/third_party/WebKit/Source/core/dom/ScriptRunner.cpp
index 333c2d8..69056c01 100644
--- a/third_party/WebKit/Source/core/dom/ScriptRunner.cpp
+++ b/third_party/WebKit/Source/core/dom/ScriptRunner.cpp
@@ -142,7 +142,7 @@
                       m_pendingInOrderScripts.end(), scriptLoader);
   if (it == m_pendingInOrderScripts.end())
     return false;
-  m_pendingInOrderScripts.remove(it);
+  m_pendingInOrderScripts.erase(it);
   SECURITY_CHECK(m_numberOfInOrderScriptsWithPendingNotification > 0);
   m_numberOfInOrderScriptsWithPendingNotification--;
   return true;
diff --git a/third_party/WebKit/Source/core/editing/commands/UndoStack.cpp b/third_party/WebKit/Source/core/editing/commands/UndoStack.cpp
index 10db110..a48da7b0 100644
--- a/third_party/WebKit/Source/core/editing/commands/UndoStack.cpp
+++ b/third_party/WebKit/Source/core/editing/commands/UndoStack.cpp
@@ -70,7 +70,7 @@
   if (canUndo()) {
     UndoStepStack::iterator back = --m_undoStack.end();
     UndoStep* step(back->get());
-    m_undoStack.remove(back);
+    m_undoStack.erase(back);
     step->unapply();
     // unapply will call us back to push this command onto the redo stack.
   }
@@ -80,7 +80,7 @@
   if (canRedo()) {
     UndoStepStack::iterator back = --m_redoStack.end();
     UndoStep* step(back->get());
-    m_redoStack.remove(back);
+    m_redoStack.erase(back);
 
     DCHECK(!m_inRedo);
     AutoReset<bool> redoScope(&m_inRedo, true);
diff --git a/third_party/WebKit/Source/core/editing/spellcheck/SpellCheckRequester.cpp b/third_party/WebKit/Source/core/editing/spellcheck/SpellCheckRequester.cpp
index 0876b64..b7cb287 100644
--- a/third_party/WebKit/Source/core/editing/spellcheck/SpellCheckRequester.cpp
+++ b/third_party/WebKit/Source/core/editing/spellcheck/SpellCheckRequester.cpp
@@ -225,7 +225,7 @@
                               queuedRequest->rootEditableElement();
                      });
     if (sameElementRequest != m_requestQueue.end())
-      m_requestQueue.remove(sameElementRequest);
+      m_requestQueue.erase(sameElementRequest);
   }
 
   m_requestQueue.push_back(request);
diff --git a/third_party/WebKit/Source/core/fileapi/FileReader.cpp b/third_party/WebKit/Source/core/fileapi/FileReader.cpp
index 58a75173..01bf733 100644
--- a/third_party/WebKit/Source/core/fileapi/FileReader.cpp
+++ b/third_party/WebKit/Source/core/fileapi/FileReader.cpp
@@ -150,7 +150,7 @@
     for (FileReaderDeque::const_iterator it = m_pendingReaders.begin();
          it != dequeEnd; ++it) {
       if (*it == reader) {
-        m_pendingReaders.remove(it);
+        m_pendingReaders.erase(it);
         break;
       }
     }
diff --git a/third_party/WebKit/Source/core/frame/Navigator.h b/third_party/WebKit/Source/core/frame/Navigator.h
index 34b7e5cb..d738620d 100644
--- a/third_party/WebKit/Source/core/frame/Navigator.h
+++ b/third_party/WebKit/Source/core/frame/Navigator.h
@@ -49,6 +49,7 @@
  public:
   static Navigator* create(LocalFrame* frame) { return new Navigator(frame); }
 
+  // NavigatorCookies
   bool cookieEnabled() const;
 
   String productSub() const;
diff --git a/third_party/WebKit/Source/core/frame/Navigator.idl b/third_party/WebKit/Source/core/frame/Navigator.idl
index 15f91f5..a229722 100644
--- a/third_party/WebKit/Source/core/frame/Navigator.idl
+++ b/third_party/WebKit/Source/core/frame/Navigator.idl
@@ -33,7 +33,7 @@
 };
 
 Navigator implements NavigatorCPU;
+Navigator implements NavigatorCookies;
 Navigator implements NavigatorID;
 Navigator implements NavigatorLanguage;
 Navigator implements NavigatorOnLine;
-Navigator implements NavigatorStorageUtils;
diff --git a/third_party/WebKit/Source/core/frame/NavigatorCookies.idl b/third_party/WebKit/Source/core/frame/NavigatorCookies.idl
new file mode 100644
index 0000000..c77322a1
--- /dev/null
+++ b/third_party/WebKit/Source/core/frame/NavigatorCookies.idl
@@ -0,0 +1,10 @@
+// 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.
+
+// https://html.spec.whatwg.org/multipage/webappapis.html#cookies
+
+[NoInterfaceObject]
+interface NavigatorCookies {
+  readonly attribute boolean cookieEnabled;
+};
diff --git a/third_party/WebKit/Source/core/frame/NavigatorStorageUtils.idl b/third_party/WebKit/Source/core/frame/NavigatorStorageUtils.idl
deleted file mode 100644
index b408dc7d..0000000
--- a/third_party/WebKit/Source/core/frame/NavigatorStorageUtils.idl
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// https://html.spec.whatwg.org/#manually-releasing-the-storage-mutex
-
-[
-    NoInterfaceObject, // Always used on target of 'implements'
-] interface NavigatorStorageUtils {
-    readonly attribute boolean cookieEnabled;
-};
diff --git a/third_party/WebKit/Source/core/html/MediaCustomControlsFullscreenDetectorTest.cpp b/third_party/WebKit/Source/core/html/MediaCustomControlsFullscreenDetectorTest.cpp
index 2d7fa04..9da6eec 100644
--- a/third_party/WebKit/Source/core/html/MediaCustomControlsFullscreenDetectorTest.cpp
+++ b/third_party/WebKit/Source/core/html/MediaCustomControlsFullscreenDetectorTest.cpp
@@ -8,7 +8,6 @@
 #include "core/html/HTMLVideoElement.h"
 #include "core/testing/DummyPageHolder.h"
 #include "platform/geometry/IntRect.h"
-#include "public/platform/WebMediaPlayer.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/html/shadow/MediaControlsOrientationLockDelegateTest.cpp b/third_party/WebKit/Source/core/html/shadow/MediaControlsOrientationLockDelegateTest.cpp
index 76499b6..283695e 100644
--- a/third_party/WebKit/Source/core/html/shadow/MediaControlsOrientationLockDelegateTest.cpp
+++ b/third_party/WebKit/Source/core/html/shadow/MediaControlsOrientationLockDelegateTest.cpp
@@ -14,8 +14,8 @@
 #include "core/loader/EmptyClients.h"
 #include "core/testing/DummyPageHolder.h"
 #include "platform/UserGestureIndicator.h"
+#include "platform/testing/EmptyWebMediaPlayer.h"
 #include "platform/testing/UnitTestHelpers.h"
-#include "public/platform/WebMediaPlayer.h"
 #include "public/platform/WebSize.h"
 #include "public/platform/modules/screen_orientation/WebLockOrientationCallback.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -36,40 +36,9 @@
   void onError(WebLockOrientationError) override {}
 };
 
-class MockVideoWebMediaPlayer : public WebMediaPlayer {
+class MockVideoWebMediaPlayer : public EmptyWebMediaPlayer {
  public:
-  void load(LoadType, const WebMediaPlayerSource&, CORSMode) override{};
-  void play() override{};
-  void pause() override{};
-  bool supportsSave() const override { return false; };
-  void seek(double seconds) override{};
-  void setRate(double) override{};
-  void setVolume(double) override{};
-  WebTimeRanges buffered() const override { return WebTimeRanges(); };
-  WebTimeRanges seekable() const override { return WebTimeRanges(); };
-  void setSinkId(const WebString& sinkId,
-                 const WebSecurityOrigin&,
-                 WebSetSinkIdCallbacks*) override{};
-  bool hasVideo() const override { return true; };
-  bool hasAudio() const override { return false; };
-  bool paused() const override { return false; };
-  bool seeking() const override { return false; };
-  double duration() const override { return 0.0; };
-  double currentTime() const override { return 0.0; };
-  NetworkState getNetworkState() const override { return NetworkStateEmpty; };
-  ReadyState getReadyState() const override { return ReadyStateHaveNothing; };
-  WebString getErrorMessage() override { return WebString(); };
-  bool didLoadingProgress() override { return false; };
-  bool hasSingleSecurityOrigin() const override { return true; };
-  bool didPassCORSAccessCheck() const override { return true; };
-  double mediaTimeForTimeValue(double timeValue) const override {
-    return timeValue;
-  };
-  unsigned decodedFrameCount() const override { return 0; };
-  unsigned droppedFrameCount() const override { return 0; };
-  size_t audioDecodedByteCount() const override { return 0; };
-  size_t videoDecodedByteCount() const override { return 0; };
-  void paint(WebCanvas*, const WebRect&, PaintFlags&) override{};
+  bool hasVideo() const override { return true; }
 
   MOCK_CONST_METHOD0(naturalSize, WebSize());
 };
diff --git a/third_party/WebKit/Source/core/html/shadow/MediaControlsTest.cpp b/third_party/WebKit/Source/core/html/shadow/MediaControlsTest.cpp
index 57ae09d6..9a3f79b 100644
--- a/third_party/WebKit/Source/core/html/shadow/MediaControlsTest.cpp
+++ b/third_party/WebKit/Source/core/html/shadow/MediaControlsTest.cpp
@@ -17,9 +17,9 @@
 #include "core/loader/EmptyClients.h"
 #include "core/testing/DummyPageHolder.h"
 #include "platform/heap/Handle.h"
+#include "platform/testing/EmptyWebMediaPlayer.h"
 #include "platform/testing/HistogramTester.h"
 #include "platform/testing/UnitTestHelpers.h"
-#include "public/platform/WebMediaPlayer.h"
 #include "public/platform/WebSize.h"
 #include "public/platform/modules/remoteplayback/WebRemotePlaybackAvailability.h"
 #include "public/platform/modules/remoteplayback/WebRemotePlaybackClient.h"
@@ -29,42 +29,11 @@
 
 namespace {
 
-class MockVideoWebMediaPlayer : public WebMediaPlayer {
+class MockVideoWebMediaPlayer : public EmptyWebMediaPlayer {
  public:
   // WebMediaPlayer overrides:
-  void load(LoadType, const WebMediaPlayerSource&, CORSMode) override{};
-  void play() override{};
-  void pause() override{};
-  bool supportsSave() const override { return false; };
-  void seek(double seconds) override{};
-  void setRate(double) override{};
-  void setVolume(double) override{};
-  WebTimeRanges buffered() const override { return WebTimeRanges(); };
-  WebTimeRanges seekable() const override { return m_seekable; };
-  void setSinkId(const WebString& sinkId,
-                 const WebSecurityOrigin&,
-                 WebSetSinkIdCallbacks*) override{};
-  bool hasVideo() const override { return true; };
-  bool hasAudio() const override { return false; };
-  WebSize naturalSize() const override { return WebSize(0, 0); };
-  bool paused() const override { return false; };
-  bool seeking() const override { return false; };
-  double duration() const override { return 0.0; };
-  double currentTime() const override { return 0.0; };
-  NetworkState getNetworkState() const override { return NetworkStateEmpty; };
-  ReadyState getReadyState() const override { return ReadyStateHaveNothing; };
-  WebString getErrorMessage() override { return WebString(); };
-  bool didLoadingProgress() override { return false; };
-  bool hasSingleSecurityOrigin() const override { return true; };
-  bool didPassCORSAccessCheck() const override { return true; };
-  double mediaTimeForTimeValue(double timeValue) const override {
-    return timeValue;
-  };
-  unsigned decodedFrameCount() const override { return 0; };
-  unsigned droppedFrameCount() const override { return 0; };
-  size_t audioDecodedByteCount() const override { return 0; };
-  size_t videoDecodedByteCount() const override { return 0; };
-  void paint(WebCanvas*, const WebRect&, PaintFlags&) override{};
+  WebTimeRanges seekable() const override { return m_seekable; }
+  bool hasVideo() const override { return true; }
 
   WebTimeRanges m_seekable;
 };
diff --git a/third_party/WebKit/Source/core/loader/PingLoader.cpp b/third_party/WebKit/Source/core/loader/PingLoader.cpp
index 6656313..7ba64a6 100644
--- a/third_party/WebKit/Source/core/loader/PingLoader.cpp
+++ b/third_party/WebKit/Source/core/loader/PingLoader.cpp
@@ -426,7 +426,7 @@
     return false;
 
   unsigned long long entitySize = beacon.size();
-  if (allowance > 0 && static_cast<unsigned long long>(allowance) < entitySize)
+  if (allowance < 0 || static_cast<unsigned long long>(allowance) < entitySize)
     return false;
 
   payloadLength = entitySize;
diff --git a/third_party/WebKit/Source/core/paint/VideoPainterTest.cpp b/third_party/WebKit/Source/core/paint/VideoPainterTest.cpp
index 2d62267..6b1fe21 100644
--- a/third_party/WebKit/Source/core/paint/VideoPainterTest.cpp
+++ b/third_party/WebKit/Source/core/paint/VideoPainterTest.cpp
@@ -10,12 +10,12 @@
 #include "core/loader/EmptyClients.h"
 #include "core/paint/StubChromeClientForSPv2.h"
 #include "core/testing/DummyPageHolder.h"
+#include "platform/testing/EmptyWebMediaPlayer.h"
 #include "platform/testing/RuntimeEnabledFeaturesTestHelpers.h"
 #include "platform/testing/UnitTestHelpers.h"
 #include "public/platform/Platform.h"
 #include "public/platform/WebCompositorSupport.h"
 #include "public/platform/WebLayer.h"
-#include "public/platform/WebMediaPlayer.h"
 #include "public/platform/WebSize.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -24,7 +24,7 @@
 namespace blink {
 namespace {
 
-class StubWebMediaPlayer : public WebMediaPlayer {
+class StubWebMediaPlayer : public EmptyWebMediaPlayer {
  public:
   StubWebMediaPlayer(WebMediaPlayerClient* client) : m_client(client) {}
 
@@ -39,38 +39,8 @@
     m_webLayer = Platform::current()->compositorSupport()->createLayer();
     m_client->setWebLayer(m_webLayer.get());
   }
-  void play() override {}
-  void pause() override {}
-  bool supportsSave() const override { return false; }
-  void seek(double seconds) override {}
-  void setRate(double) override {}
-  void setVolume(double) override {}
-  WebTimeRanges buffered() const override { return WebTimeRanges(); }
-  WebTimeRanges seekable() const override { return WebTimeRanges(); }
-  void setSinkId(const WebString& sinkId,
-                 const WebSecurityOrigin&,
-                 WebSetSinkIdCallbacks*) override {}
-  bool hasVideo() const override { return false; }
-  bool hasAudio() const override { return false; }
-  WebSize naturalSize() const override { return WebSize(0, 0); }
-  bool paused() const override { return false; }
-  bool seeking() const override { return false; }
-  double duration() const override { return 0.0; }
-  double currentTime() const override { return 0.0; }
   NetworkState getNetworkState() const override { return m_networkState; }
   ReadyState getReadyState() const override { return m_readyState; }
-  WebString getErrorMessage() override { return WebString(); }
-  bool didLoadingProgress() override { return false; }
-  bool hasSingleSecurityOrigin() const override { return true; }
-  bool didPassCORSAccessCheck() const override { return true; }
-  double mediaTimeForTimeValue(double timeValue) const override {
-    return timeValue;
-  }
-  unsigned decodedFrameCount() const override { return 0; }
-  unsigned droppedFrameCount() const override { return 0; }
-  size_t audioDecodedByteCount() const override { return 0; }
-  size_t videoDecodedByteCount() const override { return 0; }
-  void paint(WebCanvas*, const WebRect&, PaintFlags&) override {}
 
  private:
   WebMediaPlayerClient* m_client;
diff --git a/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp b/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp
index 7350420..1e530ca 100644
--- a/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp
+++ b/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp
@@ -1013,7 +1013,7 @@
   //    the self-destruction of this Canvas2DLayerBridge
   // 2) Release the SkImage, which will return the texture to skia's scratch
   //    texture pool.
-  m_mailboxes.remove(releasedMailboxInfo);
+  m_mailboxes.erase(releasedMailboxInfo);
 
   if (m_mailboxes.isEmpty() && m_accelerationMode == DisableAcceleration)
     m_layer.reset();
diff --git a/third_party/WebKit/Source/wtf/Deque.h b/third_party/WebKit/Source/wtf/Deque.h
index c7c2251..aaed1c9 100644
--- a/third_party/WebKit/Source/wtf/Deque.h
+++ b/third_party/WebKit/Source/wtf/Deque.h
@@ -127,8 +127,8 @@
 
   template <typename U>
   void prepend(U&&);
-  void remove(iterator&);
-  void remove(const_iterator&);
+  void erase(iterator&);
+  void erase(const_iterator&);
 
   // STL compatibility.
   template <typename U>
@@ -183,7 +183,7 @@
   typedef VectorTypeOperations<T> TypeOperations;
   typedef DequeIteratorBase<T, inlineCapacity, Allocator> IteratorBase;
 
-  void remove(size_t position);
+  void erase(size_t position);
   void destroyAll();
   void expandCapacityIfNeeded();
   void expandCapacity();
@@ -565,17 +565,17 @@
 }
 
 template <typename T, size_t inlineCapacity, typename Allocator>
-inline void Deque<T, inlineCapacity, Allocator>::remove(iterator& it) {
-  remove(it.m_index);
+inline void Deque<T, inlineCapacity, Allocator>::erase(iterator& it) {
+  erase(it.m_index);
 }
 
 template <typename T, size_t inlineCapacity, typename Allocator>
-inline void Deque<T, inlineCapacity, Allocator>::remove(const_iterator& it) {
-  remove(it.m_index);
+inline void Deque<T, inlineCapacity, Allocator>::erase(const_iterator& it) {
+  erase(it.m_index);
 }
 
 template <typename T, size_t inlineCapacity, typename Allocator>
-inline void Deque<T, inlineCapacity, Allocator>::remove(size_t position) {
+inline void Deque<T, inlineCapacity, Allocator>::erase(size_t position) {
   if (position == m_end)
     return;
 
diff --git a/third_party/WebKit/Source/wtf/DequeTest.cpp b/third_party/WebKit/Source/wtf/DequeTest.cpp
index 5a676ce1..3e1971a 100644
--- a/third_party/WebKit/Source/wtf/DequeTest.cpp
+++ b/third_party/WebKit/Source/wtf/DequeTest.cpp
@@ -590,7 +590,7 @@
   // Remove the even numbers while iterating.
   for (auto it = deque.begin(); it != deque.end(); ++it) {
     if (*it % 2 == 0) {
-      deque.remove(it);
+      deque.erase(it);
       --it;
     }
   }
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 540d233..459eda5 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -99469,6 +99469,7 @@
   <int value="-418868128" label="enable-experimental-web-platform-features"/>
   <int value="-410852857" label="ImprovedA2HS:disabled"/>
   <int value="-396994784" label="enable-vr-shell"/>
+  <int value="-396496344" label="ViewsTaskManager:enabled"/>
   <int value="-395606844" label="enable-site-settings"/>
   <int value="-387606010" label="ArcBootCompletedBroadcast:enabled"/>
   <int value="-385337473" label="enable-fast-unload"/>
@@ -99572,6 +99573,7 @@
   <int value="10458238" label="disable-print-preview-simplify"/>
   <int value="11698808" label="enable-dom-distiller-button-animation"/>
   <int value="27507364" label="apps-keep-chrome-alive"/>
+  <int value="31848187" label="ViewsTaskManager:disabled"/>
   <int value="33778663" label="OriginTrials:enabled"/>
   <int value="37024318" label="disable-affiliation-based-matching"/>
   <int value="44088203" label="ExpensiveBackgroundTimerThrottling:enabled"/>
diff --git a/tools/perf/benchmarks/webrtc.py b/tools/perf/benchmarks/webrtc.py
index bf9582ab..947ab94 100644
--- a/tools/perf/benchmarks/webrtc.py
+++ b/tools/perf/benchmarks/webrtc.py
@@ -94,3 +94,34 @@
   @classmethod
   def Name(cls):
     return 'webrtc.webrtc_smoothness'
+
+
+# WebrtcRenderingTBMv2 must be a PerfBenchmark, and not a _Webrtc, because it is
+# a timeline-based metric.
+print dir(benchmark)
+@benchmark.Owner(emails=['ehmaldonado@chromium.org',
+                         'phoglund@chromium.org',
+                         'qiangchen@chromium.org'])
+class WebrtcRenderingTBMv2(perf_benchmark.PerfBenchmark):
+  """Specific time measurements (e.g. fps, smoothness) for WebRtc rendering."""
+
+  page_set = page_sets.WebrtcRenderingPageSet
+
+  def CreateTimelineBasedMeasurementOptions(self):
+    category_filter = chrome_trace_category_filter.ChromeTraceCategoryFilter(
+        filter_string='webrtc,toplevel')
+    options = timeline_based_measurement.Options(category_filter)
+    options.SetTimelineBasedMetrics([
+        'cpuTimeMetric',
+        'expectedQueueingTimeMetric',
+        'webrtcRenderingMetric',
+    ])
+    return options
+
+  def SetExtraBrowserOptions(self, options):
+    options.AppendExtraBrowserArgs('--use-fake-device-for-media-stream')
+    options.AppendExtraBrowserArgs('--use-fake-ui-for-media-stream')
+
+  @classmethod
+  def Name(cls):
+    return 'webrtc.webrtc_smoothness_tbmv2'
diff --git a/tools/valgrind/memcheck/suppressions.txt b/tools/valgrind/memcheck/suppressions.txt
index 6fc159861..24bb24f2 100644
--- a/tools/valgrind/memcheck/suppressions.txt
+++ b/tools/valgrind/memcheck/suppressions.txt
@@ -914,14 +914,6 @@
    fun:_ZN16ExtensionInfoMap12AddExtensionEPK9Extension
 }
 {
-   Bug_69934_a
-   Memcheck:Leak
-   fun:_Znw*
-   fun:_ZN*NPObjectProxy10NPAllocateEP4_NPPP7NPClass
-   fun:_NPN_CreateObject
-   fun:_ZN5blink11WebBindings12createObjectEP4_NPPP7NPClass
-}
-{
    Bug_69934_b
    Memcheck:Leak
    fun:_Znw*
@@ -950,19 +942,6 @@
    fun:_ZN5blink13AXObjectCache24postPlatformNotificationEPNS_19AccessibilityObjectENS0_14AXNotificationE
 }
 {
-   bug_73675
-   Memcheck:Leak
-   fun:_Znw*
-   fun:_ZN20LayoutTestController13waitUntilDoneERKN3WTF6VectorI10CppVariantLj0EEEPS2_
-   fun:_ZN13CppBoundClass14MemberCallbackI20LayoutTestControllerE3runERKN3WTF6VectorI10CppVariantLj0EEEPS5_
-   fun:_ZN13CppBoundClass6invokeEPvPK10_NPVariantjPS1_
-   fun:_ZN11CppNPObject6invokeEP8NPObjectPvPK10_NPVariantjPS3_
-   fun:_ZN5blink18npObjectInvokeImplERKN2v89ArgumentsENS_18InvokeFunctionTypeE
-   fun:_ZN5blink21npObjectMethodHandlerERKN2v89ArgumentsE
-   fun:_ZN2v88internal19HandleApiCallHelperILb0EEEPNS0_11MaybeObjectENS0_47_GLOBAL__N_v8_src_builtins.cc_*BuiltinArgumentsILNS0_21BuiltinExtraArgumentsE1EEE
-   obj:*
-}
-{
    bug_75019
    Memcheck:Leak
    fun:_Znw*
@@ -1382,32 +1361,6 @@
    fun:_ZNK7blink11RenderLayer18backgroundClipRectEPKS0_PNS_12RenderRegionENS_13ClipRectsTypeENS_29OverlayScrollbarSizeRelevancyE
 }
 {
-   bug_138060
-   Memcheck:Uninitialized
-   fun:_NPN_EvaluateHelper
-   fun:_NPN_Evaluate
-   fun:_ZN5blink11WebBindings8evaluateEP4_NPPP8NPObjectP9_NPStringP10_NPVariant
-   fun:_ZL13executeScriptPK12PluginObjectPKc
-   fun:NPP_Destroy
-   fun:_ZN6webkit5npapi14PluginInstance11NPP_DestroyEv
-   fun:_ZN6webkit5npapi21WebPluginDelegateImpl15DestroyInstanceEv
-   fun:_ZN6webkit5npapi21WebPluginDelegateImplD0Ev
-   fun:_ZN6webkit5npapi21WebPluginDelegateImpl15PluginDestroyedEv
-   fun:_ZN6webkit5npapi13WebPluginImpl22TearDownPluginInstanceEPN5blink12WebURLLoaderE
-   fun:_ZN6webkit5npapi13WebPluginImpl12SetContainerEPN5blink18WebPluginContainerE
-   fun:_ZN6webkit5npapi13WebPluginImpl7destroyEv
-   fun:_ZN5blink22WebPluginContainerImplD0Ev
-   fun:_ZN3WTF10RefCountedIN7blink6WidgetEE5derefEv
-   fun:_ZNSt4pairIN3WTF6RefPtrIN7blink6WidgetEEEPNS2_9FrameViewEED1Ev
-   fun:_ZN3WTF9HashTableINS_6RefPtrIN7blink6WidgetEEESt4pairIS4_PNS2_9FrameViewEENS_18PairFirstExtractorIS8_EENS_7PtrHashIS4_EENS_14PairHashTraitsINS_10HashTraitsIS4_EENSE_IS7_EEEESF_E15deallocateTableEPS8_i
-   fun:_ZN3WTF9HashTableINS_6RefPtrIN7blink6WidgetEEESt4pairIS4_PNS2_9FrameViewEENS_18PairFirstExtractorIS8_EENS_7PtrHashIS4_EENS_14PairHashTraitsINS_10HashTraitsIS4_EENSE_IS7_EEEESF_ED1Ev
-   fun:_ZN3WTF7HashMapINS_6RefPtrIN7blink6WidgetEEEPNS2_9FrameViewENS_7PtrHashIS4_EENS_10HashTraitsIS4_EENS9_IS6_EEED1Ev
-   fun:_ZN5blink12RenderWidget28resumeWidgetHierarchyUpdatesEv
-   fun:_ZN5blink7Element6detachEv
-   fun:_ZN5blink13ContainerNode14detachChildrenEv
-   fun:_ZN5blink13ContainerNode6detachEv
-}
-{
    bug_138233_a
    Memcheck:Leak
    fun:malloc
diff --git a/ui/aura/BUILD.gn b/ui/aura/BUILD.gn
index acf6b8a..605e60a 100644
--- a/ui/aura/BUILD.gn
+++ b/ui/aura/BUILD.gn
@@ -147,6 +147,8 @@
     "//base/third_party/dynamic_annotations",
     "//cc",
     "//cc/surfaces",
+    "//components/discardable_memory/client",
+    "//components/discardable_memory/public/interfaces",
     "//gpu/ipc/client",
     "//mojo/public/cpp/system",
     "//net",
diff --git a/ui/aura/mus/DEPS b/ui/aura/mus/DEPS
index 3f8d7fba..f3685608 100644
--- a/ui/aura/mus/DEPS
+++ b/ui/aura/mus/DEPS
@@ -7,6 +7,7 @@
   "+cc/surfaces/surface_info.h",
   "+cc/surfaces/surface_manager.h",
   "+cc/surfaces/surface_reference_factory.h",
+  "+components/discardable_memory/client/client_discardable_shared_memory_manager.h",
   "+gpu/command_buffer/client/gpu_memory_buffer_manager.h",
   "+gpu/ipc/client/gpu_channel_host.h",
   "+mojo/public/cpp/system/buffer.h",
diff --git a/ui/aura/mus/window_tree_client.cc b/ui/aura/mus/window_tree_client.cc
index bc00034d..1b57f14 100644
--- a/ui/aura/mus/window_tree_client.cc
+++ b/ui/aura/mus/window_tree_client.cc
@@ -13,6 +13,8 @@
 #include "base/auto_reset.h"
 #include "base/bind.h"
 #include "base/memory/ptr_util.h"
+#include "base/threading/thread.h"
+#include "components/discardable_memory/client/client_discardable_shared_memory_manager.h"
 #include "mojo/public/cpp/bindings/map.h"
 #include "services/service_manager/public/cpp/connector.h"
 #include "services/ui/common/accelerator_util.h"
@@ -173,7 +175,8 @@
     WindowTreeClientDelegate* delegate,
     WindowManagerDelegate* window_manager_delegate,
     mojo::InterfaceRequest<ui::mojom::WindowTreeClient> request,
-    scoped_refptr<base::SingleThreadTaskRunner> io_task_runner)
+    scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
+    bool create_discardable_memory)
     : connector_(connector),
       client_id_(0),
       next_window_id_(1),
@@ -192,17 +195,42 @@
   if (window_manager_delegate)
     window_manager_delegate->SetWindowManagerClient(this);
   if (connector) {  // |connector| can be null in tests.
-    gpu_ = ui::Gpu::Create(connector, std::move(io_task_runner));
+    if (!io_task_runner) {
+      // |io_task_runner| is null in most case. But for the browser process,
+      // the |io_task_runner| is the browser's IO thread.
+      io_thread_ = base::MakeUnique<base::Thread>("IOThread");
+      base::Thread::Options thread_options(base::MessageLoop::TYPE_IO, 0);
+      thread_options.priority = base::ThreadPriority::NORMAL;
+      CHECK(io_thread_->StartWithOptions(thread_options));
+      io_task_runner = io_thread_->task_runner();
+    }
+
+    gpu_ = ui::Gpu::Create(connector, io_task_runner);
     compositor_context_factory_ =
         base::MakeUnique<MusContextFactory>(gpu_.get());
     initial_context_factory_ = Env::GetInstance()->context_factory();
     Env::GetInstance()->set_context_factory(compositor_context_factory_.get());
+
+    // WindowServerTest will create more than one WindowTreeClient. We will not
+    // create the discardable memory manager for those tests.
+    if (create_discardable_memory) {
+      discardable_memory::mojom::DiscardableSharedMemoryManagerPtr manager_ptr;
+      connector->BindInterface(ui::mojom::kServiceName, &manager_ptr);
+      discardable_shared_memory_manager_ = base::MakeUnique<
+          discardable_memory::ClientDiscardableSharedMemoryManager>(
+          std::move(manager_ptr), std::move(io_task_runner));
+      base::DiscardableMemoryAllocator::SetInstance(
+          discardable_shared_memory_manager_.get());
+    }
   }
 }
 
 WindowTreeClient::~WindowTreeClient() {
   in_destructor_ = true;
 
+  if (discardable_shared_memory_manager_)
+    base::DiscardableMemoryAllocator::SetInstance(nullptr);
+
   for (WindowTreeClientObserver& observer : observers_)
     observer.OnWillDestroyClient(this);
 
diff --git a/ui/aura/mus/window_tree_client.h b/ui/aura/mus/window_tree_client.h
index 6307371..fa338c8e 100644
--- a/ui/aura/mus/window_tree_client.h
+++ b/ui/aura/mus/window_tree_client.h
@@ -30,6 +30,14 @@
 #include "ui/aura/mus/window_manager_delegate.h"
 #include "ui/aura/mus/window_tree_host_mus_delegate.h"
 
+namespace base {
+class Thread;
+}
+
+namespace discardable_memory {
+class ClientDiscardableSharedMemoryManager;
+}
+
 namespace display {
 class Display;
 }
@@ -86,12 +94,17 @@
       public WindowTreeHostMusDelegate,
       public client::TransientWindowClientObserver {
  public:
-  explicit WindowTreeClient(
+  // |create_discardable_memory| If it is true, WindowTreeClient will setup the
+  // dicardable shared memory manager for this process. In some test, more than
+  // one WindowTreeClient will be created, so we need pass false to avoid
+  // setup the discardable shared memory manager more than once.
+  WindowTreeClient(
       service_manager::Connector* connector,
       WindowTreeClientDelegate* delegate,
       WindowManagerDelegate* window_manager_delegate = nullptr,
       ui::mojom::WindowTreeClientRequest request = nullptr,
-      scoped_refptr<base::SingleThreadTaskRunner> io_task_runner = nullptr);
+      scoped_refptr<base::SingleThreadTaskRunner> io_task_runner = nullptr,
+      bool create_discardable_memory = true);
   ~WindowTreeClient() override;
 
   // Establishes the connection by way of the WindowTreeFactory.
@@ -543,9 +556,15 @@
 
   base::ObserverList<WindowTreeClientTestObserver> test_observers_;
 
+  // IO thread for GPU and discardable shared memory IPC.
+  std::unique_ptr<base::Thread> io_thread_;
+
   std::unique_ptr<ui::Gpu> gpu_;
   std::unique_ptr<MusContextFactory> compositor_context_factory_;
 
+  std::unique_ptr<discardable_memory::ClientDiscardableSharedMemoryManager>
+      discardable_shared_memory_manager_;
+
   // If |compositor_context_factory_| is installed on Env, then this is the
   // ContextFactory that was set on Env originally.
   ui::ContextFactory* initial_context_factory_ = nullptr;
diff --git a/ui/compositor/BUILD.gn b/ui/compositor/BUILD.gn
index 6932265..bca847ba 100644
--- a/ui/compositor/BUILD.gn
+++ b/ui/compositor/BUILD.gn
@@ -87,6 +87,7 @@
     "//skia",
     "//ui/base",
     "//ui/gfx",
+    "//ui/gfx/animation",
     "//ui/gfx/geometry",
     "//ui/gl",
   ]
diff --git a/ui/gfx/BUILD.gn b/ui/gfx/BUILD.gn
index 4ea3d50..23cd695 100644
--- a/ui/gfx/BUILD.gn
+++ b/ui/gfx/BUILD.gn
@@ -49,25 +49,6 @@
     "android/java_bitmap.h",
     "android/view_configuration.cc",
     "android/view_configuration.h",
-    "animation/animation.cc",
-    "animation/animation.h",
-    "animation/animation_container.cc",
-    "animation/animation_container.h",
-    "animation/animation_container_element.h",
-    "animation/animation_container_observer.h",
-    "animation/animation_delegate.h",
-    "animation/animation_mac.mm",
-    "animation/animation_win.cc",
-    "animation/linear_animation.cc",
-    "animation/linear_animation.h",
-    "animation/multi_animation.cc",
-    "animation/multi_animation.h",
-    "animation/slide_animation.cc",
-    "animation/slide_animation.h",
-    "animation/throb_animation.cc",
-    "animation/throb_animation.h",
-    "animation/tween.cc",
-    "animation/tween.h",
     "break_list.h",
     "codec/jpeg_codec.cc",
     "codec/jpeg_codec.h",
@@ -273,6 +254,7 @@
     "//base",
     "//skia",
     "//third_party/icu",
+    "//ui/gfx/animation",
     "//ui/gfx/geometry",
     "//ui/gfx/range",
   ]
@@ -345,7 +327,6 @@
       sources += [ "font_fallback_android.cc" ]
     } else {
       sources -= [
-        "animation/throb_animation.cc",
         "canvas_skia.cc",
         "path.cc",
         "selection_model.cc",
@@ -597,6 +578,7 @@
     "//base/test:test_support",
     "//skia",
     "//testing/gtest",
+    "//ui/gfx/animation",
     "//ui/gfx/geometry",
   ]
 
@@ -710,6 +692,7 @@
     "//third_party/libpng",
     "//third_party/zlib",
     "//ui/base",
+    "//ui/gfx/animation",
     "//ui/gfx/geometry",
     "//ui/gfx/range",
     "//ui/resources:ui_test_pak",
diff --git a/ui/gfx/animation/BUILD.gn b/ui/gfx/animation/BUILD.gn
new file mode 100644
index 0000000..d561028d
--- /dev/null
+++ b/ui/gfx/animation/BUILD.gn
@@ -0,0 +1,63 @@
+# Copyright 2017 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//build/config/ui.gni")
+
+if (is_android) {
+  import("//build/config/android/config.gni")
+  import("//build/config/android/rules.gni")
+}
+
+component("animation") {
+  sources = [
+    "animation.cc",
+    "animation.h",
+    "animation_container.cc",
+    "animation_container.h",
+    "animation_container_element.h",
+    "animation_container_observer.h",
+    "animation_delegate.h",
+    "animation_export.h",
+    "animation_mac.mm",
+    "animation_win.cc",
+    "linear_animation.cc",
+    "linear_animation.h",
+    "multi_animation.cc",
+    "multi_animation.h",
+    "slide_animation.cc",
+    "slide_animation.h",
+    "throb_animation.cc",
+    "throb_animation.h",
+    "tween.cc",
+    "tween.h",
+  ]
+
+  if (is_android) {
+    if (!use_aura) {
+      sources -= [
+        "throb_animation.cc",
+        "throb_animation.h",
+      ]
+    }
+  }
+
+  if (is_mac) {
+    libs = [
+      "AppKit.framework",
+      "CoreFoundation.framework",
+      "CoreGraphics.framework",
+      "CoreText.framework",
+      "IOSurface.framework",
+    ]
+  }
+
+  deps = [
+    "//base",
+    "//skia",
+    "//ui/gfx:geometry_skia",
+    "//ui/gfx:gfx_export",
+    "//ui/gfx/geometry",
+  ]
+  defines = [ "ANIMATION_IMPLEMENTATION" ]
+}
diff --git a/ui/gfx/animation/animation.h b/ui/gfx/animation/animation.h
index 8d8b4d03..e26bb21 100644
--- a/ui/gfx/animation/animation.h
+++ b/ui/gfx/animation/animation.h
@@ -26,7 +26,7 @@
 //
 // To subclass override Step, which is invoked as the animation progresses and
 // GetCurrentValue() to return the value appropriate to the animation.
-class GFX_EXPORT Animation : public AnimationContainerElement {
+class ANIMATION_EXPORT Animation : public AnimationContainerElement {
  public:
   explicit Animation(base::TimeDelta timer_interval);
   ~Animation() override;
diff --git a/ui/gfx/animation/animation_container.h b/ui/gfx/animation/animation_container.h
index 45977387..a19c053 100644
--- a/ui/gfx/animation/animation_container.h
+++ b/ui/gfx/animation/animation_container.h
@@ -11,7 +11,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/time/time.h"
 #include "base/timer/timer.h"
-#include "ui/gfx/gfx_export.h"
+#include "ui/gfx/animation/animation_export.h"
 
 namespace gfx {
 
@@ -26,7 +26,7 @@
 //
 // AnimationContainer is ref counted. Each Animation contained within the
 // AnimationContainer own it.
-class GFX_EXPORT AnimationContainer
+class ANIMATION_EXPORT AnimationContainer
     : public base::RefCounted<AnimationContainer> {
  public:
   AnimationContainer();
diff --git a/ui/gfx/animation/animation_container_element.h b/ui/gfx/animation/animation_container_element.h
index 224655e..6e39ef4 100644
--- a/ui/gfx/animation/animation_container_element.h
+++ b/ui/gfx/animation/animation_container_element.h
@@ -6,13 +6,13 @@
 #define UI_GFX_ANIMATION_ANIMATION_CONTAINER_ELEMENT_H_
 
 #include "base/time/time.h"
-#include "ui/gfx/gfx_export.h"
+#include "ui/gfx/animation/animation_export.h"
 
 namespace gfx {
 
 // Interface for the elements the AnimationContainer contains. This is
 // implemented by Animation.
-class GFX_EXPORT AnimationContainerElement {
+class ANIMATION_EXPORT AnimationContainerElement {
  public:
   // Sets the start of the animation. This is invoked from
   // AnimationContainer::Start.
diff --git a/ui/gfx/animation/animation_container_observer.h b/ui/gfx/animation/animation_container_observer.h
index a505167..169ed041 100644
--- a/ui/gfx/animation/animation_container_observer.h
+++ b/ui/gfx/animation/animation_container_observer.h
@@ -5,7 +5,7 @@
 #ifndef UI_GFX_ANIMATION_ANIMATION_CONTAINER_OBSERVER_H_
 #define UI_GFX_ANIMATION_ANIMATION_CONTAINER_OBSERVER_H_
 
-#include "ui/gfx/gfx_export.h"
+#include "ui/gfx/animation/animation_export.h"
 
 namespace gfx {
 
@@ -13,7 +13,7 @@
 
 // The observer is notified after every update of the animations managed by
 // the container.
-class GFX_EXPORT AnimationContainerObserver {
+class ANIMATION_EXPORT AnimationContainerObserver {
  public:
   // Invoked on every tick of the timer managed by the container and after
   // all the animations have updated.
diff --git a/ui/gfx/animation/animation_delegate.h b/ui/gfx/animation/animation_delegate.h
index b1e88d2..5ac2fd4 100644
--- a/ui/gfx/animation/animation_delegate.h
+++ b/ui/gfx/animation/animation_delegate.h
@@ -5,7 +5,7 @@
 #ifndef UI_GFX_ANIMATION_ANIMATION_DELEGATE_H_
 #define UI_GFX_ANIMATION_ANIMATION_DELEGATE_H_
 
-#include "ui/gfx/gfx_export.h"
+#include "ui/gfx/animation/animation_export.h"
 
 namespace gfx {
 
@@ -15,7 +15,7 @@
 //
 //  Implement this interface when you want to receive notifications about the
 //  state of an animation.
-class GFX_EXPORT AnimationDelegate {
+class ANIMATION_EXPORT AnimationDelegate {
  public:
   virtual ~AnimationDelegate() {}
 
diff --git a/ui/gfx/animation/animation_export.h b/ui/gfx/animation/animation_export.h
new file mode 100644
index 0000000..0b03b1b
--- /dev/null
+++ b/ui/gfx/animation/animation_export.h
@@ -0,0 +1,29 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_GFX_ANIMATION_ANIMATION_EXPORT_H_
+#define UI_GFX_ANIMATION_ANIMATION_EXPORT_H_
+
+#if defined(COMPONENT_BUILD)
+#if defined(WIN32)
+
+#if defined(ANIMATION_IMPLEMENTATION)
+#define ANIMATION_EXPORT __declspec(dllexport)
+#else
+#define ANIMATION_EXPORT __declspec(dllimport)
+#endif  // defined(ANIMATION_IMPLEMENTATION)
+
+#else  // defined(WIN32)
+#if defined(ANIMATION_IMPLEMENTATION)
+#define ANIMATION_EXPORT __attribute__((visibility("default")))
+#else
+#define ANIMATION_EXPORT
+#endif
+#endif
+
+#else  // defined(COMPONENT_BUILD)
+#define ANIMATION_EXPORT
+#endif
+
+#endif  // UI_GFX_ANIMATION_ANIMATION_EXPORT_H_
diff --git a/ui/gfx/animation/linear_animation.h b/ui/gfx/animation/linear_animation.h
index cd4c3a2..17b10a5 100644
--- a/ui/gfx/animation/linear_animation.h
+++ b/ui/gfx/animation/linear_animation.h
@@ -15,7 +15,7 @@
 
 // Linear time bounded animation. As the animation progresses AnimateToState is
 // invoked.
-class GFX_EXPORT LinearAnimation : public Animation {
+class ANIMATION_EXPORT LinearAnimation : public Animation {
  public:
   // Default frame rate (hz).
   static const int kDefaultFrameRate = 60;
diff --git a/ui/gfx/animation/multi_animation.h b/ui/gfx/animation/multi_animation.h
index a74656989..65e80247 100644
--- a/ui/gfx/animation/multi_animation.h
+++ b/ui/gfx/animation/multi_animation.h
@@ -19,7 +19,7 @@
 // To create a MultiAnimation pass in the parts, invoke Start() and the delegate
 // is notified as the animation progresses. By default MultiAnimation runs until
 // Stop is invoked, see |set_continuous()| for details.
-class GFX_EXPORT MultiAnimation : public Animation {
+class ANIMATION_EXPORT MultiAnimation : public Animation {
  public:
   // Defines part of the animation. Each part consists of the following:
   //
diff --git a/ui/gfx/animation/slide_animation.h b/ui/gfx/animation/slide_animation.h
index 02ebda7c..de17b95c 100644
--- a/ui/gfx/animation/slide_animation.h
+++ b/ui/gfx/animation/slide_animation.h
@@ -45,7 +45,7 @@
 //  private:
 //   std::unique_ptr<SlideAnimation> animation_;
 // }
-class GFX_EXPORT SlideAnimation : public LinearAnimation {
+class ANIMATION_EXPORT SlideAnimation : public LinearAnimation {
  public:
   explicit SlideAnimation(AnimationDelegate* target);
   ~SlideAnimation() override;
diff --git a/ui/gfx/animation/throb_animation.h b/ui/gfx/animation/throb_animation.h
index 1eaedd1..7226382 100644
--- a/ui/gfx/animation/throb_animation.h
+++ b/ui/gfx/animation/throb_animation.h
@@ -17,7 +17,7 @@
 //
 // A ThrobAnimation has two durations: the duration used when behavior like
 // a SlideAnimation, and the duration used when throbbing.
-class GFX_EXPORT ThrobAnimation : public SlideAnimation {
+class ANIMATION_EXPORT ThrobAnimation : public SlideAnimation {
  public:
   explicit ThrobAnimation(AnimationDelegate* target);
   ~ThrobAnimation() override {}
diff --git a/ui/gfx/animation/tween.h b/ui/gfx/animation/tween.h
index 0b2a2d40..dbc506e03 100644
--- a/ui/gfx/animation/tween.h
+++ b/ui/gfx/animation/tween.h
@@ -7,8 +7,8 @@
 
 #include "base/macros.h"
 #include "third_party/skia/include/core/SkColor.h"
+#include "ui/gfx/animation/animation_export.h"
 #include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/gfx_export.h"
 #include "ui/gfx/transform.h"
 
 namespace base {
@@ -17,7 +17,7 @@
 
 namespace gfx {
 
-class GFX_EXPORT Tween {
+class ANIMATION_EXPORT Tween {
  public:
   enum Type {
     LINEAR,             // Linear.
diff --git a/ui/views/BUILD.gn b/ui/views/BUILD.gn
index 6d7003e..4729d36 100644
--- a/ui/views/BUILD.gn
+++ b/ui/views/BUILD.gn
@@ -449,6 +449,7 @@
     "//ui/events:events_base",
     "//ui/events/platform",
     "//ui/gfx",
+    "//ui/gfx/animation",
     "//ui/gfx/geometry",
     "//ui/vector_icons",
     "//ui/views/resources",
diff --git a/ui/views/mus/BUILD.gn b/ui/views/mus/BUILD.gn
index c568ec3..e72f23d 100644
--- a/ui/views/mus/BUILD.gn
+++ b/ui/views/mus/BUILD.gn
@@ -48,8 +48,6 @@
     "//base/third_party/dynamic_annotations",
     "//cc",
     "//cc/surfaces",
-    "//components/discardable_memory/client",
-    "//components/discardable_memory/public/interfaces",
     "//mojo/common",
     "//mojo/public/cpp/bindings",
     "//net",
diff --git a/ui/views/mus/DEPS b/ui/views/mus/DEPS
index d1b837d..4d8a1fd 100644
--- a/ui/views/mus/DEPS
+++ b/ui/views/mus/DEPS
@@ -1,7 +1,6 @@
 include_rules = [
   "+cc",
   "-cc/blink",
-  "+components/discardable_memory/client",
   "+components/font_service/public",
   "+components/gpu",
   "+mojo/cc",
diff --git a/ui/views/mus/mus_client.cc b/ui/views/mus/mus_client.cc
index da055be..41401ad 100644
--- a/ui/views/mus/mus_client.cc
+++ b/ui/views/mus/mus_client.cc
@@ -7,7 +7,6 @@
 #include "base/bind.h"
 #include "base/memory/ptr_util.h"
 #include "base/threading/thread.h"
-#include "components/discardable_memory/client/client_discardable_shared_memory_manager.h"
 #include "services/service_manager/public/cpp/connection.h"
 #include "services/service_manager/public/cpp/connector.h"
 #include "services/ui/public/cpp/gpu/gpu.h"
@@ -86,15 +85,6 @@
   if (create_wm_state)
     wm_state_ = base::MakeUnique<wm::WMState>();
 
-  discardable_memory::mojom::DiscardableSharedMemoryManagerPtr manager_ptr;
-  connector->BindInterface(ui::mojom::kServiceName, &manager_ptr);
-
-  discardable_shared_memory_manager_ = base::MakeUnique<
-      discardable_memory::ClientDiscardableSharedMemoryManager>(
-      std::move(manager_ptr), io_task_runner);
-  base::DiscardableMemoryAllocator::SetInstance(
-      discardable_shared_memory_manager_.get());
-
   window_tree_client_ = base::MakeUnique<aura::WindowTreeClient>(
       connector, this, nullptr /* window_manager_delegate */,
       nullptr /* window_tree_client_request */, std::move(io_task_runner));
@@ -131,7 +121,6 @@
         ViewsDelegate::DesktopWindowTreeHostFactory());
   }
 
-  base::DiscardableMemoryAllocator::SetInstance(nullptr);
   DCHECK_EQ(instance_, this);
   instance_ = nullptr;
   DCHECK(aura::Env::GetInstance());
diff --git a/ui/views/mus/mus_client.h b/ui/views/mus/mus_client.h
index 781edb57..42e1ac5 100644
--- a/ui/views/mus/mus_client.h
+++ b/ui/views/mus/mus_client.h
@@ -30,10 +30,6 @@
 class Thread;
 }
 
-namespace discardable_memory {
-class ClientDiscardableSharedMemoryManager;
-}
-
 namespace service_manager {
 class Connector;
 }
@@ -161,9 +157,6 @@
 
   std::unique_ptr<PointerWatcherEventRouter> pointer_watcher_event_router_;
 
-  std::unique_ptr<discardable_memory::ClientDiscardableSharedMemoryManager>
-      discardable_shared_memory_manager_;
-
   DISALLOW_COPY_AND_ASSIGN(MusClient);
 };
 
diff --git a/ui/wm/BUILD.gn b/ui/wm/BUILD.gn
index 1fb7cf1..f0a07f1 100644
--- a/ui/wm/BUILD.gn
+++ b/ui/wm/BUILD.gn
@@ -79,6 +79,7 @@
     "//ui/events/devices",
     "//ui/events/platform",
     "//ui/gfx",
+    "//ui/gfx/animation",
     "//ui/gfx/geometry",
     "//ui/resources",
   ]
@@ -142,6 +143,7 @@
     "//ui/events:test_support",
     "//ui/events/platform",
     "//ui/gfx",
+    "//ui/gfx/animation",
     "//ui/gfx/geometry",
     "//ui/gl:test_support",
     "//ui/resources",