diff --git a/DEPS b/DEPS
index 64d1b25..9aa62496 100644
--- a/DEPS
+++ b/DEPS
@@ -44,7 +44,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'v8_revision': '041e67fe01d8be05dd9d56514dd2b88be273ef21',
+  'v8_revision': 'b7b57175c330acb8abeda6061eb172f43ed252f4',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling swarming_client
   # and whatever else without interference from each other.
@@ -151,7 +151,7 @@
     Var('chromium_git') + '/external/colorama.git' + '@' + '799604a1041e9b3bc5d2789ecbd7e8db2e18e6b8',
 
   'src/third_party/googletest/src':
-    Var('chromium_git') + '/external/github.com/google/googletest.git' + '@' + '43359642a1c16ad3f4fc575c7edd0cb935810815',
+    Var('chromium_git') + '/external/github.com/google/googletest.git' + '@' + '8c7f93fedaca1b0158e67af0f5dd63a044066eab',
 
   'src/third_party/icu':
     Var('chromium_git') + '/chromium/deps/icu.git' + '@' + '4b06aadd0556135d3a90a4eb03eca24ef249e03e',
diff --git a/ash/resources/vector_icons/BUILD.gn b/ash/resources/vector_icons/BUILD.gn
index 1e57c91da..fc21c9b 100644
--- a/ash/resources/vector_icons/BUILD.gn
+++ b/ash/resources/vector_icons/BUILD.gn
@@ -246,11 +246,11 @@
 
 source_set("vector_icons") {
   sources = get_target_outputs(":ash_vector_icons")
-  sources += [ "//ui/gfx/vector_icon_types.h" ]
 
   deps = [
     ":ash_vector_icons",
     "//base",
     "//skia",
+    "//ui/gfx",
   ]
 }
diff --git a/base/profiler/native_stack_sampler.cc b/base/profiler/native_stack_sampler.cc
index 968455f1..b78d725 100644
--- a/base/profiler/native_stack_sampler.cc
+++ b/base/profiler/native_stack_sampler.cc
@@ -4,12 +4,29 @@
 
 #include "base/profiler/native_stack_sampler.h"
 
+#include "base/memory/ptr_util.h"
+
 namespace base {
 
+NativeStackSampler::StackBuffer::StackBuffer(size_t buffer_size)
+    : buffer_(new uintptr_t[(buffer_size + sizeof(uintptr_t) - 1) /
+                            sizeof(uintptr_t)]),
+      size_(buffer_size) {}
+
+NativeStackSampler::StackBuffer::~StackBuffer() {}
+
 NativeStackSampler::NativeStackSampler() {}
 
 NativeStackSampler::~NativeStackSampler() {}
 
+std::unique_ptr<NativeStackSampler::StackBuffer>
+NativeStackSampler::CreateStackBuffer() {
+  size_t size = GetStackBufferSize();
+  if (size == 0)
+    return nullptr;
+  return MakeUnique<StackBuffer>(size);
+}
+
 NativeStackSamplerTestDelegate::~NativeStackSamplerTestDelegate() {}
 
 NativeStackSamplerTestDelegate::NativeStackSamplerTestDelegate() {}
diff --git a/base/profiler/native_stack_sampler.h b/base/profiler/native_stack_sampler.h
index 8d7e441b..ebd7c3c4 100644
--- a/base/profiler/native_stack_sampler.h
+++ b/base/profiler/native_stack_sampler.h
@@ -21,6 +21,26 @@
 // given thread.
 class NativeStackSampler {
  public:
+  // This class contains a buffer for stack copies that can be shared across
+  // multiple instances of NativeStackSampler.
+  class StackBuffer {
+   public:
+    StackBuffer(size_t buffer_size);
+    ~StackBuffer();
+
+    void* buffer() const { return buffer_.get(); }
+    size_t size() const { return size_; }
+
+   private:
+    // The word-aligned buffer.
+    const std::unique_ptr<uintptr_t[]> buffer_;
+
+    // The size of the buffer.
+    const size_t size_;
+
+    DISALLOW_COPY_AND_ASSIGN(StackBuffer);
+  };
+
   // The callback type used to add annotations to a sample during collection.
   // This is passed to the native sampler to be applied at the most appropriate
   // time. It is a simple function-pointer because the generated code must be
@@ -39,6 +59,13 @@
       AnnotateCallback annotator,
       NativeStackSamplerTestDelegate* test_delegate);
 
+  // Gets the required size of the stack buffer.
+  static size_t GetStackBufferSize();
+
+  // Creates an instance of the a stack buffer that can be used for calls to
+  // any NativeStackSampler object.
+  static std::unique_ptr<StackBuffer> CreateStackBuffer();
+
   // The following functions are all called on the SamplingThread (not the
   // thread being sampled).
 
@@ -48,11 +75,12 @@
       std::vector<StackSamplingProfiler::Module>* modules) = 0;
 
   // Records a stack sample to |sample|.
-  virtual void RecordStackSample(StackSamplingProfiler::Sample* sample) = 0;
+  virtual void RecordStackSample(StackBuffer* stackbuffer,
+                                 StackSamplingProfiler::Sample* sample) = 0;
 
   // Notifies the sampler that we've stopped recording the current
   // profile.
-  virtual void ProfileRecordingStopped() = 0;
+  virtual void ProfileRecordingStopped(StackBuffer* stackbuffer) = 0;
 
  protected:
   NativeStackSampler();
diff --git a/base/profiler/native_stack_sampler_mac.cc b/base/profiler/native_stack_sampler_mac.cc
index dcaaa6f..5a51f26 100644
--- a/base/profiler/native_stack_sampler_mac.cc
+++ b/base/profiler/native_stack_sampler_mac.cc
@@ -29,27 +29,6 @@
 
 namespace {
 
-// Miscellaneous --------------------------------------------------------------
-
-size_t StackCopyBufferSize() {
-  static size_t stack_size = 0;
-  if (stack_size)
-    return stack_size;
-
-  // In platform_thread_mac's GetDefaultThreadStackSize(), RLIMIT_STACK is used
-  // for all stacks, not just the main thread's, so it is good for use here.
-  struct rlimit stack_rlimit;
-  if (getrlimit(RLIMIT_STACK, &stack_rlimit) == 0 &&
-      stack_rlimit.rlim_cur != RLIM_INFINITY) {
-    stack_size = stack_rlimit.rlim_cur;
-    return stack_size;
-  }
-
-  // If getrlimit somehow fails, return the default macOS main thread stack size
-  // of 8 MB (DFLSSIZ in <i386/vmparam.h>) with extra wiggle room.
-  return 12 * 1024 * 1024;
-}
-
 // Stack walking --------------------------------------------------------------
 
 // Fills |state| with |target_thread|'s context.
@@ -323,13 +302,15 @@
   // StackSamplingProfiler::NativeStackSampler:
   void ProfileRecordingStarting(
       std::vector<StackSamplingProfiler::Module>* modules) override;
-  void RecordStackSample(StackSamplingProfiler::Sample* sample) override;
-  void ProfileRecordingStopped() override;
+  void RecordStackSample(StackBuffer* stack_buffer,
+                         StackSamplingProfiler::Sample* sample) override;
+  void ProfileRecordingStopped(StackBuffer* stack_buffer) override;
 
  private:
   // Suspends the thread with |thread_port_|, copies its stack and resumes the
   // thread, then records the stack frames and associated modules into |sample|.
-  void SuspendThreadAndRecordStack(StackSamplingProfiler::Sample* sample);
+  void SuspendThreadAndRecordStack(StackBuffer* stack_buffer,
+                                   StackSamplingProfiler::Sample* sample);
 
   // Weak reference: Mach port for thread being profiled.
   mach_port_t thread_port_;
@@ -341,13 +322,6 @@
   // The stack base address corresponding to |thread_handle_|.
   const void* const thread_stack_base_address_;
 
-  // The size of the |stack_copy_buffer_|.
-  const size_t stack_copy_buffer_size_;
-
-  // Buffer to use for copies of the stack. We use the same buffer for all the
-  // samples to avoid the overhead of multiple allocations and frees.
-  const std::unique_ptr<unsigned char[]> stack_copy_buffer_;
-
   // Weak. Points to the modules associated with the profile being recorded
   // between ProfileRecordingStarting() and ProfileRecordingStopped().
   std::vector<StackSamplingProfiler::Module>* current_modules_ = nullptr;
@@ -367,9 +341,7 @@
       annotator_(annotator),
       test_delegate_(test_delegate),
       thread_stack_base_address_(
-          pthread_get_stackaddr_np(pthread_from_mach_thread_np(thread_port))),
-      stack_copy_buffer_size_(StackCopyBufferSize()),
-      stack_copy_buffer_(new unsigned char[stack_copy_buffer_size_]) {
+          pthread_get_stackaddr_np(pthread_from_mach_thread_np(thread_port))) {
   DCHECK(annotator_);
 
   // This class suspends threads, and those threads might be suspended in dyld.
@@ -389,17 +361,19 @@
 }
 
 void NativeStackSamplerMac::RecordStackSample(
+    StackBuffer* stack_buffer,
     StackSamplingProfiler::Sample* sample) {
   DCHECK(current_modules_);
 
-  SuspendThreadAndRecordStack(sample);
+  SuspendThreadAndRecordStack(stack_buffer, sample);
 }
 
-void NativeStackSamplerMac::ProfileRecordingStopped() {
+void NativeStackSamplerMac::ProfileRecordingStopped(StackBuffer* stack_buffer) {
   current_modules_ = nullptr;
 }
 
 void NativeStackSamplerMac::SuspendThreadAndRecordStack(
+    StackBuffer* stack_buffer,
     StackSamplingProfiler::Sample* sample) {
   x86_thread_state64_t thread_state;
 
@@ -424,18 +398,18 @@
       return;
     uintptr_t stack_size = stack_top - stack_bottom;
 
-    if (stack_size > stack_copy_buffer_size_)
+    if (stack_size > stack_buffer->size())
       return;
 
     (*annotator_)(sample);
 
     CopyStackAndRewritePointers(
-        reinterpret_cast<uintptr_t*>(stack_copy_buffer_.get()),
+        reinterpret_cast<uintptr_t*>(stack_buffer->buffer()),
         reinterpret_cast<uintptr_t*>(stack_bottom),
         reinterpret_cast<uintptr_t*>(stack_top), &thread_state);
 
     new_stack_top =
-        reinterpret_cast<uintptr_t>(stack_copy_buffer_.get()) + stack_size;
+        reinterpret_cast<uintptr_t>(stack_buffer->buffer()) + stack_size;
   }  // ScopedSuspendThread
 
   if (test_delegate_)
@@ -468,4 +442,18 @@
                                                  test_delegate);
 }
 
+size_t NativeStackSampler::GetStackBufferSize() {
+  // In platform_thread_mac's GetDefaultThreadStackSize(), RLIMIT_STACK is used
+  // for all stacks, not just the main thread's, so it is good for use here.
+  struct rlimit stack_rlimit;
+  if (getrlimit(RLIMIT_STACK, &stack_rlimit) == 0 &&
+      stack_rlimit.rlim_cur != RLIM_INFINITY) {
+    return stack_rlimit.rlim_cur;
+  }
+
+  // If getrlimit somehow fails, return the default macOS main thread stack size
+  // of 8 MB (DFLSSIZ in <i386/vmparam.h>) with extra wiggle room.
+  return 12 * 1024 * 1024;
+}
+
 }  // namespace base
diff --git a/base/profiler/native_stack_sampler_posix.cc b/base/profiler/native_stack_sampler_posix.cc
index 54abb2e3..1055d44 100644
--- a/base/profiler/native_stack_sampler_posix.cc
+++ b/base/profiler/native_stack_sampler_posix.cc
@@ -13,4 +13,8 @@
   return std::unique_ptr<NativeStackSampler>();
 }
 
+size_t NativeStackSampler::GetStackBufferSize() {
+  return 0;
+}
+
 }  // namespace base
diff --git a/base/profiler/native_stack_sampler_win.cc b/base/profiler/native_stack_sampler_win.cc
index d320fea9..480e29c3 100644
--- a/base/profiler/native_stack_sampler_win.cc
+++ b/base/profiler/native_stack_sampler_win.cc
@@ -18,6 +18,7 @@
 #include "base/lazy_instance.h"
 #include "base/logging.h"
 #include "base/macros.h"
+#include "base/memory/ptr_util.h"
 #include "base/profiler/win32_stack_frame_unwinder.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
@@ -394,17 +395,11 @@
   // StackSamplingProfiler::NativeStackSampler:
   void ProfileRecordingStarting(
       std::vector<StackSamplingProfiler::Module>* modules) override;
-  void RecordStackSample(StackSamplingProfiler::Sample* sample) override;
-  void ProfileRecordingStopped() override;
+  void RecordStackSample(StackBuffer* stack_buffer,
+                         StackSamplingProfiler::Sample* sample) override;
+  void ProfileRecordingStopped(StackBuffer* stack_buffer) override;
 
  private:
-  // Intended to hold the largest stack used by Chrome. The default Win32
-  // reserved stack size is 1 MB and Chrome Windows threads currently always
-  // use the default, but this allows for expansion if it occurs. The size
-  // beyond the actual stack size consists of unallocated virtual memory pages
-  // so carries little cost (just a bit of wasted address space).
-  static constexpr size_t kStackCopyBufferSize = 2 * 1024 * 1024;
-
   // Attempts to query the module filename, base address, and id for
   // |module_handle|, and store them in |module|. Returns true if it succeeded.
   static bool GetModuleForHandle(HMODULE module_handle,
@@ -431,10 +426,6 @@
   // The stack base address corresponding to |thread_handle_|.
   const void* const thread_stack_base_address_;
 
-  // Buffer to use for copies of the stack. We use the same buffer for all the
-  // samples to avoid the overhead of multiple allocations and frees.
-  const std::unique_ptr<unsigned char[]> stack_copy_buffer_;
-
   // Weak. Points to the modules associated with the profile being recorded
   // between ProfileRecordingStarting() and ProfileRecordingStopped().
   std::vector<StackSamplingProfiler::Module>* current_modules_;
@@ -454,8 +445,7 @@
       annotator_(annotator),
       test_delegate_(test_delegate),
       thread_stack_base_address_(
-          GetThreadEnvironmentBlock(thread_handle_.Get())->Tib.StackBase),
-      stack_copy_buffer_(new unsigned char[kStackCopyBufferSize]) {
+          GetThreadEnvironmentBlock(thread_handle_.Get())->Tib.StackBase) {
   DCHECK(annotator_);
 }
 
@@ -469,17 +459,19 @@
 }
 
 void NativeStackSamplerWin::RecordStackSample(
+    StackBuffer* stack_buffer,
     StackSamplingProfiler::Sample* sample) {
+  DCHECK(stack_buffer);
   DCHECK(current_modules_);
 
   std::vector<RecordedFrame> stack;
   SuspendThreadAndRecordStack(thread_handle_.Get(), thread_stack_base_address_,
-                              stack_copy_buffer_.get(), kStackCopyBufferSize,
+                              stack_buffer->buffer(), stack_buffer->size(),
                               &stack, annotator_, sample, test_delegate_);
   CopyToSample(stack, sample, current_modules_);
 }
 
-void NativeStackSamplerWin::ProfileRecordingStopped() {
+void NativeStackSamplerWin::ProfileRecordingStopped(StackBuffer* stack_buffer) {
   current_modules_ = nullptr;
 }
 
@@ -558,4 +550,13 @@
   return std::unique_ptr<NativeStackSampler>();
 }
 
+size_t NativeStackSampler::GetStackBufferSize() {
+  // The default Win32 reserved stack size is 1 MB and Chrome Windows threads
+  // currently always use the default, but this allows for expansion if it
+  // occurs. The size beyond the actual stack size consists of unallocated
+  // virtual memory pages so carries little cost (just a bit of wasted address
+  // space).
+  return 2 << 20;  // 2 MiB
+}
+
 }  // namespace base
diff --git a/base/profiler/stack_sampling_profiler.cc b/base/profiler/stack_sampling_profiler.cc
index 0263a9f..76ad81df 100644
--- a/base/profiler/stack_sampling_profiler.cc
+++ b/base/profiler/stack_sampling_profiler.cc
@@ -250,6 +250,11 @@
   // Thread:
   void CleanUp() override;
 
+  // A stack-buffer used by the native sampler for its work. This buffer can
+  // be re-used for multiple native sampler objects so long as the API calls
+  // that take it are not called concurrently.
+  std::unique_ptr<NativeStackSampler::StackBuffer> stack_buffer_;
+
   // A map of IDs to collection contexts. Because this class is a singleton
   // that is never destroyed, context objects will never be destructed except
   // by explicit action. Thus, it's acceptable to pass unretained pointers
@@ -421,6 +426,9 @@
     Stop();
   }
 
+  DCHECK(!stack_buffer_);
+  stack_buffer_ = NativeStackSampler::CreateStackBuffer();
+
   // The thread is not running. Start it and get associated runner. The task-
   // runner has to be saved for future use because though it can be used from
   // any thread, it can be acquired via task_runner() only on the created
@@ -517,12 +525,13 @@
 
   // Record a single sample.
   profile.samples.push_back(Sample());
-  collection->native_sampler->RecordStackSample(&profile.samples.back());
+  collection->native_sampler->RecordStackSample(stack_buffer_.get(),
+                                                &profile.samples.back());
 
   // If this is the last sample of a burst, record the total time.
   if (collection->sample == collection->params.samples_per_burst - 1) {
     profile.profile_duration = Time::Now() - collection->profile_start_time;
-    collection->native_sampler->ProfileRecordingStopped();
+    collection->native_sampler->ProfileRecordingStopped(stack_buffer_.get());
   }
 }
 
@@ -647,6 +656,7 @@
   // confusion.
   thread_execution_state_ = EXITING;
   thread_execution_state_task_runner_ = nullptr;
+  stack_buffer_.reset();
 }
 
 bool StackSamplingProfiler::SamplingThread::UpdateNextSampleTime(
diff --git a/build/vs_toolchain.py b/build/vs_toolchain.py
index 1004d9e..0ff5181 100755
--- a/build/vs_toolchain.py
+++ b/build/vs_toolchain.py
@@ -8,6 +8,7 @@
 import os
 import pipes
 import platform
+import re
 import shutil
 import stat
 import subprocess
@@ -51,8 +52,8 @@
       win_sdk = toolchain_data['win8sdk']
     wdk = toolchain_data['wdk']
     # TODO(scottmg): The order unfortunately matters in these. They should be
-    # split into separate keys for x86 and x64. (See CopyVsRuntimeDlls call
-    # below). http://crbug.com/345992
+    # split into separate keys for x86 and x64. (See CopyDlls call below).
+    # http://crbug.com/345992
     vs_runtime_dll_dirs = toolchain_data['runtime_dirs']
 
     os.environ['GYP_MSVS_OVERRIDE_PATH'] = toolchain
@@ -170,17 +171,6 @@
                    ' not found.') % (version_as_year))
 
 
-def _VersionNumber():
-  """Gets the standard version number ('120', '140', etc.) based on
-  GYP_MSVS_VERSION."""
-  vs_version = GetVisualStudioVersion()
-  if vs_version == '2015':
-    return '140'
-  if vs_version == '2017':
-    return '150'
-  raise ValueError('Unexpected GYP_MSVS_VERSION')
-
-
 def _CopyRuntimeImpl(target, source, verbose=True):
   """Copy |source| to |target| if it doesn't already exist or if it needs to be
   updated (comparing last modified time as an approximate float match as for
@@ -228,6 +218,55 @@
                     os.path.join(source_dir, 'ucrtbase' + suffix))
 
 
+def _CopyPGORuntime(target_dir, target_cpu):
+  """Copy the runtime dependencies required during a PGO build.
+  """
+  env_version = GetVisualStudioVersion()
+  # These dependencies will be in a different location depending on the version
+  # of the toolchain.
+  if env_version == '2015':
+    pgo_x86_runtime_dir = os.path.join(os.environ.get('GYP_MSVS_OVERRIDE_PATH'),
+                                       'VC', 'bin')
+    pgo_x64_runtime_dir = os.path.join(pgo_x86_runtime_dir, 'amd64')
+  elif env_version == '2017':
+    # In VS2017 the PGO runtime dependencies are located in
+    # {toolchain_root}/VC/Tools/MSVC/{x.y.z}/bin/Host{target_cpu}/{target_cpu}/,
+    # the {version_number} part is likely to change in case of a minor update of
+    # the toolchain so we don't hardcode this value here (except for the major
+    # number).
+    vc_tools_msvc_root = os.path.join(os.environ.get('GYP_MSVS_OVERRIDE_PATH'),
+        'VC', 'Tools', 'MSVC')
+    pgo_runtime_root = None
+    for directory in os.listdir(vc_tools_msvc_root):
+      if not os.path.isdir(os.path.join(vc_tools_msvc_root, directory)):
+        continue
+      if re.match('14\.\d+\.\d+', directory):
+        pgo_runtime_root = os.path.join(vc_tools_msvc_root, directory, 'bin')
+        break
+    assert pgo_runtime_root
+    # There's no version of pgosweep.exe in HostX64/x86, so we use the copy
+    # from HostX86/x86.
+    pgo_x86_runtime_dir = os.path.join(pgo_runtime_root, 'HostX86', 'x86')
+    pgo_x64_runtime_dir = os.path.join(pgo_runtime_root, 'HostX64', 'x64')
+  else:
+    raise Exception('Unexpected toolchain version: %s.' % env_version)
+
+  # We need to copy 2 runtime dependencies used during the profiling step:
+  #     - pgort140.dll: runtime library required to run the instrumented image.
+  #     - pgosweep.exe: executable used to collect the profiling data
+  pgo_runtimes = ['pgort140.dll', 'pgosweep.exe']
+  for runtime in pgo_runtimes:
+    if target_cpu == 'x86':
+      source = os.path.join(pgo_x86_runtime_dir, runtime)
+    elif target_cpu == 'x64':
+      source = os.path.join(pgo_x64_runtime_dir, runtime)
+    else:
+      raise NotImplementedError("Unexpected target_cpu value: " + target_cpu)
+    if not os.path.exists(source):
+      raise Exception('Unable to find %s.' % source)
+    _CopyRuntimeImpl(os.path.join(target_dir, runtime), source)
+
+
 def _CopyRuntime(target_dir, source_dir, target_cpu, debug):
   """Copy the VS runtime DLLs, only if the target doesn't exist, but the target
   directory does exist. Handles VS 2015 and VS 2017."""
@@ -236,54 +275,6 @@
   _CopyUCRTRuntime(target_dir, source_dir, target_cpu, '%s140' + suffix,
                     suffix)
 
-  # Copy the PGO runtime library to the release directories.
-  if not debug and os.environ.get('GYP_MSVS_OVERRIDE_PATH'):
-    pgo_x86_runtime_dir = os.path.join(os.environ.get('GYP_MSVS_OVERRIDE_PATH'),
-                                        'VC', 'bin')
-    pgo_x64_runtime_dir = os.path.join(pgo_x86_runtime_dir, 'amd64')
-    pgo_runtime_dll = 'pgort' + _VersionNumber() + '.dll'
-    if target_cpu == "x86":
-      source_x86 = os.path.join(pgo_x86_runtime_dir, pgo_runtime_dll)
-      if os.path.exists(source_x86):
-        _CopyRuntimeImpl(os.path.join(target_dir, pgo_runtime_dll), source_x86)
-    elif target_cpu == "x64":
-      source_x64 = os.path.join(pgo_x64_runtime_dir, pgo_runtime_dll)
-      if os.path.exists(source_x64):
-        _CopyRuntimeImpl(os.path.join(target_dir, pgo_runtime_dll),
-                          source_x64)
-    else:
-      raise NotImplementedError("Unexpected target_cpu value:" + target_cpu)
-
-
-def CopyVsRuntimeDlls(output_dir, runtime_dirs):
-  """Copies the VS runtime DLLs from the given |runtime_dirs| to the output
-  directory so that even if not system-installed, built binaries are likely to
-  be able to run.
-
-  This needs to be run after gyp has been run so that the expected target
-  output directories are already created.
-
-  This is used for the GYP build and gclient runhooks.
-  """
-  x86, x64 = runtime_dirs
-  out_debug = os.path.join(output_dir, 'Debug')
-  out_debug_nacl64 = os.path.join(output_dir, 'Debug', 'x64')
-  out_release = os.path.join(output_dir, 'Release')
-  out_release_nacl64 = os.path.join(output_dir, 'Release', 'x64')
-  out_debug_x64 = os.path.join(output_dir, 'Debug_x64')
-  out_release_x64 = os.path.join(output_dir, 'Release_x64')
-
-  if os.path.exists(out_debug) and not os.path.exists(out_debug_nacl64):
-    os.makedirs(out_debug_nacl64)
-  if os.path.exists(out_release) and not os.path.exists(out_release_nacl64):
-    os.makedirs(out_release_nacl64)
-  _CopyRuntime(out_debug,          x86, "x86", debug=True)
-  _CopyRuntime(out_release,        x86, "x86", debug=False)
-  _CopyRuntime(out_debug_x64,      x64, "x64", debug=True)
-  _CopyRuntime(out_release_x64,    x64, "x64", debug=False)
-  _CopyRuntime(out_debug_nacl64,   x64, "x64", debug=True)
-  _CopyRuntime(out_release_nacl64, x64, "x64", debug=False)
-
 
 def CopyDlls(target_dir, configuration, target_cpu):
   """Copy the VS runtime DLLs into the requested directory as needed.
@@ -293,8 +284,6 @@
 
   The debug configuration gets both the debug and release DLLs; the
   release config only the latter.
-
-  This is used for the GN build.
   """
   vs_runtime_dll_dirs = SetEnvironmentAndGetRuntimeDllDirs()
   if not vs_runtime_dll_dirs:
@@ -305,6 +294,8 @@
   _CopyRuntime(target_dir, runtime_dir, target_cpu, debug=False)
   if configuration == 'Debug':
     _CopyRuntime(target_dir, runtime_dir, target_cpu, debug=True)
+  else:
+    _CopyPGORuntime(target_dir, target_cpu)
 
   _CopyDebugger(target_dir, target_cpu)
 
diff --git a/build/win/run_pgo_profiling_benchmarks.py b/build/win/run_pgo_profiling_benchmarks.py
index 2bff09d..163682a 100644
--- a/build/win/run_pgo_profiling_benchmarks.py
+++ b/build/win/run_pgo_profiling_benchmarks.py
@@ -52,39 +52,8 @@
 }
 
 
-def FindPgosweep(target_cpu):
-  """Find the directory containing pgosweep.exe.
-
-  Note: |target_cpu| should be x86 or x64.
-  """
-  if target_cpu not in ('x86', 'x64'):
-    raise Exception('target_cpu should be x86 or x64.')
-  win_toolchain_json_file = os.path.join(_CHROME_BUILD_DIR,
-                                         'win_toolchain.json')
-  if not os.path.exists(win_toolchain_json_file):
-    raise Exception('The toolchain JSON file (%s) is missing.' %
-                    win_toolchain_json_file)
-  with open(win_toolchain_json_file) as temp_f:
-    toolchain_data = json.load(temp_f)
-  if not os.path.isdir(toolchain_data['path']):
-    raise Exception('The toolchain JSON file\'s "path" entry (%s) does not '
-                    'refer to a path.' % win_toolchain_json_file)
-
-  pgo_sweep_dir = os.path.join(toolchain_data['path'], 'VC', 'bin')
-  if target_cpu == 'x64':
-    pgo_sweep_dir = os.path.join(pgo_sweep_dir, 'amd64')
-
-  if not os.path.exists(os.path.join(pgo_sweep_dir, 'pgosweep.exe')):
-    raise Exception('pgosweep.exe is missing from %s.' % pgo_sweep_dir)
-
-  return pgo_sweep_dir
-
-
 def RunBenchmarks(options):
   """Run the benchmarks."""
-  # Starts by finding the directory containing pgosweep.exe
-  pgo_sweep_dir = FindPgosweep(options.target_cpu)
-
   # Find the run_benchmark script.
   chrome_run_benchmark_script = os.path.join(_CHROME_SRC_DIR, 'tools',
                                              'perf', 'run_benchmark')
@@ -95,8 +64,7 @@
   # Augment the PATH to make sure that the benchmarking script can find
   # pgosweep.exe and its runtime libraries.
   env = os.environ.copy()
-  env['PATH'] = str(os.pathsep.join([pgo_sweep_dir, options.build_dir,
-                                     os.environ['PATH']]))
+  env['PATH'] = str(os.pathsep.join([options.build_dir, os.environ['PATH']]))
   env['PogoSafeMode'] = '1'
   # Apply a scaling factor of 0.5 to the PGO profiling buffers for the 32-bit
   # builds, without this the buffers will be too large and the process will
diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc
index a235729..10bc522 100644
--- a/cc/layers/layer.cc
+++ b/cc/layers/layer.cc
@@ -1301,11 +1301,6 @@
     inputs_.client->didChangeScrollbarsHidden(hidden);
 }
 
-bool Layer::FilterIsAnimating() const {
-  return GetMutatorHost()->IsAnimatingFilterProperty(
-      element_id(), GetElementTypeForAnimation());
-}
-
 bool Layer::TransformIsAnimating() const {
   return GetMutatorHost()->IsAnimatingTransformProperty(
       element_id(), GetElementTypeForAnimation());
diff --git a/cc/layers/layer.h b/cc/layers/layer.h
index 5d0c6d08..bb8f2f1 100644
--- a/cc/layers/layer.h
+++ b/cc/layers/layer.h
@@ -472,7 +472,6 @@
   void OnTransformAnimated(const gfx::Transform& transform);
   void OnScrollOffsetAnimated(const gfx::ScrollOffset& scroll_offset);
 
-  bool FilterIsAnimating() const;
   bool TransformIsAnimating() const;
   bool ScrollOffsetAnimationWasInterrupted() const;
 
diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc
index 5d2ed7e..e438943 100644
--- a/cc/layers/layer_impl.cc
+++ b/cc/layers/layer_impl.cc
@@ -611,11 +611,6 @@
   return color;
 }
 
-bool LayerImpl::FilterIsAnimating() const {
-  return GetMutatorHost()->IsAnimatingFilterProperty(
-      element_id(), GetElementTypeForAnimation());
-}
-
 bool LayerImpl::HasPotentiallyRunningFilterAnimation() const {
   return GetMutatorHost()->HasPotentiallyRunningFilterAnimation(
       element_id(), GetElementTypeForAnimation());
diff --git a/cc/layers/layer_impl.h b/cc/layers/layer_impl.h
index 75e96c91..4f419eb 100644
--- a/cc/layers/layer_impl.h
+++ b/cc/layers/layer_impl.h
@@ -176,7 +176,6 @@
   // non-opaque color.  Tries to return background_color(), if possible.
   SkColor SafeOpaqueBackgroundColor() const;
 
-  bool FilterIsAnimating() const;
   bool HasPotentiallyRunningFilterAnimation() const;
 
   void SetMasksToBounds(bool masks_to_bounds);
diff --git a/cc/trees/layer_tree_host_common_unittest.cc b/cc/trees/layer_tree_host_common_unittest.cc
index 49e5efd..e4a6f57 100644
--- a/cc/trees/layer_tree_host_common_unittest.cc
+++ b/cc/trees/layer_tree_host_common_unittest.cc
@@ -8329,6 +8329,11 @@
   EXPECT_EQ(GetRenderSurface(grandchild), GetRenderSurface(child));
 }
 
+static bool FilterIsAnimating(LayerImpl* layer) {
+  return layer->GetMutatorHost()->IsAnimatingFilterProperty(
+      layer->element_id(), layer->GetElementTypeForAnimation());
+}
+
 // Verify that having an animated filter (but no current filter, as these
 // are mutually exclusive) correctly creates a render surface.
 TEST_F(LayerTreeHostCommonTest, AnimatedFilterCreatesRenderSurface) {
@@ -8352,9 +8357,9 @@
   EXPECT_TRUE(GetRenderSurface(root)->Filters().IsEmpty());
   EXPECT_TRUE(GetRenderSurface(child)->Filters().IsEmpty());
 
-  EXPECT_FALSE(root->FilterIsAnimating());
-  EXPECT_TRUE(child->FilterIsAnimating());
-  EXPECT_FALSE(grandchild->FilterIsAnimating());
+  EXPECT_FALSE(FilterIsAnimating(root));
+  EXPECT_TRUE(FilterIsAnimating(child));
+  EXPECT_FALSE(FilterIsAnimating(grandchild));
 }
 
 // Verify that having a filter animation with a delayed start time creates a
@@ -8396,11 +8401,11 @@
   EXPECT_TRUE(GetRenderSurface(root)->Filters().IsEmpty());
   EXPECT_TRUE(GetRenderSurface(child)->Filters().IsEmpty());
 
-  EXPECT_FALSE(root->FilterIsAnimating());
+  EXPECT_FALSE(FilterIsAnimating(root));
   EXPECT_FALSE(root->HasPotentiallyRunningFilterAnimation());
-  EXPECT_FALSE(child->FilterIsAnimating());
+  EXPECT_FALSE(FilterIsAnimating(child));
   EXPECT_TRUE(child->HasPotentiallyRunningFilterAnimation());
-  EXPECT_FALSE(grandchild->FilterIsAnimating());
+  EXPECT_FALSE(FilterIsAnimating(grandchild));
   EXPECT_FALSE(grandchild->HasPotentiallyRunningFilterAnimation());
 }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java
index 6259177..d2cb332f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java
@@ -160,6 +160,7 @@
     public static final String CONTENT_SUGGESTIONS_SHOW_SUMMARY = "ContentSuggestionsShowSummary";
     public static final String CONTEXTUAL_SEARCH_SINGLE_ACTIONS = "ContextualSearchSingleActions";
     public static final String CONTEXTUAL_SEARCH_URL_ACTIONS = "ContextualSearchUrlActions";
+    public static final String CONTEXTUAL_SUGGESTIONS_CAROUSEL = "ContextualSuggestionsCarousel";
     public static final String COPYLESS_PASTE = "CopylessPaste";
     public static final String CUSTOM_CONTEXT_MENU = "CustomContextMenu";
     public static final String CUSTOM_FEEDBACK_UI = "CustomFeedbackUi";
diff --git a/chrome/app/vector_icons/BUILD.gn b/chrome/app/vector_icons/BUILD.gn
index 2d7895c..95716560 100644
--- a/chrome/app/vector_icons/BUILD.gn
+++ b/chrome/app/vector_icons/BUILD.gn
@@ -113,11 +113,11 @@
 
 source_set("vector_icons") {
   sources = get_target_outputs(":chrome_vector_icons")
-  sources += [ "//ui/gfx/vector_icon_types.h" ]
 
   deps = [
     ":chrome_vector_icons",
     "//base",
     "//skia",
+    "//ui/gfx",
   ]
 }
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index e46c068..0af672d 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -83,6 +83,7 @@
 #include "device/vr/features/features.h"
 #include "extensions/features/features.h"
 #include "gin/public/gin_features.h"
+#include "google_apis/drive/drive_switches.h"
 #include "gpu/config/gpu_switches.h"
 #include "media/audio/audio_features.h"
 #include "media/base/media_switches.h"
@@ -2254,6 +2255,10 @@
      flag_descriptions::kEnableNtpSnippetsVisibilityName,
      flag_descriptions::kEnableNtpSnippetsVisibilityDescription, kOsAndroid,
      FEATURE_VALUE_TYPE(ntp_snippets::kIncreasedVisibility)},
+    {"enable-contextual-suggestions-carousel",
+     flag_descriptions::kContextualSuggestionsCarouselName,
+     flag_descriptions::kContextualSuggestionsCarouselDescription, kOsAndroid,
+     FEATURE_VALUE_TYPE(chrome::android::kContextualSuggestionsCarousel)},
     {"enable-content-suggestions-new-favicon-server",
      flag_descriptions::kEnableContentSuggestionsNewFaviconServerName,
      flag_descriptions::kEnableContentSuggestionsNewFaviconServerDescription,
@@ -2658,6 +2663,11 @@
      flag_descriptions::kTouchscreenCalibrationDescription, kOsCrOS,
      SINGLE_VALUE_TYPE(chromeos::switches::kEnableTouchCalibrationSetting)},
 #endif // defined(OS_CHROMEOS)
+#if defined(OS_CHROMEOS)
+    {"team-drives", flag_descriptions::kTeamDrivesName,
+     flag_descriptions::kTeamDrivesDescription, kOsCrOS,
+     SINGLE_VALUE_TYPE(google_apis::kEnableTeamDrives)},
+#endif  // OS_CHROMEOS
 
 #if defined(OS_WIN)
     {"gdi-text-printing", flag_descriptions::kGdiTextPrinting,
diff --git a/chrome/browser/android/chrome_feature_list.cc b/chrome/browser/android/chrome_feature_list.cc
index c78155c..62038f2c 100644
--- a/chrome/browser/android/chrome_feature_list.cc
+++ b/chrome/browser/android/chrome_feature_list.cc
@@ -56,6 +56,7 @@
     &kContentSuggestionsShowSummary,
     &kContextualSearchSingleActions,
     &kContextualSearchUrlActions,
+    &kContextualSuggestionsCarousel,
     &kCustomContextMenu,
     &kCustomFeedbackUi,
     &data_reduction_proxy::features::kDataReductionMainMenu,
@@ -142,6 +143,9 @@
 const base::Feature kContextualSearchUrlActions{
     "ContextualSearchUrlActions", base::FEATURE_ENABLED_BY_DEFAULT};
 
+const base::Feature kContextualSuggestionsCarousel{
+    "ContextualSuggestionsCarousel", base::FEATURE_DISABLED_BY_DEFAULT};
+
 const base::Feature kCustomContextMenu{"CustomContextMenu",
                                        base::FEATURE_DISABLED_BY_DEFAULT};
 
diff --git a/chrome/browser/android/chrome_feature_list.h b/chrome/browser/android/chrome_feature_list.h
index 149c5d5e..81c6071 100644
--- a/chrome/browser/android/chrome_feature_list.h
+++ b/chrome/browser/android/chrome_feature_list.h
@@ -25,6 +25,7 @@
 extern const base::Feature kContentSuggestionsShowSummary;
 extern const base::Feature kContextualSearchSingleActions;
 extern const base::Feature kContextualSearchUrlActions;
+extern const base::Feature kContextualSuggestionsCarousel;
 extern const base::Feature kCustomContextMenu;
 extern const base::Feature kCustomFeedbackUi;
 extern const base::Feature kDownloadAutoResumptionThrottling;
diff --git a/chrome/browser/android/vr_shell/ui_scene_manager.cc b/chrome/browser/android/vr_shell/ui_scene_manager.cc
index ce55844d97..5143d43 100644
--- a/chrome/browser/android/vr_shell/ui_scene_manager.cc
+++ b/chrome/browser/android/vr_shell/ui_scene_manager.cc
@@ -47,10 +47,6 @@
 static constexpr vr::Colorf kBackgroundHorizonColor = {0.57, 0.57, 0.57, 1.0};
 static constexpr vr::Colorf kBackgroundCenterColor = {0.48, 0.48, 0.48, 1.0};
 
-// Placeholders to demonstrate UI changes when in CCT.
-static constexpr vr::Colorf kCctBackgroundHorizonColor = {0.2, 0.6, 0.2, 1.0};
-static constexpr vr::Colorf kCctBackgroundCenterColor = {0.13, 0.52, 0.13, 1.0};
-
 // Tiny distance to offset textures that should appear in the same plane.
 static constexpr float kTextureOffset = 0.01;
 
@@ -140,10 +136,6 @@
 
 void UiSceneManager::CreateBackground() {
   std::unique_ptr<UiElement> element;
-  vr::Colorf horizon =
-      in_cct_ ? kCctBackgroundHorizonColor : kBackgroundHorizonColor;
-  vr::Colorf center =
-      in_cct_ ? kCctBackgroundCenterColor : kBackgroundCenterColor;
 
   // Floor.
   element = base::MakeUnique<UiElement>();
@@ -152,8 +144,8 @@
   element->set_translation({0.0, -kSceneHeight / 2, 0.0});
   element->set_rotation({1.0, 0.0, 0.0, -M_PI / 2.0});
   element->set_fill(vr_shell::Fill::OPAQUE_GRADIENT);
-  element->set_edge_color(horizon);
-  element->set_center_color(center);
+  element->set_edge_color(kBackgroundHorizonColor);
+  element->set_center_color(kBackgroundCenterColor);
   element->set_draw_phase(0);
   browser_ui_elements_.push_back(element.get());
   scene_->AddUiElement(std::move(element));
@@ -166,8 +158,8 @@
   element->set_translation({0.0, kSceneHeight / 2, 0.0});
   element->set_rotation({1.0, 0.0, 0.0, M_PI / 2});
   element->set_fill(vr_shell::Fill::OPAQUE_GRADIENT);
-  element->set_edge_color(horizon);
-  element->set_center_color(center);
+  element->set_edge_color(kBackgroundHorizonColor);
+  element->set_center_color(kBackgroundCenterColor);
   element->set_draw_phase(0);
   browser_ui_elements_.push_back(element.get());
   scene_->AddUiElement(std::move(element));
@@ -180,8 +172,8 @@
   element->set_translation({0.0, -kSceneHeight / 2 + kTextureOffset, 0.0});
   element->set_rotation({1.0, 0.0, 0.0, -M_PI / 2});
   element->set_fill(vr_shell::Fill::GRID_GRADIENT);
-  element->set_center_color(horizon);
-  vr::Colorf edge_color = horizon;
+  element->set_center_color(kBackgroundHorizonColor);
+  vr::Colorf edge_color = kBackgroundHorizonColor;
   edge_color.a = 0.0;
   element->set_edge_color(edge_color);
   element->set_gridline_count(kFloorGridlineCount);
@@ -189,7 +181,7 @@
   browser_ui_elements_.push_back(element.get());
   scene_->AddUiElement(std::move(element));
 
-  scene_->SetBackgroundColor(horizon);
+  scene_->SetBackgroundColor(kBackgroundHorizonColor);
 }
 
 void UiSceneManager::CreateUrlBar() {
diff --git a/chrome/browser/android/vr_shell/vr_shell_gl.cc b/chrome/browser/android/vr_shell/vr_shell_gl.cc
index e58d6aeaa..5296650 100644
--- a/chrome/browser/android/vr_shell/vr_shell_gl.cc
+++ b/chrome/browser/android/vr_shell/vr_shell_gl.cc
@@ -42,7 +42,9 @@
 
 namespace {
 static constexpr float kZNear = 0.1f;
-static constexpr float kZFar = 1000.0f;
+// This should be kept fairly small with current reticle rendering technique
+// which requires fairly high precision to draw on top of elements correctly.
+static constexpr float kZFar = 100.0f;
 
 static constexpr float kReticleWidth = 0.025f;
 static constexpr float kReticleHeight = 0.025f;
@@ -51,9 +53,12 @@
 
 static constexpr gfx::Point3F kOrigin = {0.0f, 0.0f, 0.0f};
 
-// Fraction of the distance to the object the cursor is drawn at to avoid
-// rounding errors drawing the cursor behind the object.
-static constexpr float kReticleOffset = 0.99f;
+// Fraction of the distance to the object the reticle is drawn at to avoid
+// rounding errors drawing the reticle behind the object.
+// TODO(mthiesse): Find a better approach for drawing the reticle on an object.
+// Right now we have to wedge it very precisely between the content window and
+// backplane to avoid rendering artifacts.
+static constexpr float kReticleOffset = 0.999f;
 
 // GVR buffer indices for use with viewport->SetSourceBufferIndex
 // or frame.BindBuffer. We use one for world content (with reprojection)
@@ -536,9 +541,9 @@
     return;
   gfx::PointF target_local_point;
   gfx::Vector3dF eye_to_target;
-  cursor_render_target_ = nullptr;
+  reticle_render_target_ = nullptr;
   GetVisualTargetElement(controller_direction, eye_to_target, target_point_,
-                         &cursor_render_target_, target_local_point);
+                         &reticle_render_target_, target_local_point);
 
   UiElement* target_element = nullptr;
   if (input_locked_element_) {
@@ -549,7 +554,7 @@
                         plane_intersection_point, distance_to_plane);
     target_element = input_locked_element_;
   } else if (!in_scroll_ && !in_click_) {
-    target_element = cursor_render_target_;
+    target_element = reticle_render_target_;
   }
 
   // Handle input targeting on the content quad, ignoring any other elements.
@@ -1075,7 +1080,7 @@
                            const std::vector<const UiElement*>& elements,
                            const gfx::Size& render_size,
                            int viewport_offset,
-                           bool draw_cursor) {
+                           bool draw_reticle) {
   TRACE_EVENT0("gpu", "VrShellGl::DrawUiView");
 
   auto elementsInDrawOrder = GetElementsInDrawOrder(head_pose, elements);
@@ -1094,59 +1099,81 @@
     glViewport(pixel_rect.x(), pixel_rect.y(), pixel_rect.width(),
                pixel_rect.height());
 
-    vr::Mat4f render_matrix;
+    vr::Mat4f view_proj_matrix;
     vr::Mat4f perspective_matrix;
     GvrMatToMatf(PerspectiveMatrixFromView(buffer_viewport_->GetSourceFov(),
                                            kZNear, kZFar),
                  &perspective_matrix);
 
-    vr::MatrixMul(perspective_matrix, eye_view_matrix, &render_matrix);
+    vr::MatrixMul(perspective_matrix, eye_view_matrix, &view_proj_matrix);
 
-    DrawElements(render_matrix, elementsInDrawOrder);
-    if (draw_cursor) {
-      DrawController(render_matrix);
-      DrawCursor(render_matrix);
+    DrawElements(view_proj_matrix, elementsInDrawOrder, draw_reticle);
+    if (draw_reticle) {
+      DrawLaser(view_proj_matrix);
+      DrawController(view_proj_matrix);
     }
   }
 }
 
 void VrShellGl::DrawElements(const vr::Mat4f& view_proj_matrix,
-                             const std::vector<const UiElement*>& elements) {
-  for (const auto* rect : elements) {
-    vr::Mat4f transform;
-    vr::MatrixMul(view_proj_matrix, rect->TransformMatrix(), &transform);
+                             const std::vector<const UiElement*>& elements,
+                             bool draw_reticle) {
+  if (elements.empty())
+    return;
+  int initial_draw_phase = elements.front()->draw_phase();
+  bool drawn_reticle = false;
+  for (const auto* element : elements) {
+    // If we have no element to draw the reticle on, draw it after the
+    // background (the initial draw phase).
+    if (!reticle_render_target_ && draw_reticle && !drawn_reticle &&
+        element->draw_phase() > initial_draw_phase) {
+      DrawReticle(view_proj_matrix);
+      drawn_reticle = true;
+    }
 
-    switch (rect->fill()) {
-      case Fill::OPAQUE_GRADIENT: {
-        vr_shell_renderer_->GetGradientQuadRenderer()->Draw(
-            transform, rect->edge_color(), rect->center_color(),
-            rect->computed_opacity());
-        break;
-      }
-      case Fill::GRID_GRADIENT: {
-        vr_shell_renderer_->GetGradientGridRenderer()->Draw(
-            transform, rect->edge_color(), rect->center_color(),
-            rect->gridline_count(), rect->computed_opacity());
-        break;
-      }
-      case Fill::CONTENT: {
-        gfx::RectF copy_rect(0, 0, 1, 1);
-        vr_shell_renderer_->GetExternalTexturedQuadRenderer()->Draw(
-            content_texture_id_, transform, copy_rect,
-            rect->computed_opacity());
-        break;
-      }
-      case Fill::SELF: {
-        rect->Render(vr_shell_renderer_.get(), transform);
-        break;
-      }
-      default:
-        break;
+    DrawElement(view_proj_matrix, *element);
+
+    if (draw_reticle && (reticle_render_target_ == element)) {
+      DrawReticle(view_proj_matrix);
     }
   }
   vr_shell_renderer_->Flush();
 }
 
+void VrShellGl::DrawElement(const vr::Mat4f& view_proj_matrix,
+                            const UiElement& element) {
+  vr::Mat4f transform;
+  vr::MatrixMul(view_proj_matrix, element.TransformMatrix(), &transform);
+
+  switch (element.fill()) {
+    case Fill::OPAQUE_GRADIENT: {
+      vr_shell_renderer_->GetGradientQuadRenderer()->Draw(
+          transform, element.edge_color(), element.center_color(),
+          element.computed_opacity());
+      break;
+    }
+    case Fill::GRID_GRADIENT: {
+      vr_shell_renderer_->GetGradientGridRenderer()->Draw(
+          transform, element.edge_color(), element.center_color(),
+          element.gridline_count(), element.computed_opacity());
+      break;
+    }
+    case Fill::CONTENT: {
+      gfx::RectF copy_rect(0, 0, 1, 1);
+      vr_shell_renderer_->GetExternalTexturedQuadRenderer()->Draw(
+          content_texture_id_, transform, copy_rect,
+          element.computed_opacity());
+      break;
+    }
+    case Fill::SELF: {
+      element.Render(vr_shell_renderer_.get(), transform);
+      break;
+    }
+    default:
+      break;
+  }
+}
+
 std::vector<const UiElement*> VrShellGl::GetElementsInDrawOrder(
     const vr::Mat4f& view_matrix,
     const std::vector<const UiElement*>& elements) {
@@ -1171,13 +1198,11 @@
   return sorted_elements;
 }
 
-void VrShellGl::DrawCursor(const vr::Mat4f& render_matrix) {
+void VrShellGl::DrawReticle(const vr::Mat4f& render_matrix) {
   vr::Mat4f mat;
   vr::SetIdentityM(&mat);
 
-  // Draw the reticle.
-
-  // Scale the pointer to have a fixed FOV size at any distance.
+  // Scale the reticle to have a fixed FOV size at any distance.
   const float eye_to_target =
       std::sqrt(target_point_.SquaredDistanceTo(kOrigin));
   vr::ScaleM(
@@ -1186,11 +1211,11 @@
       &mat);
 
   vr::Quatf rotation;
-  if (cursor_render_target_ != nullptr) {
+  if (reticle_render_target_ != nullptr) {
     // Make the reticle planar to the element it's hitting.
-    rotation = GetRotationFromZAxis(cursor_render_target_->GetNormal());
+    rotation = GetRotationFromZAxis(reticle_render_target_->GetNormal());
   } else {
-    // Rotate the cursor to directly face the eyes.
+    // Rotate the reticle to directly face the eyes.
     rotation = GetRotationFromZAxis(target_point_ - kOrigin);
   }
   vr::Mat4f rotation_mat;
@@ -1204,13 +1229,15 @@
   vr::Mat4f transform;
   vr::MatrixMul(render_matrix, mat, &transform);
   vr_shell_renderer_->GetReticleRenderer()->Draw(transform);
+}
 
-  // Draw the laser.
-
+void VrShellGl::DrawLaser(const vr::Mat4f& render_matrix) {
+  gfx::Point3F target_point = ScalePoint(target_point_, kReticleOffset);
   // Find the length of the beam (from hand to target).
   const float laser_length =
       std::sqrt(pointer_start_.SquaredDistanceTo(target_point));
 
+  vr::Mat4f mat;
   // Build a beam, originating from the origin.
   vr::SetIdentityM(&mat);
 
@@ -1220,6 +1247,7 @@
 
   // Tip back 90 degrees to flat, pointing at the scene.
   const vr::Quatf quat = vr::QuatFromAxisAngle({1.0f, 0.0f, 0.0f, -M_PI / 2});
+  vr::Mat4f rotation_mat;
   vr::QuatToMatrix(quat, &rotation_mat);
   vr::MatrixMul(rotation_mat, mat, &mat);
 
@@ -1231,11 +1259,12 @@
   float opacity = controller_->GetOpacity();
   // Render multiple faces to make the laser appear cylindrical.
   const int faces = 4;
+  vr::Mat4f face_transform;
+  vr::Mat4f transform;
   for (int i = 0; i < faces; i++) {
     // Rotate around Z.
     const float angle = M_PI * 2 * i / faces;
     const vr::Quatf rot = vr::QuatFromAxisAngle({0.0f, 0.0f, 1.0f, angle});
-    vr::Mat4f face_transform;
     vr::QuatToMatrix(rot, &face_transform);
     vr::MatrixMul(face_transform, mat, &face_transform);
     // Orient according to target direction.
@@ -1243,7 +1272,6 @@
 
     // Move the beam origin to the hand.
     vr::TranslateM(face_transform, pointer_start_ - kOrigin, &face_transform);
-
     vr::MatrixMul(render_matrix, face_transform, &transform);
     vr_shell_renderer_->GetLaserRenderer()->Draw(opacity, transform);
   }
diff --git a/chrome/browser/android/vr_shell/vr_shell_gl.h b/chrome/browser/android/vr_shell/vr_shell_gl.h
index 5da1123..c41e1eb5 100644
--- a/chrome/browser/android/vr_shell/vr_shell_gl.h
+++ b/chrome/browser/android/vr_shell/vr_shell_gl.h
@@ -120,11 +120,14 @@
                   int viewport_offset,
                   bool draw_cursor);
   void DrawElements(const vr::Mat4f& view_proj_matrix,
-                    const std::vector<const UiElement*>& elements);
+                    const std::vector<const UiElement*>& elements,
+                    bool draw_cursor);
+  void DrawElement(const vr::Mat4f& view_proj_matrix, const UiElement& element);
   std::vector<const UiElement*> GetElementsInDrawOrder(
       const vr::Mat4f& view_matrix,
       const std::vector<const UiElement*>& elements);
-  void DrawCursor(const vr::Mat4f& render_matrix);
+  void DrawReticle(const vr::Mat4f& view_proj_matrix);
+  void DrawLaser(const vr::Mat4f& view_proj_matrix);
   void DrawController(const vr::Mat4f& view_proj_matrix);
   bool ShouldDrawWebVr();
   void DrawWebVr();
@@ -218,7 +221,7 @@
 
   // TODO(mthiesse): We need to handle elements being removed, and update this
   // state appropriately.
-  UiElement* cursor_render_target_ = nullptr;
+  UiElement* reticle_render_target_ = nullptr;
   UiElement* hover_target_ = nullptr;
   // TODO(mthiesse): We shouldn't have a fling target. Elements should fling
   // independently and we should only cancel flings on the relevant element
diff --git a/chrome/browser/chrome_notification_types.h b/chrome/browser/chrome_notification_types.h
index 6c46a710..1d72e8f1 100644
--- a/chrome/browser/chrome_notification_types.h
+++ b/chrome/browser/chrome_notification_types.h
@@ -40,12 +40,6 @@
   // containing the affected Browser.  No details are expected.
   NOTIFICATION_BROWSER_WINDOW_READY,
 
-  // This message is sent when a browser is closing. The source is a
-  // Source<Browser> containing the affected Browser. No details are expected.
-  // This is sent prior to BROWSER_CLOSED, and may be sent more than once for a
-  // particular browser.
-  NOTIFICATION_BROWSER_CLOSING,
-
   // This message is sent after a window has been closed.  The source is a
   // Source<Browser> containing the affected Browser.  No details are exptected.
   NOTIFICATION_BROWSER_CLOSED,
diff --git a/chrome/browser/extensions/api/image_writer_private/image_writer_utility_client.cc b/chrome/browser/extensions/api/image_writer_private/image_writer_utility_client.cc
index 8e2a1e1..297df8d0 100644
--- a/chrome/browser/extensions/api/image_writer_private/image_writer_utility_client.cc
+++ b/chrome/browser/extensions/api/image_writer_private/image_writer_utility_client.cc
@@ -24,7 +24,8 @@
   RemovableStorageWriterClientImpl(
       ImageWriterUtilityClient* owner,
       extensions::mojom::RemovableStorageWriterClientPtr* interface)
-      : binding_(this, interface), image_writer_utility_client_(owner) {
+      : binding_(this, mojo::MakeRequest(interface)),
+        image_writer_utility_client_(owner) {
     DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
 
     binding_.set_connection_error_handler(
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index a48b1e25..ef872145 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -51,6 +51,13 @@
     "If enabled, reporting an issue will load the Material Design feedback "
     "UI.";
 
+const char kContextualSuggestionsCarouselName[] =
+    "Enable Contextual Suggestions";
+
+const char kContextualSuggestionsCarouselDescription[] =
+    "If enabled, shows contextual suggestions in a horizontal carousel in "
+    "bottom sheet content.";
+
 //  Report URL to SafeSearch
 
 const char kSafeSearchUrlReportingName[] = "SafeSearch URLs reporting.";
@@ -1861,6 +1868,10 @@
     "If enabled, the user can calibrate the touch screen displays in "
     "chrome://md-settings/display.";
 
+const char kTeamDrivesName[] = "Enable Team Drives Integration";
+const char kTeamDrivesDescription[] =
+    "If enabled, files under Team Drives will appear in the Files app.";
+
 #endif  // defined(OS_CHROMEOS)
 
 //  Strings for controlling credit card assist feature in about:flags.
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 84aeb23..80b6f93 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -54,6 +54,12 @@
 // Name for the flag to enable the material design feedback UI.
 extern const char kEnableMaterialDesignFeedbackName[];
 
+// Name for the flag to enable contextual suggestions carousel.
+extern const char kContextualSuggestionsCarouselName[];
+
+// Description for the flag to enable contextual suggestions carousel.
+extern const char kContextualSuggestionsCarouselDescription[];
+
 // Description for the flag to enable the material design feedback UI.
 extern const char kEnableMaterialDesignFeedbackDescription[];
 
@@ -2064,6 +2070,12 @@
 // chrome://md-settings/display.
 extern const char kTouchscreenCalibrationDescription[];
 
+// Name of option to enable Team Drives integration
+extern const char kTeamDrivesName[];
+
+// Description of option to enable Team Drives integration
+extern const char kTeamDrivesDescription[];
+
 #endif  // defined(OS_CHROMEOS)
 
 //  Strings for controlling credit card assist feature in about:flags.
diff --git a/chrome/browser/media_galleries/fileapi/safe_media_metadata_parser.cc b/chrome/browser/media_galleries/fileapi/safe_media_metadata_parser.cc
index e784cabe..c0883f7 100644
--- a/chrome/browser/media_galleries/fileapi/safe_media_metadata_parser.cc
+++ b/chrome/browser/media_galleries/fileapi/safe_media_metadata_parser.cc
@@ -20,7 +20,8 @@
  public:
   MediaDataSourceImpl(SafeMediaMetadataParser* owner,
                       extensions::mojom::MediaDataSourcePtr* interface)
-      : binding_(this, interface), safe_media_metadata_parser_(owner) {
+      : binding_(this, mojo::MakeRequest(interface)),
+        safe_media_metadata_parser_(owner) {
     DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
   }
 
diff --git a/chrome/browser/spellchecker/spellcheck_service_browsertest.cc b/chrome/browser/spellchecker/spellcheck_service_browsertest.cc
index 533eeabd..5abe4b7 100644
--- a/chrome/browser/spellchecker/spellcheck_service_browsertest.cc
+++ b/chrome/browser/spellchecker/spellcheck_service_browsertest.cc
@@ -177,7 +177,7 @@
 
   // Binds requests for the SpellChecker interface.
   void Bind(mojo::ScopedMessagePipeHandle handle) {
-    binding_.Bind(std::move(handle));
+    binding_.Bind(spellcheck::mojom::SpellCheckerRequest(std::move(handle)));
     binding_.set_connection_error_handler(
         base::Bind(&SpellcheckServiceBrowserTest::BoundConnectionClosed,
                    base::Unretained(this)));
diff --git a/chrome/browser/ui/ash/cast_config_client_media_router.cc b/chrome/browser/ui/ash/cast_config_client_media_router.cc
index a2b6afa..f9d8da9 100644
--- a/chrome/browser/ui/ash/cast_config_client_media_router.cc
+++ b/chrome/browser/ui/ash/cast_config_client_media_router.cc
@@ -155,7 +155,7 @@
 
   // Register this object as the client interface implementation.
   ash::mojom::CastConfigClientAssociatedPtrInfo ptr_info;
-  binding_.Bind(&ptr_info);
+  binding_.Bind(mojo::MakeRequest(&ptr_info));
   cast_config_->SetClient(std::move(ptr_info));
 }
 
diff --git a/chrome/browser/ui/ash/chrome_new_window_client.cc b/chrome/browser/ui/ash/chrome_new_window_client.cc
index e9a75ec..0355cbe 100644
--- a/chrome/browser/ui/ash/chrome_new_window_client.cc
+++ b/chrome/browser/ui/ash/chrome_new_window_client.cc
@@ -65,7 +65,7 @@
 
   // Register this object as the client interface implementation.
   ash::mojom::NewWindowClientAssociatedPtrInfo ptr_info;
-  binding_.Bind(&ptr_info);
+  binding_.Bind(mojo::MakeRequest(&ptr_info));
   new_window_controller_->SetClient(std::move(ptr_info));
 }
 
diff --git a/chrome/browser/ui/ash/launcher/browser_shortcut_launcher_item_controller.cc b/chrome/browser/ui/ash/launcher/browser_shortcut_launcher_item_controller.cc
index ac73581..ecc5962 100644
--- a/chrome/browser/ui/ash/launcher/browser_shortcut_launcher_item_controller.cc
+++ b/chrome/browser/ui/ash/launcher/browser_shortcut_launcher_item_controller.cc
@@ -13,7 +13,6 @@
 #include "ash/shelf/shelf_model.h"
 #include "ash/wm_window.h"
 #include "base/memory/ptr_util.h"
-#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h"
 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller_util.h"
@@ -32,7 +31,6 @@
 #include "chrome/grit/chromium_strings.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/strings/grit/components_strings.h"
-#include "content/public/browser/notification_service.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/url_constants.h"
 #include "ui/aura/window.h"
@@ -107,7 +105,8 @@
 BrowserShortcutLauncherItemController::BrowserShortcutLauncherItemController(
     ash::ShelfModel* shelf_model)
     : ash::ShelfItemDelegate(ash::ShelfID(extension_misc::kChromeAppId)),
-      shelf_model_(shelf_model) {
+      shelf_model_(shelf_model),
+      browser_list_observer_(this) {
   // Tag all open browser windows with the appropriate shelf id property. This
   // associates each window with the shelf item for the active web contents.
   for (auto* browser : *BrowserList::GetInstance()) {
@@ -221,7 +220,7 @@
 ash::MenuItemList BrowserShortcutLauncherItemController::GetAppMenuItems(
     int event_flags) {
   browser_menu_items_.clear();
-  registrar_.RemoveAll();
+  browser_list_observer_.RemoveAll();
 
   ash::MenuItemList items;
   bool found_tabbed_browser = false;
@@ -253,15 +252,15 @@
       }
     }
     browser_menu_items_.push_back(browser);
-    registrar_.Add(this, chrome::NOTIFICATION_BROWSER_CLOSING,
-                   content::Source<Browser>(browser));
+    if (!browser_list_observer_.IsObservingSources())
+      browser_list_observer_.Add(BrowserList::GetInstance());
   }
   // If only windowed applications are open, we return an empty list to
   // enforce the creation of a new browser.
   if (!found_tabbed_browser) {
     items.clear();
     browser_menu_items_.clear();
-    registrar_.RemoveAll();
+    browser_list_observer_.RemoveAll();
   }
   return items;
 }
@@ -294,7 +293,7 @@
   }
 
   browser_menu_items_.clear();
-  registrar_.RemoveAll();
+  browser_list_observer_.RemoveAll();
 }
 
 void BrowserShortcutLauncherItemController::Close() {
@@ -393,18 +392,11 @@
   return active_browsers;
 }
 
-void BrowserShortcutLauncherItemController::Observe(
-    int type,
-    const content::NotificationSource& source,
-    const content::NotificationDetails& details) {
-  DCHECK_EQ(chrome::NOTIFICATION_BROWSER_CLOSING, type);
-  Browser* browser = content::Source<Browser>(source).ptr();
+void BrowserShortcutLauncherItemController::OnBrowserClosing(Browser* browser) {
   DCHECK(browser);
   BrowserList::BrowserVector::iterator item = std::find(
       browser_menu_items_.begin(), browser_menu_items_.end(), browser);
-  DCHECK(item != browser_menu_items_.end());
   // Clear the entry for the closed browser and leave other indices intact.
-  *item = nullptr;
-  registrar_.Remove(this, chrome::NOTIFICATION_BROWSER_CLOSING,
-                    content::Source<Browser>(browser));
+  if (item != browser_menu_items_.end())
+    *item = nullptr;
 }
diff --git a/chrome/browser/ui/ash/launcher/browser_shortcut_launcher_item_controller.h b/chrome/browser/ui/ash/launcher/browser_shortcut_launcher_item_controller.h
index 0fca4e3a..0a9d4fc 100644
--- a/chrome/browser/ui/ash/launcher/browser_shortcut_launcher_item_controller.h
+++ b/chrome/browser/ui/ash/launcher/browser_shortcut_launcher_item_controller.h
@@ -7,9 +7,9 @@
 
 #include "ash/public/cpp/shelf_item_delegate.h"
 #include "base/macros.h"
+#include "base/scoped_observer.h"
 #include "chrome/browser/ui/browser_list.h"
-#include "content/public/browser/notification_observer.h"
-#include "content/public/browser/notification_registrar.h"
+#include "chrome/browser/ui/browser_list_observer.h"
 
 namespace ash {
 class ShelfModel;
@@ -23,7 +23,7 @@
 // This item shows an application menu that lists open browser windows or tabs.
 class BrowserShortcutLauncherItemController
     : public ash::ShelfItemDelegate,
-      public content::NotificationObserver {
+      public chrome::BrowserListObserver {
  public:
   explicit BrowserShortcutLauncherItemController(ash::ShelfModel* shelf_model);
 
@@ -61,18 +61,16 @@
   // Get a list of active browsers.
   BrowserList::BrowserVector GetListOfActiveBrowsers();
 
-  // content::NotificationObserver:
-  void Observe(int type,
-               const content::NotificationSource& source,
-               const content::NotificationDetails& details) override;
+  // chrome::BrowserListObserver:
+  void OnBrowserClosing(Browser* browser) override;
 
   ash::ShelfModel* shelf_model_;
 
   // The cached list of open browser windows shown in an application menu.
   BrowserList::BrowserVector browser_menu_items_;
 
-  // Registers for notifications of closing browser windows.
-  content::NotificationRegistrar registrar_;
+  // Observer for browser windows closing events.
+  ScopedObserver<BrowserList, BrowserListObserver> browser_list_observer_;
 
   DISALLOW_COPY_AND_ASSIGN(BrowserShortcutLauncherItemController);
 };
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc
index da9ac15..4f5ad157 100644
--- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc
+++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc
@@ -278,7 +278,7 @@
   // Start observing the shelf controller.
   if (ConnectToShelfController()) {
     ash::mojom::ShelfObserverAssociatedPtrInfo ptr_info;
-    observer_binding_.Bind(&ptr_info);
+    observer_binding_.Bind(mojo::MakeRequest(&ptr_info));
     shelf_controller_->AddObserver(std::move(ptr_info));
   }
 
diff --git a/chrome/browser/ui/ash/media_client.cc b/chrome/browser/ui/ash/media_client.cc
index a8affc52..7baf556 100644
--- a/chrome/browser/ui/ash/media_client.cc
+++ b/chrome/browser/ui/ash/media_client.cc
@@ -136,7 +136,7 @@
 
   // Register this object as the client interface implementation.
   ash::mojom::MediaClientAssociatedPtrInfo ptr_info;
-  binding_.Bind(&ptr_info);
+  binding_.Bind(mojo::MakeRequest(&ptr_info));
   media_controller_->SetClient(std::move(ptr_info));
 }
 
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc
index 7d0394f..ac29b0c2 100644
--- a/chrome/browser/ui/browser.cc
+++ b/chrome/browser/ui/browser.cc
@@ -751,11 +751,7 @@
   if (tab_restore_service && is_type_tabbed() && tab_strip_model_->count())
     tab_restore_service->BrowserClosing(live_tab_context());
 
-  // TODO(sky): convert session/tab restore to use notification.
-  content::NotificationService::current()->Notify(
-      chrome::NOTIFICATION_BROWSER_CLOSING,
-      content::Source<Browser>(this),
-      content::NotificationService::NoDetails());
+  BrowserList::NotifyBrowserCloseStarted(this);
 
   if (!IsFastTabUnloadEnabled())
     tab_strip_model_->CloseAllTabs();
diff --git a/chrome/browser/ui/browser_list.cc b/chrome/browser/ui/browser_list.cc
index 8e7a084..92107074 100644
--- a/chrome/browser/ui/browser_list.cc
+++ b/chrome/browser/ui/browser_list.cc
@@ -250,6 +250,12 @@
 }
 
 // static
+void BrowserList::NotifyBrowserCloseStarted(Browser* browser) {
+  for (chrome::BrowserListObserver& observer : observers_.Get())
+    observer.OnBrowserClosing(browser);
+}
+
+// static
 bool BrowserList::IsIncognitoSessionActive() {
   for (auto* browser : *BrowserList::GetInstance()) {
     if (browser->profile()->IsOffTheRecord())
diff --git a/chrome/browser/ui/browser_list.h b/chrome/browser/ui/browser_list.h
index 705e423d..7fff2637 100644
--- a/chrome/browser/ui/browser_list.h
+++ b/chrome/browser/ui/browser_list.h
@@ -82,6 +82,10 @@
   // Notifies the observers when the current active browser becomes not active.
   static void NotifyBrowserNoLongerActive(Browser* browser);
 
+  // Notifies the observers when browser close was started. This may be called
+  // more than once for a particular browser.
+  static void NotifyBrowserCloseStarted(Browser* browser);
+
   // Closes all browsers for |profile| across all desktops.
   // TODO(mlerman): Move the Profile Deletion flow to use the overloaded
   // version of this method with a callback, then remove this method.
diff --git a/chrome/browser/ui/browser_list_observer.h b/chrome/browser/ui/browser_list_observer.h
index 42af6d30..e514b65 100644
--- a/chrome/browser/ui/browser_list_observer.h
+++ b/chrome/browser/ui/browser_list_observer.h
@@ -14,6 +14,10 @@
   // Called immediately after a browser is added to the list
   virtual void OnBrowserAdded(Browser* browser) {}
 
+  // Called when a Browser starts closing. This is called prior to
+  // removing the tabs. Removing the tabs may delay or stop the close.
+  virtual void OnBrowserClosing(Browser* browser) {}
+
   // Called immediately after a browser is removed from the list
   virtual void OnBrowserRemoved(Browser* browser) {}
 
diff --git a/chrome/browser/ui/cocoa/profiles/profile_chooser_controller.mm b/chrome/browser/ui/cocoa/profiles/profile_chooser_controller.mm
index a6af133..777e1f1 100644
--- a/chrome/browser/ui/cocoa/profiles/profile_chooser_controller.mm
+++ b/chrome/browser/ui/cocoa/profiles/profile_chooser_controller.mm
@@ -11,13 +11,13 @@
 #include "base/mac/bundle_locations.h"
 #include "base/macros.h"
 #include "base/metrics/user_metrics.h"
+#include "base/scoped_observer.h"
 #include "base/strings/string_util.h"
 #include "base/strings/sys_string_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/app/vector_icons/vector_icons.h"
 #include "chrome/browser/browser_process.h"
-#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/lifetime/application_lifetime.h"
 #include "chrome/browser/prefs/incognito_mode_prefs.h"
 #include "chrome/browser/profiles/avatar_menu.h"
@@ -38,6 +38,7 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/browser_list.h"
+#include "chrome/browser/ui/browser_list_observer.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/chrome_pages.h"
 #import "chrome/browser/ui/cocoa/browser_window_utils.h"
@@ -64,7 +65,6 @@
 #include "components/signin/core/browser/signin_metrics.h"
 #include "components/signin/core/common/profile_management_switches.h"
 #include "content/public/browser/native_web_keyboard_event.h"
-#include "content/public/browser/notification_service.h"
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
 #include "google_apis/gaia/oauth2_token_service.h"
@@ -325,16 +325,16 @@
 // Class that listens to changes to the OAuth2Tokens for the active profile,
 // changes to the avatar menu model or browser close notifications.
 class ActiveProfileObserverBridge : public AvatarMenuObserver,
-                                    public content::NotificationObserver,
+                                    public chrome::BrowserListObserver,
                                     public OAuth2TokenService::Observer {
  public:
   ActiveProfileObserverBridge(ProfileChooserController* controller,
                               Browser* browser)
       : controller_(controller),
         browser_(browser),
+        browser_list_observer_(this),
         token_observer_registered_(false) {
-    registrar_.Add(this, chrome::NOTIFICATION_BROWSER_CLOSING,
-                   content::NotificationService::AllSources());
+    browser_list_observer_.Add(BrowserList::GetInstance());
     if (!browser_->profile()->IsGuestSession())
       AddTokenServiceObserver();
   }
@@ -394,12 +394,9 @@
     }
   }
 
-  // content::NotificationObserver:
-  void Observe(int type,
-               const content::NotificationSource& source,
-               const content::NotificationDetails& details) override {
-    DCHECK_EQ(chrome::NOTIFICATION_BROWSER_CLOSING, type);
-    if (browser_ == content::Source<Browser>(source).ptr()) {
+  // chrome::BrowserListObserver:
+  void OnBrowserClosing(Browser* browser) override {
+    if (browser_ == browser) {
       RemoveTokenServiceObserver();
       // Clean up the bubble's WebContents (used by the Gaia embedded view), to
       // make sure the guest profile doesn't have any dangling host renderers.
@@ -412,7 +409,7 @@
 
   ProfileChooserController* controller_;  // Weak; owns this.
   Browser* browser_;  // Weak.
-  content::NotificationRegistrar registrar_;
+  ScopedObserver<BrowserList, BrowserListObserver> browser_list_observer_;
 
   // The observer can be removed both when closing the browser, and by just
   // closing the avatar bubble. However, in the case of closing the browser,
diff --git a/chrome/browser/ui/extensions/extension_installed_bubble.cc b/chrome/browser/ui/extensions/extension_installed_bubble.cc
index 267af8b6..def034c 100644
--- a/chrome/browser/ui/extensions/extension_installed_bubble.cc
+++ b/chrome/browser/ui/extensions/extension_installed_bubble.cc
@@ -15,19 +15,17 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/time/time.h"
-#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/commands/command_service.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_list.h"
+#include "chrome/browser/ui/browser_list_observer.h"
 #include "chrome/browser/ui/sync/sync_promo_ui.h"
 #include "chrome/common/extensions/api/extension_action/action_info.h"
 #include "chrome/common/extensions/api/omnibox/omnibox_handler.h"
 #include "chrome/common/extensions/command.h"
 #include "chrome/common/extensions/sync_helper.h"
 #include "chrome/grit/generated_resources.h"
-#include "content/public/browser/notification_observer.h"
-#include "content/public/browser/notification_registrar.h"
-#include "content/public/browser/notification_source.h"
 #include "extensions/browser/extension_registry.h"
 #include "extensions/browser/extension_registry_observer.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -43,22 +41,21 @@
 
 // Class responsible for showing the bubble after it's installed. Owns itself.
 class ExtensionInstalledBubbleObserver
-    : public content::NotificationObserver,
+    : public chrome::BrowserListObserver,
       public extensions::ExtensionRegistryObserver {
  public:
   explicit ExtensionInstalledBubbleObserver(
       std::unique_ptr<ExtensionInstalledBubble> bubble)
       : bubble_(std::move(bubble)),
         extension_registry_observer_(this),
+        browser_list_observer_(this),
         animation_wait_retries_(0),
         weak_factory_(this) {
     // |extension| has been initialized but not loaded at this point. We need to
     // wait on showing the Bubble until the EXTENSION_LOADED gets fired.
     extension_registry_observer_.Add(
         extensions::ExtensionRegistry::Get(bubble_->browser()->profile()));
-
-    registrar_.Add(this, chrome::NOTIFICATION_BROWSER_CLOSING,
-                   content::Source<Browser>(bubble_->browser()));
+    browser_list_observer_.Add(BrowserList::GetInstance());
   }
 
   void Run() { OnExtensionLoaded(nullptr, bubble_->extension()); }
@@ -66,15 +63,13 @@
  private:
   ~ExtensionInstalledBubbleObserver() override {}
 
-  // content::NotificationObserver:
-  void Observe(int type,
-               const content::NotificationSource& source,
-               const content::NotificationDetails& details) override {
-    DCHECK_EQ(type, chrome::NOTIFICATION_BROWSER_CLOSING)
-        << "Received unexpected notification";
-    // Browser is closing before the bubble was shown.
-    // TODO(hcarmona): Look into logging this with the BubbleManager.
-    delete this;
+  // chrome::BrowserListObserver:
+  void OnBrowserClosing(Browser* browser) override {
+    if (bubble_->browser() == browser) {
+      // Browser is closing before the bubble was shown.
+      // TODO(hcarmona): Look into logging this with the BubbleManager.
+      delete this;
+    }
   }
 
   // extensions::ExtensionRegistryObserver:
@@ -141,7 +136,7 @@
                  extensions::ExtensionRegistryObserver>
       extension_registry_observer_;
 
-  content::NotificationRegistrar registrar_;
+  ScopedObserver<BrowserList, BrowserListObserver> browser_list_observer_;
 
   // The number of times to retry showing the bubble if the bubble_->browser()
   // action toolbar is animating.
diff --git a/chrome/browser/ui/tabs/pinned_tab_service.cc b/chrome/browser/ui/tabs/pinned_tab_service.cc
index 5f56a5e..ad016fdf 100644
--- a/chrome/browser/ui/tabs/pinned_tab_service.cc
+++ b/chrome/browser/ui/tabs/pinned_tab_service.cc
@@ -30,17 +30,19 @@
 PinnedTabService::PinnedTabService(Profile* profile)
     : profile_(profile),
       save_pinned_tabs_(true),
-      has_normal_browser_(false) {
+      has_normal_browser_(false),
+      browser_list_observer_(this) {
   registrar_.Add(this, chrome::NOTIFICATION_BROWSER_OPENED,
                  content::NotificationService::AllBrowserContextsAndSources());
-  registrar_.Add(this, chrome::NOTIFICATION_BROWSER_CLOSING,
-                 content::NotificationService::AllSources());
   registrar_.Add(this, chrome::NOTIFICATION_CLOSE_ALL_BROWSERS_REQUEST,
                  content::NotificationService::AllSources());
   registrar_.Add(this, chrome::NOTIFICATION_TAB_ADDED,
                  content::NotificationService::AllSources());
+  browser_list_observer_.Add(BrowserList::GetInstance());
 }
 
+PinnedTabService::~PinnedTabService() {}
+
 void PinnedTabService::Observe(int type,
                                const content::NotificationSource& source,
                                const content::NotificationDetails& details) {
@@ -77,18 +79,6 @@
       break;
     }
 
-    case chrome::NOTIFICATION_BROWSER_CLOSING: {
-      Browser* browser = content::Source<Browser>(source).ptr();
-      if (has_normal_browser_ && save_pinned_tabs_ &&
-          browser->profile() == profile_) {
-        if (IsOnlyNormalBrowser(browser)) {
-          has_normal_browser_ = false;
-          PinnedTabCodec::WritePinnedTabs(profile_);
-        }
-      }
-      break;
-    }
-
     case chrome::NOTIFICATION_CLOSE_ALL_BROWSERS_REQUEST: {
       if (has_normal_browser_ && save_pinned_tabs_) {
         PinnedTabCodec::WritePinnedTabs(profile_);
@@ -101,3 +91,11 @@
       NOTREACHED();
   }
 }
+
+void PinnedTabService::OnBrowserClosing(Browser* browser) {
+  if (has_normal_browser_ && save_pinned_tabs_ &&
+      browser->profile() == profile_ && IsOnlyNormalBrowser(browser)) {
+    has_normal_browser_ = false;
+    PinnedTabCodec::WritePinnedTabs(profile_);
+  }
+}
diff --git a/chrome/browser/ui/tabs/pinned_tab_service.h b/chrome/browser/ui/tabs/pinned_tab_service.h
index f1dc573..d36b640 100644
--- a/chrome/browser/ui/tabs/pinned_tab_service.h
+++ b/chrome/browser/ui/tabs/pinned_tab_service.h
@@ -7,6 +7,9 @@
 
 #include "base/compiler_specific.h"
 #include "base/macros.h"
+#include "base/scoped_observer.h"
+#include "chrome/browser/ui/browser_list.h"
+#include "chrome/browser/ui/browser_list_observer.h"
 #include "components/keyed_service/core/keyed_service.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
@@ -17,9 +20,11 @@
 // pinned tabs to restore at startup. PinnedTabService listens for the
 // appropriate set of notifications to know it should update preferences.
 class PinnedTabService : public content::NotificationObserver,
+                         public chrome::BrowserListObserver,
                          public KeyedService {
  public:
   explicit PinnedTabService(Profile* profile);
+  ~PinnedTabService() override;
 
  private:
   // content::NotificationObserver.
@@ -27,6 +32,9 @@
                const content::NotificationSource& source,
                const content::NotificationDetails& details) override;
 
+  // chrome::BrowserListObserver:
+  void OnBrowserClosing(Browser* browser) override;
+
   Profile* profile_;
 
   // True if we should save the pinned tabs when a browser window closes or the
@@ -38,6 +46,8 @@
 
   content::NotificationRegistrar registrar_;
 
+  ScopedObserver<BrowserList, BrowserListObserver> browser_list_observer_;
+
   DISALLOW_COPY_AND_ASSIGN(PinnedTabService);
 };
 
diff --git a/chrome/browser/ui/views/payments/error_message_view_controller_browsertest.cc b/chrome/browser/ui/views/payments/error_message_view_controller_browsertest.cc
index 770b81f..88ccc0a 100644
--- a/chrome/browser/ui/views/payments/error_message_view_controller_browsertest.cc
+++ b/chrome/browser/ui/views/payments/error_message_view_controller_browsertest.cc
@@ -43,6 +43,7 @@
 
   ResetEventObserver(DialogEvent::ERROR_MESSAGE_SHOWN);
   ClickOnDialogViewAndWait(DialogViewID::CVC_PROMPT_CONFIRM_BUTTON);
+  EXPECT_FALSE(dialog_view()->throbber_overlay_for_testing()->visible());
 
   // The user can only close the dialog at this point.
   ResetEventObserver(DialogEvent::DIALOG_CLOSED);
diff --git a/chrome/browser/ui/views/payments/payment_request_dialog_view.cc b/chrome/browser/ui/views/payments/payment_request_dialog_view.cc
index 0a770a7..12c798d 100644
--- a/chrome/browser/ui/views/payments/payment_request_dialog_view.cc
+++ b/chrome/browser/ui/views/payments/payment_request_dialog_view.cc
@@ -141,6 +141,8 @@
                             request_->spec(), request_->state(), this),
                         &controller_map_),
                     /* animate = */ false);
+  HideProcessingSpinner();
+
   if (observer_for_testing_)
     observer_for_testing_->OnErrorMessageShown();
 }
@@ -349,6 +351,11 @@
   AddChildView(&throbber_overlay_);
 }
 
+void PaymentRequestDialogView::HideProcessingSpinner() {
+  throbber_.Stop();
+  throbber_overlay_.SetVisible(false);
+}
+
 gfx::Size PaymentRequestDialogView::GetPreferredSize() const {
   return gfx::Size(GetActualDialogWidth(), kDialogHeight);
 }
diff --git a/chrome/browser/ui/views/payments/payment_request_dialog_view.h b/chrome/browser/ui/views/payments/payment_request_dialog_view.h
index 6c156710..4e18583 100644
--- a/chrome/browser/ui/views/payments/payment_request_dialog_view.h
+++ b/chrome/browser/ui/views/payments/payment_request_dialog_view.h
@@ -155,10 +155,12 @@
   Profile* GetProfile();
 
   ViewStack* view_stack_for_testing() { return view_stack_.get(); }
+  views::View* throbber_overlay_for_testing() { return &throbber_overlay_; }
 
  private:
   void ShowInitialPaymentSheet();
   void SetupSpinnerOverlay();
+  void HideProcessingSpinner();
 
   // views::View
   gfx::Size GetPreferredSize() const override;
diff --git a/chrome/browser/ui/views/payments/shipping_address_editor_view_controller.cc b/chrome/browser/ui/views/payments/shipping_address_editor_view_controller.cc
index de7486c..94732c0 100644
--- a/chrome/browser/ui/views/payments/shipping_address_editor_view_controller.cc
+++ b/chrome/browser/ui/views/payments/shipping_address_editor_view_controller.cc
@@ -334,7 +334,7 @@
       success = profile->SetInfo(autofill::AutofillType(field.second.type),
                                  field.first->text(), locale);
     }
-    LOG_IF(ERROR, success || ignore_errors)
+    LOG_IF(ERROR, !success && !ignore_errors)
         << "Can't setinfo(" << field.second.type << ", " << field.first->text();
     if (!success && !ignore_errors)
       return false;
@@ -356,7 +356,7 @@
             combobox->GetTextForRow(combobox->selected_index()), locale);
       }
     }
-    LOG_IF(ERROR, success || ignore_errors)
+    LOG_IF(ERROR, !success && !ignore_errors)
         << "Can't setinfo(" << field.second.type << ", "
         << combobox->GetTextForRow(combobox->selected_index());
     if (!success && !ignore_errors)
diff --git a/chrome/renderer/searchbox/searchbox.cc b/chrome/renderer/searchbox/searchbox.cc
index be43fba0..a5e3c52 100644
--- a/chrome/renderer/searchbox/searchbox.cc
+++ b/chrome/renderer/searchbox/searchbox.cc
@@ -247,7 +247,7 @@
   chrome::mojom::EmbeddedSearchConnectorAssociatedPtr connector;
   render_frame->GetRemoteAssociatedInterfaces()->GetInterface(&connector);
   chrome::mojom::SearchBoxAssociatedPtrInfo search_box;
-  binding_.Bind(&search_box);
+  binding_.Bind(mojo::MakeRequest(&search_box));
   connector->Connect(mojo::MakeRequest(&instant_service_),
                      std::move(search_box));
 }
diff --git a/chromecast/renderer/media/media_caps_observer_impl.cc b/chromecast/renderer/media/media_caps_observer_impl.cc
index d80ae37..a2f361d4 100644
--- a/chromecast/renderer/media/media_caps_observer_impl.cc
+++ b/chromecast/renderer/media/media_caps_observer_impl.cc
@@ -14,7 +14,8 @@
 MediaCapsObserverImpl::MediaCapsObserverImpl(
     mojom::MediaCapsObserverPtr* proxy,
     SupportedCodecProfileLevelsMemo* supported_profiles)
-    : supported_profiles_(supported_profiles), binding_(this, proxy) {}
+    : supported_profiles_(supported_profiles),
+      binding_(this, mojo::MakeRequest(proxy)) {}
 
 MediaCapsObserverImpl::~MediaCapsObserverImpl() = default;
 
diff --git a/components/cronet/ios/test/cronet_http_test.mm b/components/cronet/ios/test/cronet_http_test.mm
index aa5d462..35d677e 100644
--- a/components/cronet/ios/test/cronet_http_test.mm
+++ b/components/cronet/ios/test/cronet_http_test.mm
@@ -37,11 +37,16 @@
 // Error the request this delegate is attached to failed with, if any.
 @property(retain, atomic) NSError* error;
 
+// Contains total amount of received data.
+@property(readonly) long totalBytesReceived;
+
 @end
 
 @implementation TestDelegate
+
 @synthesize semaphore = _semaphore;
 @synthesize error = _error;
+@synthesize totalBytesReceived = _totalBytesReceived;
 
 NSMutableArray<NSData*>* _responseData;
 
@@ -63,6 +68,7 @@
   [_responseData dealloc];
   _responseData = nil;
   _error = nil;
+  _totalBytesReceived = 0;
 }
 
 - (NSString*)responseBody {
@@ -110,6 +116,7 @@
 - (void)URLSession:(NSURLSession*)session
           dataTask:(NSURLSessionDataTask*)dataTask
     didReceiveData:(NSData*)data {
+  _totalBytesReceived += [data length];
   if (_responseData == nil) {
     _responseData = [[NSMutableArray alloc] init];
   }
@@ -181,13 +188,32 @@
   base::scoped_nsobject<TestDelegate> delegate_;
 };
 
-TEST_F(HttpTest, CreateFile) {
-  bool ssl_file_created = [[NSFileManager defaultManager]
-      fileExistsAtPath:[Cronet getNetLogPathForFile:@"SSLKEYLOGFILE"]];
+TEST_F(HttpTest, CreateSslKeyLogFile) {
+  // Shutdown Cronet so that it can be restarted with specific configuration
+  // (SSL key log file specified in experimental options) for this one test.
+  // This is necessary because SslKeyLogFile can only be set once, before any
+  // SSL Client Sockets are created.
 
-  [[NSFileManager defaultManager]
-      removeItemAtPath:[Cronet getNetLogPathForFile:@"SSLKEYLOGFILE"]
-                 error:nil];
+  [Cronet shutdownForTesting];
+
+  NSString* ssl_key_log_file = [Cronet getNetLogPathForFile:@"SSLKEYLOGFILE"];
+
+  // Ensure that the keylog file doesn't exist.
+  [[NSFileManager defaultManager] removeItemAtPath:ssl_key_log_file error:nil];
+
+  [Cronet setExperimentalOptions:
+              [NSString stringWithFormat:@"{\"ssl_key_log_file\":\"%@\"}",
+                                         ssl_key_log_file]];
+
+  StartCronet(grpc_support::GetQuicTestServerPort());
+
+  bool ssl_file_created =
+      [[NSFileManager defaultManager] fileExistsAtPath:ssl_key_log_file];
+
+  [[NSFileManager defaultManager] removeItemAtPath:ssl_key_log_file error:nil];
+
+  [Cronet shutdownForTesting];
+  [Cronet setExperimentalOptions:@""];
 
   EXPECT_TRUE(ssl_file_created);
 }
@@ -232,6 +258,7 @@
       elapsed_max = elapsed;
     EXPECT_TRUE(block_used);
     EXPECT_EQ(nil, [delegate_ error]);
+    EXPECT_EQ(size, [delegate_ totalBytesReceived]);
   }
   // Release the response buffer.
   TestServer::ReleaseBigDataURL();
diff --git a/components/cronet/ios/test/start_cronet.mm b/components/cronet/ios/test/start_cronet.mm
index 6431ecf..3e46b9b 100644
--- a/components/cronet/ios/test/start_cronet.mm
+++ b/components/cronet/ios/test/start_cronet.mm
@@ -18,11 +18,6 @@
   [Cronet setHttp2Enabled:true];
   [Cronet setQuicEnabled:true];
   [Cronet setAcceptLanguages:@"en-US,en"];
-  [Cronet
-      setExperimentalOptions:
-          [NSString
-              stringWithFormat:@"{\"ssl_key_log_file\":\"%@\"}",
-                               [Cronet getNetLogPathForFile:@"SSLKEYLOGFILE"]]];
   [Cronet addQuicHint:@"test.example.com" port:443 altPort:443];
   [Cronet enableTestCertVerifierForTesting];
   [Cronet setHttpCacheType:CRNHttpCacheTypeDisabled];
diff --git a/components/favicon/content/content_favicon_driver.cc b/components/favicon/content/content_favicon_driver.cc
index 0b7c089..e5935ff 100644
--- a/components/favicon/content/content_favicon_driver.cc
+++ b/components/favicon/content/content_favicon_driver.cc
@@ -156,7 +156,7 @@
     return;
 
   favicon_urls_ = candidates;
-  OnUpdateFaviconURL(entry->GetURL(),
+  OnUpdateCandidates(entry->GetURL(),
                      FaviconURLsFromContentFaviconURLs(candidates));
 }
 
diff --git a/components/favicon/core/favicon_driver_impl.cc b/components/favicon/core/favicon_driver_impl.cc
index f77d11b..2c0bfa4 100644
--- a/components/favicon/core/favicon_driver_impl.cc
+++ b/components/favicon/core/favicon_driver_impl.cc
@@ -96,13 +96,13 @@
   }
 }
 
-void FaviconDriverImpl::OnUpdateFaviconURL(
+void FaviconDriverImpl::OnUpdateCandidates(
     const GURL& page_url,
     const std::vector<FaviconURL>& candidates) {
   DCHECK(!candidates.empty());
   RecordCandidateMetrics(candidates);
   for (const std::unique_ptr<FaviconHandler>& handler : handlers_)
-    handler->OnUpdateFaviconURL(page_url, candidates);
+    handler->OnUpdateCandidates(page_url, candidates);
 }
 
 }  // namespace favicon
diff --git a/components/favicon/core/favicon_driver_impl.h b/components/favicon/core/favicon_driver_impl.h
index 2faa6f3..1dd7311 100644
--- a/components/favicon/core/favicon_driver_impl.h
+++ b/components/favicon/core/favicon_driver_impl.h
@@ -59,7 +59,7 @@
   void SetFaviconOutOfDateForPage(const GURL& url, bool force_reload);
 
   // Broadcasts new favicon URL candidates to FaviconHandlers.
-  void OnUpdateFaviconURL(const GURL& page_url,
+  void OnUpdateCandidates(const GURL& page_url,
                           const std::vector<FaviconURL>& candidates);
 
  protected:
diff --git a/components/favicon/core/favicon_handler.cc b/components/favicon/core/favicon_handler.cc
index d5386a1..1434eb5e 100644
--- a/components/favicon/core/favicon_handler.cc
+++ b/components/favicon/core/favicon_handler.cc
@@ -198,7 +198,7 @@
       notification_icon_type_(favicon_base::INVALID_ICON),
       service_(service),
       delegate_(delegate),
-      num_download_requests_(0),
+      num_image_download_requests_(0),
       current_candidate_index_(0u) {
   DCHECK(delegate_);
 }
@@ -228,11 +228,11 @@
   initial_history_result_expired_or_incomplete_ = false;
   redownload_icons_ = false;
   got_favicon_from_history_ = false;
-  download_request_.Cancel();
+  image_download_request_.Cancel();
   candidates_.clear();
   notification_icon_url_ = GURL();
   notification_icon_type_ = favicon_base::INVALID_ICON;
-  num_download_requests_ = 0;
+  num_image_download_requests_ = 0;
   current_candidate_index_ = 0u;
   best_favicon_ = DownloadedFavicon();
 
@@ -314,7 +314,7 @@
   notification_icon_type_ = icon_type;
 }
 
-void FaviconHandler::OnUpdateFaviconURL(
+void FaviconHandler::OnUpdateCandidates(
     const GURL& page_url,
     const std::vector<FaviconURL>& candidates) {
   if (page_url != url_)
@@ -340,9 +340,9 @@
   }
 
   cancelable_task_tracker_for_candidates_.TryCancelAll();
-  download_request_.Cancel();
+  image_download_request_.Cancel();
   candidates_ = std::move(sorted_candidates);
-  num_download_requests_ = 0;
+  num_image_download_requests_ = 0;
   current_candidate_index_ = 0u;
   best_favicon_ = DownloadedFavicon();
 
@@ -387,7 +387,7 @@
     const std::vector<SkBitmap>& bitmaps,
     const std::vector<gfx::Size>& original_bitmap_sizes) {
   // Mark download as finished.
-  download_request_.Cancel();
+  image_download_request_.Cancel();
 
   if (bitmaps.empty() && http_status_code == 404) {
     DVLOG(1) << "Failed to Download Favicon:" << image_url;
@@ -433,8 +433,9 @@
     DownloadCurrentCandidateOrAskFaviconService();
   } else {
     // OnDidDownloadFavicon() can only be called after requesting a download, so
-    // |num_download_requests_| can never be 0.
-    RecordDownloadAttemptsForHandlerType(handler_type_, num_download_requests_);
+    // |num_image_download_requests_| can never be 0.
+    RecordDownloadAttemptsForHandlerType(handler_type_,
+                                         num_image_download_requests_);
     // We have either found the ideal candidate or run out of candidates.
     if (best_favicon_.candidate.icon_type != favicon_base::INVALID_ICON) {
       // No more icons to request, set the favicon from the candidate.
@@ -443,7 +444,7 @@
     }
     // Clear download related state.
     current_candidate_index_ = candidates_.size();
-    num_download_requests_ = 0;
+    num_image_download_requests_ = 0;
     best_favicon_ = DownloadedFavicon();
   }
 }
@@ -456,7 +457,7 @@
 }
 
 bool FaviconHandler::HasPendingTasksForTest() {
-  return !download_request_.IsCancelled() ||
+  return !image_download_request_.IsCancelled() ||
          cancelable_task_tracker_for_page_url_.HasTrackedTasks() ||
          cancelable_task_tracker_for_candidates_.HasTrackedTasks();
 }
@@ -502,7 +503,7 @@
 
   if (redownload_icons_) {
     // We have the mapping, but the favicon is out of date. Download it now.
-    ScheduleDownload(icon_url, icon_type);
+    ScheduleImageDownload(icon_url, icon_type);
   } else {
     // We don't know the favicon, but we may have previously downloaded the
     // favicon for another page that shares the same favicon. Ask for the
@@ -542,18 +543,20 @@
   }
 
   if (has_expired_or_incomplete_result) {
-    ScheduleDownload(current_candidate()->icon_url,
-                     current_candidate()->icon_type);
-  } else if (num_download_requests_ > 0) {
-    RecordDownloadAttemptsForHandlerType(handler_type_, num_download_requests_);
+    ScheduleImageDownload(current_candidate()->icon_url,
+                          current_candidate()->icon_type);
+  } else if (num_image_download_requests_ > 0) {
+    RecordDownloadAttemptsForHandlerType(handler_type_,
+                                         num_image_download_requests_);
   }
 }
 
-void FaviconHandler::ScheduleDownload(const GURL& image_url,
-                                      favicon_base::IconType icon_type) {
+void FaviconHandler::ScheduleImageDownload(const GURL& image_url,
+                                           favicon_base::IconType icon_type) {
   DCHECK(image_url.is_valid());
   // Note that CancelableCallback starts cancelled.
-  DCHECK(download_request_.IsCancelled()) << "More than one ongoing download";
+  DCHECK(image_download_request_.IsCancelled())
+      << "More than one ongoing download";
   if (service_->WasUnableToDownloadFavicon(image_url)) {
     DVLOG(1) << "Skip Failed FavIcon: " << image_url;
     RecordDownloadOutcome(DownloadOutcome::SKIPPED);
@@ -561,15 +564,16 @@
                          std::vector<gfx::Size>());
     return;
   }
-  ++num_download_requests_;
-  download_request_.Reset(base::Bind(&FaviconHandler::OnDidDownloadFavicon,
-                                     base::Unretained(this), icon_type));
+  ++num_image_download_requests_;
+  image_download_request_.Reset(
+      base::Bind(&FaviconHandler::OnDidDownloadFavicon, base::Unretained(this),
+                 icon_type));
   // A max bitmap size is specified to avoid receiving huge bitmaps in
   // OnDidDownloadFavicon(). See FaviconDriver::StartDownload()
   // for more details about the max bitmap size.
   const int download_id =
       delegate_->DownloadImage(image_url, GetMaximalIconSize(handler_type_),
-                               download_request_.callback());
+                               image_download_request_.callback());
   DCHECK_NE(download_id, 0);
 }
 
diff --git a/components/favicon/core/favicon_handler.h b/components/favicon/core/favicon_handler.h
index b49f4e5..0e579b3 100644
--- a/components/favicon/core/favicon_handler.h
+++ b/components/favicon/core/favicon_handler.h
@@ -139,7 +139,7 @@
 
   // Message Handler.  Must be public, because also called from
   // PrerenderContents. Collects the |image_urls| list.
-  void OnUpdateFaviconURL(const GURL& page_url,
+  void OnUpdateCandidates(const GURL& page_url,
                           const std::vector<favicon::FaviconURL>& candidates);
 
   // For testing.
@@ -206,9 +206,9 @@
                          favicon_bitmap_results);
 
   // Schedules a download for the specified entry. This adds the request to
-  // download_requests_.
-  void ScheduleDownload(const GURL& image_url,
-                        favicon_base::IconType icon_type);
+  // image_download_requests_.
+  void ScheduleImageDownload(const GURL& image_url,
+                             favicon_base::IconType icon_type);
 
   // Triggered when a download of an image has finished.
   void OnDidDownloadFavicon(
@@ -285,7 +285,7 @@
 
   // Requests to the renderer to download favicons.
   base::CancelableCallback<Delegate::ImageDownloadCallback::RunType>
-      download_request_;
+      image_download_request_;
 
   // The combination of the supported icon types.
   const int icon_types_;
@@ -310,7 +310,7 @@
 
   // Captures the number of download requests that were initiated for the
   // current url_.
-  int num_download_requests_;
+  int num_image_download_requests_;
 
   // The index of the favicon URL in |image_urls_| which is currently being
   // requested from history or downloaded.
diff --git a/components/favicon/core/favicon_handler_unittest.cc b/components/favicon/core/favicon_handler_unittest.cc
index 1cce8b1..4ff91269 100644
--- a/components/favicon/core/favicon_handler_unittest.cc
+++ b/components/favicon/core/favicon_handler_unittest.cc
@@ -212,8 +212,8 @@
   MockDelegate() {
     // Delegate image downloading to FakeImageDownloader.
     ON_CALL(*this, DownloadImage(_, _, _))
-        .WillByDefault(
-            Invoke(&fake_downloader_, &FakeImageDownloader::DownloadImage));
+        .WillByDefault(Invoke(&fake_image_downloader_,
+                              &FakeImageDownloader::DownloadImage));
   }
 
   MOCK_METHOD3(DownloadImage,
@@ -229,14 +229,18 @@
                     bool icon_url_changed,
                     const gfx::Image& image));
 
-  FakeImageDownloader& fake_downloader() { return fake_downloader_; }
+  FakeImageDownloader& fake_image_downloader() {
+    return fake_image_downloader_;
+  }
 
   // Convenience getter for test readability. Returns pending and completed
   // download URLs.
-  const URLVector& downloads() const { return fake_downloader_.downloads(); }
+  const URLVector& downloads() const {
+    return fake_image_downloader_.downloads();
+  }
 
  private:
-  FakeImageDownloader fake_downloader_;
+  FakeImageDownloader fake_image_downloader_;
 };
 
 // FakeFaviconService mimics a FaviconService backend that allows setting up
@@ -383,10 +387,10 @@
       : scoped_task_environment_(
             base::test::ScopedTaskEnvironment::MainThreadType::UI) {
     // Register various known icon URLs.
-    delegate_.fake_downloader().Add(kIconURL10x10, IntVector{10});
-    delegate_.fake_downloader().Add(kIconURL12x12, IntVector{12});
-    delegate_.fake_downloader().Add(kIconURL16x16, IntVector{16});
-    delegate_.fake_downloader().Add(kIconURL64x64, IntVector{64});
+    delegate_.fake_image_downloader().Add(kIconURL10x10, IntVector{10});
+    delegate_.fake_image_downloader().Add(kIconURL12x12, IntVector{12});
+    delegate_.fake_image_downloader().Add(kIconURL16x16, IntVector{16});
+    delegate_.fake_image_downloader().Add(kIconURL64x64, IntVector{64});
 
     // The score computed by SelectFaviconFrames() is dependent on the supported
     // scale factors of the platform. It is used for determining the goodness of
@@ -400,7 +404,7 @@
   bool VerifyAndClearExpectations() {
     base::RunLoop().RunUntilIdle();
     favicon_service_.fake()->ClearDbRequests();
-    delegate_.fake_downloader().ClearDownloads();
+    delegate_.fake_image_downloader().ClearDownloads();
     return testing::Mock::VerifyAndClearExpectations(&favicon_service_) &&
            testing::Mock::VerifyAndClearExpectations(&delegate_);
   }
@@ -414,9 +418,9 @@
                                                     &delegate_, handler_type);
     handler->FetchFavicon(kPageURL);
     // The first RunUntilIdle() causes the FaviconService lookups be faster than
-    // OnUpdateFaviconURL(), which is the most likely scenario.
+    // OnUpdateCandidates(), which is the most likely scenario.
     base::RunLoop().RunUntilIdle();
-    handler->OnUpdateFaviconURL(kPageURL, candidates);
+    handler->OnUpdateCandidates(kPageURL, candidates);
     base::RunLoop().RunUntilIdle();
     return handler;
   }
@@ -475,7 +479,7 @@
 // - There is data in the database for neither the page URL nor the icon URL.
 // AND
 // - FaviconService::GetFaviconForPageURL() callback returns before
-//   FaviconHandler::OnUpdateFaviconURL() is called.
+//   FaviconHandler::OnUpdateCandidates() is called.
 TEST_F(FaviconHandlerTest, DownloadUnknownFaviconIfCandidatesSlower) {
   // Defer the database lookup completion to control the exact timing.
   favicon_service_.fake()->SetRunCallbackManuallyForUrl(kPageURL);
@@ -489,7 +493,7 @@
   base::RunLoop().RunUntilIdle();
   // Database lookup for |kPageURL| is ongoing.
   ASSERT_TRUE(favicon_service_.fake()->HasPendingManualCallback());
-  // Causes FaviconService lookups be faster than OnUpdateFaviconURL().
+  // Causes FaviconService lookups be faster than OnUpdateCandidates().
   ASSERT_TRUE(favicon_service_.fake()->RunCallbackManually());
   ASSERT_TRUE(VerifyAndClearExpectations());
 
@@ -499,7 +503,7 @@
                              kPageURL, FaviconDriverObserver::NON_TOUCH_16_DIP,
                              kIconURL16x16, /*icon_url_changed=*/true, _));
   // Feed in favicons now that the database lookup is completed.
-  handler.OnUpdateFaviconURL(kPageURL,
+  handler.OnUpdateCandidates(kPageURL,
                              {FaviconURL(kIconURL16x16, FAVICON, kEmptySizes)});
   base::RunLoop().RunUntilIdle();
 
@@ -512,7 +516,7 @@
 // - There is data in the database for neither the page URL nor the icon URL.
 // AND
 // - FaviconService::GetFaviconForPageURL() callback returns after
-//   FaviconHandler::OnUpdateFaviconURL() is called.
+//   FaviconHandler::OnUpdateCandidates() is called.
 TEST_F(FaviconHandlerTest, DownloadUnknownFaviconIfCandidatesFaster) {
   // Defer the database lookup completion to control the exact timing.
   favicon_service_.fake()->SetRunCallbackManuallyForUrl(kPageURL);
@@ -525,7 +529,7 @@
   handler.FetchFavicon(kPageURL);
   base::RunLoop().RunUntilIdle();
   // Feed in favicons before completing the database lookup.
-  handler.OnUpdateFaviconURL(kPageURL,
+  handler.OnUpdateCandidates(kPageURL,
                              {FaviconURL(kIconURL16x16, FAVICON, kEmptySizes)});
 
   ASSERT_TRUE(VerifyAndClearExpectations());
@@ -590,8 +594,9 @@
       CreateRawBitmapResult(kIconURL, FAVICON, /*expired=*/true,
                             gfx::kFaviconSize, kOldColor));
 
-  delegate_.fake_downloader().Add(kIconURL, IntVector{gfx::kFaviconSize},
-                                  IntVector{gfx::kFaviconSize}, kNewColor);
+  delegate_.fake_image_downloader().Add(kIconURL, IntVector{gfx::kFaviconSize},
+                                        IntVector{gfx::kFaviconSize},
+                                        kNewColor);
 
   EXPECT_CALL(favicon_service_,
               SetFavicons(_, kIconURL, _, ImageColorIs(kNewColor)));
@@ -638,8 +643,9 @@
 TEST_F(FaviconHandlerTest, FaviconInHistoryInvalid) {
   const GURL kIconURL("http://www.google.com/favicon");
 
-  delegate_.fake_downloader().Add(kIconURL, IntVector{gfx::kFaviconSize},
-                                  IntVector{gfx::kFaviconSize}, SK_ColorBLUE);
+  delegate_.fake_image_downloader().Add(kIconURL, IntVector{gfx::kFaviconSize},
+                                        IntVector{gfx::kFaviconSize},
+                                        SK_ColorBLUE);
 
   // Set non empty but invalid data.
   std::vector<FaviconRawBitmapResult> bitmap_result =
@@ -685,7 +691,7 @@
 TEST_F(FaviconHandlerTest, Download2ndFaviconURLCandidate) {
   const GURL kIconURLReturning500("http://www.google.com/500.png");
 
-  delegate_.fake_downloader().AddError(kIconURLReturning500, 500);
+  delegate_.fake_image_downloader().AddError(kIconURLReturning500, 500);
 
   favicon_service_.fake()->Store(
       kPageURL, kIconURL64x64,
@@ -712,7 +718,7 @@
 
 // Test that download data for icon URLs other than the current favicon
 // candidate URLs is ignored. This test tests the scenario where a download is
-// in flight when FaviconHandler::OnUpdateFaviconURL() is called.
+// in flight when FaviconHandler::OnUpdateCandidates() is called.
 // TODO(mastiz): Make this test deal with FaviconURLs of type
 // favicon_base::FAVICON and add new ones like OnlyDownloadMatchingIconType and
 // CallSetFaviconsWithCorrectIconType.
@@ -723,27 +729,27 @@
 
   // Defer the download completion such that RunUntilIdle() doesn't complete
   // the download.
-  delegate_.fake_downloader().SetRunCallbackManuallyForUrl(kIconURL1);
+  delegate_.fake_image_downloader().SetRunCallbackManuallyForUrl(kIconURL1);
 
-  delegate_.fake_downloader().Add(kIconURL1, IntVector{16});
-  delegate_.fake_downloader().Add(kIconURL3, IntVector{64});
+  delegate_.fake_image_downloader().Add(kIconURL1, IntVector{16});
+  delegate_.fake_image_downloader().Add(kIconURL3, IntVector{64});
 
   std::unique_ptr<FaviconHandler> handler =
       RunHandlerWithSimpleFaviconCandidates({kIconURL1, kIconURL2});
 
   ASSERT_TRUE(VerifyAndClearExpectations());
-  ASSERT_TRUE(delegate_.fake_downloader().HasPendingManualCallback());
+  ASSERT_TRUE(delegate_.fake_image_downloader().HasPendingManualCallback());
 
   // Favicon update should invalidate the ongoing download.
   EXPECT_CALL(favicon_service_, SetFavicons(_, kIconURL3, _, _));
   EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kIconURL3, _, _));
 
-  handler->OnUpdateFaviconURL(kPageURL,
+  handler->OnUpdateCandidates(kPageURL,
                               {FaviconURL(kIconURL3, FAVICON, kEmptySizes)});
 
   // Finalizes download, which should be thrown away as the favicon URLs were
   // updated.
-  EXPECT_TRUE(delegate_.fake_downloader().RunCallbackManually());
+  EXPECT_TRUE(delegate_.fake_image_downloader().RunCallbackManually());
   base::RunLoop().RunUntilIdle();
 
   EXPECT_THAT(favicon_service_.fake()->db_requests(), ElementsAre(kIconURL3));
@@ -761,8 +767,8 @@
   // lookup.
   favicon_service_.fake()->SetRunCallbackManuallyForUrl(kIconURL1);
 
-  delegate_.fake_downloader().Add(kIconURL1, IntVector{16});
-  delegate_.fake_downloader().Add(kIconURL2, IntVector{64});
+  delegate_.fake_image_downloader().Add(kIconURL1, IntVector{16});
+  delegate_.fake_image_downloader().Add(kIconURL2, IntVector{64});
 
   std::unique_ptr<FaviconHandler> handler =
       RunHandlerWithSimpleFaviconCandidates(URLVector{kIconURL1});
@@ -775,7 +781,7 @@
   EXPECT_CALL(favicon_service_, SetFavicons(_, kIconURL2, _, _));
   EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kIconURL2, _, _));
 
-  handler->OnUpdateFaviconURL(kPageURL,
+  handler->OnUpdateCandidates(kPageURL,
                               {FaviconURL(kIconURL2, FAVICON, kEmptySizes)});
 
   // Finalizes the DB lookup, which should be thrown away as the favicon URLs
@@ -799,8 +805,9 @@
 
   // Defer the download completion such that RunUntilIdle() doesn't complete
   // the download.
-  delegate_.fake_downloader().SetRunCallbackManuallyForUrl(kSlowLoadingIconURL);
-  delegate_.fake_downloader().Add(kSlowLoadingIconURL, IntVector{16});
+  delegate_.fake_image_downloader().SetRunCallbackManuallyForUrl(
+      kSlowLoadingIconURL);
+  delegate_.fake_image_downloader().Add(kSlowLoadingIconURL, IntVector{16});
 
   std::unique_ptr<FaviconHandler> handler = RunHandlerWithCandidates(
       FaviconDriverObserver::NON_TOUCH_16_DIP, favicon_urls);
@@ -808,11 +815,11 @@
   ASSERT_THAT(favicon_service_.fake()->db_requests(),
               ElementsAre(kPageURL, kIconURL64x64, kSlowLoadingIconURL));
   ASSERT_TRUE(VerifyAndClearExpectations());
-  ASSERT_TRUE(delegate_.fake_downloader().HasPendingManualCallback());
+  ASSERT_TRUE(delegate_.fake_image_downloader().HasPendingManualCallback());
 
-  // Calling OnUpdateFaviconURL() with the same icon URLs should have no effect,
+  // Calling OnUpdateCandidates() with the same icon URLs should have no effect,
   // despite the ongoing download.
-  handler->OnUpdateFaviconURL(kPageURL, favicon_urls);
+  handler->OnUpdateCandidates(kPageURL, favicon_urls);
   base::RunLoop().RunUntilIdle();
   EXPECT_THAT(favicon_service_.fake()->db_requests(), IsEmpty());
   EXPECT_THAT(delegate_.downloads(), IsEmpty());
@@ -820,7 +827,7 @@
   // Complete the download.
   EXPECT_CALL(favicon_service_, SetFavicons(_, _, _, _));
   EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, _, _, _));
-  EXPECT_TRUE(delegate_.fake_downloader().RunCallbackManually());
+  EXPECT_TRUE(delegate_.fake_image_downloader().RunCallbackManually());
   base::RunLoop().RunUntilIdle();
   EXPECT_THAT(delegate_.downloads(), IsEmpty());
 }
@@ -844,9 +851,9 @@
   ASSERT_TRUE(VerifyAndClearExpectations());
   ASSERT_TRUE(favicon_service_.fake()->HasPendingManualCallback());
 
-  // Calling OnUpdateFaviconURL() with the same icon URLs should have no effect,
+  // Calling OnUpdateCandidates() with the same icon URLs should have no effect,
   // despite the ongoing DB lookup.
-  handler->OnUpdateFaviconURL(kPageURL, favicon_urls);
+  handler->OnUpdateCandidates(kPageURL, favicon_urls);
   base::RunLoop().RunUntilIdle();
   EXPECT_THAT(favicon_service_.fake()->db_requests(), IsEmpty());
   EXPECT_THAT(delegate_.downloads(), IsEmpty());
@@ -873,11 +880,11 @@
 
   ASSERT_TRUE(VerifyAndClearExpectations());
 
-  // Calling OnUpdateFaviconURL() with identical data should be a no-op.
+  // Calling OnUpdateCandidates() with identical data should be a no-op.
   EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, _, _, _)).Times(0);
   EXPECT_CALL(favicon_service_, SetFavicons(_, _, _, _)).Times(0);
 
-  handler->OnUpdateFaviconURL(kPageURL, favicon_urls);
+  handler->OnUpdateCandidates(kPageURL, favicon_urls);
   base::RunLoop().RunUntilIdle();
   EXPECT_THAT(favicon_service_.fake()->db_requests(), IsEmpty());
   EXPECT_THAT(delegate_.downloads(), IsEmpty());
@@ -898,8 +905,8 @@
       "http://wwww.page_which_animates_favicon.com/frame2.png");
 
   // |kIconURL1| is the better match.
-  delegate_.fake_downloader().Add(kIconURL1, IntVector{15});
-  delegate_.fake_downloader().Add(kIconURL2, IntVector{10});
+  delegate_.fake_image_downloader().Add(kIconURL1, IntVector{15});
+  delegate_.fake_image_downloader().Add(kIconURL2, IntVector{10});
 
   // Two FaviconDriver::OnFaviconUpdated() notifications should be sent for
   // |kIconURL1|, one before and one after the download.
@@ -919,7 +926,7 @@
   // Simulate the page changing it's icon URL to just |kIconURL2| via
   // Javascript.
   EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kIconURL2, _, _));
-  handler->OnUpdateFaviconURL(kPageURL,
+  handler->OnUpdateCandidates(kPageURL,
                               {FaviconURL(kIconURL2, FAVICON, kEmptySizes)});
   base::RunLoop().RunUntilIdle();
 }
@@ -957,7 +964,7 @@
       const GURL icon_url(base::StringPrintf(
           "https://www.google.com/generated/%dx%d", icon_size, icon_size));
       // Set up 200 responses for all images, and the corresponding size.
-      delegate_.fake_downloader().Add(icon_url, IntVector{icon_size});
+      delegate_.fake_image_downloader().Add(icon_url, IntVector{icon_size});
       // Create test candidates of type FAVICON and a fake URL.
       candidate_icons.emplace_back(icon_url, FAVICON, kEmptySizes);
 
@@ -1013,7 +1020,7 @@
 TEST_F(FaviconHandlerTest, NotReport503) {
   const GURL k503IconURL("http://www.google.com/503.png");
 
-  delegate_.fake_downloader().AddError(k503IconURL, 503);
+  delegate_.fake_image_downloader().AddError(k503IconURL, 503);
 
   EXPECT_CALL(favicon_service_, UnableToDownloadFavicon(_)).Times(0);
 
@@ -1146,8 +1153,8 @@
   const GURL kIconURL1("http://www.google.com/b");
   const GURL kIconURL2("http://www.google.com/c");
 
-  delegate_.fake_downloader().Add(kIconURL1, IntVector{15});
-  delegate_.fake_downloader().Add(kIconURL2, IntVector{14, 16});
+  delegate_.fake_image_downloader().Add(kIconURL1, IntVector{15});
+  delegate_.fake_image_downloader().Add(kIconURL2, IntVector{14, 16});
 
   // Verify NotifyFaviconAvailable().
   EXPECT_CALL(delegate_,
@@ -1172,10 +1179,12 @@
   const int kOriginalSize1 = kMaximalSize + 1;
   const int kOriginalSize2 = kMaximalSize + 2;
 
-  delegate_.fake_downloader().Add(kIconURL1, IntVector{kMaximalSize},
-                                  IntVector{kOriginalSize1}, SK_ColorBLUE);
-  delegate_.fake_downloader().Add(kIconURL2, IntVector{kMaximalSize},
-                                  IntVector{kOriginalSize2}, SK_ColorBLUE);
+  delegate_.fake_image_downloader().Add(kIconURL1, IntVector{kMaximalSize},
+                                        IntVector{kOriginalSize1},
+                                        SK_ColorBLUE);
+  delegate_.fake_image_downloader().Add(kIconURL2, IntVector{kMaximalSize},
+                                        IntVector{kOriginalSize2},
+                                        SK_ColorBLUE);
 
   // Verify the best bitmap was selected (although smaller than |kIconURL2|)
   // and that it was scaled down to |kMaximalSize|.
@@ -1334,7 +1343,7 @@
   base::HistogramTester histogram_tester;
   const GURL k404IconURL("http://www.google.com/404.png");
 
-  delegate_.fake_downloader().AddError(k404IconURL, 404);
+  delegate_.fake_image_downloader().AddError(k404IconURL, 404);
 
   EXPECT_CALL(favicon_service_, UnableToDownloadFavicon(k404IconURL));
 
diff --git a/components/favicon/ios/web_favicon_driver.mm b/components/favicon/ios/web_favicon_driver.mm
index cba29896..321acb6c 100644
--- a/components/favicon/ios/web_favicon_driver.mm
+++ b/components/favicon/ios/web_favicon_driver.mm
@@ -141,7 +141,7 @@
 void WebFaviconDriver::FaviconUrlUpdated(
     const std::vector<web::FaviconURL>& candidates) {
   DCHECK(!candidates.empty());
-  OnUpdateFaviconURL(GetActiveURL(), FaviconURLsFromWebFaviconURLs(candidates));
+  OnUpdateCandidates(GetActiveURL(), FaviconURLsFromWebFaviconURLs(candidates));
 }
 
 }  // namespace favicon
diff --git a/components/google/core/browser/google_util.cc b/components/google/core/browser/google_util.cc
index a16d55e..b8f8c1da 100644
--- a/components/google/core/browser/google_util.cc
+++ b/components/google/core/browser/google_util.cc
@@ -45,6 +45,12 @@
   return (path == "/") || (path == "/webhp");
 }
 
+// Removes a single trailing dot if present in |host|.
+void StripTrailingDot(base::StringPiece* host) {
+  if (host->ends_with("."))
+    host->remove_suffix(1);
+}
+
 // True if the given canonical |host| is "[www.]<domain_in_lower_case>.<TLD>"
 // with a valid TLD. If |subdomain_permission| is ALLOW_SUBDOMAIN, we check
 // against host "*.<domain_in_lower_case>.<TLD>" instead. Will return the TLD
@@ -104,11 +110,31 @@
   if (!IsValidHostName(canonical_host, "google", subdomain_permission, &tld))
     return false;
 
+  // Remove the trailing dot from tld if present, as for google domain it's the
+  // same page.
+  StripTrailingDot(&tld);
+
   CR_DEFINE_STATIC_LOCAL(std::set<std::string>, google_tlds,
                          ({GOOGLE_TLD_LIST}));
   return base::ContainsKey(google_tlds, tld.as_string());
 }
 
+// True if |url| is a valid URL with a host that is in the static list of
+// Google subdomains for google search, and an HTTP or HTTPS scheme. Requires
+// |url| to use the standard port for its scheme (80 for HTTP, 443 for HTTPS).
+bool IsGoogleSearchSubdomainUrl(const GURL& url) {
+  if (!IsValidURL(url, PortPermission::DISALLOW_NON_STANDARD_PORTS))
+    return false;
+
+  base::StringPiece host(url.host_piece());
+  StripTrailingDot(&host);
+
+  CR_DEFINE_STATIC_LOCAL(std::set<std::string>, google_subdomains,
+                         ({"ipv4.google.com", "ipv6.google.com"}));
+
+  return base::ContainsKey(google_subdomains, host.as_string());
+}
+
 }  // namespace
 
 // Global functions -----------------------------------------------------------
@@ -148,10 +174,10 @@
 
 std::string GetGoogleCountryCode(const GURL& google_homepage_url) {
   base::StringPiece google_hostname = google_homepage_url.host_piece();
+  // TODO(igorcov): This needs a fix for case when the host has a trailing dot,
+  // like "google.com./". https://crbug.com/720295.
   const size_t last_dot = google_hostname.find_last_of('.');
-  if (last_dot == std::string::npos) {
-    NOTREACHED();
-  }
+  DCHECK_NE(std::string::npos, last_dot);
   base::StringPiece country_code = google_hostname.substr(last_dot + 1);
   // Assume the com TLD implies the US.
   if (country_code == "com")
@@ -217,8 +243,11 @@
 
 bool IsGoogleHomePageUrl(const GURL& url) {
   // First check to see if this has a Google domain.
-  if (!IsGoogleDomainUrl(url, DISALLOW_SUBDOMAIN, DISALLOW_NON_STANDARD_PORTS))
+  if (!IsGoogleDomainUrl(url, DISALLOW_SUBDOMAIN,
+                         DISALLOW_NON_STANDARD_PORTS) &&
+      !IsGoogleSearchSubdomainUrl(url)) {
     return false;
+  }
 
   // Make sure the path is a known home page path.
   base::StringPiece path(url.path_piece());
@@ -228,8 +257,11 @@
 
 bool IsGoogleSearchUrl(const GURL& url) {
   // First check to see if this has a Google domain.
-  if (!IsGoogleDomainUrl(url, DISALLOW_SUBDOMAIN, DISALLOW_NON_STANDARD_PORTS))
+  if (!IsGoogleDomainUrl(url, DISALLOW_SUBDOMAIN,
+                         DISALLOW_NON_STANDARD_PORTS) &&
+      !IsGoogleSearchSubdomainUrl(url)) {
     return false;
+  }
 
   // Make sure the path is a known search path.
   base::StringPiece path(url.path_piece());
diff --git a/components/google/core/browser/google_util_unittest.cc b/components/google/core/browser/google_util_unittest.cc
index d30d03b..46072bf5 100644
--- a/components/google/core/browser/google_util_unittest.cc
+++ b/components/google/core/browser/google_util_unittest.cc
@@ -64,6 +64,14 @@
   EXPECT_TRUE(IsHomePage("http://www.google.com/ig/foo"));
   EXPECT_TRUE(IsHomePage("http://www.google.com/ig?rlz=TEST"));
   EXPECT_TRUE(IsHomePage("http://www.google.com/ig/foo?rlz=TEST"));
+
+  // Accepted subdomains.
+  EXPECT_TRUE(IsHomePage("http://ipv4.google.com/"));
+  EXPECT_TRUE(IsHomePage("http://ipv6.google.com/"));
+
+  // Trailing dots.
+  EXPECT_TRUE(IsHomePage("http://ipv4.google.com./"));
+  EXPECT_TRUE(IsHomePage("http://google.com./"));
 }
 
 TEST(GoogleUtilTest, GoodHomePagesSecure) {
@@ -121,37 +129,52 @@
 
   // Path is case sensitive.
   EXPECT_FALSE(IsHomePage("https://www.google.com/WEBHP"));
+
+  // Only .com subdomain and no www.
+  EXPECT_FALSE(IsHomePage("http://ipv4.google.co.uk"));
+  EXPECT_FALSE(IsHomePage("http://www.ipv4.google.com"));
 }
 
 TEST(GoogleUtilTest, GoodSearches) {
   const std::string patterns[] = {
-    // Queries with path "/search" need to have the query parameter in either
-    // the url parameter or the hash fragment.
-    "%s://www.google.com/search?%s=something",
-    "%s://www.google.com/search#%s=something",
-    "%s://www.google.com/search?name=bob&%s=something",
-    "%s://www.google.com/search?name=bob#%s=something",
-    "%s://www.google.com/search?name=bob#age=24&%s=thng",
-    "%s://www.google.co.uk/search?%s=something",
-    // It's actually valid for both to have the query parameter.
-    "%s://www.google.com/search?%s=something#q=other",
+      // Queries with path "/search" need to have the query parameter in either
+      // the url parameter or the hash fragment.
+      "%s://www.google.com/search?%s=something",
+      "%s://www.google.com/search#%s=something",
+      "%s://www.google.com/search?name=bob&%s=something",
+      "%s://www.google.com/search?name=bob#%s=something",
+      "%s://www.google.com/search?name=bob#age=24&%s=thng",
+      "%s://www.google.co.uk/search?%s=something",
+      // It's actually valid for both to have the query parameter.
+      "%s://www.google.com/search?%s=something#q=other",
 
-    // Queries with path "/webhp", "/" or "" need to have the query parameter in
-    // the hash fragment.
-    "%s://www.google.com/webhp#%s=something",
-    "%s://www.google.com/webhp#name=bob&%s=something",
-    "%s://www.google.com/webhp?name=bob#%s=something",
-    "%s://www.google.com/webhp?name=bob#age=24&%s=thing",
+      // Queries with path "/webhp", "/" or "" need to have the query parameter
+      // in the hash fragment.
+      "%s://www.google.com/webhp#%s=something",
+      "%s://www.google.com/webhp#name=bob&%s=something",
+      "%s://www.google.com/webhp?name=bob#%s=something",
+      "%s://www.google.com/webhp?name=bob#age=24&%s=thing",
 
-    "%s://www.google.com/#%s=something",
-    "%s://www.google.com/#name=bob&%s=something",
-    "%s://www.google.com/?name=bob#%s=something",
-    "%s://www.google.com/?name=bob#age=24&%s=something",
+      "%s://www.google.com/#%s=something",
+      "%s://www.google.com/#name=bob&%s=something",
+      "%s://www.google.com/?name=bob#%s=something",
+      "%s://www.google.com/?name=bob#age=24&%s=something",
 
-    "%s://www.google.com#%s=something",
-    "%s://www.google.com#name=bob&%s=something",
-    "%s://www.google.com?name=bob#%s=something",
-    "%s://www.google.com?name=bob#age=24&%s=something"
+      "%s://www.google.com#%s=something",
+      "%s://www.google.com#name=bob&%s=something",
+      "%s://www.google.com?name=bob#%s=something",
+      "%s://www.google.com?name=bob#age=24&%s=something",
+
+      // Google subdomain queries.
+      "%s://ipv4.google.com/search?%s=something",
+      "%s://ipv4.google.com#name=bob&%s=something",
+      "%s://ipv6.google.com?name=bob#%s=something",
+      "%s://ipv6.google.com?name=bob#age=24&%s=something",
+
+      // Trailing dots in the hosts.
+      "%s://www.google.com./#%s=something", "%s://www.google.de./#%s=something",
+      "%s://ipv4.google.com./#%s=something",
+      "%s://ipv6.google.com./#%s=something",
   };
 
   for (const std::string& pattern : patterns) {
diff --git a/components/payments/content/payment_request_state.cc b/components/payments/content/payment_request_state.cc
index 39abcfb..fb728d1 100644
--- a/components/payments/content/payment_request_state.cc
+++ b/components/payments/content/payment_request_state.cc
@@ -224,13 +224,11 @@
 
   // PaymentRequest may outlive the Profiles returned by the Data Manager.
   // Thus, we store copies, and return a vector of pointers to these copies
-  // whenever Profiles are requested. The same is true for credit cards.
+  // whenever Profiles are requested.
   for (size_t i = 0; i < profiles.size(); i++) {
     profile_cache_.push_back(
         base::MakeUnique<autofill::AutofillProfile>(*profiles[i]));
 
-    // TODO(tmartino): Implement deduplication rules specific to shipping
-    // profiles.
     shipping_profiles_.push_back(profile_cache_[i].get());
   }
 
@@ -245,7 +243,8 @@
   contact_profiles_ = profile_comparator()->FilterProfilesForContact(
       raw_profiles_for_filtering);
 
-  // Create the list of available instruments.
+  // Create the list of available instruments. A copy of each card will be made
+  // by their respective AutofillPaymentInstrument.
   const std::vector<autofill::CreditCard*>& cards =
       personal_data_manager_->GetCreditCardsToSuggest();
   for (autofill::CreditCard* card : cards)
@@ -255,9 +254,20 @@
 void PaymentRequestState::SetDefaultProfileSelections() {
   // Only pre-select an address if the merchant provided at least one selected
   // shipping option.
-  if (!shipping_profiles().empty() && spec_->selected_shipping_option())
-    selected_shipping_profile_ = shipping_profiles()[0];
+  if (!shipping_profiles().empty() && spec_->selected_shipping_option()) {
+    // Choose any complete shipping profile, or default to the most frecent
+    // address if no complete address could be found.
+    selected_shipping_profile_ = shipping_profiles_[0];
+    for (autofill::AutofillProfile* profile : shipping_profiles_) {
+      if (profile_comparator_.IsShippingComplete(profile)) {
+        selected_shipping_profile_ = profile;
+        break;
+      }
+    }
+  }
 
+  // Contact profiles were ordered by completeness in addition to frecency;
+  // the first one is the best default selection.
   if (!contact_profiles().empty())
     selected_contact_profile_ = contact_profiles()[0];
 
diff --git a/content/browser/dom_storage/local_storage_context_mojo_unittest.cc b/content/browser/dom_storage/local_storage_context_mojo_unittest.cc
index 60b3e98a..04bc509 100644
--- a/content/browser/dom_storage/local_storage_context_mojo_unittest.cc
+++ b/content/browser/dom_storage/local_storage_context_mojo_unittest.cc
@@ -74,7 +74,7 @@
 
   mojom::LevelDBObserverAssociatedPtrInfo Bind() {
     mojom::LevelDBObserverAssociatedPtrInfo ptr_info;
-    binding_.Bind(&ptr_info);
+    binding_.Bind(mojo::MakeRequest(&ptr_info));
     return ptr_info;
   }
 
diff --git a/content/browser/leveldb_wrapper_impl_unittest.cc b/content/browser/leveldb_wrapper_impl_unittest.cc
index 45b7a2a..3a54e20b 100644
--- a/content/browser/leveldb_wrapper_impl_unittest.cc
+++ b/content/browser/leveldb_wrapper_impl_unittest.cc
@@ -114,7 +114,7 @@
 
     level_db_wrapper_.Bind(mojo::MakeRequest(&level_db_wrapper_ptr_));
     mojom::LevelDBObserverAssociatedPtrInfo ptr_info;
-    observer_binding_.Bind(&ptr_info);
+    observer_binding_.Bind(mojo::MakeRequest(&ptr_info));
     level_db_wrapper_ptr_->AddObserver(std::move(ptr_info));
   }
 
diff --git a/content/browser/loader/navigation_url_loader_network_service.cc b/content/browser/loader/navigation_url_loader_network_service.cc
index 3cf2541..1f7d428 100644
--- a/content/browser/loader/navigation_url_loader_network_service.cc
+++ b/content/browser/loader/navigation_url_loader_network_service.cc
@@ -231,7 +231,7 @@
     binding_.Unbind();
 
   mojom::URLLoaderClientPtr url_loader_client_ptr_to_pass;
-  binding_.Bind(&url_loader_client_ptr_to_pass);
+  binding_.Bind(mojo::MakeRequest(&url_loader_client_ptr_to_pass));
 
   mojom::URLLoaderFactory* factory = nullptr;
   // This |factory_ptr| will be destroyed when it goes out of scope. Because
diff --git a/content/browser/loader/test_url_loader_client.cc b/content/browser/loader/test_url_loader_client.cc
index deab6e3..7bee5363 100644
--- a/content/browser/loader/test_url_loader_client.cc
+++ b/content/browser/loader/test_url_loader_client.cc
@@ -113,7 +113,7 @@
 
 mojom::URLLoaderClientPtr TestURLLoaderClient::CreateInterfacePtr() {
   mojom::URLLoaderClientPtr client_ptr;
-  binding_.Bind(&client_ptr);
+  binding_.Bind(mojo::MakeRequest(&client_ptr));
   return client_ptr;
 }
 
diff --git a/content/browser/renderer_host/media/render_frame_audio_output_stream_factory_unittest.cc b/content/browser/renderer_host/media/render_frame_audio_output_stream_factory_unittest.cc
index 23f3e82a..df12b52e2 100644
--- a/content/browser/renderer_host/media/render_frame_audio_output_stream_factory_unittest.cc
+++ b/content/browser/renderer_host/media/render_frame_audio_output_stream_factory_unittest.cc
@@ -153,8 +153,8 @@
     factory_ = base::MakeUnique<RenderFrameAudioOutputStreamFactory>(
         kRenderFrameId, this);
     factory_binding_ = base::MakeUnique<
-        mojo::Binding<mojom::RendererAudioOutputStreamFactory>>(factory_.get(),
-                                                                &ret);
+        mojo::Binding<mojom::RendererAudioOutputStreamFactory>>(
+        factory_.get(), mojo::MakeRequest(&ret));
     return ret;
   }
 
diff --git a/content/browser/service_worker/embedded_worker_instance.cc b/content/browser/service_worker/embedded_worker_instance.cc
index 0a2990c..92351588 100644
--- a/content/browser/service_worker/embedded_worker_instance.cc
+++ b/content/browser/service_worker/embedded_worker_instance.cc
@@ -592,7 +592,7 @@
 
   DCHECK(!instance_host_binding_.is_bound());
   mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo host_ptr_info;
-  instance_host_binding_.Bind(&host_ptr_info);
+  instance_host_binding_.Bind(mojo::MakeRequest(&host_ptr_info));
 
   DCHECK(pending_dispatcher_request_.is_pending());
   client_->StartWorker(*params, std::move(pending_dispatcher_request_),
diff --git a/content/browser/service_worker/service_worker_fetch_dispatcher.cc b/content/browser/service_worker/service_worker_fetch_dispatcher.cc
index e4deaa6..81e72bc 100644
--- a/content/browser/service_worker/service_worker_fetch_dispatcher.cc
+++ b/content/browser/service_worker/service_worker_fetch_dispatcher.cc
@@ -197,7 +197,9 @@
         base::Bind(&NotifyNavigationPreloadCompletedOnUI, completion_status));
   }
 
-  void Bind(mojom::URLLoaderClientPtr* ptr_info) { binding_.Bind(ptr_info); }
+  void Bind(mojom::URLLoaderClientPtr* ptr_info) {
+    binding_.Bind(mojo::MakeRequest(ptr_info));
+  }
 
  private:
   void MayBeRunDevToolsCallbacks() {
diff --git a/content/browser/service_worker/service_worker_register_job.cc b/content/browser/service_worker/service_worker_register_job.cc
index 5564f72..29c53149 100644
--- a/content/browser/service_worker/service_worker_register_job.cc
+++ b/content/browser/service_worker/service_worker_register_job.cc
@@ -38,7 +38,7 @@
 
   void BindInterface(
       mojom::ServiceWorkerInstallEventMethodsAssociatedPtrInfo* ptr_info) {
-    install_methods_binding_.Bind(ptr_info);
+    install_methods_binding_.Bind(mojo::MakeRequest(ptr_info));
   }
 
   // Implements mojom::ServiceWorkerInstallEventMethod.
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc
index 9f40f6c..7eebfa3c 100644
--- a/content/browser/site_per_process_browsertest.cc
+++ b/content/browser/site_per_process_browsertest.cc
@@ -9742,8 +9742,12 @@
 // the fullscreen feature. Since there are no HTTP header policies involved,
 // this verifies the presence of the container policy in the iframe.
 // https://crbug.com/703703
+// TODO(lunalu): Currently feature policy is shipped without fullscreen (e.g.,
+// the implementation of allowfullscreen does not use feature policy
+// information). Once allowfullscreen is controlled by feature policy, re-enable
+// this test.
 IN_PROC_BROWSER_TEST_F(SitePerProcessFeaturePolicyBrowserTest,
-                       ContainerPolicyCrossOriginNavigation) {
+                       DISABLED_ContainerPolicyCrossOriginNavigation) {
   WebContentsImpl* contents = web_contents();
   FrameTreeNode* root = contents->GetFrameTree()->root();
 
diff --git a/content/child/url_loader_client_impl.cc b/content/child/url_loader_client_impl.cc
index dd7e1b5..6671134 100644
--- a/content/child/url_loader_client_impl.cc
+++ b/content/child/url_loader_client_impl.cc
@@ -29,7 +29,7 @@
 }
 
 void URLLoaderClientImpl::Bind(mojom::URLLoaderClientPtr* client_ptr) {
-  binding_.Bind(client_ptr, task_runner_);
+  binding_.Bind(mojo::MakeRequest(client_ptr), task_runner_);
 }
 
 void URLLoaderClientImpl::SetDefersLoading() {
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc
index f13ec8b3..d122d0e44 100644
--- a/content/public/common/content_features.cc
+++ b/content/public/common/content_features.cc
@@ -64,7 +64,7 @@
 // Enables the Feature Policy framework for granting and removing access to
 // other features through HTTP headers.
 const base::Feature kFeaturePolicy{"FeaturePolicy",
-                                   base::FEATURE_DISABLED_BY_DEFAULT};
+                                   base::FEATURE_ENABLED_BY_DEFAULT};
 
 // Enable filtering of same-origin tiny plugins
 const base::Feature kFilterSameOriginTinyPlugin{
diff --git a/content/renderer/dom_storage/local_storage_cached_area.cc b/content/renderer/dom_storage/local_storage_cached_area.cc
index e832efeb..89feaca 100644
--- a/content/renderer/dom_storage/local_storage_cached_area.cc
+++ b/content/renderer/dom_storage/local_storage_cached_area.cc
@@ -99,7 +99,7 @@
   storage_partition_service->OpenLocalStorage(origin_,
                                               mojo::MakeRequest(&leveldb_));
   mojom::LevelDBObserverAssociatedPtrInfo ptr_info;
-  binding_.Bind(&ptr_info);
+  binding_.Bind(mojo::MakeRequest(&ptr_info));
   leveldb_->AddObserver(std::move(ptr_info));
 }
 
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 7cf21c4d..2e952fd 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -775,7 +775,7 @@
 NOINLINE void ExhaustMemory() {
   volatile void* ptr = nullptr;
   do {
-    ptr = malloc(0x1000000);
+    ptr = malloc(0x10000000);
     base::debug::Alias(&ptr);
   } while (ptr);
 }
diff --git a/content/renderer/service_worker/worker_fetch_context_impl.cc b/content/renderer/service_worker/worker_fetch_context_impl.cc
index bba1ed6d..8a71700 100644
--- a/content/renderer/service_worker/worker_fetch_context_impl.cc
+++ b/content/renderer/service_worker/worker_fetch_context_impl.cc
@@ -29,7 +29,7 @@
   DCHECK(provider_info_.is_valid());
   provider_.Bind(std::move(provider_info_));
   mojom::ServiceWorkerWorkerClientAssociatedPtrInfo ptr_info;
-  binding_->Bind(&ptr_info);
+  binding_->Bind(mojo::MakeRequest(&ptr_info));
   provider_->GetURLLoaderFactoryAndRegisterClient(
       mojo::MakeRequest(&url_loader_factory_), std::move(ptr_info),
       service_worker_provider_id_);
diff --git a/docs/updating_clang.md b/docs/updating_clang.md
index 6d2ff23..407c221 100644
--- a/docs/updating_clang.md
+++ b/docs/updating_clang.md
@@ -3,10 +3,27 @@
 1.  Sync your Chromium tree to the latest revision to pick up any plugin
     changes
 1.  Run `python tools/clang/scripts/upload_revision.py --clang_revision=NNNN`
-    with the target LLVM SVN revision number
-1.  If the clang upload try bots succeed, run the goma package update script to
-    push these packages to goma. If you do not have the necessary credentials to
-    do the upload, ask clang@chromium.org to find someone who does
+    with the target LLVM SVN revision number. This creates a roll CL on a new
+    branch, uploads it and starts tryjobs that build the compiler binaries into
+    a staging bucket on Google Cloud Storage (GCS).
+1.  If the clang upload try bots succeed, copy the binaries from the staging
+    bucket to the production one. For example:
+
+```
+$ export rev=123456-1
+$ for x in Linux_x64 Mac Win ; do \
+    gsutil cp -n -a public-read gs://chromium-browser-clang-staging/$x/clang-$rev.tgz \
+        gs://chromium-browser-clang/$x/clang-$rev.tgz ; \
+    gsutil cp -n -a public-read gs://chromium-browser-clang-staging/$x/llvmobjdump-$rev.tgz \
+        gs://chromium-browser-clang/$x/llvmobjdump-$rev.tgz ; \
+    done
+$ gsutil cp -n -a public-read gs://chromium-browser-clang-staging/Linux_x64/llvmgold-$rev.tgz \
+    gs://chromium-browser-clang/Linux_x64/llvmgold-$rev.tgz
+```
+
+1.  Run the goma package update script to push these packages to goma. If you do
+    not have the necessary credentials to do the upload, ask clang@chromium.org
+    to find someone who does
 1.  Run an exhaustive set of try jobs to test the new compiler:
 ```
     git cl try &&
diff --git a/ios/chrome/browser/payments/payment_request.h b/ios/chrome/browser/payments/payment_request.h
index e7341c78..37917450 100644
--- a/ios/chrome/browser/payments/payment_request.h
+++ b/ios/chrome/browser/payments/payment_request.h
@@ -12,6 +12,7 @@
 
 #include "base/macros.h"
 #include "components/payments/core/payment_options_provider.h"
+#include "components/payments/core/payments_profile_comparator.h"
 #include "ios/web/public/payments/payment_request.h"
 
 namespace autofill {
@@ -53,7 +54,7 @@
   // Updates the payment details of the |web_payment_request_|. It also updates
   // the cached references to the shipping options in |web_payment_request_| as
   // well as the reference to the selected shipping option.
-  void set_payment_details(const web::PaymentDetails& details);
+  void UpdatePaymentDetails(const web::PaymentDetails& details);
 
   // PaymentOptionsProvider:
   bool request_shipping() const override;
@@ -208,6 +209,8 @@
   std::vector<web::PaymentShippingOption*> shipping_options_;
   web::PaymentShippingOption* selected_shipping_option_;
 
+  payments::PaymentsProfileComparator profile_comparator_;
+
   DISALLOW_COPY_AND_ASSIGN(PaymentRequest);
 };
 
diff --git a/ios/chrome/browser/payments/payment_request.mm b/ios/chrome/browser/payments/payment_request.mm
index c4f2493..4b31ba3 100644
--- a/ios/chrome/browser/payments/payment_request.mm
+++ b/ios/chrome/browser/payments/payment_request.mm
@@ -4,6 +4,7 @@
 
 #include "ios/chrome/browser/payments/payment_request.h"
 
+#include "base/containers/adapters.h"
 #include "base/strings/utf_string_conversions.h"
 #include "components/autofill/core/browser/autofill_data_util.h"
 #include "components/autofill/core/browser/autofill_profile.h"
@@ -27,15 +28,17 @@
       selected_shipping_profile_(nullptr),
       selected_contact_profile_(nullptr),
       selected_credit_card_(nullptr),
-      selected_shipping_option_(nullptr) {
+      selected_shipping_option_(nullptr),
+      profile_comparator_(GetApplicationContext()->GetApplicationLocale(),
+                          *this) {
+  PopulateShippingOptionCache();
   PopulateProfileCache();
   PopulateCreditCardCache();
-  PopulateShippingOptionCache();
 }
 
 PaymentRequest::~PaymentRequest() {}
 
-void PaymentRequest::set_payment_details(const web::PaymentDetails& details) {
+void PaymentRequest::UpdatePaymentDetails(const web::PaymentDetails& details) {
   web_payment_request_.details = details;
   PopulateShippingOptionCache();
 }
@@ -91,25 +94,39 @@
 void PaymentRequest::PopulateProfileCache() {
   const std::vector<autofill::AutofillProfile*>& profiles_to_suggest =
       personal_data_manager_->GetProfilesToSuggest();
+  // Return early if the user has no stored Autofill profiles.
+  if (profiles_to_suggest.empty())
+    return;
+
   profile_cache_.reserve(profiles_to_suggest.size());
   for (const auto* profile : profiles_to_suggest) {
     profile_cache_.push_back(*profile);
     shipping_profiles_.push_back(&profile_cache_.back());
-    contact_profiles_.push_back(&profile_cache_.back());
   }
 
-  payments::PaymentsProfileComparator comparator(
-      GetApplicationContext()->GetApplicationLocale(), *this);
-
-  // TODO(crbug.com/602666): Implement deduplication and prioritization rules
-  // for shipping profiles.
-
-  contact_profiles_ = comparator.FilterProfilesForContact(contact_profiles_);
-
-  if (!shipping_profiles_.empty())
+  // If the merchant provided a shipping option, select a suitable default
+  // shipping profile. We pick the profile that is most complete, going down
+  // the list in Frecency order.
+  // TODO(crbug.com/719652): Have a proper ordering of shipping addresses by
+  // completeness.
+  if (selected_shipping_option_) {
     selected_shipping_profile_ = shipping_profiles_[0];
+    for (autofill::AutofillProfile* profile : shipping_profiles_) {
+      if (profile_comparator_.IsShippingComplete(profile)) {
+        selected_shipping_profile_ = profile;
+        break;
+      }
+    }
+  }
+
+  // Contact profiles are deduped and ordered in completeness.
+  contact_profiles_ =
+      profile_comparator_.FilterProfilesForContact(shipping_profiles_);
+
+  // If the highest-ranking contact profile is usable, select it. Otherwise,
+  // select none.
   if (!contact_profiles_.empty() &&
-      comparator.IsContactInfoComplete(contact_profiles_[0])) {
+      profile_comparator_.IsContactInfoComplete(contact_profiles_[0])) {
     selected_contact_profile_ = contact_profiles_[0];
   }
 }
@@ -144,6 +161,10 @@
 
 void PaymentRequest::PopulateShippingOptionCache() {
   shipping_options_.clear();
+  selected_shipping_option_ = nullptr;
+  if (web_payment_request_.details.shipping_options.empty())
+    return;
+
   shipping_options_.reserve(
       web_payment_request_.details.shipping_options.size());
   std::transform(std::begin(web_payment_request_.details.shipping_options),
@@ -151,12 +172,12 @@
                  std::back_inserter(shipping_options_),
                  [](web::PaymentShippingOption& option) { return &option; });
 
-  selected_shipping_option_ = nullptr;
-  for (auto* shipping_option : shipping_options_) {
+  for (auto* shipping_option : base::Reversed(shipping_options_)) {
     if (shipping_option->selected) {
       // If more than one option has |selected| set, the last one in the
       // sequence should be treated as the selected item.
       selected_shipping_option_ = shipping_option;
+      break;
     }
   }
 }
diff --git a/ios/chrome/browser/payments/payment_request_unittest.mm b/ios/chrome/browser/payments/payment_request_unittest.mm
index ed86712b..39598ac 100644
--- a/ios/chrome/browser/payments/payment_request_unittest.mm
+++ b/ios/chrome/browser/payments/payment_request_unittest.mm
@@ -6,6 +6,8 @@
 
 #include "base/strings/utf_string_conversions.h"
 #include "components/autofill/core/browser/autofill_test_utils.h"
+#include "components/autofill/core/browser/autofill_type.h"
+#include "components/autofill/core/browser/field_types.h"
 #include "components/autofill/core/browser/test_personal_data_manager.h"
 #include "components/payments/core/currency_formatter.h"
 #include "components/payments/core/payment_method_data.h"
@@ -17,9 +19,37 @@
 #error "This file requires ARC support."
 #endif
 
+class PaymentRequestTest : public testing::Test {
+ protected:
+  // Returns PaymentDetails with one shipping option that's selected.
+  web::PaymentDetails CreateDetailsWithShippingOption() {
+    web::PaymentDetails details;
+    std::vector<web::PaymentShippingOption> shipping_options;
+    web::PaymentShippingOption option1;
+    option1.id = base::UTF8ToUTF16("option:1");
+    option1.selected = true;
+    shipping_options.push_back(std::move(option1));
+    details.shipping_options = std::move(shipping_options);
+
+    return details;
+  }
+
+  web::PaymentOptions CreatePaymentOptions(bool request_payer_name,
+                                           bool request_payer_phone,
+                                           bool request_payer_email,
+                                           bool request_shipping) {
+    web::PaymentOptions options;
+    options.request_payer_name = request_payer_name;
+    options.request_payer_phone = request_payer_phone;
+    options.request_payer_email = request_payer_email;
+    options.request_shipping = request_shipping;
+    return options;
+  }
+};
+
 // Tests that the payments::CurrencyFormatter is constructed with the correct
 // currency code and currency system.
-TEST(PaymentRequestTest, CreatesCurrencyFormatterCorrectly) {
+TEST_F(PaymentRequestTest, CreatesCurrencyFormatterCorrectly) {
   ASSERT_EQ("en", GetApplicationContext()->GetApplicationLocale());
 
   web::PaymentRequest web_payment_request;
@@ -48,7 +78,7 @@
 }
 
 // Tests that the accepted card networks are identified correctly.
-TEST(PaymentRequestTest, AcceptedPaymentNetworks) {
+TEST_F(PaymentRequestTest, AcceptedPaymentNetworks) {
   web::PaymentRequest web_payment_request;
   autofill::TestPersonalDataManager personal_data_manager;
 
@@ -67,7 +97,7 @@
 
 // Test that parsing supported methods (with invalid values and duplicates)
 // works as expected.
-TEST(PaymentRequestTest, SupportedMethods) {
+TEST_F(PaymentRequestTest, SupportedMethods) {
   web::PaymentRequest web_payment_request;
   autofill::TestPersonalDataManager personal_data_manager;
 
@@ -87,7 +117,7 @@
 
 // Test that parsing supported methods in different method data entries (with
 // invalid values and duplicates) works as expected.
-TEST(PaymentRequestTest, SupportedMethods_MultipleEntries) {
+TEST_F(PaymentRequestTest, SupportedMethods_MultipleEntries) {
   web::PaymentRequest web_payment_request;
   autofill::TestPersonalDataManager personal_data_manager;
 
@@ -111,7 +141,7 @@
 }
 
 // Test that only specifying basic-card means that all are supported.
-TEST(PaymentRequestTest, SupportedMethods_OnlyBasicCard) {
+TEST_F(PaymentRequestTest, SupportedMethods_OnlyBasicCard) {
   web::PaymentRequest web_payment_request;
   autofill::TestPersonalDataManager personal_data_manager;
 
@@ -135,7 +165,7 @@
 
 // Test that specifying a method AND basic-card means that all are supported,
 // but with the method as first.
-TEST(PaymentRequestTest, SupportedMethods_BasicCard_WithSpecificMethod) {
+TEST_F(PaymentRequestTest, SupportedMethods_BasicCard_WithSpecificMethod) {
   web::PaymentRequest web_payment_request;
   autofill::TestPersonalDataManager personal_data_manager;
 
@@ -161,7 +191,7 @@
 
 // Test that specifying basic-card with a supported network (with previous
 // supported methods) will work as expected
-TEST(PaymentRequestTest, SupportedMethods_BasicCard_Overlap) {
+TEST_F(PaymentRequestTest, SupportedMethods_BasicCard_Overlap) {
   web::PaymentRequest web_payment_request;
   autofill::TestPersonalDataManager personal_data_manager;
 
@@ -186,7 +216,7 @@
 
 // Test that specifying basic-card with supported networks after specifying
 // some methods
-TEST(PaymentRequestTest, SupportedMethods_BasicCard_WithSupportedNetworks) {
+TEST_F(PaymentRequestTest, SupportedMethods_BasicCard_WithSupportedNetworks) {
   web::PaymentRequest web_payment_request;
   autofill::TestPersonalDataManager personal_data_manager;
 
@@ -205,7 +235,7 @@
 }
 
 // Tests that credit cards can be added to the list of cached credit cards.
-TEST(PaymentRequestTest, AddCreditCard) {
+TEST_F(PaymentRequestTest, AddCreditCard) {
   web::PaymentRequest web_payment_request;
   autofill::TestPersonalDataManager personal_data_manager;
 
@@ -219,3 +249,162 @@
   ASSERT_EQ(1U, payment_request.credit_cards().size());
   EXPECT_EQ(credit_card, *added_credit_card);
 }
+
+// Test that parsing shipping options works as expected.
+TEST_F(PaymentRequestTest, SelectedShippingOptions) {
+  web::PaymentRequest web_payment_request;
+  autofill::TestPersonalDataManager personal_data_manager;
+
+  web::PaymentDetails details;
+  std::vector<web::PaymentShippingOption> shipping_options;
+  web::PaymentShippingOption option1;
+  option1.id = base::UTF8ToUTF16("option:1");
+  option1.selected = false;
+  shipping_options.push_back(std::move(option1));
+  web::PaymentShippingOption option2;
+  option2.id = base::UTF8ToUTF16("option:2");
+  option2.selected = true;
+  shipping_options.push_back(std::move(option2));
+  web::PaymentShippingOption option3;
+  option3.id = base::UTF8ToUTF16("option:3");
+  option3.selected = true;
+  shipping_options.push_back(std::move(option3));
+  details.shipping_options = std::move(shipping_options);
+  web_payment_request.details = std::move(details);
+
+  PaymentRequest payment_request(web_payment_request, &personal_data_manager);
+  // The last one marked "selected" should be selected.
+  EXPECT_EQ(base::UTF8ToUTF16("option:3"),
+            payment_request.selected_shipping_option()->id);
+
+  // Simulate an update that no longer has any shipping options. There is no
+  // longer a selected shipping option.
+  web::PaymentDetails new_details;
+  payment_request.UpdatePaymentDetails(std::move(new_details));
+  EXPECT_EQ(nullptr, payment_request.selected_shipping_option());
+}
+
+// Test that loading profiles when none are available works as expected.
+TEST_F(PaymentRequestTest, SelectedProfiles_NoProfiles) {
+  autofill::TestPersonalDataManager personal_data_manager;
+  web::PaymentRequest web_payment_request;
+  web_payment_request.details = CreateDetailsWithShippingOption();
+  web_payment_request.options = CreatePaymentOptions(
+      /*request_payer_name=*/true, /*request_payer_phone=*/true,
+      /*request_payer_email=*/true, /*request_shipping=*/true);
+
+  // No profiles are selected because none are available!
+  PaymentRequest payment_request(web_payment_request, &personal_data_manager);
+  EXPECT_EQ(nullptr, payment_request.selected_shipping_profile());
+  EXPECT_EQ(nullptr, payment_request.selected_contact_profile());
+}
+
+// Test that loading complete shipping and contact profiles works as expected.
+TEST_F(PaymentRequestTest, SelectedProfiles_Complete) {
+  autofill::TestPersonalDataManager personal_data_manager;
+  autofill::AutofillProfile address = autofill::test::GetFullProfile();
+  address.set_use_count(5U);
+  personal_data_manager.AddTestingProfile(&address);
+  autofill::AutofillProfile address2 = autofill::test::GetFullProfile2();
+  address2.set_use_count(15U);
+  personal_data_manager.AddTestingProfile(&address2);
+
+  web::PaymentRequest web_payment_request;
+  web_payment_request.details = CreateDetailsWithShippingOption();
+  web_payment_request.options = CreatePaymentOptions(
+      /*request_payer_name=*/true, /*request_payer_phone=*/true,
+      /*request_payer_email=*/true, /*request_shipping=*/true);
+
+  // address2 is selected because it has the most use count (Frecency model).
+  PaymentRequest payment_request(web_payment_request, &personal_data_manager);
+  EXPECT_EQ(address2.guid(),
+            payment_request.selected_shipping_profile()->guid());
+  EXPECT_EQ(address2.guid(),
+            payment_request.selected_contact_profile()->guid());
+}
+
+// Test that loading complete shipping and contact profiles, when there are no
+// shipping options available, works as expected.
+TEST_F(PaymentRequestTest, SelectedProfiles_Complete_NoShippingOption) {
+  autofill::TestPersonalDataManager personal_data_manager;
+  autofill::AutofillProfile address = autofill::test::GetFullProfile();
+  address.set_use_count(5U);
+  personal_data_manager.AddTestingProfile(&address);
+
+  web::PaymentRequest web_payment_request;
+  // No shipping options.
+  web_payment_request.details = web::PaymentDetails();
+  web_payment_request.options = CreatePaymentOptions(
+      /*request_payer_name=*/true, /*request_payer_phone=*/true,
+      /*request_payer_email=*/true, /*request_shipping=*/true);
+
+  // No shipping profile is selected because the merchant has not selected a
+  // shipping option. However there is a suitable contact profile.
+  PaymentRequest payment_request(web_payment_request, &personal_data_manager);
+  EXPECT_EQ(nullptr, payment_request.selected_shipping_profile());
+  EXPECT_EQ(address.guid(), payment_request.selected_contact_profile()->guid());
+}
+
+// Test that loading incomplete shipping and contact profiles works as expected.
+TEST_F(PaymentRequestTest, SelectedProfiles_Incomplete) {
+  autofill::TestPersonalDataManager personal_data_manager;
+  // Add a profile with no phone (incomplete).
+  autofill::AutofillProfile address1 = autofill::test::GetFullProfile();
+  address1.SetInfo(autofill::AutofillType(autofill::PHONE_HOME_WHOLE_NUMBER),
+                   base::string16(), "en-US");
+  address1.set_use_count(5U);
+  personal_data_manager.AddTestingProfile(&address1);
+  // Add a complete profile, with fewer use counts.
+  autofill::AutofillProfile address2 = autofill::test::GetFullProfile2();
+  address2.set_use_count(3U);
+  personal_data_manager.AddTestingProfile(&address2);
+
+  web::PaymentRequest web_payment_request;
+  web_payment_request.details = CreateDetailsWithShippingOption();
+  web_payment_request.options = CreatePaymentOptions(
+      /*request_payer_name=*/true, /*request_payer_phone=*/true,
+      /*request_payer_email=*/true, /*request_shipping=*/true);
+
+  // Even though address1 has more use counts, address2 is selected because it
+  // is complete.
+  PaymentRequest payment_request(web_payment_request, &personal_data_manager);
+  EXPECT_EQ(address2.guid(),
+            payment_request.selected_shipping_profile()->guid());
+  EXPECT_EQ(address2.guid(),
+            payment_request.selected_contact_profile()->guid());
+}
+
+// Test that loading incomplete contact profiles works as expected when the
+// merchant is not interested in the missing field. Test that the most complete
+// shipping profile is selected.
+TEST_F(PaymentRequestTest,
+       SelectedProfiles_IncompleteContact_NoRequestPayerPhone) {
+  autofill::TestPersonalDataManager personal_data_manager;
+  // Add a profile with no phone (incomplete).
+  autofill::AutofillProfile address1 = autofill::test::GetFullProfile();
+  address1.SetInfo(autofill::AutofillType(autofill::PHONE_HOME_WHOLE_NUMBER),
+                   base::string16(), "en-US");
+  address1.set_use_count(5U);
+  personal_data_manager.AddTestingProfile(&address1);
+  // Add a complete profile, with fewer use counts.
+  autofill::AutofillProfile address2 = autofill::test::GetFullProfile();
+  address2.set_use_count(3U);
+  personal_data_manager.AddTestingProfile(&address2);
+
+  web::PaymentRequest web_payment_request;
+  web_payment_request.details = CreateDetailsWithShippingOption();
+  // The merchant doesn't care about the phone number.
+  web_payment_request.options = CreatePaymentOptions(
+      /*request_payer_name=*/true, /*request_payer_phone=*/false,
+      /*request_payer_email=*/true, /*request_shipping=*/true);
+
+  // address1 has more use counts, and even though it has no phone number, it's
+  // still selected as the contact profile because merchant doesn't require
+  // phone. address2 is selected as the shipping profile because it's the most
+  // complete for shipping.
+  PaymentRequest payment_request(web_payment_request, &personal_data_manager);
+  EXPECT_EQ(address2.guid(),
+            payment_request.selected_shipping_profile()->guid());
+  EXPECT_EQ(address1.guid(),
+            payment_request.selected_contact_profile()->guid());
+}
diff --git a/ios/chrome/browser/ui/authentication/signin_promo_view.h b/ios/chrome/browser/ui/authentication/signin_promo_view.h
index cd08711..680585a1 100644
--- a/ios/chrome/browser/ui/authentication/signin_promo_view.h
+++ b/ios/chrome/browser/ui/authentication/signin_promo_view.h
@@ -54,10 +54,12 @@
 // Enables SigninPromoView to send ShowSigninCommand when primary or secondary
 // buttons are tapped, and sets the metric access point. By default, command is
 // disabled.
-// This method should be called only once.
 - (void)enableChromeCommandWithAccessPoint:
     (signin_metrics::AccessPoint)accessPoint;
 
+// Disables ShowSigninCommand to be sent.
+- (void)disableChromeCommand;
+
 @end
 
 #endif  // IOS_CHROME_BROWSER_UI_AUTHENTICATION_SIGN_PROMO_VIEW_H_
diff --git a/ios/chrome/browser/ui/authentication/signin_promo_view.mm b/ios/chrome/browser/ui/authentication/signin_promo_view.mm
index 3e38e1fd..397ce6d 100644
--- a/ios/chrome/browser/ui/authentication/signin_promo_view.mm
+++ b/ios/chrome/browser/ui/authentication/signin_promo_view.mm
@@ -50,7 +50,7 @@
   self = [super initWithFrame:frame];
   if (self) {
     self.isAccessibilityElement = YES;
-    _accessPoint = signin_metrics::AccessPoint::ACCESS_POINT_UNKNOWN;
+    [self disableChromeCommand];
 
     // Adding subviews.
     self.clipsToBounds = YES;
@@ -211,11 +211,15 @@
 
 - (void)enableChromeCommandWithAccessPoint:
     (signin_metrics::AccessPoint)accessPoint {
-  DCHECK(!_shouldSendChromeCommand);
   _shouldSendChromeCommand = YES;
   _accessPoint = accessPoint;
 }
 
+- (void)disableChromeCommand {
+  _shouldSendChromeCommand = NO;
+  _accessPoint = signin_metrics::AccessPoint::ACCESS_POINT_UNKNOWN;
+}
+
 - (void)onPrimaryButtonAction:(id)unused {
   if (!_shouldSendChromeCommand) {
     return;
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_signin_promo_cell.mm b/ios/chrome/browser/ui/bookmarks/bookmark_signin_promo_cell.mm
index e316381..3dbaea8 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_signin_promo_cell.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_signin_promo_cell.mm
@@ -78,6 +78,7 @@
 
 - (void)prepareForReuse {
   _closeButtonAction = nil;
+  [_signinPromoView disableChromeCommand];
 }
 
 - (void)closeButtonAction:(id)sender {
diff --git a/ios/chrome/browser/ui/payments/payment_request_coordinator.mm b/ios/chrome/browser/ui/payments/payment_request_coordinator.mm
index 611b488..7c961705 100644
--- a/ios/chrome/browser/ui/payments/payment_request_coordinator.mm
+++ b/ios/chrome/browser/ui/payments/payment_request_coordinator.mm
@@ -120,7 +120,7 @@
 - (void)updatePaymentDetails:(web::PaymentDetails)paymentDetails {
   BOOL totalValueChanged =
       (_paymentRequest->payment_details().total != paymentDetails.total);
-  _paymentRequest->set_payment_details(paymentDetails);
+  _paymentRequest->UpdatePaymentDetails(paymentDetails);
 
   if (_paymentRequest->shipping_options().empty()) {
     // Display error in the shipping address/option selection view.
diff --git a/ios/chrome/browser/ui/payments/payment_request_view_controller_unittest.mm b/ios/chrome/browser/ui/payments/payment_request_view_controller_unittest.mm
index 5b4fd27c..7fd061f 100644
--- a/ios/chrome/browser/ui/payments/payment_request_view_controller_unittest.mm
+++ b/ios/chrome/browser/ui/payments/payment_request_view_controller_unittest.mm
@@ -114,7 +114,7 @@
   CreateController();
   CheckController();
 
-  payment_request_->set_payment_details(web::PaymentDetails());
+  payment_request_->UpdatePaymentDetails(web::PaymentDetails());
   [GetPaymentRequestViewController() loadModel];
 
   // The only item in the Summary section should stil be of type PriceItem, but
@@ -152,7 +152,7 @@
   CheckController();
 
   // Resetting the payment details should reset the selected shipping option.
-  payment_request_->set_payment_details(web::PaymentDetails());
+  payment_request_->UpdatePaymentDetails(web::PaymentDetails());
   [GetPaymentRequestViewController() loadModel];
 
   // There should still be two items in the Shipping section.
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_collection_view_controller.mm b/ios/chrome/browser/ui/reading_list/reading_list_collection_view_controller.mm
index 0dc1e4e..83990bf 100644
--- a/ios/chrome/browser/ui/reading_list/reading_list_collection_view_controller.mm
+++ b/ios/chrome/browser/ui/reading_list/reading_list_collection_view_controller.mm
@@ -615,16 +615,17 @@
       distillationState:reading_list::UIStatusFromModelStatus(
                             entry.DistilledState())];
 
-  [self setItem:item
-      faviconURL:entry.DistilledURL().is_valid() ? entry.DistilledURL() : url];
+  const GURL& realURL =
+      entry.DistilledURL().is_valid() ? entry.DistilledURL() : url;
+  [self setItem:item faviconURL:realURL];
 
   BOOL has_distillation_details =
       entry.DistilledState() == ReadingListEntry::PROCESSED &&
       entry.DistillationSize() != 0 && entry.DistillationTime() != 0;
   NSString* fullUrlString =
-      base::SysUTF16ToNSString(url_formatter::FormatUrl(url));
+      base::SysUTF16ToNSString(url_formatter::FormatUrl(realURL));
   NSString* urlString =
-      base::SysUTF16ToNSString(url_formatter::FormatUrl(url.GetOrigin()));
+      base::SysUTF16ToNSString(url_formatter::FormatUrl(realURL.GetOrigin()));
   NSString* title = base::SysUTF8ToNSString(entry.Title());
   item.title = [title length] ? title : fullUrlString;
   item.subtitle = urlString;
diff --git a/ios/net/crn_http_protocol_handler.mm b/ios/net/crn_http_protocol_handler.mm
index 03ac857..bdfe4527 100644
--- a/ios/net/crn_http_protocol_handler.mm
+++ b/ios/net/crn_http_protocol_handler.mm
@@ -53,6 +53,10 @@
 // Size of the buffer used to read the net::URLRequest.
 const int kIOBufferSize = 64 * 1024;
 
+// The maximum size of NSData that can be passed to the client 'didReceiveData'
+// callback. This value must always be greater or equal to |kIOBufferSize|.
+const int kClientMaxBufferSize = 4 * kIOBufferSize;
+
 // Global instance of the HTTPProtocolHandlerDelegate.
 net::HTTPProtocolHandlerDelegate* g_protocol_handler_delegate = nullptr;
 
@@ -514,27 +518,29 @@
   if (net_request_ == nullptr)
     return;
 
-  base::scoped_nsobject<NSMutableData> data([[NSMutableData alloc] init]);
+  DCHECK_EQ(net_request_, request);
+  DCHECK_GE(kClientMaxBufferSize, kIOBufferSize);
 
   // Read all we can from the socket and put it into data.
   // TODO(droger): It may be possible to avoid some of the copies (using
   // WrappedIOBuffer for example).
-  NSUInteger data_length;
-  uint64_t total_byte_read = 0;
+  uint64_t total_bytes_read = 0;
   while (bytes_read > 0) {
-    total_byte_read += bytes_read;
-    data_length = [data length];  // Assumes that getting the length is fast.
-    [data increaseLengthBy:bytes_read];
-    memcpy(reinterpret_cast<char*>([data mutableBytes]) + data_length,
-           buffer_->data(), bytes_read);
-    bytes_read = request->Read(buffer_.get(), kIOBufferSize);
-  }
+    base::scoped_nsobject<NSMutableData> data(
+        [[NSMutableData alloc] initWithCapacity:bytes_read]);
+    // |bytes_read| should always be less or equal to |kClientMaxBufferSize|.
+    // This is ensured by the fact that the max read buffer size (i.e.
+    // |kIOBufferSize|) is always smaller or equal to |kClientMaxBufferSize|.
+    while (bytes_read > 0 &&
+           [data length] + bytes_read <= kClientMaxBufferSize) {
+      total_bytes_read += bytes_read;
+      NSUInteger data_length = [data length];
+      [data increaseLengthBy:bytes_read];
+      memcpy(reinterpret_cast<char*>([data mutableBytes]) + data_length,
+             buffer_->data(), bytes_read);
+      bytes_read = request->Read(buffer_.get(), kIOBufferSize);
+    }
 
-  if (tracker_)
-    tracker_->CaptureReceivedBytes(request, total_byte_read);
-
-  // Notify the client.
-  if (bytes_read == net::OK || bytes_read == net::ERR_IO_PENDING) {
     if ([data length] > 0) {
       // If the data is not encoded in UTF8, the NSString is nil.
       DVLOG(3) << "To client:" << std::endl
@@ -543,14 +549,17 @@
                           encoding:NSUTF8StringEncoding]);
       [client_ didLoadData:data];
     }
-    if (bytes_read == 0) {
-      DCHECK_EQ(net_request_, request);
-      // There is nothing more to read.
-      StopNetRequest();
-      [client_ didFinishLoading];
-    }
-  } else {
-    // Request failed (not canceled).
+  }
+
+  if (tracker_)
+    tracker_->CaptureReceivedBytes(request, total_bytes_read);
+
+  if (bytes_read == net::OK) {
+    // If there is nothing more to read.
+    StopNetRequest();
+    [client_ didFinishLoading];
+  } else if (bytes_read != net::ERR_IO_PENDING) {
+    // If there was an error (not canceled).
     int error = bytes_read;
     StopRequestWithError(IOSErrorCode(error), error);
   }
diff --git a/ios/web_view/internal/cwv_scroll_view.mm b/ios/web_view/internal/cwv_scroll_view.mm
index 53dc5d8c..4dc63c53 100644
--- a/ios/web_view/internal/cwv_scroll_view.mm
+++ b/ios/web_view/internal/cwv_scroll_view.mm
@@ -42,14 +42,30 @@
   _proxy.contentOffset = contentOffset;
 }
 
+- (UIEdgeInsets)scrollIndicatorInsets {
+  return _proxy.scrollIndicatorInsets;
+}
+
+- (void)setScrollIndicatorInsets:(UIEdgeInsets)scrollIndicatorInsets {
+  _proxy.scrollIndicatorInsets = scrollIndicatorInsets;
+}
+
 - (CGRect)bounds {
   return {_proxy.contentOffset, _proxy.frame.size};
 }
 
+- (BOOL)isDecelerating {
+  return _proxy.decelerating;
+}
+
 - (BOOL)isDragging {
   return _proxy.dragging;
 }
 
+- (UIPanGestureRecognizer*)panGestureRecognizer {
+  return _proxy.panGestureRecognizer;
+}
+
 - (UIEdgeInsets)contentInset {
   return _proxy.contentInset;
 }
@@ -58,10 +74,18 @@
   _proxy.contentInset = contentInset;
 }
 
+- (void)setContentOffset:(CGPoint)contentOffset animated:(BOOL)animated {
+  [_proxy setContentOffset:contentOffset animated:animated];
+}
+
 - (void)addGestureRecognizer:(UIGestureRecognizer*)gestureRecognizer {
   [_proxy addGestureRecognizer:gestureRecognizer];
 }
 
+- (void)removeGestureRecognizer:(UIGestureRecognizer*)gestureRecognizer {
+  [_proxy removeGestureRecognizer:gestureRecognizer];
+}
+
 #pragma mark - NSObject
 
 - (void)dealloc {
@@ -74,7 +98,7 @@
 
 - (void)webViewScrollViewWillBeginDragging:
     (CRWWebViewScrollViewProxy*)webViewScrollViewProxy {
-  SEL selector = @selector(webViewScrollViewWillBeginDragging:);
+  SEL selector = @selector(scrollViewWillBeginDragging:);
   if ([_delegate respondsToSelector:selector]) {
     [_delegate scrollViewWillBeginDragging:self];
   }
@@ -83,8 +107,8 @@
             (CRWWebViewScrollViewProxy*)webViewScrollViewProxy
                             withVelocity:(CGPoint)velocity
                      targetContentOffset:(inout CGPoint*)targetContentOffset {
-  SEL selector = @selector
-      (webViewScrollViewWillEndDragging:withVelocity:targetContentOffset:);
+  SEL selector =
+      @selector(scrollViewWillEndDragging:withVelocity:targetContentOffset:);
   if ([_delegate respondsToSelector:selector]) {
     [_delegate scrollViewWillEndDragging:self
                             withVelocity:velocity
@@ -102,12 +126,20 @@
 
 - (void)webViewScrollViewDidEndDecelerating:
     (CRWWebViewScrollViewProxy*)webViewScrollViewProxy {
-  SEL selector = @selector(webViewScrollViewDidEndDecelerating:);
+  SEL selector = @selector(scrollViewDidEndDecelerating:);
   if ([_delegate respondsToSelector:selector]) {
     [_delegate scrollViewDidEndDecelerating:self];
   }
 }
 
+- (void)webViewScrollViewWillBeginZooming:
+    (CRWWebViewScrollViewProxy*)webViewScrollViewProxy {
+  SEL selector = @selector(scrollViewWillBeginZooming:);
+  if ([_delegate respondsToSelector:selector]) {
+    [_delegate scrollViewWillBeginZooming:self];
+  }
+}
+
 - (void)webViewScrollViewDidResetContentSize:
     (CRWWebViewScrollViewProxy*)webViewScrollViewProxy {
   self.contentSize = _proxy.contentSize;
diff --git a/ios/web_view/public/cwv_scroll_view.h b/ios/web_view/public/cwv_scroll_view.h
index 4b5c268f..e076cd0 100644
--- a/ios/web_view/public/cwv_scroll_view.h
+++ b/ios/web_view/public/cwv_scroll_view.h
@@ -25,8 +25,11 @@
 
 @property(nonatomic, readonly) CGRect bounds;
 @property(nonatomic) CGPoint contentOffset;
+@property(nonatomic) UIEdgeInsets scrollIndicatorInsets;
 @property(nonatomic, weak) id<CWVScrollViewDelegate> delegate;
+@property(nonatomic, readonly, getter=isDecelerating) BOOL decelerating;
 @property(nonatomic, readonly, getter=isDragging) BOOL dragging;
+@property(nonatomic, readonly) UIPanGestureRecognizer* panGestureRecognizer;
 
 // KVO compliant.
 @property(nonatomic, readonly) CGSize contentSize;
@@ -40,7 +43,9 @@
 // rdar://23584409 (not available on Open Radar)
 @property(nonatomic) UIEdgeInsets contentInset;
 
+- (void)setContentOffset:(CGPoint)contentOffset animated:(BOOL)animated;
 - (void)addGestureRecognizer:(UIGestureRecognizer*)gestureRecognizer;
+- (void)removeGestureRecognizer:(UIGestureRecognizer*)gestureRecognizer;
 
 @end
 
diff --git a/ios/web_view/public/cwv_scroll_view_delegate.h b/ios/web_view/public/cwv_scroll_view_delegate.h
index d5eee58..f9bc5cac 100644
--- a/ios/web_view/public/cwv_scroll_view_delegate.h
+++ b/ios/web_view/public/cwv_scroll_view_delegate.h
@@ -23,6 +23,11 @@
               targetContentOffset:(inout CGPoint*)targetContentOffset;
 - (void)scrollViewDidScroll:(CWVScrollView*)scrollView;
 - (void)scrollViewDidEndDecelerating:(CWVScrollView*)scrollView;
+
+// The equivalent in UIScrollViewDelegate also takes a parameter (UIView*)view,
+// but CWVScrollViewDelegate doesn't expose it for flexibility of future
+// implementation.
+- (void)scrollViewWillBeginZooming:(CWVScrollView*)webViewScrollViewProxy;
 @end
 
 #endif  // IOS_WEB_VIEW_PUBLIC_CWV_SCROLL_VIEW_DELEGATE_H_
diff --git a/ipc/ipc_mojo_perftest.cc b/ipc/ipc_mojo_perftest.cc
index 439c14f..ecf4099 100644
--- a/ipc/ipc_mojo_perftest.cc
+++ b/ipc/ipc_mojo_perftest.cc
@@ -471,7 +471,7 @@
 class ReflectorImpl : public IPC::mojom::Reflector {
  public:
   explicit ReflectorImpl(mojo::ScopedMessagePipeHandle handle)
-      : binding_(this, std::move(handle)) {}
+      : binding_(this, IPC::mojom::ReflectorRequest(std::move(handle))) {}
   ~ReflectorImpl() override {
     ignore_result(binding_.Unbind().PassMessagePipe().release());
   }
diff --git a/media/mojo/clients/mojo_audio_decoder.cc b/media/mojo/clients/mojo_audio_decoder.cc
index 45425b7..2023236 100644
--- a/media/mojo/clients/mojo_audio_decoder.cc
+++ b/media/mojo/clients/mojo_audio_decoder.cc
@@ -141,7 +141,7 @@
       base::Bind(&MojoAudioDecoder::OnConnectionError, base::Unretained(this)));
 
   mojom::AudioDecoderClientAssociatedPtrInfo client_ptr_info;
-  client_binding_.Bind(&client_ptr_info);
+  client_binding_.Bind(mojo::MakeRequest(&client_ptr_info));
 
   remote_decoder_->Construct(std::move(client_ptr_info));
 }
diff --git a/media/mojo/clients/mojo_renderer.cc b/media/mojo/clients/mojo_renderer.cc
index 7563d58..1331ce3 100644
--- a/media/mojo/clients/mojo_renderer.cc
+++ b/media/mojo/clients/mojo_renderer.cc
@@ -95,7 +95,7 @@
   BindRemoteRendererIfNeeded();
 
   mojom::RendererClientAssociatedPtrInfo client_ptr_info;
-  client_binding_.Bind(&client_ptr_info);
+  client_binding_.Bind(mojo::MakeRequest(&client_ptr_info));
 
   // Using base::Unretained(this) is safe because |this| owns
   // |remote_renderer_|, and the callback won't be dispatched if
@@ -113,7 +113,7 @@
   BindRemoteRendererIfNeeded();
 
   mojom::RendererClientAssociatedPtrInfo client_ptr_info;
-  client_binding_.Bind(&client_ptr_info);
+  client_binding_.Bind(mojo::MakeRequest(&client_ptr_info));
 
   MediaUrlParams url_params = media_resource_->GetMediaUrlParams();
 
diff --git a/media/mojo/clients/mojo_video_decoder.cc b/media/mojo/clients/mojo_video_decoder.cc
index 89607a6a..c297fe24 100644
--- a/media/mojo/clients/mojo_video_decoder.cc
+++ b/media/mojo/clients/mojo_video_decoder.cc
@@ -196,7 +196,7 @@
 
   // TODO(sandersd): Does this need its own error handler?
   mojom::VideoDecoderClientAssociatedPtrInfo client_ptr_info;
-  client_binding_.Bind(&client_ptr_info);
+  client_binding_.Bind(mojo::MakeRequest(&client_ptr_info));
 
   // TODO(sandersd): Better buffer sizing.
   mojo::ScopedDataPipeConsumerHandle remote_consumer_handle;
diff --git a/media/mojo/services/media_service_unittest.cc b/media/mojo/services/media_service_unittest.cc
index cabe0e3..ff05705 100644
--- a/media/mojo/services/media_service_unittest.cc
+++ b/media/mojo/services/media_service_unittest.cc
@@ -126,7 +126,7 @@
         &video_stream_, MakeRequest(&video_stream_proxy)));
 
     mojom::RendererClientAssociatedPtrInfo client_ptr_info;
-    renderer_client_binding_.Bind(&client_ptr_info);
+    renderer_client_binding_.Bind(mojo::MakeRequest(&client_ptr_info));
 
     EXPECT_CALL(*this, OnRendererInitialized(expected_result))
         .Times(Exactly(1))
diff --git a/mojo/public/cpp/bindings/associated_binding.h b/mojo/public/cpp/bindings/associated_binding.h
index b4c828b..30583d8 100644
--- a/mojo/public/cpp/bindings/associated_binding.h
+++ b/mojo/public/cpp/bindings/associated_binding.h
@@ -123,17 +123,6 @@
 
   ~AssociatedBinding() {}
 
-  // Creates an associated inteface and sets up this object as the
-  // implementation side. The output |ptr_info| should be sent by another
-  // interface.
-  void Bind(AssociatedInterfacePtrInfo<Interface>* ptr_info,
-            scoped_refptr<base::SingleThreadTaskRunner> runner =
-                base::ThreadTaskRunnerHandle::Get()) {
-    auto request = MakeRequest(ptr_info);
-    ptr_info->set_version(Interface::Version_);
-    Bind(std::move(request), std::move(runner));
-  }
-
   // Sets up this object as the implementation side of an associated interface.
   void Bind(AssociatedInterfaceRequest<Interface> request,
             scoped_refptr<base::SingleThreadTaskRunner> runner =
diff --git a/mojo/public/cpp/bindings/binding.h b/mojo/public/cpp/bindings/binding.h
index 88d2f4b..5e4bb2696e 100644
--- a/mojo/public/cpp/bindings/binding.h
+++ b/mojo/public/cpp/bindings/binding.h
@@ -77,29 +77,6 @@
   // Does not take ownership of |impl|, which must outlive the binding.
   explicit Binding(ImplPointerType impl) : internal_state_(std::move(impl)) {}
 
-  // Constructs a completed binding of message pipe |handle| to implementation
-  // |impl|. Does not take ownership of |impl|, which must outlive the binding.
-  Binding(ImplPointerType impl,
-          ScopedMessagePipeHandle handle,
-          scoped_refptr<base::SingleThreadTaskRunner> runner =
-              base::ThreadTaskRunnerHandle::Get())
-      : Binding(std::move(impl)) {
-    Bind(std::move(handle), std::move(runner));
-  }
-
-  // Constructs a completed binding of |impl| to a new message pipe, passing the
-  // client end to |ptr|, which takes ownership of it. The caller is expected to
-  // pass |ptr| on to the client of the service. Does not take ownership of any
-  // of the parameters. |impl| must outlive the binding. |ptr| only needs to
-  // last until the constructor returns.
-  Binding(ImplPointerType impl,
-          InterfacePtr<Interface>* ptr,
-          scoped_refptr<base::SingleThreadTaskRunner> runner =
-              base::ThreadTaskRunnerHandle::Get())
-      : Binding(std::move(impl)) {
-    Bind(ptr, std::move(runner));
-  }
-
   // Constructs a completed binding of |impl| to the message pipe endpoint in
   // |request|, taking ownership of the endpoint. Does not take ownership of
   // |impl|, which must outlive the binding.
@@ -108,7 +85,7 @@
           scoped_refptr<base::SingleThreadTaskRunner> runner =
               base::ThreadTaskRunnerHandle::Get())
       : Binding(std::move(impl)) {
-    Bind(request.PassMessagePipe(), std::move(runner));
+    Bind(std::move(request), std::move(runner));
   }
 
   // Tears down the binding, closing the message pipe and leaving the interface
@@ -121,41 +98,17 @@
       scoped_refptr<base::SingleThreadTaskRunner> runner =
           base::ThreadTaskRunnerHandle::Get()) {
     InterfacePtr<Interface> interface_ptr;
-    Bind(&interface_ptr, std::move(runner));
+    Bind(MakeRequest(&interface_ptr), std::move(runner));
     return interface_ptr;
   }
 
   // Completes a binding that was constructed with only an interface
-  // implementation. Takes ownership of |handle| and binds it to the previously
-  // specified implementation.
-  void Bind(ScopedMessagePipeHandle handle,
-            scoped_refptr<base::SingleThreadTaskRunner> runner =
-                base::ThreadTaskRunnerHandle::Get()) {
-    internal_state_.Bind(std::move(handle), std::move(runner));
-  }
-
-  // Completes a binding that was constructed with only an interface
-  // implementation by creating a new message pipe, binding one end of it to the
-  // previously specified implementation, and passing the other to |ptr|, which
-  // takes ownership of it. The caller is expected to pass |ptr| on to the
-  // eventual client of the service. Does not take ownership of |ptr|.
-  void Bind(InterfacePtr<Interface>* ptr,
-            scoped_refptr<base::SingleThreadTaskRunner> runner =
-                base::ThreadTaskRunnerHandle::Get()) {
-    MessagePipe pipe;
-    ptr->Bind(InterfacePtrInfo<Interface>(std::move(pipe.handle0),
-                                          Interface::Version_),
-              runner);
-    Bind(std::move(pipe.handle1), std::move(runner));
-  }
-
-  // Completes a binding that was constructed with only an interface
   // implementation by removing the message pipe endpoint from |request| and
   // binding it to the previously specified implementation.
   void Bind(InterfaceRequest<Interface> request,
             scoped_refptr<base::SingleThreadTaskRunner> runner =
                 base::ThreadTaskRunnerHandle::Get()) {
-    Bind(request.PassMessagePipe(), std::move(runner));
+    internal_state_.Bind(request.PassMessagePipe(), std::move(runner));
   }
 
   // Adds a message filter to be notified of each incoming message before
diff --git a/mojo/public/cpp/bindings/interface_request.h b/mojo/public/cpp/bindings/interface_request.h
index d1720920..a515b078 100644
--- a/mojo/public/cpp/bindings/interface_request.h
+++ b/mojo/public/cpp/bindings/interface_request.h
@@ -33,6 +33,9 @@
   InterfaceRequest() {}
   InterfaceRequest(decltype(nullptr)) {}
 
+  explicit InterfaceRequest(ScopedMessagePipeHandle handle)
+      : handle_(std::move(handle)) {}
+
   // Creates a new message pipe over which Interface is to be served, binding
   // the specified InterfacePtr to one end of the message pipe and this
   // InterfaceRequest to the other. For example usage, see comments on
diff --git a/mojo/public/cpp/bindings/tests/binding_set_unittest.cc b/mojo/public/cpp/bindings/tests/binding_set_unittest.cc
index 07acfbe..f184878 100644
--- a/mojo/public/cpp/bindings/tests/binding_set_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/binding_set_unittest.cc
@@ -329,7 +329,8 @@
 TEST_F(BindingSetTest, AssociatedBindingSetConnectionErrorWithReason) {
   AssociatedPingProviderPtr master_ptr;
   PingProviderImpl master_impl;
-  Binding<AssociatedPingProvider> master_binding(&master_impl, &master_ptr);
+  Binding<AssociatedPingProvider> master_binding(&master_impl,
+                                                 MakeRequest(&master_ptr));
 
   base::RunLoop run_loop;
   master_impl.ping_bindings().set_connection_error_with_reason_handler(
diff --git a/mojo/public/cpp/bindings/tests/binding_unittest.cc b/mojo/public/cpp/bindings/tests/binding_unittest.cc
index e76993b..ce3fd055 100644
--- a/mojo/public/cpp/bindings/tests/binding_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/binding_unittest.cc
@@ -262,13 +262,6 @@
   DISALLOW_COPY_AND_ASSIGN(IntegerAccessorImpl);
 };
 
-TEST_F(BindingTest, SetInterfacePtrVersion) {
-  IntegerAccessorImpl impl;
-  sample::IntegerAccessorPtr ptr;
-  Binding<sample::IntegerAccessor> binding(&impl, &ptr);
-  EXPECT_EQ(3u, ptr.version());
-}
-
 TEST_F(BindingTest, PauseResume) {
   bool called = false;
   base::RunLoop run_loop;
diff --git a/mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc b/mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc
index b292b13..5d041b3 100644
--- a/mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc
@@ -1,3 +1,4 @@
+
 // Copyright 2013 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
@@ -544,14 +545,14 @@
 
 class WeakMathCalculatorImpl : public math::Calculator {
  public:
-  WeakMathCalculatorImpl(ScopedMessagePipeHandle handle,
+  WeakMathCalculatorImpl(math::CalculatorRequest request,
                          bool* error_received,
                          bool* destroyed,
                          const base::Closure& closure)
       : error_received_(error_received),
         destroyed_(destroyed),
         closure_(closure),
-        binding_(this, std::move(handle)) {
+        binding_(this, std::move(request)) {
     binding_.set_connection_error_handler(
         base::Bind(&SetFlagAndRunClosure, error_received_, closure_));
   }
@@ -585,8 +586,9 @@
   bool destroyed = false;
   MessagePipe pipe;
   base::RunLoop run_loop;
-  WeakMathCalculatorImpl impl(std::move(pipe.handle0), &error_received,
-                              &destroyed, run_loop.QuitClosure());
+  WeakMathCalculatorImpl impl(math::CalculatorRequest(std::move(pipe.handle0)),
+                              &error_received, &destroyed,
+                              run_loop.QuitClosure());
 
   math::CalculatorPtr calc;
   calc.Bind(InterfacePtrInfo<math::Calculator>(std::move(pipe.handle1), 0u));
diff --git a/net/data/ssl/certificate_transparency/log_list.json b/net/data/ssl/certificate_transparency/log_list.json
index 97d6df3c0..de13269 100644
--- a/net/data/ssl/certificate_transparency/log_list.json
+++ b/net/data/ssl/certificate_transparency/log_list.json
@@ -130,6 +130,16 @@
    "dns_api_endpoint": "venafi.ct.googleapis.com"
   },
   {
+   "description": "Venafi Gen2 CT log",
+   "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEjicnerZVCXTrbEuUhGW85BXx6lrYfA43zro/bAna5ymW00VQb94etBzSg4j/KS/Oqf/fNN51D8DMGA2ULvw3AQ==",
+   "url": "ctlog-gen2.api.venafi.com/",
+   "maximum_merge_delay": 86400,
+   "operated_by": [
+    6
+   ],
+   "dns_api_endpoint": "venafi2.ct.googleapis.com"
+  },
+  {
    "description": "CNNIC CT log",
    "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv7UIYZopMgTTJWPp2IXhhuAf1l6a9zM7gBvntj5fLaFm9pVKhKYhVnno94XuXeN8EsDgiSIJIj66FpUGvai5samyetZhLocRuXhAiXXbDNyQ4KR51tVebtEq2zT0mT9liTtGwiksFQccyUsaVPhsHq9gJ2IKZdWauVA2Fm5x9h8B9xKn/L/2IaMpkIYtd967TNTP/dLPgixN1PLCLaypvurDGSVDsuWabA3FHKWL9z8wr7kBkbdpEhLlg2H+NAC+9nGKx+tQkuhZ/hWR65aX+CNUPy2OB9/u2rNPyDydb988LENXoUcMkQT0dU3aiYGkFAY0uZjD2vH97TM20xYtNQIDAQAB",
    "url": "ctserver.cnnic.cn/",
diff --git a/net/socket/sequenced_socket_data_unittest.cc b/net/socket/sequenced_socket_data_unittest.cc
index b35d1fb..4d54f23 100644
--- a/net/socket/sequenced_socket_data_unittest.cc
+++ b/net/socket/sequenced_socket_data_unittest.cc
@@ -671,8 +671,8 @@
 
   static const char* kExpectedFailures[] = {
       "Expected: (data.length()) >= (expected_data.length())",
-      "Value of: actual_data",
-      "Value of: sock_->Write(buf.get(), len, failing_callback_)"};
+      "To be equal to: actual_data",
+      "To be equal to: sock_->Write(buf.get(), len, failing_callback_)"};
   ASSERT_EQ(arraysize(kExpectedFailures),
             static_cast<size_t>(gtest_failures.size()));
 
diff --git a/services/ui/ws/window_tree_client_unittest.cc b/services/ui/ws/window_tree_client_unittest.cc
index eda6f4b..c857194 100644
--- a/services/ui/ws/window_tree_client_unittest.cc
+++ b/services/ui/ws/window_tree_client_unittest.cc
@@ -1964,7 +1964,8 @@
 
   TestWindowTreeClient client2;
   mojom::WindowTreeClientPtr client2_ptr;
-  mojo::Binding<WindowTreeClient> client2_binding(&client2, &client2_ptr);
+  mojo::Binding<WindowTreeClient> client2_binding(
+      &client2, mojo::MakeRequest(&client2_ptr));
   ASSERT_TRUE(Embed(wt1(), BuildWindowId(client_id_1(), 1),
                     std::move(client2_ptr)));
   client2.WaitForOnEmbed();
diff --git a/skia/config/SkUserConfig.h b/skia/config/SkUserConfig.h
index 1f2ef7c1..989c1dc 100644
--- a/skia/config/SkUserConfig.h
+++ b/skia/config/SkUserConfig.h
@@ -208,6 +208,10 @@
 #   define SK_USE_LEGACY_DISTANCE_FIELDS
 #endif
 
+#ifndef SK_SUPPORT_LEGACY_IMGEN_API
+#define SK_SUPPORT_LEGACY_IMGEN_API
+#endif
+
 #ifndef SK_DISABLE_DEFERRED_PROXIES
 #define SK_DISABLE_DEFERRED_PROXIES
 #endif
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
index 3f0ad4d..bdc9e84 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
@@ -1084,7 +1084,6 @@
 Bug(none) paint/frames/frameset-with-stacking-context-and-not-stacking-context-children.html [ Failure ]
 Bug(none) paint/frames/frameset-with-stacking-contexts.html [ Failure ]
 Bug(none) paint/invalidation/4776765.html [ Failure ]
-Bug(none) paint/invalidation/absolute-display-block-to-none.html [ Failure ]
 Bug(none) paint/invalidation/absolute-margin-change-repaint.html [ Failure ]
 Bug(none) paint/invalidation/absolute-position-change-containing-block.html [ Failure ]
 Bug(none) paint/invalidation/absolute-position-changed.html [ Failure ]
@@ -1123,7 +1122,6 @@
 Bug(none) paint/invalidation/border-current-color.html [ Failure ]
 Bug(none) paint/invalidation/border-image-outset-add-repaint.html [ Failure ]
 Bug(none) paint/invalidation/border-image-outset-change-repaint.html [ Failure ]
-Bug(none) paint/invalidation/border-outline-0.html [ Failure ]
 Bug(none) paint/invalidation/border-radius-repaint-2.html [ Failure ]
 Bug(none) paint/invalidation/border-radius-repaint.html [ Failure ]
 Bug(none) paint/invalidation/border-radius-with-outline.html [ Failure ]
@@ -1229,8 +1227,6 @@
 Bug(none) paint/invalidation/create-layer-repaint.html [ Failure ]
 Bug(none) paint/invalidation/css-grid-layout/grid-element-change-columns-repaint.html [ Failure ]
 Bug(none) paint/invalidation/css-grid-layout/grid-element-change-rows-repaint.html [ Failure ]
-Bug(none) paint/invalidation/css-grid-layout/grid-item-change-column-repaint.html [ Failure ]
-Bug(none) paint/invalidation/css-grid-layout/grid-item-change-row-repaint.html [ Failure ]
 Bug(none) paint/invalidation/css-grid-layout/grid-item-z-index-change-repaint.html [ Failure ]
 Bug(none) paint/invalidation/delete-into-nested-block.html [ Failure ]
 Bug(none) paint/invalidation/destroy-composited-scrollbar.html [ Failure ]
@@ -1366,7 +1362,6 @@
 Bug(none) paint/invalidation/justify-self-overflow-change.html [ Failure ]
 Bug(none) paint/invalidation/layer-full-repaint.html [ Failure ]
 Bug(none) paint/invalidation/layer-hide-when-needs-layout.html [ Failure ]
-Bug(none) paint/invalidation/layer-visibility.html [ Failure ]
 Bug(none) paint/invalidation/layout-state-only-positioned.html [ Failure ]
 Bug(none) paint/invalidation/layout-state-relative.html [ Failure ]
 Bug(none) paint/invalidation/layout-state-scrolloffset.html [ Failure ]
@@ -1447,7 +1442,6 @@
 Bug(none) paint/invalidation/overflow-scroll-in-overflow-scroll-scrolled.html [ Failure ]
 Bug(none) paint/invalidation/overflow-scroll-local-background-text-color-change.html [ Failure ]
 Bug(none) paint/invalidation/overflow-show.html [ Failure ]
-Bug(none) paint/invalidation/overhanging-float-detach-repaint.html [ Failure ]
 Bug(none) paint/invalidation/padding-border-keeping-border-box-and-content-box.html [ Failure ]
 Bug(none) paint/invalidation/padding-keeping-content-size.html [ Failure ]
 Bug(none) paint/invalidation/padding-keeping-visual-size.html [ Failure ]
@@ -1536,7 +1530,6 @@
 Bug(none) paint/invalidation/shift-relative-positioned-container-with-image-removal.html [ Failure ]
 Bug(none) paint/invalidation/stacked-diacritics.html [ Failure ]
 Bug(none) paint/invalidation/stacking-context-lost.html [ Failure ]
-Bug(none) paint/invalidation/static-to-positioned.html [ Failure ]
 Bug(none) paint/invalidation/subpixel-offset-scaled-transform.html [ Failure ]
 Bug(none) paint/invalidation/subpixel-shadow-included-in-invalidation.html [ Failure ]
 Bug(none) paint/invalidation/subtree-layoutstate-transform.html [ Failure ]
@@ -1665,7 +1658,6 @@
 Bug(none) paint/invalidation/svg/shape-with-nested-outline.html [ Failure ]
 Bug(none) paint/invalidation/svg/stroke-opacity-update.svg [ Failure ]
 Bug(none) paint/invalidation/svg/svg-absolute-children.svg [ Failure ]
-Bug(none) paint/invalidation/svg/svg-background-partial-redraw.html [ Failure ]
 Bug(none) paint/invalidation/svg/svg-image-change-content-size.xhtml [ Failure ]
 Bug(none) paint/invalidation/svg/svg-image-par-resize.html [ Failure ]
 Bug(none) paint/invalidation/svg/svgsvgelement-repaint-children.html [ Failure ]
@@ -1743,7 +1735,6 @@
 Bug(none) paint/invalidation/textarea-caret.html [ Failure ]
 Bug(none) paint/invalidation/textarea-resize-property-change.html [ Failure ]
 Bug(none) paint/invalidation/textarea-set-disabled.html [ Failure ]
-Bug(none) paint/invalidation/trailing-floats-root-line-box-overflow.html [ Failure ]
 Bug(none) paint/invalidation/transform-absolute-child.html [ Failure ]
 Bug(none) paint/invalidation/transform-absolute-in-positioned-container.html [ Failure ]
 Bug(none) paint/invalidation/transform-disable-layoutstate.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 5342be8d..efd5677 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -1238,6 +1238,13 @@
 crbug.com/538697 [ Win7 Debug ] virtual/threaded/printing/webgl-oversized-printing.html [ Failure Crash ]
 crbug.com/538697 [ Win7 Debug ] printing/webgl-oversized-printing.html [ Failure Crash ]
 
+# ====== Fullscreen tests failing with feature policy ======
+# TODO(lunalu): Turn tests on once feature policy implements allowfullscreen.
+crbug.com/666761 virtual/feature-policy/http/tests/feature-policy/fullscreen-allowed-by-container-policy-relocate.html [ Failure ]
+crbug.com/666761 virtual/feature-policy/http/tests/feature-policy/fullscreen-allowed-by-container-policy.html [ Failure ]
+crbug.com/666761 virtual/feature-policy/http/tests/feature-policy/fullscreen-disabled.php [ Failure ]
+crbug.com/666761 virtual/feature-policy/http/tests/feature-policy/fullscreen-enabledforall.php [ Failure ]
+
 #crbug.com/492664 [ Linux ] external/wpt/css/css-writing-modes-3/box-offsets-rel-pos-vlr-005.xht [ Failure ]
 #crbug.com/492664 [ Linux ] external/wpt/css/css-writing-modes-3/box-offsets-rel-pos-vrl-004.xht [ Failure ]
 #crbug.com/492664 [ Mac ] external/wpt/css/css-writing-modes-3/bidi-embed-002.html [ Failure ]
@@ -3124,8 +3131,6 @@
 
 crbug.com/667371 inspector/elements/styles-1/color-aware-property-value-edit.html [ Pass Failure ]
 
-crbug.com/617168 [ Linux ] fast/text/shaping/same-script-different-lang.html [ NeedsRebaseline ]
-
 # [css-ui] Imported tests from W3C suite.
 crbug.com/669473 external/wpt/css/css-ui-3/box-sizing-014.html [ Failure ]
 crbug.com/669473 external/wpt/css/css-ui-3/box-sizing-015.html [ Failure ]
@@ -3379,6 +3384,10 @@
 crbug.com/716569 [ Android ] tables/mozilla_expected_failures/bugs/bug1055-2.html [ Failure ]
 crbug.com/716569 [ Android ] tables/mozilla_expected_failures/bugs/bug2479-5.html [ Failure ]
 
+# Feature Policy changes same-origin allowpaymentrequest behaviour, tests need updating
+crbug.com/718155 payments/payment-request-in-iframe.html [ Failure ]
+crbug.com/718155 payments/payment-request-in-iframe-nested-not-allowed.html [ Failure ]
+
 # Layout Tests on Swarming (Windows) - https://crbug.com/717347
 crbug.com/719298 [ Win ] fast/dnd/dropEffect-for-effectAllowed.html [ Failure Pass Timeout ]
 crbug.com/719299 [ Win ] external/wpt/css/css-ui-3/outline-004.html [ Failure Pass Timeout ]
diff --git a/third_party/WebKit/LayoutTests/external/wpt/payment-request/allowpaymentrequest/allowpaymentrequest-attribute-same-origin-bc-containers.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/payment-request/allowpaymentrequest/allowpaymentrequest-attribute-same-origin-bc-containers.https-expected.txt
deleted file mode 100644
index a4053a8..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/payment-request/allowpaymentrequest/allowpaymentrequest-attribute-same-origin-bc-containers.https-expected.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-This is a testharness.js-based test.
-PASS iframe 
-FAIL frame assert_equals: expected "Success" but got "Exception"
-FAIL object assert_equals: expected "Success" but got "Exception"
-FAIL embed assert_equals: expected "Success" but got "Exception"
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/payment-request/allowpaymentrequest/no-attribute-same-origin-bc-containers.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/payment-request/allowpaymentrequest/no-attribute-same-origin-bc-containers.https-expected.txt
deleted file mode 100644
index ab65a93..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/payment-request/allowpaymentrequest/no-attribute-same-origin-bc-containers.https-expected.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-This is a testharness.js-based test.
-FAIL iframe assert_equals: expected "Success" but got "Exception"
-FAIL frame assert_equals: expected "Success" but got "Exception"
-FAIL object assert_equals: expected "Success" but got "Exception"
-FAIL embed assert_equals: expected "Success" but got "Exception"
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/payment-request/allowpaymentrequest/removing-allowpaymentrequest.https.sub-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/payment-request/allowpaymentrequest/removing-allowpaymentrequest.https.sub-expected.txt
deleted file mode 100644
index 8754c0b..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/payment-request/allowpaymentrequest/removing-allowpaymentrequest.https.sub-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL PaymentRequest removing allowpaymentrequest after load and then navigating assert_equals: before navigation expected "Success" but got "Exception"
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/payment-request/allowpaymentrequest/setting-allowpaymentrequest.https.sub-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/payment-request/allowpaymentrequest/setting-allowpaymentrequest.https.sub-expected.txt
deleted file mode 100644
index 0949a911..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/payment-request/allowpaymentrequest/setting-allowpaymentrequest.https.sub-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL PaymentRequest setting allowpaymentrequest after load and then navigating assert_equals: before navigation expected "Exception" but got "Success"
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/fast/forms/text-control-selection-after-blur.html b/third_party/WebKit/LayoutTests/fast/forms/text-control-selection-after-blur.html
new file mode 100644
index 0000000..6c5a4c6
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/forms/text-control-selection-after-blur.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<title>Tests for crbug.com/714425</title>
+<body>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+
+<input>
+<textarea></textarea>
+
+<script>
+function testSelectionAfterBlur(element) {
+  test(() => {
+    assert_exists(window, 'eventSender');
+    element.value = '';
+    element.focus();
+    eventSender.keyDown('a');
+    eventSender.keyDown('b');
+    eventSender.keyDown('Backspace');
+    assert_equals(element.selectionStart, 1, 'selectionStart before blur');
+    assert_equals(element.selectionEnd, 1, 'selectionEnd before blur');
+    element.blur();
+    assert_equals(element.selectionStart, 1, 'selectionStart after blur');
+    assert_equals(element.selectionEnd, 1, 'selectionEnd after blur');
+  }, `${element.tagName}: selectionStart/selectionEnd should be correct after blur()`);
+}
+
+testSelectionAfterBlur(document.querySelector('input'));
+testSelectionAfterBlur(document.querySelector('textarea'));
+</script>
+</body>
diff --git a/third_party/WebKit/LayoutTests/fast/forms/text/text-selection-after-type-change.html b/third_party/WebKit/LayoutTests/fast/forms/text/text-selection-after-type-change.html
new file mode 100644
index 0000000..9c2c084
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/forms/text/text-selection-after-type-change.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<body>
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+
+<input>
+
+<script>
+var t = async_test('selectionStart/selectionEnd should be kept after input type changes.');
+t.step(() => {
+  assert_exists(window, 'eventSender');
+  var element = document.querySelector('input');
+  element.value = '';
+  element.focus();
+  eventSender.keyDown('c');
+  assert_equals(element.selectionStart, 1);
+  element.type = 'button';
+  assert_equals(element.selectionStart, null);
+  element.type = 'text';
+
+  // TODO(tkent): We need some delay before checking selectionStart because
+  // input type change doesn't update selectionStart immediately to avoid force
+  // layout. crbug.com/721217
+  t.step_timeout(() => {
+    assert_equals(element.selectionStart, 1);
+    t.done();
+  }, 1);
+});
+</script>
+</body>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/infinite-height-causing-fractional-row-height-crash.html b/third_party/WebKit/LayoutTests/fast/multicol/infinite-height-causing-fractional-row-height-crash.html
new file mode 100644
index 0000000..3ea60314
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/infinite-height-causing-fractional-row-height-crash.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<div style="columns:12;">
+    <div style="height:1234567890px; margin-top:17179869177px;">
+        <div style="height:1px;"></div>
+        <div style="column-span:all;"></div>
+    </div>
+    <div style="columns:2; column-fill:auto; height:20px;">
+        <div style="height:1px;"></div>
+        <div style="margin-top:1px;"></div>
+    </div>
+</div>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script>
+test(() => { }, "No crash or assertion failure.");
+</script>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/insane-column-count-and-padding-nested-crash.html b/third_party/WebKit/LayoutTests/fast/multicol/insane-column-count-and-padding-nested-crash.html
new file mode 100644
index 0000000..3af6b386
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/insane-column-count-and-padding-nested-crash.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<div style="columns:25000;">
+    <div style="position:relative;">
+        <div style="position:absolute; padding-top:2147483647px; columns:10; offset-path:path('m 2 0 v -1');">
+            <div style="padding-bottom:1px;"></div>
+            <div style="margin-top:1px;"></div>
+        </div>
+    </div>
+</div>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script>
+    test(() => { }, "No crash or assertion failure.");
+</script>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/zero-height-with-children.html b/third_party/WebKit/LayoutTests/fast/multicol/zero-height-with-children.html
new file mode 100644
index 0000000..1eee8ba
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/zero-height-with-children.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<style>
+    .multicol { position:relative; margin-bottom:1px; columns:5; width:20px; column-gap:0; column-fill:auto; height:0; background:red; }
+    .multicol > div { height:1px; background:blue; }
+</style>
+<p>There should be a small blue square below.</p>
+<div style="display:flow-root; position:relative;">
+    <div class="multicol"><div></div><div></div></div>
+    <div class="multicol"><div></div><div></div></div>
+    <div class="multicol"><div></div><div></div></div>
+    <div class="multicol"><div></div><div></div></div>
+    <div class="multicol"><div></div><div></div></div>
+    <div class="multicol"><div></div><div></div></div>
+    <div class="multicol"><div></div><div></div></div>
+    <div class="multicol"><div></div><div></div></div>
+</div>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script>
+    test(() => {
+        var multicols = document.getElementsByClassName("multicol");
+        var offset = 0;
+        for (var i = 0; i < multicols.length; i++) {
+            var multicol = multicols[i];
+            assert_equals(multicol.firstChild.offsetLeft, 0);
+            assert_equals(multicol.firstChild.nextSibling.offsetLeft, 4);
+            assert_equals(multicol.offsetTop, offset);
+            offset++;
+        }
+    }, "Zero-height multicol should force 1px tall columns");
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/feature-policy/payment-allowed-by-container-policy-expected.txt b/third_party/WebKit/LayoutTests/http/tests/feature-policy/payment-allowed-by-container-policy-expected.txt
deleted file mode 100644
index e8fb2be..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/feature-policy/payment-allowed-by-container-policy-expected.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-   
-
---------
-Frame: '<!--framePath //<!--frame0-->-->'
---------
-This is a testharness.js-based test.
-FAIL Any iframes may construct PaymentRequest when enabled. assert_unreached: PaymentRequest should be enabled by FeaturePolicy Reached unreachable code
-Harness: the test ran to completion.
-
-
---------
-Frame: '<!--framePath //<!--frame1-->-->'
---------
-This is a testharness.js-based test.
-FAIL Any iframes may construct PaymentRequest when enabled. assert_unreached: PaymentRequest should be enabled by FeaturePolicy Reached unreachable code
-Harness: the test ran to completion.
-
-
---------
-Frame: '<!--framePath //<!--frame2-->-->'
---------
-This is a testharness.js-based test.
-PASS Any iframes may construct PaymentRequest when enabled. 
-Harness: the test ran to completion.
-
-
---------
-Frame: '<!--framePath //<!--frame3-->-->'
---------
-This is a testharness.js-based test.
-PASS Any iframes may construct PaymentRequest when enabled. 
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/http/tests/feature-policy/payment-allowed-by-container-policy-relocate-expected.txt b/third_party/WebKit/LayoutTests/http/tests/feature-policy/payment-allowed-by-container-policy-relocate-expected.txt
deleted file mode 100644
index 655b3f3..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/feature-policy/payment-allowed-by-container-policy-relocate-expected.txt
+++ /dev/null
@@ -1,49 +0,0 @@
-     
-
---------
-Frame: '<!--framePath //<!--frame0-->-->'
---------
-This is a testharness.js-based test.
-FAIL Any iframes may construct PaymentRequest when enabled. assert_unreached: PaymentRequest should be enabled by FeaturePolicy Reached unreachable code
-Harness: the test ran to completion.
-
-
---------
-Frame: '<!--framePath //<!--frame1-->-->'
---------
-This is a testharness.js-based test.
-PASS Any iframes may construct PaymentRequest when enabled. 
-Harness: the test ran to completion.
-
-
---------
-Frame: '<!--framePath //<!--frame2-->-->'
---------
-This is a testharness.js-based test.
-PASS Any iframes may construct PaymentRequest when enabled. 
-Harness: the test ran to completion.
-
-
---------
-Frame: '<!--framePath //<!--frame3-->-->'
---------
-This is a testharness.js-based test.
-PASS No iframe may construct PaymentRequest when disabled. 
-Harness: the test ran to completion.
-
-
---------
-Frame: '<!--framePath //<!--frame4-->-->'
---------
-This is a testharness.js-based test.
-FAIL No iframe may construct PaymentRequest when disabled. assert_unreached: PaymentRequest should be disabled by FeaturePolicy Reached unreachable code
-Harness: the test ran to completion.
-
-
---------
-Frame: '<!--framePath //<!--frame5-->-->'
---------
-This is a testharness.js-based test.
-PASS Any iframes may construct PaymentRequest when enabled. 
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/http/tests/feature-policy/payment-disabled-expected.txt b/third_party/WebKit/LayoutTests/http/tests/feature-policy/payment-disabled-expected.txt
deleted file mode 100644
index 674a76bf..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/feature-policy/payment-disabled-expected.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-   
-
---------
-Frame: '<!--framePath //<!--frame0-->-->'
---------
-This is a testharness.js-based test.
-PASS No iframe may construct PaymentRequest when disabled. 
-Harness: the test ran to completion.
-
-
---------
-Frame: '<!--framePath //<!--frame1-->-->'
---------
-This is a testharness.js-based test.
-PASS No iframe may construct PaymentRequest when disabled. 
-Harness: the test ran to completion.
-
-
---------
-Frame: '<!--framePath //<!--frame2-->-->'
---------
-This is a testharness.js-based test.
-FAIL No iframe may construct PaymentRequest when disabled. assert_unreached: PaymentRequest should be disabled by FeaturePolicy Reached unreachable code
-Harness: the test ran to completion.
-
-
---------
-Frame: '<!--framePath //<!--frame3-->-->'
---------
-This is a testharness.js-based test.
-FAIL No iframe may construct PaymentRequest when disabled. assert_unreached: PaymentRequest should be disabled by FeaturePolicy Reached unreachable code
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/http/tests/feature-policy/payment-enabledforall-expected.txt b/third_party/WebKit/LayoutTests/http/tests/feature-policy/payment-enabledforall-expected.txt
deleted file mode 100644
index e8fb2be..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/feature-policy/payment-enabledforall-expected.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-   
-
---------
-Frame: '<!--framePath //<!--frame0-->-->'
---------
-This is a testharness.js-based test.
-FAIL Any iframes may construct PaymentRequest when enabled. assert_unreached: PaymentRequest should be enabled by FeaturePolicy Reached unreachable code
-Harness: the test ran to completion.
-
-
---------
-Frame: '<!--framePath //<!--frame1-->-->'
---------
-This is a testharness.js-based test.
-FAIL Any iframes may construct PaymentRequest when enabled. assert_unreached: PaymentRequest should be enabled by FeaturePolicy Reached unreachable code
-Harness: the test ran to completion.
-
-
---------
-Frame: '<!--framePath //<!--frame2-->-->'
---------
-This is a testharness.js-based test.
-PASS Any iframes may construct PaymentRequest when enabled. 
-Harness: the test ran to completion.
-
-
---------
-Frame: '<!--framePath //<!--frame3-->-->'
---------
-This is a testharness.js-based test.
-PASS Any iframes may construct PaymentRequest when enabled. 
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/http/tests/feature-policy/payment-enabledforself-expected.txt b/third_party/WebKit/LayoutTests/http/tests/feature-policy/payment-enabledforself-expected.txt
deleted file mode 100644
index 3ae1f16..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/feature-policy/payment-enabledforself-expected.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-   
-
---------
-Frame: '<!--framePath //<!--frame0-->-->'
---------
-This is a testharness.js-based test.
-FAIL Any iframes may construct PaymentRequest when enabled. assert_unreached: PaymentRequest should be enabled by FeaturePolicy Reached unreachable code
-Harness: the test ran to completion.
-
-
---------
-Frame: '<!--framePath //<!--frame1-->-->'
---------
-This is a testharness.js-based test.
-PASS No iframe may construct PaymentRequest when disabled. 
-Harness: the test ran to completion.
-
-
---------
-Frame: '<!--framePath //<!--frame2-->-->'
---------
-This is a testharness.js-based test.
-PASS Any iframes may construct PaymentRequest when enabled. 
-Harness: the test ran to completion.
-
-
---------
-Frame: '<!--framePath //<!--frame3-->-->'
---------
-This is a testharness.js-based test.
-PASS Any iframes may construct PaymentRequest when enabled. 
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/appcache-ordering-main.html b/third_party/WebKit/LayoutTests/http/tests/serviceworker/appcache-ordering-main.html
deleted file mode 100644
index 5a39c26..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/appcache-ordering-main.html
+++ /dev/null
@@ -1,86 +0,0 @@
-<!DOCTYPE html>
-<script src="../resources/testharness.js"></script>
-<script src="../resources/testharnessreport.js"></script>
-<script src="resources/test-helpers.js"></script>
-<body>
-<script>
-
-var INSTALL_APPCACHE_URL = "resources/appcache-ordering.install.html";
-var IS_APPCACHED_URL = "resources/appcache-ordering.is-appcached.html";
-var SERVICE_WORKER_SCOPE = "resources/appcache-ordering";
-var SERVICE_WORKER_SCRIPT = "resources/empty-worker.js";
-
-var resolve_install_appcache = undefined;
-var reject_install_appcache = undefined;
-
-// Called by the INSTALL_APPCACHE_URL child frame.
-function notify_appcache_installed(success) {
-  if (success)
-    resolve_install_appcache();
-  else
-    reject_install_appcache();
-}
-
-function install_appcache() {
-  return new Promise(function(resolve, reject) {
-      var frame = document.createElement('iframe');
-      frame.src = INSTALL_APPCACHE_URL;
-      document.body.appendChild(frame);      
-      resolve_install_appcache = function() {
-          document.body.removeChild(frame);
-          resolve();
-        };
-      reject_install_appcache = function() {
-          document.body.removeChild(frame);
-          reject();
-        };
-  });
-}
-
-var resolve_is_appcached = undefined;
-
-// Called by the IS_APPCACHED_URL child frame.
-function notify_is_appcached(is) {
-  resolve_is_appcached(is);
-}
-
-function is_appcached() {
-  return new Promise(function(resolve) {
-      var frame = document.createElement('iframe');
-      frame.src = IS_APPCACHED_URL;
-      document.body.appendChild(frame);
-      resolve_is_appcached = function(is) {
-          document.body.removeChild(frame);
-          resolve(is);
-        };
-  });
-}
-
-async_test(function(t) {
-    service_worker_unregister(t, SERVICE_WORKER_SCOPE)
-      .then(function() {
-          return install_appcache();
-        })
-      .then(function() {
-          return is_appcached();
-        })
-      .then(function(result) {
-          assert_true(result, 'appcache should initially be utilized');
-          return service_worker_unregister_and_register(
-              t, SERVICE_WORKER_SCRIPT, SERVICE_WORKER_SCOPE);
-        })
-      .then(function(r) {  
-          return wait_for_state(t, r.installing, 'activated');
-        })
-      .then(function() {  
-          return is_appcached();
-        })
-      .then(function(result) {
-          assert_false(result, 'but serviceworkers should take priority');
-          service_worker_unregister_and_done(t, SERVICE_WORKER_SCOPE);
-        })
-      .catch(unreached_rejection(t));
-  }, 'serviceworkers take priority over appcaches');
-
-</script>
-</body>
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/appcache-ordering.install.html b/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/appcache-ordering.install.html
deleted file mode 100644
index 428ad92..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/appcache-ordering.install.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<html manifest="appcache-ordering.manifest">
-<script>
-var handled = false;
-
-function installComplete() {
-  if (handled)
-    return;
-  handled = true;
-  window.parent.notify_appcache_installed(true);
-}
-
-function installFailed() {
-  if (handled)
-    return;
-  handled = true;
-  window.parent.notify_appcache_installed(false);
-}
-
-applicationCache.oncached = installComplete;
-applicationCache.onnoupdate = installComplete;
-applicationCache.onupdateready = installFailed;
-applicationCache.onerror = installFailed;
-applicationCache.onobsolete = installFailed;
-
-</script>
-</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/appcache-ordering.is-appcached.html b/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/appcache-ordering.is-appcached.html
deleted file mode 100644
index 485ab17..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/appcache-ordering.is-appcached.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<html> <!-- Intentionally does NOT include a manifest attribute -->
-<body>
-<!-- This should FALLBACK to ordering.is_appcached.js as specified in manifest
-     when the appcache is present -->
-<script src="appcache-ordering.is-appcached404.js"></script>
-<script>
-
-// If the script of the fallback resource loaded, is_appcached will be defined.
-window.parent.notify_is_appcached(typeof is_appcached != 'undefined');
-
-</script>
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/appcache-ordering.is-appcached.js b/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/appcache-ordering.is-appcached.js
deleted file mode 100644
index a562b6f..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/appcache-ordering.is-appcached.js
+++ /dev/null
@@ -1 +0,0 @@
-var is_appcached = true;
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/appcache-ordering.manifest b/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/appcache-ordering.manifest
deleted file mode 100644
index 0deed0e..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/appcache-ordering.manifest
+++ /dev/null
@@ -1,7 +0,0 @@
-CACHE MANIFEST
-
-appcache-ordering.is-appcached.html
-
-FALLBACK:
-appcache-ordering.is-appcached404.js appcache-ordering.is-appcached.js
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu/fast/canvas/image-object-in-canvas-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu/fast/canvas/image-object-in-canvas-expected.png
index 7eadd309..4fba742 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu/fast/canvas/image-object-in-canvas-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu/fast/canvas/image-object-in-canvas-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu/fast/canvas/image-object-in-canvas-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu/fast/canvas/image-object-in-canvas-expected.png
index b3bdae59..34b331b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu/fast/canvas/image-object-in-canvas-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu/fast/canvas/image-object-in-canvas-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/stable/webexposed/global-interface-listing-expected.txt
index bbee8ef2..3921550 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/stable/webexposed/global-interface-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -2056,6 +2056,7 @@
 interface HTMLIFrameElement : HTMLElement
     attribute @@toStringTag
     getter align
+    getter allow
     getter allowFullscreen
     getter allowPaymentRequest
     getter contentDocument
@@ -2075,6 +2076,7 @@
     method constructor
     method getSVGDocument
     setter align
+    setter allow
     setter allowFullscreen
     setter allowPaymentRequest
     setter frameBorder
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/image-object-in-canvas-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/image-object-in-canvas-expected.png
index d82fe69..a885c4e 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/image-object-in-canvas-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/image-object-in-canvas-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/platform/win/virtual/stable/webexposed/global-interface-listing-expected.txt
index 27df4cb6..473be16 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/stable/webexposed/global-interface-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -1985,6 +1985,7 @@
 interface HTMLIFrameElement : HTMLElement
     attribute @@toStringTag
     getter align
+    getter allow
     getter allowFullscreen
     getter allowPaymentRequest
     getter contentDocument
@@ -2004,6 +2005,7 @@
     method constructor
     method getSVGDocument
     setter align
+    setter allow
     setter allowFullscreen
     setter allowPaymentRequest
     setter frameBorder
diff --git a/third_party/WebKit/LayoutTests/typedcssom/computedstyle/background-image.html b/third_party/WebKit/LayoutTests/typedcssom/computedstyle/background-image.html
new file mode 100644
index 0000000..a21b5a06
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/typedcssom/computedstyle/background-image.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src='../../resources/testharness.js'></script>
+<script src='../../resources/testharnessreport.js'></script>
+</head>
+<body>
+<div id='testElement'></div>
+<style>
+#testElement {
+  background-image: url("resources/1x1-green.png");
+}
+</style>
+<script>
+var locationPath = location.href.substring(0, location.href.lastIndexOf('/'));
+var imagePath = locationPath + '/resources/1x1-green.png';
+
+var computedStyleMap = getComputedStyleMap(testElement);
+
+function checks() {
+  var result = computedStyleMap.get('background-image');
+  assert_true(result instanceof CSSURLImageValue);
+  assert_equals(result.cssText, 'url(\"' + imagePath + '\")');
+  assert_equals(result.state, 'loaded');
+  assert_equals(result.intrinsicWidth, 1);
+  assert_equals(result.intrinsicHeight, 1);
+  assert_equals(result.intrinsicRatio, 1);
+}
+
+var t1 = async_test('Getting a background-image with a relative URL image value returns a CSSURLImageValue');
+function t1Callback() {
+  t1.step(checks);
+  t1.done();
+}
+
+var t2 = async_test('Getting a background-image with a URL image value returns a CSSURLImageValue');
+function t2Callback() {
+  testElement.style.backgroundImage = 'url(\"' + imagePath + '\")';
+  t2.step(checks);
+  t2.done();
+}
+
+document.onreadystatechange = function() {
+  if(document.readyState == 'complete') {
+    t1Callback();
+    t2Callback();
+  }
+};
+
+</script>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload-disabled/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload-disabled/webexposed/global-interface-listing-expected.txt
index b345a412..16b2aca 100644
--- a/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload-disabled/webexposed/global-interface-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload-disabled/webexposed/global-interface-listing-expected.txt
@@ -2654,6 +2654,7 @@
 interface HTMLIFrameElement : HTMLElement
     attribute @@toStringTag
     getter align
+    getter allow
     getter allowFullscreen
     getter allowPaymentRequest
     getter contentDocument
@@ -2674,6 +2675,7 @@
     method constructor
     method getSVGDocument
     setter align
+    setter allow
     setter allowFullscreen
     setter allowPaymentRequest
     setter csp
diff --git a/third_party/WebKit/LayoutTests/virtual/spv2/paint/invalidation/margin-expected.txt b/third_party/WebKit/LayoutTests/virtual/spv2/paint/invalidation/margin-expected.txt
index 002d805..47d2f4f 100644
--- a/third_party/WebKit/LayoutTests/virtual/spv2/paint/invalidation/margin-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/spv2/paint/invalidation/margin-expected.txt
@@ -12,9 +12,9 @@
           "reason": "location change"
         },
         {
-          "object": "",
+          "object": "LayoutBlockFlow (positioned) DIV id='target'",
           "rect": [0, 0, 100, 100],
-          "reason": "full"
+          "reason": "location change"
         }
       ]
     }
diff --git a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/element-instance-property-listing-expected.txt b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/element-instance-property-listing-expected.txt
index 5fd9718..bb07f71 100644
--- a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/element-instance-property-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/element-instance-property-listing-expected.txt
@@ -541,6 +541,7 @@
 html element i
 html element iframe
     property align
+    property allow
     property allowFullscreen
     property allowPaymentRequest
     property contentDocument
diff --git a/third_party/WebKit/LayoutTests/webexposed/element-instance-property-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/element-instance-property-listing-expected.txt
index 27455518..fda4edc5 100644
--- a/third_party/WebKit/LayoutTests/webexposed/element-instance-property-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/element-instance-property-listing-expected.txt
@@ -556,6 +556,7 @@
 html element i
 html element iframe
     property align
+    property allow
     property allowFullscreen
     property allowPaymentRequest
     property contentDocument
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
index 7cc3128..fa4b409 100644
--- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -2654,6 +2654,7 @@
 interface HTMLIFrameElement : HTMLElement
     attribute @@toStringTag
     getter align
+    getter allow
     getter allowFullscreen
     getter allowPaymentRequest
     getter contentDocument
@@ -2674,6 +2675,7 @@
     method constructor
     method getSVGDocument
     setter align
+    setter allow
     setter allowFullscreen
     setter allowPaymentRequest
     setter csp
diff --git a/third_party/WebKit/Source/bindings/core/v8/BUILD.gn b/third_party/WebKit/Source/bindings/core/v8/BUILD.gn
index b5c4e82..329c32e2 100644
--- a/third_party/WebKit/Source/bindings/core/v8/BUILD.gn
+++ b/third_party/WebKit/Source/bindings/core/v8/BUILD.gn
@@ -167,6 +167,8 @@
   "$blink_core_output_dir/page/scrolling/ScrollStateInit.h",
   "$blink_core_output_dir/timing/PerformanceObserverInit.cpp",
   "$blink_core_output_dir/timing/PerformanceObserverInit.h",
+  "$blink_core_output_dir/workers/WorkletOptions.cpp",
+  "$blink_core_output_dir/workers/WorkletOptions.h",
 ]
 
 bindings_core_generated_union_type_files = [
diff --git a/third_party/WebKit/Source/core/BUILD.gn b/third_party/WebKit/Source/core/BUILD.gn
index 8a2c4bd2..c0572c1 100644
--- a/third_party/WebKit/Source/core/BUILD.gn
+++ b/third_party/WebKit/Source/core/BUILD.gn
@@ -504,6 +504,7 @@
     "$blink_core_output_dir/css/properties/CSSPropertyAPIMarker.h",
     "$blink_core_output_dir/css/properties/CSSPropertyAPIOffsetAnchor.h",
     "$blink_core_output_dir/css/properties/CSSPropertyAPIOffsetDistance.h",
+    "$blink_core_output_dir/css/properties/CSSPropertyAPIOffsetPath.h",
     "$blink_core_output_dir/css/properties/CSSPropertyAPIOffsetPosition.h",
     "$blink_core_output_dir/css/properties/CSSPropertyAPIOffsetRotate.h",
     "$blink_core_output_dir/css/properties/CSSPropertyAPIOpacity.h",
diff --git a/third_party/WebKit/Source/core/core_idl_files.gni b/third_party/WebKit/Source/core/core_idl_files.gni
index 3f45dd6..5e97ebbb 100644
--- a/third_party/WebKit/Source/core/core_idl_files.gni
+++ b/third_party/WebKit/Source/core/core_idl_files.gni
@@ -588,6 +588,7 @@
                     "offscreencanvas/ImageEncodeOptions.idl",
                     "page/scrolling/ScrollStateInit.idl",
                     "timing/PerformanceObserverInit.idl",
+                    "workers/WorkletOptions.idl",
                   ],
                   "abspath")
 
diff --git a/third_party/WebKit/Source/core/css/BUILD.gn b/third_party/WebKit/Source/core/css/BUILD.gn
index 05ec632b..ca7aaf63 100644
--- a/third_party/WebKit/Source/core/css/BUILD.gn
+++ b/third_party/WebKit/Source/core/css/BUILD.gn
@@ -431,6 +431,7 @@
     "properties/CSSPropertyAPIMarker.cpp",
     "properties/CSSPropertyAPIOffsetAnchor.cpp",
     "properties/CSSPropertyAPIOffsetDistance.cpp",
+    "properties/CSSPropertyAPIOffsetPath.cpp",
     "properties/CSSPropertyAPIOffsetPosition.cpp",
     "properties/CSSPropertyAPIOffsetRotate.cpp",
     "properties/CSSPropertyAPIOpacity.cpp",
diff --git a/third_party/WebKit/Source/core/css/CSSProperties.json5 b/third_party/WebKit/Source/core/css/CSSProperties.json5
index f29ab683..79f6f22 100644
--- a/third_party/WebKit/Source/core/css/CSSProperties.json5
+++ b/third_party/WebKit/Source/core/css/CSSProperties.json5
@@ -1502,6 +1502,8 @@
     },
     {
       name: "offset-path",
+      api_class: true,
+      api_methods: ["parseSingleValue"],
       converter: "ConvertPathOrNone",
     },
     {
diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
index 4aee2677..a959114 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
+++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
@@ -1731,8 +1731,6 @@
     case CSSPropertyWebkitTextDecorationsInEffect:
     case CSSPropertyTextDecorationLine:
       return ConsumeTextDecorationLine(range_);
-    case CSSPropertyOffsetPath:
-      return CSSPropertyOffsetPathUtils::ConsumeOffsetPath(range_, context_);
     case CSSPropertyOffsetDistance:
       return ConsumeLengthOrPercent(range_, context_->Mode(), kValueRangeAll);
     case CSSPropertyOffsetRotate:
diff --git a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIOffsetPath.cpp b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIOffsetPath.cpp
new file mode 100644
index 0000000..2d4e00d2
--- /dev/null
+++ b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIOffsetPath.cpp
@@ -0,0 +1,18 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "core/css/properties/CSSPropertyAPIOffsetPath.h"
+
+#include "core/css/properties/CSSPropertyOffsetPathUtils.h"
+
+namespace blink {
+
+const CSSValue* CSSPropertyAPIOffsetPath::parseSingleValue(
+    CSSParserTokenRange& range,
+    const CSSParserContext& context,
+    CSSPropertyID) {
+  return CSSPropertyOffsetPathUtils::ConsumeOffsetPath(range, &context);
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/core/dom/Fullscreen.cpp b/third_party/WebKit/Source/core/dom/Fullscreen.cpp
index f0e48fbf..a40e830b 100644
--- a/third_party/WebKit/Source/core/dom/Fullscreen.cpp
+++ b/third_party/WebKit/Source/core/dom/Fullscreen.cpp
@@ -49,6 +49,7 @@
 #include "core/svg/SVGSVGElement.h"
 #include "platform/ScopedOrientationChangeIndicator.h"
 #include "platform/UserGestureIndicator.h"
+#include "platform/feature_policy/FeaturePolicy.h"
 
 namespace blink {
 
@@ -63,7 +64,7 @@
   if (!frame)
     return false;
 
-  if (!RuntimeEnabledFeatures::featurePolicyEnabled()) {
+  if (!IsSupportedInFeaturePolicy(WebFeaturePolicyFeature::kFullscreen)) {
     // 2. If |document|'s browsing context is a top-level browsing context, then
     // return true.
     if (frame->IsMainFrame())
diff --git a/third_party/WebKit/Source/core/editing/CaretDisplayItemClientTest.cpp b/third_party/WebKit/Source/core/editing/CaretDisplayItemClientTest.cpp
index c783f12..406799e 100644
--- a/third_party/WebKit/Source/core/editing/CaretDisplayItemClientTest.cpp
+++ b/third_party/WebKit/Source/core/editing/CaretDisplayItemClientTest.cpp
@@ -312,10 +312,10 @@
   EXPECT_EQ(1, caret_visual_rect.Width());
   EXPECT_EQ(block->Location(), caret_visual_rect.Location());
 
+  GetDocument().View()->SetTracksPaintInvalidations(true);
   // Simulate that the blinking cursor becomes invisible.
   Selection().SetCaretVisible(false);
   // Move the caret to the end of the text.
-  GetDocument().View()->SetTracksPaintInvalidations(true);
   Selection().SetSelection(
       SelectionInDOMTree::Builder().Collapse(Position(text, 5)).Build());
   // Simulate that the cursor blinking is restarted.
diff --git a/third_party/WebKit/Source/core/frame/DOMWindow.cpp b/third_party/WebKit/Source/core/frame/DOMWindow.cpp
index 0eef068..494b9c9 100644
--- a/third_party/WebKit/Source/core/frame/DOMWindow.cpp
+++ b/third_party/WebKit/Source/core/frame/DOMWindow.cpp
@@ -18,6 +18,7 @@
 #include "core/frame/Location.h"
 #include "core/frame/Settings.h"
 #include "core/frame/UseCounter.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
 #include "core/input/InputDeviceCapabilities.h"
 #include "core/inspector/ConsoleMessage.h"
 #include "core/loader/MixedContentChecker.h"
@@ -235,6 +236,13 @@
     }
   }
 
+  if (!source_document->GetContentSecurityPolicy()->AllowConnectToSource(
+          target_url, RedirectStatus::kNoRedirect,
+          SecurityViolationReportingPolicy::kSuppressReporting)) {
+    UseCounter::Count(
+        GetFrame(), UseCounter::kPostMessageOutgoingWouldBeBlockedByConnectSrc);
+  }
+
   MessageEvent* event =
       MessageEvent::Create(std::move(channels), std::move(message),
                            source_origin, String(), source, source_suborigin);
diff --git a/third_party/WebKit/Source/core/frame/FrameView.cpp b/third_party/WebKit/Source/core/frame/FrameView.cpp
index 7ba2b44..92fc41d 100644
--- a/third_party/WebKit/Source/core/frame/FrameView.cpp
+++ b/third_party/WebKit/Source/core/frame/FrameView.cpp
@@ -3731,6 +3731,9 @@
   if (track_paint_invalidations == IsTrackingPaintInvalidations())
     return;
 
+  // Ensure the document is up-to-date before tracking invalidations.
+  UpdateAllLifecyclePhases();
+
   for (Frame* frame = &frame_->Tree().Top(); frame;
        frame = frame->Tree().TraverseNext()) {
     if (!frame->IsLocalFrame())
diff --git a/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp b/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp
index 9007394..d9996e7 100644
--- a/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp
+++ b/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp
@@ -65,6 +65,7 @@
 #include "core/frame/Settings.h"
 #include "core/frame/SuspendableTimer.h"
 #include "core/frame/VisualViewport.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
 #include "core/html/HTMLFrameOwnerElement.h"
 #include "core/input/EventHandler.h"
 #include "core/inspector/ConsoleMessage.h"
@@ -703,6 +704,14 @@
     }
   }
 
+  KURL sender(kParsedURLString, static_cast<MessageEvent*>(event)->origin());
+  if (!document()->GetContentSecurityPolicy()->AllowConnectToSource(
+          sender, RedirectStatus::kNoRedirect,
+          SecurityViolationReportingPolicy::kSuppressReporting)) {
+    UseCounter::Count(
+        GetFrame(), UseCounter::kPostMessageIncomingWouldBeBlockedByConnectSrc);
+  }
+
   DispatchEvent(event);
 }
 
diff --git a/third_party/WebKit/Source/core/frame/UseCounter.h b/third_party/WebKit/Source/core/frame/UseCounter.h
index 08b6961..cc4a96b 100644
--- a/third_party/WebKit/Source/core/frame/UseCounter.h
+++ b/third_party/WebKit/Source/core/frame/UseCounter.h
@@ -1580,6 +1580,8 @@
     kAnchorClickDispatchForNonConnectedNode = 1971,
     kHTMLParseErrorNestedForm = 1972,
     kFontShapingNotDefGlyphObserved = 1973,
+    kPostMessageOutgoingWouldBeBlockedByConnectSrc = 1974,
+    kPostMessageIncomingWouldBeBlockedByConnectSrc = 1975,
 
     // Add new features immediately above this line. Don't change assigned
     // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/WebKit/Source/core/frame/WebLocalFrameBase.h b/third_party/WebKit/Source/core/frame/WebLocalFrameBase.h
index e3c38df..6254581 100644
--- a/third_party/WebKit/Source/core/frame/WebLocalFrameBase.h
+++ b/third_party/WebKit/Source/core/frame/WebLocalFrameBase.h
@@ -15,7 +15,10 @@
 class LocalFrame;
 class Node;
 class Page;
+class TextFinder;
+class WebDevToolsAgentImpl;
 class WebFrameClient;
+class WebFrameWidgetBase;
 class WebTextCheckClient;
 class WebViewBase;
 
@@ -35,6 +38,7 @@
 
   virtual WebViewBase* ViewImpl() const = 0;
   virtual WebFrameClient* Client() const = 0;
+  virtual void SetClient(WebFrameClient*) = 0;
   virtual WebTextCheckClient* TextCheckClient() const = 0;
   virtual void SetContextMenuNode(Node*) = 0;
   virtual void ClearContextMenuNode() = 0;
@@ -43,6 +47,9 @@
   virtual void InitializeCoreFrame(Page&,
                                    FrameOwner*,
                                    const AtomicString& name) = 0;
+  virtual TextFinder& EnsureTextFinder() = 0;
+  virtual void SetFrameWidget(WebFrameWidgetBase*) = 0;
+  virtual WebDevToolsAgentImpl* DevToolsAgentImpl() const = 0;
 
   DEFINE_INLINE_VIRTUAL_TRACE() {}
 
diff --git a/third_party/WebKit/Source/core/html/HTMLIFrameElementAllowTest.cpp b/third_party/WebKit/Source/core/html/HTMLIFrameElementAllowTest.cpp
index 7c43dc6..724c7c8 100644
--- a/third_party/WebKit/Source/core/html/HTMLIFrameElementAllowTest.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLIFrameElementAllowTest.cpp
@@ -29,11 +29,10 @@
   EXPECT_THAT(result,
               UnorderedElementsAre(WebFeaturePolicyFeature::kFullscreen));
 
-  allow->setValue("fullscreen payment vibrate");
+  allow->setValue("fullscreen payment");
   result = allow->ParseAllowedFeatureNames(error_message);
   EXPECT_THAT(result, UnorderedElementsAre(WebFeaturePolicyFeature::kFullscreen,
-                                           WebFeaturePolicyFeature::kPayment,
-                                           WebFeaturePolicyFeature::kVibrate));
+                                           WebFeaturePolicyFeature::kPayment));
 }
 
 TEST(HTMLIFrameElementAllowTest, ParseAllowedFeatureNamesInvalid) {
@@ -54,11 +53,11 @@
               UnorderedElementsAre(WebFeaturePolicyFeature::kFullscreen));
   EXPECT_EQ("'invalid1', 'invalid2' are invalid feature names.", error_message);
 
-  allow->setValue("fullscreen invalid vibrate fullscreen");
+  allow->setValue("fullscreen invalid payment fullscreen");
   result = allow->ParseAllowedFeatureNames(error_message);
   EXPECT_EQ("'invalid' is an invalid feature name.", error_message);
   EXPECT_THAT(result, UnorderedElementsAre(WebFeaturePolicyFeature::kFullscreen,
-                                           WebFeaturePolicyFeature::kVibrate));
+                                           WebFeaturePolicyFeature::kPayment));
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/html/TextControlElement.cpp b/third_party/WebKit/Source/core/html/TextControlElement.cpp
index 6eb7ed0..e7e5ad0 100644
--- a/third_party/WebKit/Source/core/html/TextControlElement.cpp
+++ b/third_party/WebKit/Source/core/html/TextControlElement.cpp
@@ -99,6 +99,18 @@
   if (event->type() == EventTypeNames::webkitEditableContentChanged &&
       GetLayoutObject() && GetLayoutObject()->IsTextControl()) {
     last_change_was_user_edit_ = !GetDocument().IsRunningExecCommand();
+
+    if (IsFocused()) {
+      // Updating the cache in SelectionChanged() isn't enough because
+      // SelectionChanged() is not called if:
+      // - Text nodes in the inner-editor is split to multiple, and
+      // - The caret is on the beginning of a Text node, and its previous node
+      //   is updated, or
+      // - The caret is on the end of a text node, and its next node is updated.
+      CacheSelection(ComputeSelectionStart(), ComputeSelectionEnd(),
+                     ComputeSelectionDirection());
+    }
+
     SubtreeHasChanged();
     return;
   }
diff --git a/third_party/WebKit/Source/core/layout/FragmentainerIterator.cpp b/third_party/WebKit/Source/core/layout/FragmentainerIterator.cpp
index 5001ea67..de39f55 100644
--- a/third_party/WebKit/Source/core/layout/FragmentainerIterator.cpp
+++ b/third_party/WebKit/Source/core/layout/FragmentainerIterator.cpp
@@ -71,7 +71,7 @@
   const MultiColumnFragmentainerGroup& group = CurrentGroup();
   LayoutUnit fragmentainer_logical_top_in_flow_thread =
       group.LogicalTopInFlowThread() +
-      current_fragmentainer_index_ * group.LogicalHeight();
+      current_fragmentainer_index_ * group.ColumnLogicalHeight();
   return group.FlowThreadTranslationAtOffset(
       fragmentainer_logical_top_in_flow_thread,
       LayoutBox::kAssociateWithLatterPage, CoordinateSpaceConversion::kVisual);
diff --git a/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.cpp b/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.cpp
index 4c6c3265..438e414 100644
--- a/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.cpp
@@ -673,7 +673,7 @@
         // multicol container.
         LayoutUnit logical_offset_in_outer =
             last_row.BlockOffsetInEnclosingFragmentationContext() +
-            last_row.LogicalHeight();
+            last_row.GroupLogicalHeight();
         enclosing_flow_thread->AppendNewFragmentainerGroupIfNeeded(
             logical_offset_in_outer, kAssociateWithLatterPage);
       }
@@ -682,8 +682,8 @@
           column_set->AppendNewFragmentainerGroup();
       // Zero-height rows should really not occur here, but if it does anyway,
       // break, so that we don't get stuck in an infinite loop.
-      DCHECK_GT(new_row.LogicalHeight(), 0);
-      if (new_row.LogicalHeight() <= 0)
+      DCHECK_GT(new_row.ColumnLogicalHeight(), 0);
+      if (new_row.ColumnLogicalHeight() <= 0)
         break;
     } while (column_set->NeedsNewFragmentainerGroupAt(offset_in_flow_thread,
                                                       page_boundary_rule));
diff --git a/third_party/WebKit/Source/core/layout/LayoutMultiColumnSet.cpp b/third_party/WebKit/Source/core/layout/LayoutMultiColumnSet.cpp
index 865422d..3ddf103 100644
--- a/third_party/WebKit/Source/core/layout/LayoutMultiColumnSet.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutMultiColumnSet.cpp
@@ -79,7 +79,7 @@
       IsHorizontalWritingMode() ? visual_point.Y() : visual_point.X();
   for (unsigned index = 0; index < fragmentainer_groups_.size(); index++) {
     const auto& row = fragmentainer_groups_[index];
-    if (row.LogicalTop() + row.LogicalHeight() > block_offset)
+    if (row.LogicalTop() + row.GroupLogicalHeight() > block_offset)
       return row;
   }
   return fragmentainer_groups_.Last();
@@ -88,7 +88,7 @@
 LayoutUnit LayoutMultiColumnSet::PageLogicalHeightForOffset(
     LayoutUnit offset_in_flow_thread) const {
   const MultiColumnFragmentainerGroup& last_row = LastFragmentainerGroup();
-  if (!last_row.LogicalHeight() && fragmentainer_groups_.size() == 1) {
+  if (!last_row.GroupLogicalHeight() && fragmentainer_groups_.size() == 1) {
     // In the first layout pass of an auto-height multicol container, height
     // isn't set. No need to perform the series of complicated dance steps below
     // to figure out that we should simply return 0. Bail now.
@@ -108,14 +108,14 @@
       // we have found so far.
       LayoutUnit enclosing_context_bottom =
           last_row.BlockOffsetInEnclosingFragmentationContext() +
-          last_row.LogicalHeight();
+          last_row.GroupLogicalHeight();
       LayoutUnit enclosing_fragmentainer_height =
           enclosing_fragmentation_context->FragmentainerLogicalHeightAt(
               enclosing_context_bottom);
       // Constrain against specified height / max-height.
       LayoutUnit current_multicol_height = LogicalTopFromMulticolContentEdge() +
                                            last_row.LogicalTop() +
-                                           last_row.LogicalHeight();
+                                           last_row.GroupLogicalHeight();
       LayoutUnit multicol_height_with_extra_row =
           current_multicol_height + enclosing_fragmentainer_height;
       multicol_height_with_extra_row =
@@ -127,7 +127,7 @@
   }
   return FragmentainerGroupAtFlowThreadOffset(offset_in_flow_thread,
                                               kAssociateWithLatterPage)
-      .LogicalHeight();
+      .ColumnLogicalHeight();
 }
 
 LayoutUnit LayoutMultiColumnSet::PageRemainingLogicalHeightForOffset(
@@ -136,7 +136,7 @@
   const MultiColumnFragmentainerGroup& row =
       FragmentainerGroupAtFlowThreadOffset(offset_in_flow_thread,
                                            page_boundary_rule);
-  LayoutUnit page_logical_height = row.LogicalHeight();
+  LayoutUnit page_logical_height = row.ColumnLogicalHeight();
   LayoutUnit page_logical_bottom =
       row.ColumnLogicalTopForOffset(offset_in_flow_thread) +
       page_logical_height;
@@ -161,7 +161,7 @@
 }
 
 bool LayoutMultiColumnSet::IsPageLogicalHeightKnown() const {
-  return FirstFragmentainerGroup().LogicalHeight();
+  return FirstFragmentainerGroup().ColumnLogicalHeight();
 }
 
 bool LayoutMultiColumnSet::NewFragmentainerGroupsAllowed() const {
@@ -214,7 +214,7 @@
   LayoutUnit new_logical_height =
       enclosing_fragmentation_context->FragmentainerLogicalHeightAt(
           first_row.BlockOffsetInEnclosingFragmentationContext() +
-          first_row.LogicalHeight());
+          first_row.GroupLogicalHeight());
   if (content_logical_height > new_logical_height) {
     // The next outer column or page doesn't have enough space either. Give up
     // and stay where we are.
@@ -283,7 +283,8 @@
   // useless fragmentainer groups, and possibly broken layout too. Instead,
   // we'll just allow additional (overflowing) columns to be created in the
   // last fragmentainer group, similar to what we do when we're not nested.
-  LayoutUnit logical_bottom = last_row.LogicalTop() + last_row.LogicalHeight();
+  LayoutUnit logical_bottom =
+      last_row.LogicalTop() + last_row.GroupLogicalHeight();
   LayoutUnit space_used = logical_bottom + LogicalTopFromMulticolContentEdge();
   LayoutUnit max_column_height =
       MultiColumnFlowThread()->MaxColumnLogicalHeight();
@@ -306,7 +307,7 @@
     previous_group.SetLogicalBottomInFlowThread(block_offset_in_flow_thread);
     new_group.SetLogicalTopInFlowThread(block_offset_in_flow_thread);
     new_group.SetLogicalTop(previous_group.LogicalTop() +
-                            previous_group.LogicalHeight());
+                            previous_group.GroupLogicalHeight());
     new_group.ResetColumnHeight();
   }
   fragmentainer_groups_.Append(new_group);
@@ -462,7 +463,7 @@
     LogicalExtentComputedValues& computed_values) const {
   LayoutUnit logical_height;
   for (const auto& group : fragmentainer_groups_)
-    logical_height += group.LogicalHeight();
+    logical_height += group.GroupLogicalHeight();
   computed_values.extent_ = logical_height;
   computed_values.position_ = logical_top;
 }
diff --git a/third_party/WebKit/Source/core/layout/LayoutMultiColumnSet.h b/third_party/WebKit/Source/core/layout/LayoutMultiColumnSet.h
index 9a3f9451..cb18996c 100644
--- a/third_party/WebKit/Source/core/layout/LayoutMultiColumnSet.h
+++ b/third_party/WebKit/Source/core/layout/LayoutMultiColumnSet.h
@@ -159,7 +159,7 @@
   // group can hold without overflowing.
   LayoutUnit FragmentainerGroupCapacity(
       const MultiColumnFragmentainerGroup& group) const {
-    return group.LogicalHeight() * UsedColumnCount();
+    return group.ColumnLogicalHeight() * UsedColumnCount();
   }
 
   LayoutRect FlowThreadPortionRect() const;
diff --git a/third_party/WebKit/Source/core/layout/MultiColumnFragmentainerGroup.cpp b/third_party/WebKit/Source/core/layout/MultiColumnFragmentainerGroup.cpp
index 663db61..728b340 100644
--- a/third_party/WebKit/Source/core/layout/MultiColumnFragmentainerGroup.cpp
+++ b/third_party/WebKit/Source/core/layout/MultiColumnFragmentainerGroup.cpp
@@ -39,10 +39,11 @@
 
 LayoutUnit MultiColumnFragmentainerGroup::LogicalHeightInFlowThreadAt(
     unsigned column_index) const {
-  if (!column_height_)
+  LayoutUnit column_height = ColumnLogicalHeight();
+  if (!column_height)
     return LayoutUnit();
   LayoutUnit logical_top = LogicalTopInFlowThreadAt(column_index);
-  LayoutUnit logical_bottom = logical_top + column_height_;
+  LayoutUnit logical_bottom = logical_top + column_height;
   if (logical_bottom > LogicalBottomInFlowThread()) {
     DCHECK_EQ(column_index + 1, ActualColumnCount());
     logical_bottom = LogicalBottomInFlowThread();
@@ -51,7 +52,7 @@
 }
 
 void MultiColumnFragmentainerGroup::ResetColumnHeight() {
-  max_column_height_ = CalculateMaxColumnHeight();
+  max_logical_height_ = CalculateMaxColumnHeight();
 
   LayoutMultiColumnFlowThread* flow_thread =
       column_set_.MultiColumnFlowThread();
@@ -64,7 +65,7 @@
       // fragmentation context, in order to tell how much content this
       // MultiColumnFragmentainerGroup can hold, and when we need to append a
       // new one.
-      column_height_ = max_column_height_;
+      logical_height_ = max_logical_height_;
       return;
     }
   }
@@ -77,15 +78,15 @@
   if (LayoutUnit logical_height = flow_thread->ColumnHeightAvailable()) {
     SetAndConstrainColumnHeight(HeightAdjustedForRowOffset(logical_height));
   } else {
-    column_height_ = LayoutUnit();
+    logical_height_ = LayoutUnit();
   }
 }
 
 bool MultiColumnFragmentainerGroup::RecalculateColumnHeight(
     LayoutMultiColumnSet& column_set) {
-  LayoutUnit old_column_height = column_height_;
+  LayoutUnit old_column_height = logical_height_;
 
-  max_column_height_ = CalculateMaxColumnHeight();
+  max_logical_height_ = CalculateMaxColumnHeight();
 
   // Only the last row may have auto height, and thus be balanced. There are no
   // good reasons to balance the preceding rows, and that could potentially lead
@@ -116,10 +117,10 @@
   } else {
     // The position of the column set may have changed, in which case height
     // available for columns may have changed as well.
-    SetAndConstrainColumnHeight(column_height_);
+    SetAndConstrainColumnHeight(logical_height_);
   }
 
-  if (column_height_ == old_column_height)
+  if (logical_height_ == old_column_height)
     return false;  // No change. We're done.
 
   return true;  // Need another pass.
@@ -211,8 +212,8 @@
                                     : column_rect.Height();
       if (local_point.X() < 0)
         local_point = LayoutPoint(LayoutUnit(), column_start);
-      else if (local_point.X() > LogicalHeight())
-        local_point = LayoutPoint(LogicalHeight(), column_start);
+      else if (local_point.X() > ColumnLogicalHeight())
+        local_point = LayoutPoint(ColumnLogicalHeight(), column_start);
     }
     return LayoutPoint(local_point.X() + LogicalTopInFlowThreadAt(column_index),
                        local_point.Y());
@@ -223,8 +224,8 @@
                                   : column_rect.Width();
     if (local_point.Y() < 0)
       local_point = LayoutPoint(column_start, LayoutUnit());
-    else if (local_point.Y() > LogicalHeight())
-      local_point = LayoutPoint(column_start, LogicalHeight());
+    else if (local_point.Y() > ColumnLogicalHeight())
+      local_point = LayoutPoint(column_start, ColumnLogicalHeight());
   }
   return LayoutPoint(local_point.X(),
                      local_point.Y() + LogicalTopInFlowThreadAt(column_index));
@@ -294,7 +295,8 @@
   // We must always return a value of 1 or greater. Column count = 0 is a
   // meaningless situation, and will confuse and cause problems in other parts
   // of the code.
-  if (!column_height_)
+  LayoutUnit column_height = ColumnLogicalHeight();
+  if (!column_height)
     return 1;
 
   // Our flow thread portion determines our column count. We have as many
@@ -303,9 +305,9 @@
   if (!flow_thread_portion_height)
     return 1;
 
-  unsigned count = (flow_thread_portion_height / column_height_).Floor();
+  unsigned count = (flow_thread_portion_height / column_height).Floor();
   // flowThreadPortionHeight may be saturated, so detect the remainder manually.
-  if (count * column_height_ < flow_thread_portion_height)
+  if (count * column_height < flow_thread_portion_height)
     count++;
   DCHECK_GE(count, 1u);
   return count;
@@ -342,9 +344,9 @@
 
 void MultiColumnFragmentainerGroup::SetAndConstrainColumnHeight(
     LayoutUnit new_height) {
-  column_height_ = new_height;
-  if (column_height_ > max_column_height_)
-    column_height_ = max_column_height_;
+  logical_height_ = new_height;
+  if (logical_height_ > max_logical_height_)
+    logical_height_ = max_logical_height_;
 }
 
 LayoutUnit MultiColumnFragmentainerGroup::RebalanceColumnHeightIfNeeded()
@@ -352,15 +354,15 @@
   if (ActualColumnCount() <= column_set_.UsedColumnCount()) {
     // With the current column height, the content fits without creating
     // overflowing columns. We're done.
-    return column_height_;
+    return logical_height_;
   }
 
-  if (column_height_ >= max_column_height_) {
+  if (logical_height_ >= max_logical_height_) {
     // We cannot stretch any further. We'll just have to live with the
     // overflowing columns. This typically happens if the max column height is
     // less than the height of the tallest piece of unbreakable content (e.g.
     // lines).
-    return column_height_;
+    return logical_height_;
   }
 
   MinimumSpaceShortageFinder shortage_finder(
@@ -370,7 +372,7 @@
       column_set_.UsedColumnCount()) {
     // Too many forced breaks to allow any implicit breaks. Initial balancing
     // should already have set a good height. There's nothing more we should do.
-    return column_height_;
+    return logical_height_;
   }
 
   // If the initial guessed column height wasn't enough, stretch it now. Stretch
@@ -381,9 +383,9 @@
   DCHECK_NE(min_space_shortage,
             LayoutUnit::Max());  // If this happens, we probably have a bug.
   if (min_space_shortage == LayoutUnit::Max())
-    return column_height_;  // So bail out rather than looping infinitely.
+    return logical_height_;  // So bail out rather than looping infinitely.
 
-  return column_height_ + min_space_shortage;
+  return logical_height_ + min_space_shortage;
 }
 
 LayoutRect MultiColumnFragmentainerGroup::ColumnRectAt(
@@ -402,7 +404,7 @@
                              column_logical_width -
                              column_index * (column_logical_width + column_gap);
   } else {
-    column_logical_top += column_index * (column_height_ + column_gap);
+    column_logical_top += column_index * (ColumnLogicalHeight() + column_gap);
   }
 
   LayoutRect column_rect(column_logical_left, column_logical_top,
@@ -498,10 +500,11 @@
   if (offset_in_flow_thread < logical_top_in_flow_thread_)
     return 0;
 
-  if (!column_height_)
+  LayoutUnit column_height = ColumnLogicalHeight();
+  if (!column_height)
     return 0;
   unsigned column_index =
-      ((offset_in_flow_thread - logical_top_in_flow_thread_) / column_height_)
+      ((offset_in_flow_thread - logical_top_in_flow_thread_) / column_height)
           .Floor();
   if (page_boundary_rule == LayoutBox::kAssociateWithFormerPage &&
       column_index > 0 &&
@@ -520,7 +523,7 @@
   bool is_horizontal_writing_mode = column_set_.IsHorizontalWritingMode();
   LayoutUnit column_length_in_column_progression_direction =
       is_column_progression_inline ? column_set_.PageLogicalWidth()
-                                   : LogicalHeight();
+                                   : ColumnLogicalHeight();
   LayoutUnit offset_in_column_progression_direction =
       is_horizontal_writing_mode == is_column_progression_inline
           ? visual_point.X()
diff --git a/third_party/WebKit/Source/core/layout/MultiColumnFragmentainerGroup.h b/third_party/WebKit/Source/core/layout/MultiColumnFragmentainerGroup.h
index 30b0725..31c7ad3 100644
--- a/third_party/WebKit/Source/core/layout/MultiColumnFragmentainerGroup.h
+++ b/third_party/WebKit/Source/core/layout/MultiColumnFragmentainerGroup.h
@@ -44,7 +44,21 @@
   LayoutUnit LogicalTop() const { return logical_top_; }
   void SetLogicalTop(LayoutUnit logical_top) { logical_top_ = logical_top; }
 
-  LayoutUnit LogicalHeight() const { return column_height_; }
+  // Return the amount of block space that this fragmentainer group takes up in
+  // its containing LayoutMultiColumnSet.
+  LayoutUnit GroupLogicalHeight() const { return logical_height_; }
+
+  // Return the block size of a column (or fragmentainer) in this fragmentainer
+  // group. The spec says that this value must always be >= 1px, to ensure
+  // progress.
+  LayoutUnit ColumnLogicalHeight() const {
+    // If the height hasn't been calculated yet, though, we allow returning 0
+    // (and the caller is then expected to refrain from attempting to fragment).
+    if (!logical_height_)
+      return logical_height_;
+
+    return std::max(LayoutUnit(1), logical_height_);
+  }
 
   LayoutSize OffsetFromColumnSet() const;
 
@@ -156,7 +170,7 @@
 
   LayoutRect ColumnRectAt(unsigned column_index) const;
   LayoutUnit LogicalTopInFlowThreadAt(unsigned column_index) const {
-    return logical_top_in_flow_thread_ + column_index * column_height_;
+    return logical_top_in_flow_thread_ + column_index * ColumnLogicalHeight();
   }
 
   // Return the column that the specified visual point belongs to. Only the
@@ -170,9 +184,13 @@
   LayoutUnit logical_top_in_flow_thread_;
   LayoutUnit logical_bottom_in_flow_thread_;
 
-  LayoutUnit column_height_;
+  // Logical height of the group. This will also be the height of each column
+  // in this group, with the difference that, while the logical height can be
+  // 0, the height of a column must be >= 1px.
+  LayoutUnit logical_height_;
 
-  LayoutUnit max_column_height_;  // Maximum column height allowed.
+  // Maximum logical height allowed.
+  LayoutUnit max_logical_height_;
 };
 
 // List of all fragmentainer groups within a column set. There will always be at
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_item.h b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_item.h
index 850fb69..5da7f0b 100644
--- a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_item.h
+++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_item.h
@@ -28,6 +28,7 @@
  public:
   enum NGInlineItemType {
     kText,
+    kControl,
     kAtomicInline,
     kOpenTag,
     kCloseTag,
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_items_builder.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_items_builder.cc
index 2aec093..1038485 100644
--- a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_items_builder.cc
+++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_items_builder.cc
@@ -113,9 +113,15 @@
   items->push_back(NGInlineItem(type, start, end, style, layout_object));
 }
 
-static inline bool IsCollapsibleSpace(UChar c, bool preserve_newline) {
+static inline bool IsCollapsibleSpace(UChar c) {
   return c == kSpaceCharacter || c == kTabulationCharacter ||
-         (!preserve_newline && c == kNewlineCharacter);
+         c == kNewlineCharacter;
+}
+
+// Characters needing a separate control item than other text items.
+// It makes the line breaker easier to handle.
+static inline bool IsControlItemCharacter(UChar c) {
+  return c == kTabulationCharacter || c == kNewlineCharacter;
 }
 
 void NGInlineItemsBuilder::Append(const String& string,
@@ -123,59 +129,60 @@
                                   LayoutObject* layout_object) {
   if (string.IsEmpty())
     return;
+  text_.ReserveCapacity(string.length());
 
   EWhiteSpace whitespace = style->WhiteSpace();
-  bool preserve_newline =
-      ComputedStyle::PreserveNewline(whitespace) && !is_svgtext_;
-  bool collapse_whitespace = ComputedStyle::CollapseWhiteSpace(whitespace);
+  if (!ComputedStyle::CollapseWhiteSpace(whitespace))
+    return AppendWithoutWhiteSpaceCollapsing(string, style, layout_object);
+  if (ComputedStyle::PreserveNewline(whitespace) && !is_svgtext_)
+    return AppendWithPreservingNewlines(string, style, layout_object);
+
+  AppendWithWhiteSpaceCollapsing(string, 0, string.length(), style,
+                                 layout_object);
+}
+
+void NGInlineItemsBuilder::AppendWithWhiteSpaceCollapsing(
+    const String& string,
+    unsigned start,
+    unsigned end,
+    const ComputedStyle* style,
+    LayoutObject* layout_object) {
   unsigned start_offset = text_.length();
-
-  if (!collapse_whitespace) {
-    text_.Append(string);
-    last_collapsible_space_ = CollapsibleSpace::kNone;
-  } else {
-    text_.ReserveCapacity(string.length());
-    for (unsigned i = 0; i < string.length();) {
-      UChar c = string[i];
-      if (c == kNewlineCharacter) {
-        if (preserve_newline) {
-          RemoveTrailingCollapsibleSpaceIfExists(&start_offset);
-          text_.Append(c);
-          // Remove collapsible spaces immediately following a newline.
-          last_collapsible_space_ = CollapsibleSpace::kSpace;
-          i++;
-          continue;
-        }
-
-        if (last_collapsible_space_ == CollapsibleSpace::kNone)
-          text_.Append(kSpaceCharacter);
-        last_collapsible_space_ = CollapsibleSpace::kNewline;
-        i++;
-        continue;
+  for (unsigned i = start; i < end;) {
+    UChar c = string[i];
+    if (c == kNewlineCharacter) {
+      // LayoutBR does not set preserve_newline, but should be preserved.
+      if (!i && end == 1 && layout_object && layout_object->IsBR()) {
+        AppendForcedBreak(style, layout_object);
+        return;
       }
 
-      if (c == kSpaceCharacter || c == kTabulationCharacter) {
-        if (last_collapsible_space_ == CollapsibleSpace::kNone) {
-          text_.Append(kSpaceCharacter);
-          last_collapsible_space_ = CollapsibleSpace::kSpace;
-        }
-        i++;
-        continue;
-      }
-
-      if (last_collapsible_space_ == CollapsibleSpace::kNewline) {
-        RemoveTrailingCollapsibleNewlineIfNeeded(&start_offset, string, i,
-                                                 style);
-      }
-
-      unsigned start_of_non_space = i;
-      for (i++; i < string.length(); i++) {
-        if (IsCollapsibleSpace(string[i], false))
-          break;
-      }
-      text_.Append(string, start_of_non_space, i - start_of_non_space);
-      last_collapsible_space_ = CollapsibleSpace::kNone;
+      if (last_collapsible_space_ == CollapsibleSpace::kNone)
+        text_.Append(kSpaceCharacter);
+      last_collapsible_space_ = CollapsibleSpace::kNewline;
+      i++;
+      continue;
     }
+
+    if (c == kSpaceCharacter || c == kTabulationCharacter) {
+      if (last_collapsible_space_ == CollapsibleSpace::kNone) {
+        text_.Append(kSpaceCharacter);
+        last_collapsible_space_ = CollapsibleSpace::kSpace;
+      }
+      i++;
+      continue;
+    }
+
+    if (last_collapsible_space_ == CollapsibleSpace::kNewline) {
+      RemoveTrailingCollapsibleNewlineIfNeeded(&start_offset, string, i, style);
+    }
+
+    size_t end_of_non_space = string.Find(IsCollapsibleSpace, i + 1);
+    if (end_of_non_space == kNotFound)
+      end_of_non_space = string.length();
+    text_.Append(string, i, end_of_non_space - i);
+    i = end_of_non_space;
+    last_collapsible_space_ = CollapsibleSpace::kNone;
   }
 
   if (text_.length() > start_offset) {
@@ -184,13 +191,69 @@
   }
 }
 
+// Even when without whitespace collapsing, control characters (newlines and
+// tabs) are in their own control items to make the line breaker easier.
+void NGInlineItemsBuilder::AppendWithoutWhiteSpaceCollapsing(
+    const String& string,
+    const ComputedStyle* style,
+    LayoutObject* layout_object) {
+  for (unsigned start = 0; start < string.length();) {
+    UChar c = string[start];
+    if (IsControlItemCharacter(c)) {
+      Append(NGInlineItem::kControl, c, style, layout_object);
+      start++;
+      continue;
+    }
+
+    size_t end = string.Find(IsControlItemCharacter, start + 1);
+    if (end == kNotFound)
+      end = string.length();
+    unsigned start_offset = text_.length();
+    text_.Append(string, start, end - start);
+    AppendItem(items_, NGInlineItem::kText, start_offset, text_.length(), style,
+               layout_object);
+    start = end;
+  }
+
+  last_collapsible_space_ = CollapsibleSpace::kNone;
+}
+
+void NGInlineItemsBuilder::AppendWithPreservingNewlines(
+    const String& string,
+    const ComputedStyle* style,
+    LayoutObject* layout_object) {
+  for (unsigned start = 0; start < string.length();) {
+    if (string[start] == kNewlineCharacter) {
+      AppendForcedBreak(style, layout_object);
+      start++;
+      continue;
+    }
+
+    size_t end = string.find(kNewlineCharacter, start + 1);
+    if (end == kNotFound)
+      end = string.length();
+    AppendWithWhiteSpaceCollapsing(string, start, end, style, layout_object);
+    start = end;
+  }
+}
+
+void NGInlineItemsBuilder::AppendForcedBreak(const ComputedStyle* style,
+                                             LayoutObject* layout_object) {
+  // Remove collapsible spaces immediately before a preserved newline.
+  unsigned start_offset = text_.length();
+  RemoveTrailingCollapsibleSpaceIfExists(&start_offset);
+
+  Append(NGInlineItem::kControl, kNewlineCharacter, style, layout_object);
+
+  // Remove collapsible spaces immediately after a preserved newline.
+  last_collapsible_space_ = CollapsibleSpace::kSpace;
+}
+
 void NGInlineItemsBuilder::Append(NGInlineItem::NGInlineItemType type,
                                   UChar character,
                                   const ComputedStyle* style,
                                   LayoutObject* layout_object) {
   DCHECK_NE(character, kSpaceCharacter);
-  DCHECK_NE(character, kTabulationCharacter);
-  DCHECK_NE(character, kNewlineCharacter);
   DCHECK_NE(character, kZeroWidthSpaceCharacter);
 
   text_.Append(character);
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_items_builder.h b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_items_builder.h
index 9d3757b..9f295706 100644
--- a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_items_builder.h
+++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_items_builder.h
@@ -92,6 +92,20 @@
   bool is_svgtext_ = false;
   bool has_bidi_controls_ = false;
 
+  void AppendWithWhiteSpaceCollapsing(const String&,
+                                      unsigned start,
+                                      unsigned end,
+                                      const ComputedStyle*,
+                                      LayoutObject*);
+  void AppendWithoutWhiteSpaceCollapsing(const String&,
+                                         const ComputedStyle*,
+                                         LayoutObject*);
+  void AppendWithPreservingNewlines(const String&,
+                                    const ComputedStyle*,
+                                    LayoutObject*);
+
+  void AppendForcedBreak(const ComputedStyle*, LayoutObject*);
+
   // Because newlines may be removed depends on following characters, newlines
   // at the end of input string is not added to |text_| but instead
   // |has_pending_newline_| flag is set.
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_items_builder_test.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_items_builder_test.cc
index 5fee20f..dac3a12 100644
--- a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_items_builder_test.cc
+++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_items_builder_test.cc
@@ -245,6 +245,18 @@
   EXPECT_EQ(0u, items_.size());
 }
 
+TEST_F(NGInlineItemsBuilderTest, NewLines) {
+  SetWhiteSpace(EWhiteSpace::kPre);
+  EXPECT_EQ("apple\norange\ngrape\n", TestAppend("apple\norange\ngrape\n"));
+  EXPECT_EQ(6u, items_.size());
+  EXPECT_EQ(NGInlineItem::kText, items_[0].Type());
+  EXPECT_EQ(NGInlineItem::kControl, items_[1].Type());
+  EXPECT_EQ(NGInlineItem::kText, items_[2].Type());
+  EXPECT_EQ(NGInlineItem::kControl, items_[3].Type());
+  EXPECT_EQ(NGInlineItem::kText, items_[4].Type());
+  EXPECT_EQ(NGInlineItem::kControl, items_[5].Type());
+}
+
 TEST_F(NGInlineItemsBuilderTest, Empty) {
   Vector<NGInlineItem> items;
   NGInlineItemsBuilder builder(&items);
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node_test.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node_test.cc
index 4adb7f83..85227ff 100644
--- a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node_test.cc
+++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node_test.cc
@@ -144,6 +144,18 @@
   EXPECT_EQ(5u, items.size());
 }
 
+TEST_F(NGInlineNodeTest, CollectInlinesBR) {
+  SetupHtml("t", u"<div id=t>Hello<br>World</div>");
+  NGInlineNodeForTest* node = CreateInlineNode();
+  node->CollectInlines(layout_object_, layout_block_flow_);
+  EXPECT_EQ("Hello\nWorld", node->Text());
+  Vector<NGInlineItem>& items = node->Items();
+  TEST_ITEM_TYPE_OFFSET(items[0], kText, 0u, 5u);
+  TEST_ITEM_TYPE_OFFSET(items[1], kControl, 5u, 6u);
+  TEST_ITEM_TYPE_OFFSET(items[2], kText, 6u, 11u);
+  EXPECT_EQ(3u, items.size());
+}
+
 TEST_F(NGInlineNodeTest, CollectInlinesRtlText) {
   SetupHtml("t", u"<div id=t dir=rtl>\u05E2 <span>\u05E2</span> \u05E2</div>");
   NGInlineNodeForTest* node = CreateInlineNode();
diff --git a/third_party/WebKit/Source/core/workers/MainThreadWorklet.cpp b/third_party/WebKit/Source/core/workers/MainThreadWorklet.cpp
index edd1b71..43ac128 100644
--- a/third_party/WebKit/Source/core/workers/MainThreadWorklet.cpp
+++ b/third_party/WebKit/Source/core/workers/MainThreadWorklet.cpp
@@ -11,22 +11,42 @@
 #include "core/workers/WorkletGlobalScopeProxy.h"
 #include "core/workers/WorkletPendingTasks.h"
 #include "platform/wtf/WTF.h"
+#include "public/platform/WebURLRequest.h"
 
 namespace blink {
 
+namespace {
+
+WebURLRequest::FetchCredentialsMode ParseCredentialsOption(
+    const String& credentials_option) {
+  if (credentials_option == "omit")
+    return WebURLRequest::kFetchCredentialsModeOmit;
+  if (credentials_option == "same-origin")
+    return WebURLRequest::kFetchCredentialsModeSameOrigin;
+  if (credentials_option == "include")
+    return WebURLRequest::kFetchCredentialsModeInclude;
+  NOTREACHED();
+  return WebURLRequest::kFetchCredentialsModeOmit;
+}
+
+}  // namespace
+
 MainThreadWorklet::MainThreadWorklet(LocalFrame* frame) : Worklet(frame) {}
 
 // Implementation of the second half of the "addModule(moduleURL, options)"
 // algorithm:
 // https://drafts.css-houdini.org/worklets/#dom-worklet-addmodule
 void MainThreadWorklet::FetchAndInvokeScript(const KURL& module_url_record,
+                                             const WorkletOptions& options,
                                              ScriptPromiseResolver* resolver) {
   DCHECK(IsMainThread());
   if (!GetExecutionContext())
     return;
 
   // Step 6: "Let credentialOptions be the credentials member of options."
-  // TODO(nhiroki): Implement credentialOptions (https://crbug.com/710837).
+  // TODO(nhiroki): Add tests for credentialOptions (https://crbug.com/710837).
+  WebURLRequest::FetchCredentialsMode credentials_mode =
+      ParseCredentialsOption(options.credentials());
 
   // Step 7: "Let outsideSettings be the relevant settings object of this."
   // TODO(nhiroki): outsideSettings will be used for posting a task to the
@@ -62,10 +82,9 @@
   // invoke a worklet script given workletGlobalScope, moduleURLRecord,
   // moduleResponsesMap, credentialOptions, outsideSettings, pendingTaskStruct,
   // and promise."
-  // TODO(nhiroki): Pass the remaining parameters (e.g., credentialOptions).
   // TODO(nhiroki): Queue a task instead of executing this here.
-  GetWorkletGlobalScopeProxy()->FetchAndInvokeScript(module_url_record,
-                                                     pending_tasks);
+  GetWorkletGlobalScopeProxy()->FetchAndInvokeScript(
+      module_url_record, credentials_mode, pending_tasks);
 }
 
 void MainThreadWorklet::ContextDestroyed(ExecutionContext* execution_context) {
diff --git a/third_party/WebKit/Source/core/workers/MainThreadWorklet.h b/third_party/WebKit/Source/core/workers/MainThreadWorklet.h
index 2fd6837..998ab29 100644
--- a/third_party/WebKit/Source/core/workers/MainThreadWorklet.h
+++ b/third_party/WebKit/Source/core/workers/MainThreadWorklet.h
@@ -38,6 +38,7 @@
  private:
   // Worklet.
   void FetchAndInvokeScript(const KURL& module_url_record,
+                            const WorkletOptions&,
                             ScriptPromiseResolver*) override;
 };
 
diff --git a/third_party/WebKit/Source/core/workers/MainThreadWorkletGlobalScope.cpp b/third_party/WebKit/Source/core/workers/MainThreadWorkletGlobalScope.cpp
index daaefd8..bb71248 100644
--- a/third_party/WebKit/Source/core/workers/MainThreadWorkletGlobalScope.cpp
+++ b/third_party/WebKit/Source/core/workers/MainThreadWorkletGlobalScope.cpp
@@ -51,6 +51,7 @@
 // https://drafts.css-houdini.org/worklets/#fetch-and-invoke-a-worklet-script
 void MainThreadWorkletGlobalScope::FetchAndInvokeScript(
     const KURL& module_url_record,
+    WebURLRequest::FetchCredentialsMode credentials_mode,
     WorkletPendingTasks* pending_tasks) {
   DCHECK(IsMainThread());
   // Step 1: "Let insideSettings be the workletGlobalScope's associated
@@ -58,7 +59,8 @@
   // Step 2: "Let script by the result of fetch a worklet script given
   // moduleURLRecord, moduleResponsesMap, credentialOptions, outsideSettings,
   // and insideSettings when it asynchronously completes."
-  // TODO(nhiroki): Replace this with module script loading.
+  // TODO(nhiroki): Replace this with module script loading. Set fetch request's
+  // credentials mode to |credentials_mode|.
   WorkletScriptLoader* script_loader =
       WorkletScriptLoader::Create(GetFrame()->GetDocument()->Fetcher(), this);
   loader_map_.Set(script_loader, pending_tasks);
diff --git a/third_party/WebKit/Source/core/workers/MainThreadWorkletGlobalScope.h b/third_party/WebKit/Source/core/workers/MainThreadWorkletGlobalScope.h
index 1fe4a060..96648bd6 100644
--- a/third_party/WebKit/Source/core/workers/MainThreadWorkletGlobalScope.h
+++ b/third_party/WebKit/Source/core/workers/MainThreadWorkletGlobalScope.h
@@ -11,6 +11,7 @@
 #include "core/loader/WorkletScriptLoader.h"
 #include "core/workers/WorkletGlobalScope.h"
 #include "core/workers/WorkletPendingTasks.h"
+#include "public/platform/WebURLRequest.h"
 
 namespace blink {
 
@@ -39,6 +40,7 @@
   WorkerThread* GetThread() const final;
 
   void FetchAndInvokeScript(const KURL& module_url_record,
+                            WebURLRequest::FetchCredentialsMode,
                             WorkletPendingTasks*);
   void Terminate();
 
diff --git a/third_party/WebKit/Source/core/workers/ThreadedWorklet.cpp b/third_party/WebKit/Source/core/workers/ThreadedWorklet.cpp
index 972f81a1..7ebd858 100644
--- a/third_party/WebKit/Source/core/workers/ThreadedWorklet.cpp
+++ b/third_party/WebKit/Source/core/workers/ThreadedWorklet.cpp
@@ -19,6 +19,7 @@
     : Worklet(frame), frame_(frame) {}
 
 void ThreadedWorklet::FetchAndInvokeScript(const KURL& module_url_record,
+                                           const WorkletOptions&,
                                            ScriptPromiseResolver* resolver) {
   DCHECK(IsMainThread());
   if (!GetExecutionContext())
diff --git a/third_party/WebKit/Source/core/workers/ThreadedWorklet.h b/third_party/WebKit/Source/core/workers/ThreadedWorklet.h
index 075a9e4f..7a4fb4f 100644
--- a/third_party/WebKit/Source/core/workers/ThreadedWorklet.h
+++ b/third_party/WebKit/Source/core/workers/ThreadedWorklet.h
@@ -44,6 +44,7 @@
  private:
   // Worklet
   void FetchAndInvokeScript(const KURL& module_url_record,
+                            const WorkletOptions&,
                             ScriptPromiseResolver*) override;
 
   // Called when addModule() is called for the first time.
diff --git a/third_party/WebKit/Source/core/workers/Worklet.cpp b/third_party/WebKit/Source/core/workers/Worklet.cpp
index 58dc60b6..6620d822 100644
--- a/third_party/WebKit/Source/core/workers/Worklet.cpp
+++ b/third_party/WebKit/Source/core/workers/Worklet.cpp
@@ -22,7 +22,8 @@
 // algorithm:
 // https://drafts.css-houdini.org/worklets/#dom-worklet-addmodule
 ScriptPromise Worklet::addModule(ScriptState* script_state,
-                                 const String& module_url) {
+                                 const String& module_url,
+                                 const WorkletOptions& options) {
   DCHECK(IsMainThread());
   if (!GetExecutionContext()) {
     return ScriptPromise::RejectWithDOMException(
@@ -54,9 +55,10 @@
   // |kUnspecedLoading| is used here because this is a part of script module
   // loading.
   TaskRunnerHelper::Get(TaskType::kUnspecedLoading, script_state)
-      ->PostTask(BLINK_FROM_HERE,
-                 WTF::Bind(&Worklet::FetchAndInvokeScript, WrapPersistent(this),
-                           module_url_record, WrapPersistent(resolver)));
+      ->PostTask(
+          BLINK_FROM_HERE,
+          WTF::Bind(&Worklet::FetchAndInvokeScript, WrapPersistent(this),
+                    module_url_record, options, WrapPersistent(resolver)));
   return promise;
 }
 
diff --git a/third_party/WebKit/Source/core/workers/Worklet.h b/third_party/WebKit/Source/core/workers/Worklet.h
index 9d9ba85..0ca938eb 100644
--- a/third_party/WebKit/Source/core/workers/Worklet.h
+++ b/third_party/WebKit/Source/core/workers/Worklet.h
@@ -8,6 +8,7 @@
 #include "bindings/core/v8/ScriptPromise.h"
 #include "core/CoreExport.h"
 #include "core/dom/ContextLifecycleObserver.h"
+#include "core/workers/WorkletOptions.h"
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/heap/Handle.h"
 
@@ -33,7 +34,9 @@
 
   // Worklet.idl
   // addModule() imports ES6 module scripts.
-  virtual ScriptPromise addModule(ScriptState*, const String& module_url);
+  virtual ScriptPromise addModule(ScriptState*,
+                                  const String& module_url,
+                                  const WorkletOptions&);
 
   // Returns a proxy to WorkletGlobalScope on the context thread.
   virtual WorkletGlobalScopeProxy* GetWorkletGlobalScopeProxy() const = 0;
@@ -46,6 +49,7 @@
 
  private:
   virtual void FetchAndInvokeScript(const KURL& module_url_record,
+                                    const WorkletOptions&,
                                     ScriptPromiseResolver*) = 0;
 };
 
diff --git a/third_party/WebKit/Source/core/workers/Worklet.idl b/third_party/WebKit/Source/core/workers/Worklet.idl
index 07613f55..1466299 100644
--- a/third_party/WebKit/Source/core/workers/Worklet.idl
+++ b/third_party/WebKit/Source/core/workers/Worklet.idl
@@ -8,5 +8,5 @@
     DependentLifetime,
     RuntimeEnabled=Worklet,
 ] interface Worklet {
-    [CallWith=ScriptState] Promise<void> addModule(DOMString url);
+    [CallWith=ScriptState] Promise<void> addModule(DOMString url, optional WorkletOptions options);
 };
diff --git a/third_party/WebKit/Source/core/workers/WorkletGlobalScopeProxy.h b/third_party/WebKit/Source/core/workers/WorkletGlobalScopeProxy.h
index 201cbbf..e651dda 100644
--- a/third_party/WebKit/Source/core/workers/WorkletGlobalScopeProxy.h
+++ b/third_party/WebKit/Source/core/workers/WorkletGlobalScopeProxy.h
@@ -7,6 +7,7 @@
 
 #include "core/CoreExport.h"
 #include "platform/weborigin/KURL.h"
+#include "public/platform/WebURLRequest.h"
 
 namespace blink {
 
@@ -23,6 +24,7 @@
   // Runs the "fetch and invoke a worklet script" algorithm:
   // https://drafts.css-houdini.org/worklets/#fetch-and-invoke-a-worklet-script
   virtual void FetchAndInvokeScript(const KURL& module_url_record,
+                                    WebURLRequest::FetchCredentialsMode,
                                     WorkletPendingTasks*) {}
 
   // Evaluates the given script source code. This should be called only for
diff --git a/third_party/WebKit/Source/core/workers/WorkletOptions.idl b/third_party/WebKit/Source/core/workers/WorkletOptions.idl
new file mode 100644
index 0000000..5fcff7e
--- /dev/null
+++ b/third_party/WebKit/Source/core/workers/WorkletOptions.idl
@@ -0,0 +1,14 @@
+// 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.
+
+// https://fetch.spec.whatwg.org/#requestcredentials
+// Copied from modules/fetch/Request.idl because it's not accessible from core/
+// directory.
+// TODO(nhiroki): Consider how to reuse the existing enum.
+enum RequestCredentials { "omit", "same-origin", "include" };
+
+// https://drafts.css-houdini.org/worklets/#dictdef-workletoptions
+dictionary WorkletOptions {
+    RequestCredentials credentials = "omit";
+};
diff --git a/third_party/WebKit/Source/modules/broadcastchannel/BroadcastChannel.cpp b/third_party/WebKit/Source/modules/broadcastchannel/BroadcastChannel.cpp
index b61efd7c..9d6eb3fa 100644
--- a/third_party/WebKit/Source/modules/broadcastchannel/BroadcastChannel.cpp
+++ b/third_party/WebKit/Source/modules/broadcastchannel/BroadcastChannel.cpp
@@ -129,7 +129,7 @@
   // Local BroadcastChannelClient for messages send from the browser to this
   // channel.
   mojom::blink::BroadcastChannelClientAssociatedPtrInfo local_client_info;
-  binding_.Bind(&local_client_info);
+  binding_.Bind(mojo::MakeRequest(&local_client_info));
   binding_.set_connection_error_handler(ConvertToBaseCallback(
       WTF::Bind(&BroadcastChannel::OnError, WrapWeakPersistent(this))));
 
diff --git a/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScopeProxy.cpp b/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScopeProxy.cpp
index 29b2858..6b6aab8d 100644
--- a/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScopeProxy.cpp
+++ b/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScopeProxy.cpp
@@ -28,9 +28,11 @@
 
 void PaintWorkletGlobalScopeProxy::FetchAndInvokeScript(
     const KURL& module_url_record,
+    WebURLRequest::FetchCredentialsMode credentials_mode,
     WorkletPendingTasks* pending_tasks) {
   DCHECK(IsMainThread());
-  global_scope_->FetchAndInvokeScript(module_url_record, pending_tasks);
+  global_scope_->FetchAndInvokeScript(module_url_record, credentials_mode,
+                                      pending_tasks);
 }
 
 void PaintWorkletGlobalScopeProxy::EvaluateScript(
diff --git a/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScopeProxy.h b/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScopeProxy.h
index 3aa08075..df1a68dc 100644
--- a/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScopeProxy.h
+++ b/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScopeProxy.h
@@ -26,6 +26,7 @@
 
   // Implements WorkletGlobalScopeProxy.
   void FetchAndInvokeScript(const KURL& module_url_record,
+                            WebURLRequest::FetchCredentialsMode,
                             WorkletPendingTasks*) override;
   void EvaluateScript(const ScriptSourceCode&) override;
   void TerminateWorkletGlobalScope() override;
diff --git a/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp b/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp
index 9759e63f..d6e15e4 100644
--- a/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp
+++ b/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp
@@ -40,6 +40,7 @@
 #include "platform/RuntimeEnabledFeatures.h"
 #include "platform/UUID.h"
 #include "platform/bindings/ScriptState.h"
+#include "platform/feature_policy/FeaturePolicy.h"
 #include "platform/mojo/MojoHelper.h"
 #include "platform/wtf/HashSet.h"
 #include "public/platform/InterfaceProvider.h"
@@ -599,7 +600,7 @@
   if (!frame)
     return false;
 
-  if (!RuntimeEnabledFeatures::featurePolicyEnabled()) {
+  if (!IsSupportedInFeaturePolicy(WebFeaturePolicyFeature::kPayment)) {
     // 2. If |document|'s browsing context is a top-level browsing context, then
     // return true.
     if (frame->IsMainFrame())
diff --git a/third_party/WebKit/Source/modules/vibration/NavigatorVibration.cpp b/third_party/WebKit/Source/modules/vibration/NavigatorVibration.cpp
index 0321257..2307f8e 100644
--- a/third_party/WebKit/Source/modules/vibration/NavigatorVibration.cpp
+++ b/third_party/WebKit/Source/modules/vibration/NavigatorVibration.cpp
@@ -31,6 +31,7 @@
 #include "modules/vibration/VibrationController.h"
 #include "platform/Histogram.h"
 #include "platform/UserGestureIndicator.h"
+#include "platform/feature_policy/FeaturePolicy.h"
 #include "public/platform/site_engagement.mojom-blink.h"
 
 namespace blink {
@@ -81,10 +82,7 @@
   if (!frame->GetPage()->IsPageVisible())
     return false;
 
-  // TODO(lunalu): When FeaturePolicy is ready, take out the check for the
-  // runtime flag. Please pay attention to the user gesture code below.
-  if (RuntimeEnabledFeatures::featurePolicyEnabled() &&
-      RuntimeEnabledFeatures::featurePolicyExperimentalFeaturesEnabled() &&
+  if (IsSupportedInFeaturePolicy(blink::WebFeaturePolicyFeature::kVibrate) &&
       !frame->IsFeatureEnabled(blink::WebFeaturePolicyFeature::kVibrate)) {
     frame->DomWindow()->PrintErrorMessage(
         "Navigator.vibrate() is not enabled in feature policy for this "
diff --git a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5 b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5
index 5660777..5632e3c 100644
--- a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5
+++ b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5
@@ -392,11 +392,10 @@
     },
     {
       name: "FeaturePolicy",
-      status: "experimental",
+      status: "stable",
     },
     {
       name: "FeaturePolicyExperimentalFeatures",
-      status: "experimental",
     },
     {
       name:"FetchRequestCache",
diff --git a/third_party/WebKit/Source/platform/feature_policy/FeaturePolicy.cpp b/third_party/WebKit/Source/platform/feature_policy/FeaturePolicy.cpp
index f89c965..74d15ee8 100644
--- a/third_party/WebKit/Source/platform/feature_policy/FeaturePolicy.cpp
+++ b/third_party/WebKit/Source/platform/feature_policy/FeaturePolicy.cpp
@@ -128,6 +128,22 @@
   return whitelists;
 }
 
+bool IsSupportedInFeaturePolicy(WebFeaturePolicyFeature feature) {
+  switch (feature) {
+    // TODO(lunalu): Re-enabled fullscreen in feature policy once tests have
+    // been updated.
+    // crbug.com/666761
+    case WebFeaturePolicyFeature::kFullscreen:
+      return false;
+    case WebFeaturePolicyFeature::kPayment:
+      return true;
+    case WebFeaturePolicyFeature::kVibrate:
+      return RuntimeEnabledFeatures::featurePolicyExperimentalFeaturesEnabled();
+    default:
+      return false;
+  }
+}
+
 const FeatureNameMap& GetDefaultFeatureNameMap() {
   DEFINE_STATIC_LOCAL(FeatureNameMap, default_feature_name_map, ());
   if (default_feature_name_map.IsEmpty()) {
diff --git a/third_party/WebKit/Source/platform/feature_policy/FeaturePolicy.h b/third_party/WebKit/Source/platform/feature_policy/FeaturePolicy.h
index c869c60..76bd124c 100644
--- a/third_party/WebKit/Source/platform/feature_policy/FeaturePolicy.h
+++ b/third_party/WebKit/Source/platform/feature_policy/FeaturePolicy.h
@@ -49,6 +49,10 @@
     bool allowpayment,
     RefPtr<SecurityOrigin>);
 
+// Verifies whether feature policy is enabled and |feature| is supported in
+// feature policy.
+PLATFORM_EXPORT bool IsSupportedInFeaturePolicy(WebFeaturePolicyFeature);
+
 }  // namespace blink
 
 #endif  // FeaturePolicy_h
diff --git a/third_party/WebKit/Source/platform/graphics/ImagePattern.cpp b/third_party/WebKit/Source/platform/graphics/ImagePattern.cpp
index 76098457..5aa00b6 100644
--- a/third_party/WebKit/Source/platform/graphics/ImagePattern.cpp
+++ b/third_party/WebKit/Source/platform/graphics/ImagePattern.cpp
@@ -8,6 +8,7 @@
 #include "platform/graphics/paint/PaintShader.h"
 #include "platform/graphics/skia/SkiaUtils.h"
 #include "third_party/skia/include/core/SkImage.h"
+#include "third_party/skia/include/core/SkPictureRecorder.h"
 #include "third_party/skia/include/core/SkSurface.h"
 
 namespace blink {
@@ -60,24 +61,28 @@
 
   // Create a transparent image 2 pixels wider and/or taller than the
   // original, then copy the orignal into the middle of it.
-  // FIXME: Is there a better way to pad (not scale) an image in skia?
-  sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(
-      tile_image_->width() + 2 * border_pixel_x,
-      tile_image_->height() + 2 * border_pixel_y);
-  if (!surface)
-    return WrapSkShader(SkShader::MakeColorShader(SK_ColorTRANSPARENT));
+  const SkISize tile_size =
+      SkISize::Make(tile_image_->width() + 2 * border_pixel_x,
+                    tile_image_->height() + 2 * border_pixel_y);
+  SkPictureRecorder recorder;
+  recorder.beginRecording(tile_size.width(), tile_size.height());
 
   SkPaint paint;
   paint.setBlendMode(SkBlendMode::kSrc);
-  surface->getCanvas()->drawImage(tile_image_, border_pixel_x, border_pixel_y,
-                                  &paint);
+  recorder.getRecordingCanvas()->drawImage(tile_image_, border_pixel_x,
+                                           border_pixel_y, &paint);
+  // Note: we use a picture *image* (as opposed to a picture *shader*) to
+  // lock-in the resolution (for 1px padding in particular).
+  sk_sp<SkImage> tile_image = SkImage::MakeFromPicture(
+      recorder.finishRecordingAsPicture(), tile_size, nullptr, nullptr,
+      SkImage::BitDepth::kU8, SkColorSpace::MakeSRGB());
 
   previous_local_matrix_ = local_matrix;
   SkMatrix adjusted_matrix(local_matrix);
   adjusted_matrix.postTranslate(-border_pixel_x, -border_pixel_y);
 
-  return MakePaintShaderImage(surface->makeImageSnapshot(), tile_mode_x,
-                              tile_mode_y, &adjusted_matrix);
+  return MakePaintShaderImage(std::move(tile_image), tile_mode_x, tile_mode_y,
+                              &adjusted_matrix);
 }
 
 bool ImagePattern::IsTextureBacked() const {
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp b/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp
index 4728fb0c..7ca17e5 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp
+++ b/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp
@@ -23,10 +23,18 @@
 void PaintController::SetTracksRasterInvalidations(bool value) {
   if (value ||
       RuntimeEnabledFeatures::paintUnderInvalidationCheckingEnabled()) {
-    raster_invalidation_tracking_map_ =
-        WTF::WrapUnique(new RasterInvalidationTrackingMap<const PaintChunk>);
+    raster_invalidation_tracking_info_ =
+        WTF::MakeUnique<RasterInvalidationTrackingInfo>();
+
+    // This is called just after a full document cycle update, so all clients in
+    // current_paint_artifact_ should be still alive.
+    DCHECK(new_display_item_list_.IsEmpty());
+    for (const auto& item : current_paint_artifact_.GetDisplayItemList()) {
+      raster_invalidation_tracking_info_->old_client_debug_names.Set(
+          &item.Client(), item.Client().DebugName());
+    }
   } else {
-    raster_invalidation_tracking_map_ = nullptr;
+    raster_invalidation_tracking_info_ = nullptr;
   }
 }
 
@@ -248,6 +256,11 @@
   if (IsSkippingCache())
     display_item.SetSkippedCache();
 
+  if (raster_invalidation_tracking_info_) {
+    raster_invalidation_tracking_info_->new_client_debug_names.insert(
+        &display_item.Client(), display_item.Client().DebugName());
+  }
+
   if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
     size_t last_chunk_index = new_paint_chunks_.LastChunkIndex();
     if (new_paint_chunks_.IncrementDisplayItemIndex(display_item)) {
@@ -600,9 +613,9 @@
   // The new list will not be appended to again so we can release unused memory.
   new_display_item_list_.ShrinkToFit();
 
-  if (raster_invalidation_tracking_map_) {
+  if (raster_invalidation_tracking_info_) {
     for (const auto& chunk : current_paint_artifact_.PaintChunks())
-      raster_invalidation_tracking_map_->Remove(&chunk);
+      raster_invalidation_tracking_info_->map.Remove(&chunk);
   }
   current_paint_artifact_ = PaintArtifact(
       std::move(new_display_item_list_), new_paint_chunks_.ReleasePaintChunks(),
@@ -632,6 +645,12 @@
   num_out_of_order_matches_ = 0;
   num_indexed_items_ = 0;
 #endif
+
+  if (raster_invalidation_tracking_info_) {
+    raster_invalidation_tracking_info_->old_client_debug_names.clear();
+    std::swap(raster_invalidation_tracking_info_->old_client_debug_names,
+              raster_invalidation_tracking_info_->new_client_debug_names);
+  }
 }
 
 size_t PaintController::ApproximateUnsharedMemoryUsage() const {
@@ -683,7 +702,10 @@
 
   static FloatRect infinite_float_rect(LayoutRect::InfiniteIntRect());
   if (!new_chunk.id) {
-    AddRasterInvalidation(nullptr, new_chunk, infinite_float_rect);
+    // This chunk is not cacheable, so always invalidate the whole chunk.
+    AddRasterInvalidation(
+        new_display_item_list_[new_chunk.begin_index].Client(), new_chunk,
+        infinite_float_rect);
     return;
   }
 
@@ -723,30 +745,41 @@
   }
 
   // We reach here because the chunk is new.
-  AddRasterInvalidation(nullptr, new_chunk, infinite_float_rect);
+  AddRasterInvalidation(new_display_item_list_[new_chunk.begin_index].Client(),
+                        new_chunk, infinite_float_rect);
 }
 
-void PaintController::AddRasterInvalidation(const DisplayItemClient* client,
+void PaintController::AddRasterInvalidation(const DisplayItemClient& client,
                                             PaintChunk& chunk,
                                             const FloatRect& rect) {
   chunk.raster_invalidation_rects.push_back(rect);
-  if (raster_invalidation_tracking_map_)
+  if (raster_invalidation_tracking_info_)
     TrackRasterInvalidation(client, chunk, rect);
 }
 
-void PaintController::TrackRasterInvalidation(const DisplayItemClient* client,
+void PaintController::TrackRasterInvalidation(const DisplayItemClient& client,
                                               PaintChunk& chunk,
                                               const FloatRect& rect) {
-  DCHECK(raster_invalidation_tracking_map_);
+  DCHECK(raster_invalidation_tracking_info_);
 
   RasterInvalidationInfo info;
   info.rect = EnclosingIntRect(rect);
-  info.client = client;
-  if (client) {
-    info.client_debug_name = client->DebugName();
-    info.reason = client->GetPaintInvalidationReason();
+  info.client = &client;
+  auto it =
+      raster_invalidation_tracking_info_->new_client_debug_names.find(&client);
+  if (it == raster_invalidation_tracking_info_->new_client_debug_names.end()) {
+    it = raster_invalidation_tracking_info_->old_client_debug_names.find(
+        &client);
+    // The client should be either in new list or in old list.
+    DCHECK(it !=
+           raster_invalidation_tracking_info_->old_client_debug_names.end());
+    info.reason = kPaintInvalidationLayoutObjectRemoval;
+  } else {
+    info.reason = client.GetPaintInvalidationReason();
   }
-  raster_invalidation_tracking_map_->Add(&chunk).invalidations.push_back(info);
+  info.client_debug_name = it->value;
+  raster_invalidation_tracking_info_->map.Add(&chunk).invalidations.push_back(
+      info);
 }
 
 void PaintController::GenerateRasterInvalidationsComparingChunks(
@@ -764,7 +797,7 @@
     const DisplayItem& old_item =
         current_paint_artifact_.GetDisplayItemList()[old_index];
     const DisplayItemClient* client_to_invalidate = nullptr;
-    bool is_potentially_invalid_client = false;
+
     if (!old_item.HasValidClient()) {
       size_t moved_to_index = items_moved_into_new_list_[old_index];
       if (new_display_item_list_[moved_to_index].DrawsContent()) {
@@ -777,7 +810,7 @@
           // And invalidate in the new chunk into which the item was moved.
           PaintChunk& moved_to_chunk =
               new_paint_chunks_.FindChunkByDisplayItemIndex(moved_to_index);
-          AddRasterInvalidation(client_to_invalidate, moved_to_chunk,
+          AddRasterInvalidation(*client_to_invalidate, moved_to_chunk,
                                 FloatRect(client_to_invalidate->VisualRect()));
         } else if (moved_to_index < highest_moved_to_index) {
           // The item has been moved behind other cached items, so need to
@@ -790,15 +823,13 @@
         }
       }
     } else if (old_item.DrawsContent()) {
-      is_potentially_invalid_client = true;
       client_to_invalidate = &old_item.Client();
     }
     if (client_to_invalidate &&
         invalidated_clients_in_old_chunk.insert(client_to_invalidate)
             .is_new_entry) {
       AddRasterInvalidation(
-          is_potentially_invalid_client ? nullptr : client_to_invalidate,
-          new_chunk,
+          *client_to_invalidate, new_chunk,
           FloatRect(current_paint_artifact_.GetDisplayItemList().VisualRect(
               old_index)));
     }
@@ -811,7 +842,7 @@
     if (new_item.DrawsContent() && !ClientCacheIsValid(new_item.Client()) &&
         invalidated_clients_in_new_chunk.insert(&new_item.Client())
             .is_new_entry) {
-      AddRasterInvalidation(&new_item.Client(), new_chunk,
+      AddRasterInvalidation(new_item.Client(), new_chunk,
                             FloatRect(new_item.Client().VisualRect()));
     }
   }
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintController.h b/third_party/WebKit/Source/platform/graphics/paint/PaintController.h
index 62d51c0..5bf180d 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/PaintController.h
+++ b/third_party/WebKit/Source/platform/graphics/paint/PaintController.h
@@ -195,7 +195,9 @@
   void SetTracksRasterInvalidations(bool value);
   RasterInvalidationTrackingMap<const PaintChunk>*
   PaintChunksRasterInvalidationTrackingMap() {
-    return raster_invalidation_tracking_map_.get();
+    return raster_invalidation_tracking_info_
+               ? &raster_invalidation_tracking_info_->map
+               : nullptr;
   }
 
 #if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS
@@ -283,10 +285,10 @@
   void GenerateRasterInvalidations(PaintChunk& new_chunk);
   void GenerateRasterInvalidationsComparingChunks(PaintChunk& new_chunk,
                                                   const PaintChunk& old_chunk);
-  inline void AddRasterInvalidation(const DisplayItemClient*,
+  inline void AddRasterInvalidation(const DisplayItemClient&,
                                     PaintChunk&,
                                     const FloatRect&);
-  void TrackRasterInvalidation(const DisplayItemClient*,
+  void TrackRasterInvalidation(const DisplayItemClient&,
                                PaintChunk&,
                                const FloatRect&);
 
@@ -412,8 +414,14 @@
   int skipped_probable_under_invalidation_count_;
   String under_invalidation_message_prefix_;
 
-  std::unique_ptr<RasterInvalidationTrackingMap<const PaintChunk>>
-      raster_invalidation_tracking_map_;
+  struct RasterInvalidationTrackingInfo {
+    RasterInvalidationTrackingMap<const PaintChunk> map;
+    using ClientDebugNamesMap = HashMap<const DisplayItemClient*, String>;
+    ClientDebugNamesMap new_client_debug_names;
+    ClientDebugNamesMap old_client_debug_names;
+  };
+  std::unique_ptr<RasterInvalidationTrackingInfo>
+      raster_invalidation_tracking_info_;
 
 #if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS
   // A stack recording subsequence clients that are currently painting.
diff --git a/third_party/WebKit/Source/web/TextFinder.cpp b/third_party/WebKit/Source/web/TextFinder.cpp
index b98bfc3..c8b976e 100644
--- a/third_party/WebKit/Source/web/TextFinder.cpp
+++ b/third_party/WebKit/Source/web/TextFinder.cpp
@@ -41,6 +41,7 @@
 #include "core/editing/markers/DocumentMarkerController.h"
 #include "core/exported/WebViewBase.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/WebLocalFrameBase.h"
 #include "core/layout/LayoutObject.h"
 #include "core/layout/TextAutosizer.h"
 #include "core/page/Page.h"
@@ -54,7 +55,6 @@
 #include "public/web/WebFindOptions.h"
 #include "public/web/WebFrameClient.h"
 #include "public/web/WebViewClient.h"
-#include "web/WebLocalFrameImpl.h"
 
 namespace blink {
 
@@ -563,7 +563,7 @@
   if (!find_match_rects_are_valid_)
     for (WebFrame* child = OwnerFrame().FirstChild(); child;
          child = child->NextSibling())
-      ToWebLocalFrameImpl(child)
+      ToWebLocalFrameBase(child)
           ->EnsureTextFinder()
           .find_match_rects_are_valid_ = false;
 
@@ -677,11 +677,11 @@
   return active_match_index_ + 1;
 }
 
-TextFinder* TextFinder::Create(WebLocalFrameImpl& owner_frame) {
+TextFinder* TextFinder::Create(WebLocalFrameBase& owner_frame) {
   return new TextFinder(owner_frame);
 }
 
-TextFinder::TextFinder(WebLocalFrameImpl& owner_frame)
+TextFinder::TextFinder(WebLocalFrameBase& owner_frame)
     : owner_frame_(&owner_frame),
       current_active_match_frame_(false),
       active_match_index_(-1),
diff --git a/third_party/WebKit/Source/web/TextFinder.h b/third_party/WebKit/Source/web/TextFinder.h
index 7a97bba0..aa6a334a 100644
--- a/third_party/WebKit/Source/web/TextFinder.h
+++ b/third_party/WebKit/Source/web/TextFinder.h
@@ -47,7 +47,7 @@
 namespace blink {
 
 class Range;
-class WebLocalFrameImpl;
+class WebLocalFrameBase;
 
 template <typename T>
 class WebVector;
@@ -57,7 +57,7 @@
   WTF_MAKE_NONCOPYABLE(TextFinder);
 
  public:
-  static TextFinder* Create(WebLocalFrameImpl& owner_frame);
+  static TextFinder* Create(WebLocalFrameBase& owner_frame);
 
   bool Find(int identifier,
             const WebString& search_text,
@@ -132,7 +132,7 @@
   class DeferredScopeStringMatches;
   friend class DeferredScopeStringMatches;
 
-  explicit TextFinder(WebLocalFrameImpl& owner_frame);
+  explicit TextFinder(WebLocalFrameBase& owner_frame);
 
   // Notifies the delegate about a new selection rect.
   void ReportFindInPageSelection(const WebRect& selection_rect,
@@ -205,12 +205,12 @@
   // Determines whether to invalidate the content area and scrollbar.
   void InvalidateIfNecessary();
 
-  WebLocalFrameImpl& OwnerFrame() const {
+  WebLocalFrameBase& OwnerFrame() const {
     DCHECK(owner_frame_);
     return *owner_frame_;
   }
 
-  Member<WebLocalFrameImpl> owner_frame_;
+  Member<WebLocalFrameBase> owner_frame_;
 
   // Indicates whether this frame currently has the active match.
   bool current_active_match_frame_;
diff --git a/third_party/WebKit/Source/web/WebEmbeddedWorkerImpl.cpp b/third_party/WebKit/Source/web/WebEmbeddedWorkerImpl.cpp
index f7578221..ade183d 100644
--- a/third_party/WebKit/Source/web/WebEmbeddedWorkerImpl.cpp
+++ b/third_party/WebKit/Source/web/WebEmbeddedWorkerImpl.cpp
@@ -36,6 +36,7 @@
 #include "core/dom/SecurityContext.h"
 #include "core/dom/TaskRunnerHelper.h"
 #include "core/exported/WebDataSourceImpl.h"
+#include "core/frame/WebLocalFrameBase.h"
 #include "core/frame/csp/ContentSecurityPolicy.h"
 #include "core/inspector/ConsoleMessage.h"
 #include "core/loader/FrameLoadRequest.h"
@@ -77,7 +78,6 @@
 #include "web/IndexedDBClientImpl.h"
 #include "web/ServiceWorkerGlobalScopeClientImpl.h"
 #include "web/ServiceWorkerGlobalScopeProxy.h"
-#include "web/WebLocalFrameImpl.h"
 
 namespace blink {
 
@@ -293,7 +293,7 @@
   settings->SetStrictMixedContentChecking(true);
   settings->SetAllowRunningOfInsecureContent(false);
   settings->SetDataSaverEnabled(worker_start_data_.data_saver_enabled);
-  main_frame_ = ToWebLocalFrameImpl(WebLocalFrame::Create(
+  main_frame_ = ToWebLocalFrameBase(WebLocalFrame::Create(
       WebTreeScopeType::kDocument, this, nullptr, nullptr));
   web_view_->SetMainFrame(main_frame_.Get());
   main_frame_->SetDevToolsAgentClient(this);
diff --git a/third_party/WebKit/Source/web/WebEmbeddedWorkerImpl.h b/third_party/WebKit/Source/web/WebEmbeddedWorkerImpl.h
index 7f0f72c4..d4babcb5 100644
--- a/third_party/WebKit/Source/web/WebEmbeddedWorkerImpl.h
+++ b/third_party/WebKit/Source/web/WebEmbeddedWorkerImpl.h
@@ -45,7 +45,7 @@
 
 class ThreadableLoadingContext;
 class ServiceWorkerGlobalScopeProxy;
-class WebLocalFrameImpl;
+class WebLocalFrameBase;
 class WebView;
 class WorkerInspectorProxy;
 class WorkerScriptLoader;
@@ -123,7 +123,7 @@
   // are guaranteed to exist while this object is around.
   WebView* web_view_;
 
-  Persistent<WebLocalFrameImpl> main_frame_;
+  Persistent<WebLocalFrameBase> main_frame_;
   Persistent<ThreadableLoadingContext> loading_context_;
 
   bool loading_shadow_page_;
diff --git a/third_party/WebKit/Source/web/WebFrameSerializer.cpp b/third_party/WebKit/Source/web/WebFrameSerializer.cpp
index 706ed04..5ae9b75 100644
--- a/third_party/WebKit/Source/web/WebFrameSerializer.cpp
+++ b/third_party/WebKit/Source/web/WebFrameSerializer.cpp
@@ -38,6 +38,7 @@
 #include "core/frame/FrameSerializer.h"
 #include "core/frame/LocalFrame.h"
 #include "core/frame/RemoteFrame.h"
+#include "core/frame/WebLocalFrameBase.h"
 #include "core/html/HTMLAllCollection.h"
 #include "core/html/HTMLFrameElementBase.h"
 #include "core/html/HTMLFrameOwnerElement.h"
@@ -72,7 +73,6 @@
 #include "public/web/WebFrameSerializerCacheControlPolicy.h"
 #include "public/web/WebFrameSerializerClient.h"
 #include "web/WebFrameSerializerImpl.h"
-#include "web/WebLocalFrameImpl.h"
 #include "web/WebRemoteFrameImpl.h"
 
 namespace blink {
@@ -330,22 +330,22 @@
 }
 
 bool CacheControlNoStoreHeaderPresent(
-    const WebLocalFrameImpl& web_local_frame_impl) {
+    const WebLocalFrameBase& web_local_frame) {
   const ResourceResponse& response =
-      web_local_frame_impl.DataSource()->GetResponse().ToResourceResponse();
+      web_local_frame.DataSource()->GetResponse().ToResourceResponse();
   if (response.CacheControlContainsNoStore())
     return true;
 
   const ResourceRequest& request =
-      web_local_frame_impl.DataSource()->GetRequest().ToResourceRequest();
+      web_local_frame.DataSource()->GetRequest().ToResourceRequest();
   return request.CacheControlContainsNoStore();
 }
 
 bool FrameShouldBeSerializedAsMHTML(
     WebLocalFrame* frame,
     WebFrameSerializerCacheControlPolicy cache_control_policy) {
-  WebLocalFrameImpl* web_local_frame_impl = ToWebLocalFrameImpl(frame);
-  DCHECK(web_local_frame_impl);
+  WebLocalFrameBase* web_local_frame = ToWebLocalFrameBase(frame);
+  DCHECK(web_local_frame);
 
   if (cache_control_policy == WebFrameSerializerCacheControlPolicy::kNone)
     return true;
@@ -360,7 +360,7 @@
   if (!need_to_check_no_store)
     return true;
 
-  return !CacheControlNoStoreHeaderPresent(*web_local_frame_impl);
+  return !CacheControlNoStoreHeaderPresent(*web_local_frame);
 }
 
 }  // namespace
@@ -376,10 +376,10 @@
   if (!FrameShouldBeSerializedAsMHTML(frame, delegate->CacheControlPolicy()))
     return WebThreadSafeData();
 
-  WebLocalFrameImpl* web_local_frame_impl = ToWebLocalFrameImpl(frame);
-  DCHECK(web_local_frame_impl);
+  WebLocalFrameBase* web_local_frame = ToWebLocalFrameBase(frame);
+  DCHECK(web_local_frame);
 
-  Document* document = web_local_frame_impl->GetFrame()->GetDocument();
+  Document* document = web_local_frame->GetFrame()->GetDocument();
 
   RefPtr<RawData> buffer = RawData::Create();
   MHTMLArchive::GenerateMHTMLHeader(boundary, document->title(),
@@ -401,7 +401,7 @@
     return WebThreadSafeData();
 
   // Translate arguments from public to internal blink APIs.
-  LocalFrame* frame = ToWebLocalFrameImpl(web_frame)->GetFrame();
+  LocalFrame* frame = ToWebLocalFrameBase(web_frame)->GetFrame();
   MHTMLArchive::EncodingPolicy encoding_policy =
       web_delegate->UseBinaryEncoding()
           ? MHTMLArchive::EncodingPolicy::kUseBinaryEncoding
diff --git a/third_party/WebKit/Source/web/WebFrameSerializerImpl.cpp b/third_party/WebKit/Source/web/WebFrameSerializerImpl.cpp
index 7d75fb3..92a47a79 100644
--- a/third_party/WebKit/Source/web/WebFrameSerializerImpl.cpp
+++ b/third_party/WebKit/Source/web/WebFrameSerializerImpl.cpp
@@ -83,6 +83,7 @@
 #include "core/dom/Element.h"
 #include "core/editing/serializers/Serialization.h"
 #include "core/frame/FrameSerializer.h"
+#include "core/frame/WebLocalFrameBase.h"
 #include "core/html/HTMLAllCollection.h"
 #include "core/html/HTMLElement.h"
 #include "core/html/HTMLFormElement.h"
@@ -95,7 +96,6 @@
 #include "platform/wtf/text/TextEncoding.h"
 #include "public/platform/WebCString.h"
 #include "public/platform/WebVector.h"
-#include "web/WebLocalFrameImpl.h"
 
 namespace blink {
 
@@ -445,7 +445,7 @@
       xml_entities_(true) {
   // Must specify available webframe.
   DCHECK(frame);
-  specified_web_local_frame_impl_ = ToWebLocalFrameImpl(frame);
+  specified_web_local_frame_impl_ = ToWebLocalFrameBase(frame);
   // Make sure we have non null client and delegate.
   DCHECK(client);
   DCHECK(delegate);
diff --git a/third_party/WebKit/Source/web/WebFrameSerializerImpl.h b/third_party/WebKit/Source/web/WebFrameSerializerImpl.h
index 74ee256..fce0968 100644
--- a/third_party/WebKit/Source/web/WebFrameSerializerImpl.h
+++ b/third_party/WebKit/Source/web/WebFrameSerializerImpl.h
@@ -53,7 +53,7 @@
 class Element;
 class Node;
 class WebLocalFrame;
-class WebLocalFrameImpl;
+class WebLocalFrameBase;
 
 // Responsible for serializing the specified frame into html
 // (replacing links with paths to local files).
@@ -81,7 +81,7 @@
 
  private:
   // Specified frame which need to be serialized;
-  Member<WebLocalFrameImpl> specified_web_local_frame_impl_;
+  Member<WebLocalFrameBase> specified_web_local_frame_impl_;
   // Pointer of WebFrameSerializerClient
   WebFrameSerializerClient* client_;
   // Pointer of WebFrameSerializer::LinkRewritingDelegate
diff --git a/third_party/WebKit/Source/web/WebLocalFrameImpl.h b/third_party/WebKit/Source/web/WebLocalFrameImpl.h
index d0afe6d..9e94c5cc8 100644
--- a/third_party/WebKit/Source/web/WebLocalFrameImpl.h
+++ b/third_party/WebKit/Source/web/WebLocalFrameImpl.h
@@ -367,7 +367,7 @@
     return GetFrame() ? GetFrame()->View() : 0;
   }
 
-  WebDevToolsAgentImpl* DevToolsAgentImpl() const {
+  WebDevToolsAgentImpl* DevToolsAgentImpl() const override {
     return dev_tools_agent_.Get();
   }
 
@@ -393,7 +393,7 @@
   void SetCanHaveScrollbars(bool) override;
 
   WebFrameClient* Client() const override { return client_; }
-  void SetClient(WebFrameClient* client) { client_ = client; }
+  void SetClient(WebFrameClient* client) override { client_ = client; }
 
   ContentSettingsClient& GetContentSettingsClient() {
     return content_settings_client_;
@@ -415,12 +415,12 @@
   TextFinder* GetTextFinder() const;
   // Returns the text finder object if it already exists.
   // Otherwise creates it and then returns.
-  TextFinder& EnsureTextFinder();
+  TextFinder& EnsureTextFinder() override;
 
   // Returns a hit-tested VisiblePosition for the given point
   VisiblePosition VisiblePositionForViewportPoint(const WebPoint&);
 
-  void SetFrameWidget(WebFrameWidgetBase*);
+  void SetFrameWidget(WebFrameWidgetBase*) override;
 
   // DevTools front-end bindings.
   void SetDevToolsFrontend(WebDevToolsFrontendImpl* frontend) {
diff --git a/third_party/WebKit/Source/web/WebScopedUserGesture.cpp b/third_party/WebKit/Source/web/WebScopedUserGesture.cpp
index 62e4e23..a9f47f2 100644
--- a/third_party/WebKit/Source/web/WebScopedUserGesture.cpp
+++ b/third_party/WebKit/Source/web/WebScopedUserGesture.cpp
@@ -31,9 +31,9 @@
 #include "public/web/WebScopedUserGesture.h"
 
 #include "core/dom/DocumentUserGestureToken.h"
+#include "core/frame/WebLocalFrameBase.h"
 #include "platform/UserGestureIndicator.h"
 #include "public/web/WebUserGestureToken.h"
-#include "web/WebLocalFrameImpl.h"
 
 namespace blink {
 
@@ -44,7 +44,7 @@
 
 WebScopedUserGesture::WebScopedUserGesture(WebLocalFrame* frame) {
   indicator_.reset(new UserGestureIndicator(DocumentUserGestureToken::Create(
-      frame ? ToWebLocalFrameImpl(frame)->GetFrame()->GetDocument() : nullptr,
+      frame ? ToWebLocalFrameBase(frame)->GetFrame()->GetDocument() : nullptr,
       UserGestureToken::kNewGesture)));
 }
 
diff --git a/third_party/WebKit/Source/web/WebSharedWorkerImpl.cpp b/third_party/WebKit/Source/web/WebSharedWorkerImpl.cpp
index 7cecaa0..b6358692 100644
--- a/third_party/WebKit/Source/web/WebSharedWorkerImpl.cpp
+++ b/third_party/WebKit/Source/web/WebSharedWorkerImpl.cpp
@@ -35,6 +35,7 @@
 #include "core/dom/TaskRunnerHelper.h"
 #include "core/events/MessageEvent.h"
 #include "core/exported/WebDataSourceImpl.h"
+#include "core/frame/WebLocalFrameBase.h"
 #include "core/inspector/ConsoleMessage.h"
 #include "core/loader/FrameLoadRequest.h"
 #include "core/loader/FrameLoader.h"
@@ -75,7 +76,6 @@
 #include "public/web/WebWorkerContentSettingsClientProxy.h"
 #include "web/IndexedDBClientImpl.h"
 #include "web/LocalFileSystemClient.h"
-#include "web/WebLocalFrameImpl.h"
 
 namespace blink {
 
@@ -137,7 +137,7 @@
   // FIXME: Settings information should be passed to the Worker process from
   // Browser process when the worker is created (similar to
   // RenderThread::OnCreateNewView).
-  main_frame_ = ToWebLocalFrameImpl(WebLocalFrame::Create(
+  main_frame_ = ToWebLocalFrameBase(WebLocalFrame::Create(
       WebTreeScopeType::kDocument, this,
       Platform::Current()->GetInterfaceProvider(), nullptr));
   web_view_->SetMainFrame(main_frame_.Get());
@@ -334,7 +334,7 @@
   if (RuntimeEnabledFeatures::offMainThreadFetchEnabled()) {
     std::unique_ptr<WebWorkerFetchContext> web_worker_fetch_context =
         client_->CreateWorkerFetchContext(
-            WebLocalFrameImpl::FromFrame(main_frame_->GetFrame())
+            WebLocalFrameBase::FromFrame(main_frame_->GetFrame())
                 ->DataSource()
                 ->GetServiceWorkerNetworkProvider());
     DCHECK(web_worker_fetch_context);
diff --git a/third_party/WebKit/Source/web/WebSharedWorkerImpl.h b/third_party/WebKit/Source/web/WebSharedWorkerImpl.h
index 9c90960..a230abe 100644
--- a/third_party/WebKit/Source/web/WebSharedWorkerImpl.h
+++ b/third_party/WebKit/Source/web/WebSharedWorkerImpl.h
@@ -49,7 +49,7 @@
 
 class WebApplicationCacheHost;
 class WebApplicationCacheHostClient;
-class WebLocalFrameImpl;
+class WebLocalFrameBase;
 class WebServiceWorkerNetworkProvider;
 class WebSharedWorkerClient;
 class WebString;
@@ -134,7 +134,7 @@
   Persistent<ExecutionContext> loading_document_;
   Persistent<ThreadableLoadingContext> loading_context_;
   WebView* web_view_;
-  Persistent<WebLocalFrameImpl> main_frame_;
+  Persistent<WebLocalFrameBase> main_frame_;
   bool asked_to_terminate_;
 
   std::unique_ptr<WebServiceWorkerNetworkProvider> network_provider_;
diff --git a/third_party/freetype/BUILD.gn b/third_party/freetype/BUILD.gn
index d230faa..facf28f 100644
--- a/third_party/freetype/BUILD.gn
+++ b/third_party/freetype/BUILD.gn
@@ -3,7 +3,6 @@
 # found in the LICENSE file.
 
 import("//build/config/chromecast_build.gni")
-import("//third_party/harfbuzz-ng/harfbuzz.gni")
 
 config("freetype_config") {
   include_dirs = [
@@ -29,58 +28,6 @@
   }
 }
 
-# This component is used to resolve a cyclic dependency between HarfBuzz and
-# FreeType. HarfBuzz needs basic FreeType glyph information symbols for its
-# hb-ft.* functions, FreeType needs HarfBuzz' OpenType parsing functionality in
-# the autohinting code. We start by building a minimum FreeType here - enough to
-# satisfy harfbuzz-ng-ft symbol requirements. Then we can build harfbuzz-ng-ft
-# based on the minimal FreeType and harfbuzz-ng which does not depend on
-# FreeType itself. Then we build FreeType depending on harfbuzz-ng-ft and
-# harfbuzz-ng.
-static_library("bootstrap_freetype_for_harfbuzz") {
-  visibility = [
-    "//third_party/harfbuzz-ng:harfbuzz-ng-ft",
-    ":freetype",
-  ]
-
-  defines = []
-
-  sources = [
-    "include/freetype-custom-config/ftmodule.h",
-    "include/freetype-custom-config/ftoption.h",
-    "src/src/base/ftbase.c",
-    "src/src/base/ftbitmap.c",
-    "src/src/base/ftsystem.c",
-  ]
-
-  if (is_mac && !is_component_build) {
-    defines += [ "MAC_RESTRICT_VISIBILITY" ]
-  }
-
-  defines += [
-    "FT2_BUILD_LIBRARY",
-    "DARWIN_NO_CARBON",
-
-    # Long directory name to avoid accidentally using wrong headers.
-    # GN currently does not escape '<' and '>' when generating xml based Visual
-    # Studio project files. As a result, use quotes instead of pointy brackets
-    # in these defines.
-    "FT_CONFIG_MODULES_H=\"freetype-custom-config/ftmodule.h\"",
-    "FT_CONFIG_OPTIONS_H=\"freetype-custom-config/ftoption.h\"",
-  ]
-
-  if (is_win && is_component_build) {
-    # Used for managing declspec(dllimport/export) visibility.
-    defines += [ "FT2_BUILD_DLL" ]
-  }
-
-  public_configs = [ ":freetype_config" ]
-  configs -= [ "//build/config/compiler:chromium_code" ]
-  configs += [ "//build/config/compiler:no_chromium_code" ]
-
-  configs += [ ":freetype-warnings" ]
-}
-
 component("freetype") {
   if (is_linux) {
     output_name = "freetype"
@@ -93,7 +40,9 @@
     "include/freetype-custom-config/ftmodule.h",
     "include/freetype-custom-config/ftoption.h",
     "src/src/autofit/autofit.c",
+    "src/src/base/ftbase.c",
     "src/src/base/ftbbox.c",
+    "src/src/base/ftbitmap.c",
     "src/src/base/ftfntfmt.c",
     "src/src/base/ftfstype.c",
     "src/src/base/ftgasp.c",
@@ -102,6 +51,7 @@
     "src/src/base/ftlcdfil.c",
     "src/src/base/ftmm.c",
     "src/src/base/ftstroke.c",
+    "src/src/base/ftsystem.c",
     "src/src/base/fttype1.c",
     "src/src/cff/cff.c",
     "src/src/gzip/ftgzip.c",
@@ -153,10 +103,6 @@
     "FT_CONFIG_OPTIONS_H=\"freetype-custom-config/ftoption.h\"",
   ]
 
-  if (!use_system_harfbuzz) {
-    defines += [ "HAVE_HARFBUZZ_FT" ]
-  }
-
   if (is_win && is_component_build) {
     # Used for managing declspec(dllimport/export) visibility.
     defines += [ "FT2_BUILD_DLL" ]
@@ -172,15 +118,4 @@
     "//third_party/libpng",
     "//third_party/zlib",
   ]
-
-  public_deps = [
-    ":bootstrap_freetype_for_harfbuzz",
-  ]
-
-  if (!use_system_harfbuzz) {
-    deps += [
-      "//third_party/harfbuzz-ng:harfbuzz-ng",
-      "//third_party/harfbuzz-ng:harfbuzz-ng-ft",
-    ]
-  }
 }
diff --git a/third_party/freetype/include/freetype-custom-config/ftoption.h b/third_party/freetype/include/freetype-custom-config/ftoption.h
index 84b8970..afa3c60 100644
--- a/third_party/freetype/include/freetype-custom-config/ftoption.h
+++ b/third_party/freetype/include/freetype-custom-config/ftoption.h
@@ -268,9 +268,7 @@
   /*                                                                       */
   /*   Define this macro if you want to enable this `feature'.             */
   /*                                                                       */
-#if defined(HAVE_HARFBUZZ_FT)
-#define FT_CONFIG_OPTION_USE_HARFBUZZ
-#endif
+/* #define FT_CONFIG_OPTION_USE_HARFBUZZ */
 
 
   /*************************************************************************/
diff --git a/third_party/googletest/BUILD.gn b/third_party/googletest/BUILD.gn
index d0a01adb..2ace19b 100644
--- a/third_party/googletest/BUILD.gn
+++ b/third_party/googletest/BUILD.gn
@@ -6,6 +6,11 @@
   visibility = [ ":*" ]  # gmock also shares this config.
 
   defines = [
+    # Chromium always links googletest statically, so no API qualifier is
+    # necessary. The definition in gtest-port.h at the time of this writing
+    # causes crashes in content_browsertests.
+    "GTEST_API_=",
+
     # In order to allow regex matches in gtest to be shared between Windows
     # and other systems, we tell gtest to always use its internal engine.
     "GTEST_HAS_POSIX_RE=0",
@@ -23,7 +28,7 @@
 config("gmock_config") {
   # Gmock headers need to be able to find themselves.
   include_dirs = [
-    "gmock_custom",
+    "custom",
     "src/googlemock/include",
   ]
 }
@@ -104,7 +109,7 @@
     "src/googlemock/include/gmock/internal/gmock-port.h",
 
     # gmock helpers.
-    "gmock_custom/gmock/internal/custom/gmock-port.h",
+    "custom/gmock/internal/custom/gmock-port.h",
 
     #"src/googlemock/src/gmock-all.cc",  # Not needed by our build.
     "src/googlemock/src/gmock-cardinalities.cc",
@@ -114,9 +119,6 @@
     "src/googlemock/src/gmock.cc",
   ]
 
-  # This project includes some stuff form gtest's guts.
-  include_dirs = [ "src/googletest/include" ]
-
   public_configs = [
     ":gmock_config",
     ":gtest_config",
diff --git a/third_party/googletest/README.chromium b/third_party/googletest/README.chromium
index 172e808..3fd6f3e 100644
--- a/third_party/googletest/README.chromium
+++ b/third_party/googletest/README.chromium
@@ -1,7 +1,7 @@
 Name: Google Test: Google's C++ Testing Framework
 Short Name: googletest
 URL: https://github.com/google/googletest.git
-Version: 1.7.0.git-43359642a1c16ad3f4fc575c7edd0cb935810815
+Version: 1.8.0.git-8c7f93fedaca1b0158e67af0f5dd63a044066eab
 License: BSD
 Security critical: no
 
diff --git a/third_party/googletest/gmock_custom/gmock/internal/custom/gmock-port.h b/third_party/googletest/custom/gmock/internal/custom/gmock-port.h
similarity index 77%
rename from third_party/googletest/gmock_custom/gmock/internal/custom/gmock-port.h
rename to third_party/googletest/custom/gmock/internal/custom/gmock-port.h
index b541499..de84e18 100644
--- a/third_party/googletest/gmock_custom/gmock/internal/custom/gmock-port.h
+++ b/third_party/googletest/custom/gmock/internal/custom/gmock-port.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef TESTING_GMOCK_CUSTOM_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_
-#define TESTING_GMOCK_CUSTOM_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_
+#ifndef THIRD_PARTY_GOOGLETEST_CUSTOM_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_
+#define THIRD_PARTY_GOOGLETEST_CUSTOM_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_
 
 #include <type_traits>
 
@@ -22,4 +22,4 @@
 #endif
 }
 
-#endif  // TESTING_GMOCK_CUSTOM_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_
+#endif  // THIRD_PARTY_GOOGLETEST_CUSTOM_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_
diff --git a/third_party/harfbuzz-ng/BUILD.gn b/third_party/harfbuzz-ng/BUILD.gn
index 7226d01a..b3dcc3d 100644
--- a/third_party/harfbuzz-ng/BUILD.gn
+++ b/third_party/harfbuzz-ng/BUILD.gn
@@ -7,7 +7,15 @@
 import("//build/config/linux/pkg_config.gni")
 import("//build/config/ui.gni")
 import("//testing/libfuzzer/fuzzer_test.gni")
-import("//third_party/harfbuzz-ng/harfbuzz.gni")
+
+declare_args() {
+  # Blink uses a cutting-edge version of Harfbuzz; most Linux distros do not
+  # contain a new enough version of the code to work correctly. However,
+  # ChromeOS chroots (i.e, real ChromeOS builds for devices) do contain a
+  # new enough version of the library, and so this variable exists so that
+  # ChromeOS can build against the system lib and keep binary sizes smaller.
+  use_system_harfbuzz = false
+}
 
 if (use_system_harfbuzz) {
   import("//build/config/linux/pkg_config.gni")
@@ -42,7 +50,8 @@
 
   # See also chrome/browser/ui/libgtkui/BUILD.gn which pulls this.
   config("pangoft2_link_hack") {
-    if (is_linux && use_pango && !use_system_harfbuzz && !is_component_build) {
+    if (is_linux && use_pango && !is_chromeos && !is_official_build &&
+        current_cpu != "arm" && current_cpu != "mipsel" && !is_component_build) {
       # These symbols are referenced from libpangoft2, which will be
       # dynamically linked later.
       ldflags = [ "-Wl,-uhb_ft_face_create_cached,-uhb_glib_get_unicode_funcs" ]
@@ -189,6 +198,20 @@
       ]
     }
 
+    # When without -fvisibility=hidden for pango to use the harfbuzz
+    # in the tree, all symbols pango needs must be included, or
+    # pango uses mixed versions of harfbuzz and leads to crash.
+    # See crbug.com/462689.
+    if (is_linux && use_pango && !is_chromeos && !is_official_build &&
+        current_cpu != "arm" && current_cpu != "mipsel") {
+      deps += [ "//build/config/freetype" ]
+      configs -= [ "//build/config/gcc:symbol_visibility_hidden" ]
+      configs += [ "//build/config/gcc:symbol_visibility_default" ]
+      sources += [
+        "src/hb-ft.cc",
+        "src/hb-ft.h",
+      ]
+    }
     if (use_glib) {
       configs += [ "//build/config/linux:glib" ]
       sources += [
@@ -197,39 +220,6 @@
       ]
     }
   }
-
-  static_library("harfbuzz-ng-ft") {
-    sources = [
-      "src/hb-ft.cc",
-      "src/hb-ft.h",
-    ]
-
-    if (is_component_build && !is_win) {
-      configs -= [ "//build/config/gcc:symbol_visibility_hidden" ]
-      configs += [ "//build/config/gcc:symbol_visibility_default" ]
-    }
-
-    configs -= [ "//build/config/compiler:chromium_code" ]
-    configs += [
-      "//build/config/compiler:no_chromium_code",
-
-      # Must be after no_chromium_code for warning flags to be ordered
-      # correctly.
-      ":harfbuzz_warnings",
-    ]
-    public_configs = [ ":harfbuzz-ng_config" ]
-
-    defines = [
-      "HAVE_OT",
-      "HAVE_ICU",
-      "HAVE_ICU_BUILTIN",
-      "HB_NO_MT",
-    ]
-
-    deps = [
-      "//third_party/freetype:bootstrap_freetype_for_harfbuzz",
-    ]
-  }
 }
 
 fuzzer_test("harfbuzz_fuzzer") {
diff --git a/third_party/harfbuzz-ng/harfbuzz.gni b/third_party/harfbuzz-ng/harfbuzz.gni
deleted file mode 100644
index a152b25..0000000
--- a/third_party/harfbuzz-ng/harfbuzz.gni
+++ /dev/null
@@ -1,12 +0,0 @@
-# Copyright 2017 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-declare_args() {
-  # Blink uses a cutting-edge version of Harfbuzz; most Linux distros do not
-  # contain a new enough version of the code to work correctly. However,
-  # ChromeOS chroots (i.e, real ChromeOS builds for devices) do contain a
-  # new enough version of the library, and so this variable exists so that
-  # ChromeOS can build against the system lib and keep binary sizes smaller.
-  use_system_harfbuzz = false
-}
diff --git a/tools/gn/bootstrap/bootstrap.py b/tools/gn/bootstrap/bootstrap.py
index 217add2..5e624ea 100755
--- a/tools/gn/bootstrap/bootstrap.py
+++ b/tools/gn/bootstrap/bootstrap.py
@@ -407,13 +407,13 @@
       'base/command_line.cc',
       'base/debug/activity_tracker.cc',
       'base/debug/alias.cc',
+      'base/debug/crash_logging.cc',
       'base/debug/dump_without_crashing.cc',
       'base/debug/stack_trace.cc',
       'base/debug/task_annotator.cc',
       'base/environment.cc',
       'base/feature_list.cc',
       'base/files/file.cc',
-      'base/files/file_descriptor_watcher_posix.cc',
       'base/files/file_enumerator.cc',
       'base/files/file_path.cc',
       'base/files/file_path_constants.cc',
@@ -436,7 +436,6 @@
       'base/memory/ref_counted_memory.cc',
       'base/memory/singleton.cc',
       'base/memory/shared_memory_handle.cc',
-      'base/memory/shared_memory_helper.cc',
       'base/memory/weak_ptr.cc',
       'base/message_loop/incoming_task_queue.cc',
       'base/message_loop/message_loop.cc',
@@ -538,6 +537,7 @@
       'base/trace_event/heap_profiler_serialization_state.cc',
       'base/trace_event/heap_profiler_stack_frame_deduplicator.cc',
       'base/trace_event/heap_profiler_type_name_deduplicator.cc',
+      'base/trace_event/malloc_dump_provider.cc',
       'base/trace_event/memory_allocator_dump.cc',
       'base/trace_event/memory_allocator_dump_guid.cc',
       'base/trace_event/memory_dump_manager.cc',
@@ -575,9 +575,11 @@
         'base/debug/debugger_posix.cc',
         'base/debug/stack_trace_posix.cc',
         'base/files/file_enumerator_posix.cc',
+        'base/files/file_descriptor_watcher_posix.cc',
         'base/files/file_posix.cc',
         'base/files/file_util_posix.cc',
         'base/files/memory_mapped_file_posix.cc',
+        'base/memory/shared_memory_helper.cc',
         'base/message_loop/message_pump_libevent.cc',
         'base/posix/file_descriptor_shuffle.cc',
         'base/posix/global_descriptors.cc',
@@ -646,7 +648,6 @@
         'base/strings/sys_string_conversions_posix.cc',
         'base/sys_info_linux.cc',
         'base/threading/platform_thread_linux.cc',
-        'base/trace_event/malloc_dump_provider.cc',
     ])
     if is_linux:
       static_libraries['base']['sources'].extend([
@@ -675,9 +676,6 @@
   if is_mac:
     static_libraries['base']['sources'].extend([
         'base/base_paths_mac.mm',
-        'base/build_time.cc',
-        'base/rand_util.cc',
-        'base/rand_util_posix.cc',
         'base/files/file_util_mac.mm',
         'base/mac/bundle_locations.mm',
         'base/mac/call_with_eh_frame.cc',
@@ -690,15 +688,14 @@
         'base/memory/shared_memory_handle_mac.cc',
         'base/memory/shared_memory_mac.cc',
         'base/message_loop/message_pump_mac.mm',
-        'base/metrics/field_trial.cc',
         'base/process/process_handle_mac.cc',
         'base/process/process_info_mac.cc',
         'base/process/process_iterator_mac.cc',
         'base/process/process_metrics_mac.cc',
         'base/strings/sys_string_conversions_mac.mm',
+        'base/sys_info_mac.mm',
         'base/time/time_mac.cc',
         'base/threading/platform_thread_mac.mm',
-        'base/trace_event/malloc_dump_provider.cc',
     ])
     static_libraries['libevent']['include_dirs'].extend([
         os.path.join(SRC_ROOT, 'base', 'third_party', 'libevent', 'mac')
@@ -729,6 +726,7 @@
         'base/files/file_util_win.cc',
         'base/files/file_win.cc',
         'base/files/memory_mapped_file_win.cc',
+        'base/guid.cc',
         'base/logging_win.cc',
         'base/memory/memory_pressure_monitor_win.cc',
         'base/memory/shared_memory_handle_win.cc',
@@ -746,7 +744,6 @@
         'base/process/process_win.cc',
         'base/profiler/native_stack_sampler_win.cc',
         'base/profiler/win32_stack_frame_unwinder.cc',
-        'base/rand_util.cc',
         'base/rand_util_win.cc',
         'base/strings/sys_string_conversions_win.cc',
         'base/sync_socket_win.cc',
@@ -758,7 +755,6 @@
         'base/sys_info_win.cc',
         'base/threading/platform_thread_win.cc',
         'base/threading/thread_local_storage_win.cc',
-        'base/threading/thread_local_win.cc',
         'base/threading/worker_pool_win.cc',
         'base/time/time_win.cc',
         'base/timer/hi_res_timer_manager_win.cc',
@@ -789,15 +785,16 @@
     ])
 
     libs.extend([
+        'advapi32.lib',
+        'dbghelp.lib',
         'kernel32.lib',
-        'user32.lib',
-        'shell32.lib',
         'ole32.lib',
-        'winmm.lib',
-        'ws2_32.lib',
+        'shell32.lib',
+        'user32.lib',
         'userenv.lib',
         'version.lib',
-        'dbghelp.lib',
+        'winmm.lib',
+        'ws2_32.lib',
     ])
 
   # we just build static libraries that GN needs
diff --git a/tools/md_browser/md_browser.py b/tools/md_browser/md_browser.py
index 8ed40573..ee9d9e2 100755
--- a/tools/md_browser/md_browser.py
+++ b/tools/md_browser/md_browser.py
@@ -36,10 +36,10 @@
   args = parser.parse_args(argv)
 
   top_level = os.path.realpath(args.directory)
+  server_address = ('localhost', args.port)
+  s = Server(server_address, top_level)
 
-  s = Server(args.port, top_level)
-
-  print('Listening on http://localhost:%s/' % args.port)
+  print('Listening on http://%s:%s/' % server_address)
   thread = None
   if args.file:
     path = os.path.realpath(args.file)
@@ -106,11 +106,9 @@
 
 
 class Server(SocketServer.TCPServer):
-  def __init__(self, port, top_level):
-    SocketServer.TCPServer.__init__(self, ('0.0.0.0', port), Handler)
-    self.port = port
+  def __init__(self, server_address, top_level):
+    SocketServer.TCPServer.__init__(self, server_address, Handler)
     self.top_level = top_level
-    self.retcode = None
 
   def server_bind(self):
     self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 18e27ef..069b3e0 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -14930,6 +14930,8 @@
   <int value="1971" label="AnchorClickDispatchForNonConnectedNode"/>
   <int value="1972" label="HTMLParseErrorNestedForm"/>
   <int value="1973" label="FontShapingNotDefGlyphObserved"/>
+  <int value="1974" label="PostMessageOutgoingWouldBeBlockedByConnectSrc"/>
+  <int value="1975" label="PostMessageIncomingWouldBeBlockedByConnectSrc"/>
 </enum>
 
 <enum name="FeedbackSource" type="int">
@@ -21380,6 +21382,7 @@
   <int value="-1363709707" label="MaterialDesignHistory:disabled"/>
   <int value="-1358669137" label="enable-supervised-user-blacklist"/>
   <int value="-1357655121" label="enable-iframe-based-signin"/>
+  <int value="-1357008397" label="ContextualSuggestionsCarousel:disabled"/>
   <int value="-1349896789" label="DelayNavigation:enabled"/>
   <int value="-1349872906"
       label="disallow-autofill-sync-credential-for-reauth"/>
@@ -22002,6 +22005,7 @@
   <int value="1067618884" label="enable-experimental-input-view-features"/>
   <int value="1070164693" label="MidiManagerDynamicInstantiation:disabled"/>
   <int value="1070300488" label="disable-webgl"/>
+  <int value="1070449228" label="ContextualSuggestionsCarousel:enabled"/>
   <int value="1074359194" label="UseSuggestionsEvenIfFew:enabled"/>
   <int value="1081546525" label="ash-enable-docked-windows"/>
   <int value="1087235172" label="file-manager-enable-new-audio-player"/>
diff --git a/ui/gfx/BUILD.gn b/ui/gfx/BUILD.gn
index 3e8949d..5587f35 100644
--- a/ui/gfx/BUILD.gn
+++ b/ui/gfx/BUILD.gn
@@ -183,6 +183,7 @@
     "win/direct_write.h",
     "win/hwnd_util.cc",
     "win/hwnd_util.h",
+    "win/msg_util.h",
     "win/physical_size.cc",
     "win/physical_size.h",
     "win/rendering_window_manager.cc",
@@ -739,6 +740,7 @@
       "font_fallback_win_unittest.cc",
       "icon_util_unittest.cc",
       "icon_util_unittests.rc",
+      "icon_util_unittests_resource.h",
       "path_win_unittest.cc",
       "platform_font_win_unittest.cc",
       "win/text_analysis_source_unittest.cc",
diff --git a/ui/gfx/paint_vector_icon.cc b/ui/gfx/paint_vector_icon.cc
index b644d0c..49063b6 100644
--- a/ui/gfx/paint_vector_icon.cc
+++ b/ui/gfx/paint_vector_icon.cc
@@ -13,9 +13,11 @@
 #include "base/memory/ptr_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_split.h"
+#include "base/trace_event/trace_event.h"
 #include "cc/paint/paint_canvas.h"
 #include "cc/paint/paint_flags.h"
 #include "third_party/skia/include/core/SkPath.h"
+#include "ui/gfx/animation/tween.h"
 #include "ui/gfx/canvas.h"
 #include "ui/gfx/image/canvas_image_source.h"
 #include "ui/gfx/scoped_canvas.h"
@@ -61,6 +63,7 @@
         return 2;
 
       case CIRCLE:
+      case TRANSITION_END:
         return 3;
 
       case PATH_COLOR_ARGB:
@@ -85,6 +88,8 @@
       case CLOSE:
       case DISABLE_AA:
       case FLIPS_IN_RTL:
+      case TRANSITION_FROM:
+      case TRANSITION_TO:
       case END:
         return 0;
     }
@@ -157,7 +162,8 @@
 void PaintPath(Canvas* canvas,
                const PathElement* path_elements,
                int dip_size,
-               SkColor color) {
+               SkColor color,
+               const base::TimeDelta& elapsed_time) {
   SkPath path;
   path.setFillType(SkPath::kEvenOdd_FillType);
 
@@ -172,14 +178,20 @@
        parser.Advance()) {
     auto arg = [&parser](int i) { return parser.GetArgument(i); };
     const CommandType command_type = parser.CurrentCommand();
-    if (paths.empty() || command_type == NEW_PATH) {
+    auto start_new_path = [&paths]() {
       paths.push_back(SkPath());
       paths.back().setFillType(SkPath::kEvenOdd_FillType);
-
+    };
+    auto start_new_flags = [&flags_array, &color]() {
       flags_array.push_back(cc::PaintFlags());
       flags_array.back().setColor(color);
       flags_array.back().setAntiAlias(true);
       flags_array.back().setStrokeCap(cc::PaintFlags::kRound_Cap);
+    };
+
+    if (paths.empty() || command_type == NEW_PATH) {
+      start_new_path();
+      start_new_flags();
     }
 
     SkPath& path = paths.back();
@@ -339,6 +351,67 @@
         flips_in_rtl = true;
         break;
 
+      // Transitions work by pushing new paths and a new set of flags onto the
+      // stack. When TRANSITION_END is seen, the paths and flags are
+      // interpolated based on |elapsed_time| and the tween type.
+      case TRANSITION_FROM: {
+        start_new_path();
+        break;
+      }
+
+      case TRANSITION_TO: {
+        start_new_path();
+        start_new_flags();
+        break;
+      }
+
+      case TRANSITION_END: {
+        DCHECK_GT(paths.size(), 2U);
+        // TODO(estade): check whether this operation (interpolation) is costly,
+        // and remove this TRACE log if not.
+        TRACE_EVENT0("ui", "PaintVectorIcon TRANSITION_END");
+
+        const base::TimeDelta delay =
+            base::TimeDelta::FromMillisecondsD(SkScalarToDouble(arg(0)));
+        const base::TimeDelta duration =
+            base::TimeDelta::FromMillisecondsD(SkScalarToDouble(arg(1)));
+
+        double state = 0;
+        if (elapsed_time >= delay + duration) {
+          state = 1;
+        } else if (elapsed_time > delay) {
+          state = (elapsed_time - delay).ToInternalValue() /
+                  static_cast<double>(duration.ToInternalValue());
+        }
+
+        auto weight = Tween::CalculateValue(
+            static_cast<Tween::Type>(SkScalarTruncToInt(arg(2))), state);
+
+        SkPath path1, path2;
+        path1.swap(paths.back());
+        paths.pop_back();
+        path2.swap(paths.back());
+        paths.pop_back();
+
+        SkPath interpolated_path;
+        bool could_interpolate =
+            path1.interpolate(path2, weight, &interpolated_path);
+        DCHECK(could_interpolate);
+        paths.back().addPath(interpolated_path);
+
+        // Perform manual interpolation of flags properties. TODO(estade): fill
+        // more of these in as necessary.
+        DCHECK_GT(flags_array.size(), 1U);
+        cc::PaintFlags& end_flags = flags_array.back();
+        cc::PaintFlags& start_flags = flags_array[flags_array.size() - 2];
+
+        start_flags.setColor(Tween::ColorValueBetween(
+            weight, start_flags.getColor(), end_flags.getColor()));
+
+        flags_array.pop_back();
+        break;
+      }
+
       case END:
         NOTREACHED();
         break;
@@ -347,8 +420,7 @@
     previous_command_type = command_type;
   }
 
-  gfx::ScopedRTLFlipCanvas scoped_rtl_flip_canvas(canvas, canvas_size,
-                                                  flips_in_rtl);
+  ScopedRTLFlipCanvas scoped_rtl_flip_canvas(canvas, canvas_size, flips_in_rtl);
 
   if (dip_size != canvas_size) {
     SkScalar scale = SkIntToScalar(dip_size) / SkIntToScalar(canvas_size);
@@ -369,13 +441,13 @@
                    int dip_size,
                    SkColor color,
                    const VectorIcon& badge_icon)
-      : CanvasImageSource(gfx::Size(dip_size, dip_size), false),
+      : CanvasImageSource(Size(dip_size, dip_size), false),
         color_(color),
         icon_(icon),
         badge_(badge_icon) {}
 
   VectorIconSource(const std::string& definition, int dip_size, SkColor color)
-      : CanvasImageSource(gfx::Size(dip_size, dip_size), false),
+      : CanvasImageSource(Size(dip_size, dip_size), false),
         color_(color),
         icon_(kNoneIcon),
         badge_(kNoneIcon),
@@ -388,13 +460,13 @@
     return !icon_.is_empty();
   }
 
-  void Draw(gfx::Canvas* canvas) override {
+  void Draw(Canvas* canvas) override {
     if (path_.empty()) {
       PaintVectorIcon(canvas, icon_, size_.width(), color_);
       if (!badge_.is_empty())
         PaintVectorIcon(canvas, badge_, size_.width(), color_);
     } else {
-      PaintPath(canvas, path_.data(), size_.width(), color_);
+      PaintPath(canvas, path_.data(), size_.width(), color_, base::TimeDelta());
     }
   }
 
@@ -426,7 +498,7 @@
 
     ImageSkia icon_image(
         new VectorIconSource(icon, dip_size, color, badge_icon),
-        gfx::Size(dip_size, dip_size));
+        Size(dip_size, dip_size));
     images_.insert(std::make_pair(description, icon_image));
     return icon_image;
   }
@@ -448,10 +520,10 @@
                       other.badge_icon);
     }
 
-    const gfx::VectorIcon* icon;
+    const VectorIcon* icon;
     int dip_size;
     SkColor color;
-    const gfx::VectorIcon* badge_icon;
+    const VectorIcon* badge_icon;
   };
 
   std::map<IconDescription, ImageSkia> images_;
@@ -466,19 +538,23 @@
 
 const VectorIcon kNoneIcon = {};
 
-void PaintVectorIcon(Canvas* canvas, const VectorIcon& icon, SkColor color) {
-  PaintVectorIcon(canvas, icon, GetDefaultSizeOfVectorIcon(icon), color);
+void PaintVectorIcon(Canvas* canvas,
+                     const VectorIcon& icon,
+                     SkColor color,
+                     const base::TimeDelta& elapsed_time) {
+  PaintVectorIcon(canvas, icon, GetDefaultSizeOfVectorIcon(icon), color,
+                  elapsed_time);
 }
 
 void PaintVectorIcon(Canvas* canvas,
                      const VectorIcon& icon,
                      int dip_size,
-                     SkColor color) {
+                     SkColor color,
+                     const base::TimeDelta& elapsed_time) {
   DCHECK(!icon.is_empty());
-  const PathElement* path = (canvas->image_scale() == 1.f && icon.path_1x_)
-                                ? icon.path_1x_
-                                : icon.path_;
-  PaintPath(canvas, path, dip_size, color);
+  const PathElement* path =
+      (canvas->image_scale() == 1.f && icon.path_1x) ? icon.path_1x : icon.path;
+  PaintPath(canvas, path, dip_size, color, elapsed_time);
 }
 
 ImageSkia CreateVectorIcon(const VectorIcon& icon, SkColor color) {
@@ -495,7 +571,7 @@
                                     int dip_size,
                                     SkColor color,
                                     const VectorIcon& badge_icon) {
-  return icon.is_empty() ? gfx::ImageSkia()
+  return icon.is_empty() ? ImageSkia()
                          : g_icon_cache.Get().GetOrCreateIcon(
                                icon, dip_size, color, badge_icon);
 }
@@ -507,10 +583,25 @@
                                                             color);
 }
 
-int GetDefaultSizeOfVectorIcon(const gfx::VectorIcon& icon) {
-  const PathElement* one_x_path = icon.path_1x_ ? icon.path_1x_ : icon.path_;
+int GetDefaultSizeOfVectorIcon(const VectorIcon& icon) {
+  const PathElement* one_x_path = icon.path_1x ? icon.path_1x : icon.path;
   return one_x_path[0].command == CANVAS_DIMENSIONS ? one_x_path[1].arg
                                                     : kReferenceSizeDip;
 }
 
+base::TimeDelta GetDurationOfAnimation(const VectorIcon& icon) {
+  base::TimeDelta last_motion;
+  for (PathParser parser(icon.path); parser.CurrentCommand() != END;
+       parser.Advance()) {
+    if (parser.CurrentCommand() != TRANSITION_END)
+      continue;
+
+    auto end_time = base::TimeDelta::FromMillisecondsD(parser.GetArgument(0)) +
+                    base::TimeDelta::FromMillisecondsD(parser.GetArgument(1));
+    if (end_time > last_motion)
+      last_motion = end_time;
+  }
+  return last_motion;
+}
+
 }  // namespace gfx
diff --git a/ui/gfx/paint_vector_icon.h b/ui/gfx/paint_vector_icon.h
index 799e436..2200043 100644
--- a/ui/gfx/paint_vector_icon.h
+++ b/ui/gfx/paint_vector_icon.h
@@ -5,6 +5,7 @@
 #ifndef UI_GFX_PAINT_VECTOR_ICON_H_
 #define UI_GFX_PAINT_VECTOR_ICON_H_
 
+#include "base/time/time.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "ui/gfx/gfx_export.h"
 #include "ui/gfx/image/image_skia.h"
@@ -18,17 +19,22 @@
 
 // Draws a vector icon identified by |id| onto |canvas| at (0, 0). |color| is
 // used as the fill. The size will come from the .icon file (the 1x version, if
-// multiple versions exist).
-GFX_EXPORT void PaintVectorIcon(Canvas* canvas,
-                                const VectorIcon& icon,
-                                SkColor color);
+// multiple versions exist). |elapsed_time| is used to determine the state of
+// any transitions the icon may define.
+GFX_EXPORT void PaintVectorIcon(
+    Canvas* canvas,
+    const VectorIcon& icon,
+    SkColor color,
+    const base::TimeDelta& elapsed_time = base::TimeDelta());
 
 // As above, with a specificed size. |dip_size| is the length of a single edge
 // of the square icon, in device independent pixels.
-GFX_EXPORT void PaintVectorIcon(Canvas* canvas,
-                                const VectorIcon& icon,
-                                int dip_size,
-                                SkColor color);
+GFX_EXPORT void PaintVectorIcon(
+    Canvas* canvas,
+    const VectorIcon& icon,
+    int dip_size,
+    SkColor color,
+    const base::TimeDelta& elapsed_time = base::TimeDelta());
 
 // Creates an ImageSkia which will render the icon on demand. The size will come
 // from the .icon file (the 1x version, if multiple versions exist).
@@ -58,6 +64,10 @@
 // Calculates the size that will be default for |icon|, in dip.
 GFX_EXPORT int GetDefaultSizeOfVectorIcon(const gfx::VectorIcon& icon);
 
+// Calculates and returns the elapsed time at which all animations/transitions
+// will be finished.
+base::TimeDelta GetDurationOfAnimation(const VectorIcon& icon);
+
 }  // namespace gfx
 
 #endif  // UI_GFX_PAINT_VECTOR_ICON_H_
diff --git a/ui/gfx/vector_icon_types.h b/ui/gfx/vector_icon_types.h
index b18000b4..36eb18eb 100644
--- a/ui/gfx/vector_icon_types.h
+++ b/ui/gfx/vector_icon_types.h
@@ -9,6 +9,7 @@
 #define UI_GFX_VECTOR_ICON_TYPES_H_
 
 #include "third_party/skia/include/core/SkScalar.h"
+#include "ui/gfx/animation/tween.h"
 
 namespace gfx {
 
@@ -58,6 +59,12 @@
   // Flips the x-axis in RTL locales. Default is false, this command sets it to
   // true.
   FLIPS_IN_RTL,
+  // Defines a timed transition for other elements.
+  TRANSITION_FROM,
+  TRANSITION_TO,
+  // Parameters are delay (ms), duration (ms), and tween type
+  // (gfx::Tween::Type).
+  TRANSITION_END,
   // Marks the end of the list of commands.
   END
 };
@@ -74,10 +81,10 @@
 };
 
 struct VectorIcon {
-  bool is_empty() const { return !path_; }
+  bool is_empty() const { return !path; }
 
-  const gfx::PathElement* path_;
-  const gfx::PathElement* path_1x_;
+  const gfx::PathElement* path;
+  const gfx::PathElement* path_1x;
 };
 
 // Returns an array of path commands and arguments, terminated by END.
diff --git a/ui/vector_icons/BUILD.gn b/ui/vector_icons/BUILD.gn
index 5c2ebcd..ba4ba2c 100644
--- a/ui/vector_icons/BUILD.gn
+++ b/ui/vector_icons/BUILD.gn
@@ -38,11 +38,11 @@
 
 static_library("vector_icons") {
   sources = get_target_outputs(":ui_vector_icons")
-  sources += [ "//ui/gfx/vector_icon_types.h" ]
 
   deps = [
     ":ui_vector_icons",
     "//base",
     "//skia",
+    "//ui/gfx",
   ]
 }