diff --git a/DEPS b/DEPS
index 281e840..bd5a815c 100644
--- a/DEPS
+++ b/DEPS
@@ -40,11 +40,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': 'a9a3564ff8ac4fcabd779412ee61a12e9214ec73',
+  'skia_revision': 'ba7196c0c9844bc885692cf3abee7e62a2e5ec7b',
   # 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': 'c59a968ba3e44a7c7bd7359efcfb636a373e9339',
+  'v8_revision': '643d02d9ce587dba7d0d944c01a953e99397158c',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling swarming_client
   # and whatever else without interference from each other.
diff --git a/base/BUILD.gn b/base/BUILD.gn
index 72bec6ba..ca2e3b5 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -1973,6 +1973,7 @@
     "containers/linked_list_unittest.cc",
     "containers/mru_cache_unittest.cc",
     "containers/small_map_unittest.cc",
+    "containers/span_unittest.cc",
     "containers/stack_container_unittest.cc",
     "containers/vector_buffer_unittest.cc",
     "cpu_unittest.cc",
diff --git a/base/containers/span.h b/base/containers/span.h
new file mode 100644
index 0000000..9b55740
--- /dev/null
+++ b/base/containers/span.h
@@ -0,0 +1,49 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_SPAN_H_
+#define BASE_SPAN_H_
+
+#include <stddef.h>
+
+namespace base {
+
+// A Span represents an array of elements of type T. It consists of a pointer to
+// memory with an associated size. A Span does not own the underlying memory, so
+// care must be taken to ensure that a Span does not outlive the backing store.
+// Spans should be passed by value.
+//
+// Span is somewhat analogous to StringPiece, but with arbitrary element types,
+// allowing mutation if T is non-const.
+//
+// TODO(https://crbug.com/754077): Document differences from the working group
+// proposal: http://open-std.org/JTC1/SC22/WG21/docs/papers/2016/p0122r1.pdf.
+// TODO(https://crbug.com/754077): Implement more Span support, such as
+// initialization from containers and iterators and document why this is useful
+// (greater safety since no need to manually pass in data + size)
+template <typename T>
+class Span {
+ public:
+  constexpr Span() noexcept : data_(nullptr), size_(0) {}
+  constexpr Span(T* data, size_t size) noexcept : data_(data), size_(size) {}
+  template <size_t N>
+  constexpr Span(T (&array)[N]) noexcept : data_(array), size_(N) {}
+
+  constexpr T* data() const noexcept { return data_; }
+  constexpr size_t size() const noexcept { return size_; }
+
+  constexpr Span subspan(size_t pos, size_t count) const {
+    // Note: ideally this would DCHECK, but it requires fairly horrible
+    // contortions.
+    return Span(data_ + pos, count);
+  }
+
+ private:
+  T* data_;
+  size_t size_;
+};
+
+}  // namespace base
+
+#endif  // BASE_SPAN_H_
diff --git a/base/containers/span_unittest.cc b/base/containers/span_unittest.cc
new file mode 100644
index 0000000..f7e60fa
--- /dev/null
+++ b/base/containers/span_unittest.cc
@@ -0,0 +1,127 @@
+// 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 "base/containers/span.h"
+
+#include <vector>
+
+#include "base/macros.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace base {
+
+// TODO(dcheng): Add tests for initializer list, containers, etc.
+
+TEST(SpanTest, ConstructFromDataAndSize) {
+  std::vector<int> vector = {1, 1, 2, 3, 5, 8};
+
+  Span<int> span(vector.data(), vector.size());
+  EXPECT_EQ(vector.data(), span.data());
+  EXPECT_EQ(vector.size(), span.size());
+
+  // TODO(dcheng): Use operator[] when implemented.
+  for (size_t i = 0; i < span.size(); ++i)
+    EXPECT_EQ(vector[i], span.data()[i]);
+}
+
+TEST(SpanTest, ConstructFromConstexprArray) {
+  static constexpr int kArray[] = {5, 4, 3, 2, 1};
+
+  constexpr Span<const int> span(kArray);
+  EXPECT_EQ(kArray, span.data());
+  EXPECT_EQ(arraysize(kArray), span.size());
+
+  // TODO(dcheng): Use operator[] when implemented.
+  for (size_t i = 0; i < span.size(); ++i)
+    EXPECT_EQ(kArray[i], span.data()[i]);
+}
+
+TEST(SpanTest, ConstructFromArray) {
+  int array[] = {5, 4, 3, 2, 1};
+
+  Span<const int> const_span(array);
+  EXPECT_EQ(array, const_span.data());
+  EXPECT_EQ(arraysize(array), const_span.size());
+  // TODO(dcheng): Use operator[] when implemented.
+  for (size_t i = 0; i < const_span.size(); ++i)
+    EXPECT_EQ(array[i], const_span.data()[i]);
+
+  Span<int> span(array);
+  EXPECT_EQ(array, span.data());
+  EXPECT_EQ(arraysize(array), span.size());
+  // TODO(dcheng): Use operator[] when implemented.
+  for (size_t i = 0; i < span.size(); ++i)
+    EXPECT_EQ(array[i], span.data()[i]);
+}
+
+TEST(SpanTest, Subspan) {
+  int array[] = {1, 2, 3};
+  Span<int> span(array);
+
+  {
+    auto subspan = span.subspan(0, 0);
+    EXPECT_EQ(span.data(), subspan.data());
+    EXPECT_EQ(0u, subspan.size());
+  }
+
+  {
+    auto subspan = span.subspan(1, 0);
+    EXPECT_EQ(span.data() + 1, subspan.data());
+    EXPECT_EQ(0u, subspan.size());
+  }
+
+  {
+    auto subspan = span.subspan(2, 0);
+    EXPECT_EQ(span.data() + 2, subspan.data());
+    EXPECT_EQ(0u, subspan.size());
+  }
+
+  {
+    auto subspan = span.subspan(0, 1);
+    EXPECT_EQ(span.data(), subspan.data());
+    EXPECT_EQ(1u, subspan.size());
+    EXPECT_EQ(1, subspan.data()[0]);
+  }
+
+  {
+    auto subspan = span.subspan(1, 1);
+    EXPECT_EQ(span.data() + 1, subspan.data());
+    EXPECT_EQ(1u, subspan.size());
+    EXPECT_EQ(2, subspan.data()[0]);
+  }
+
+  {
+    auto subspan = span.subspan(2, 1);
+    EXPECT_EQ(span.data() + 2, subspan.data());
+    EXPECT_EQ(1u, subspan.size());
+    EXPECT_EQ(3, subspan.data()[0]);
+  }
+
+  {
+    auto subspan = span.subspan(0, 2);
+    EXPECT_EQ(span.data(), subspan.data());
+    EXPECT_EQ(2u, subspan.size());
+    EXPECT_EQ(1, subspan.data()[0]);
+    EXPECT_EQ(2, subspan.data()[1]);
+  }
+
+  {
+    auto subspan = span.subspan(1, 2);
+    EXPECT_EQ(span.data() + 1, subspan.data());
+    EXPECT_EQ(2u, subspan.size());
+    EXPECT_EQ(2, subspan.data()[0]);
+    EXPECT_EQ(3, subspan.data()[1]);
+  }
+
+  {
+    auto subspan = span.subspan(0, 3);
+    EXPECT_EQ(span.data(), subspan.data());
+    EXPECT_EQ(span.size(), subspan.size());
+    EXPECT_EQ(1, subspan.data()[0]);
+    EXPECT_EQ(2, subspan.data()[1]);
+    EXPECT_EQ(3, subspan.data()[2]);
+  }
+}
+
+}  // namespace base
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 0429a755..0d6c1c459 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -3342,11 +3342,9 @@
      FEATURE_VALUE_TYPE(features::kVoiceSearchOnLocalNtp)},
 #endif  // !defined(OS_ANDROID)
 
-#if defined(OS_ANDROID)
     {"pwa-minimal-ui", flag_descriptions::kPwaMinimalUiName,
      flag_descriptions::kPwaMinimalUiDescription, kOsAndroid,
-     FEATURE_VALUE_TYPE(chrome::android::kPwaMinimalUi)},
-#endif  // OS_ANDROID
+     FEATURE_VALUE_TYPE(features::kPwaMinimalUi)},
 
     // NOTE: Adding new command-line switches requires adding corresponding
     // entries to enum "LoginCustomFlags" in histograms/enums.xml. See note in
diff --git a/chrome/browser/android/chrome_feature_list.cc b/chrome/browser/android/chrome_feature_list.cc
index 1532b2f6..66af908 100644
--- a/chrome/browser/android/chrome_feature_list.cc
+++ b/chrome/browser/android/chrome_feature_list.cc
@@ -87,7 +87,6 @@
     &kPayWithGoogleV1,
     &kPhysicalWebFeature,
     &kPhysicalWebSharing,
-    &kPwaMinimalUi,
     &kPwaPersistentNotification,
     &kReaderModeInCCT,
     &kSearchEnginePromoExistingDevice,
@@ -247,9 +246,6 @@
 const base::Feature kPhysicalWebSharing{"PhysicalWebSharing",
                                         base::FEATURE_DISABLED_BY_DEFAULT};
 
-const base::Feature kPwaMinimalUi{"PwaMinimalUi",
-                                  base::FEATURE_DISABLED_BY_DEFAULT};
-
 const base::Feature kPwaPersistentNotification{
     "PwaPersistentNotification", base::FEATURE_DISABLED_BY_DEFAULT};
 
diff --git a/chrome/browser/android/chrome_feature_list.h b/chrome/browser/android/chrome_feature_list.h
index 00351a79..799fa0d 100644
--- a/chrome/browser/android/chrome_feature_list.h
+++ b/chrome/browser/android/chrome_feature_list.h
@@ -52,7 +52,6 @@
 extern const base::Feature kPayWithGoogleV1;
 extern const base::Feature kPhysicalWebFeature;
 extern const base::Feature kPhysicalWebSharing;
-extern const base::Feature kPwaMinimalUi;
 extern const base::Feature kPwaPersistentNotification;
 extern const base::Feature kReaderModeInCCT;
 extern const base::Feature kSpannableInlineAutocomplete;
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index 8cbe8de..0df7d11 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -990,6 +990,10 @@
     "running after the last window is closed, and to launch at OS startup, if "
     "the Push API needs it.";
 
+const char kPwaMinimalUiName[] = "Minimal-UI display mode for PWAs";
+const char kPwaMinimalUiDescription[] =
+    "Enables support for Minimal-UI display mode for installed PWAs";
+
 const char kQuicName[] = "Experimental QUIC protocol";
 const char kQuicDescription[] = "Enable experimental QUIC protocol support.";
 
@@ -1848,9 +1852,6 @@
 const char kPullToRefreshEffectDescription[] =
     "Page reloads triggered by vertically overscrolling content.";
 
-const char kPwaMinimalUiName[] = "Minimal-UI display mode for PWAs";
-const char kPwaMinimalUiDescription[] =
-    "Enables support for Minimal-UI display mode for installed PWAs";
 const char kPwaPersistentNotificationName[] =
     "Persistent notification in standalone PWA";
 const char kPwaPersistentNotificationDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 90e0e25..754e05a 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -618,6 +618,9 @@
 extern const char kPushApiBackgroundModeName[];
 extern const char kPushApiBackgroundModeDescription[];
 
+extern const char kPwaMinimalUiName[];
+extern const char kPwaMinimalUiDescription[];
+
 extern const char kQuicName[];
 extern const char kQuicDescription[];
 
@@ -1124,8 +1127,6 @@
 extern const char kPullToRefreshEffectName[];
 extern const char kPullToRefreshEffectDescription[];
 
-extern const char kPwaMinimalUiName[];
-extern const char kPwaMinimalUiDescription[];
 extern const char kPwaPersistentNotificationName[];
 extern const char kPwaPersistentNotificationDescription[];
 
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc
index c9c3d0c..e113fad 100644
--- a/chrome/common/chrome_features.cc
+++ b/chrome/common/chrome_features.cc
@@ -346,6 +346,10 @@
 const base::Feature kPushMessagingBackgroundMode{
     "PushMessagingBackgroundMode", base::FEATURE_DISABLED_BY_DEFAULT};
 
+// Enables support for Minimal-UI PWA display mode.
+const base::Feature kPwaMinimalUi{"PwaMinimalUi",
+                                  base::FEATURE_DISABLED_BY_DEFAULT};
+
 #if defined(OS_CHROMEOS)
 // Runtime flag that indicates whether this leak detector should be enabled in
 // the current instance of Chrome.
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h
index 3ad9e91..0405db64 100644
--- a/chrome/common/chrome_features.h
+++ b/chrome/common/chrome_features.h
@@ -179,6 +179,8 @@
 
 extern const base::Feature kPushMessagingBackgroundMode;
 
+extern const base::Feature kPwaMinimalUi;
+
 #if defined(OS_CHROMEOS)
 extern const base::Feature kRuntimeMemoryLeakDetector;
 #endif  // defined(OS_CHROMEOS)
diff --git a/chrome/common/extensions/media_parser_struct_traits.h b/chrome/common/extensions/media_parser_struct_traits.h
index f53fa22..0edd0d1 100644
--- a/chrome/common/extensions/media_parser_struct_traits.h
+++ b/chrome/common/extensions/media_parser_struct_traits.h
@@ -9,7 +9,7 @@
 
 #include "chrome/common/extensions/media_parser.mojom.h"
 #include "chrome/common/media_galleries/metadata_types.h"
-#include "mojo/public/cpp/bindings/array_traits_carray.h"
+#include "mojo/public/cpp/bindings/array_traits_span.h"
 
 namespace mojo {
 
diff --git a/chrome/gpu/gpu_arc_video_encode_accelerator.cc b/chrome/gpu/gpu_arc_video_encode_accelerator.cc
index 192f5942a..8c1ff2f 100644
--- a/chrome/gpu/gpu_arc_video_encode_accelerator.cc
+++ b/chrome/gpu/gpu_arc_video_encode_accelerator.cc
@@ -19,6 +19,21 @@
 namespace chromeos {
 namespace arc {
 
+namespace {
+
+// Helper class to notify client about the end of processing a video frame.
+class VideoFrameDoneNotifier {
+ public:
+  explicit VideoFrameDoneNotifier(base::OnceClosure notify_closure)
+      : notify_closure_(std::move(notify_closure)) {}
+  ~VideoFrameDoneNotifier() { std::move(notify_closure_).Run(); }
+
+ private:
+  base::OnceClosure notify_closure_;
+};
+
+}  // namespace
+
 GpuArcVideoEncodeAccelerator::GpuArcVideoEncodeAccelerator(
     const gpu::GpuPreferences& gpu_preferences)
     : gpu_preferences_(gpu_preferences) {}
@@ -45,8 +60,9 @@
     base::TimeDelta timestamp) {
   DVLOGF(2) << "id=" << bitstream_buffer_id;
   DCHECK(client_);
-  client_->BitstreamBufferReady(bitstream_buffer_id, payload_size, key_frame,
-                                timestamp.InMicroseconds());
+  auto iter = use_bitstream_cbs_.find(bitstream_buffer_id);
+  DCHECK(iter != use_bitstream_cbs_.end());
+  iter->second.Run(payload_size, key_frame, timestamp.InMicroseconds());
 }
 
 void GpuArcVideoEncodeAccelerator::NotifyError(Error error) {
@@ -87,21 +103,26 @@
   callback.Run(true);
 }
 
-static void DropSharedMemory(std::unique_ptr<base::SharedMemory> shm) {
-  // Just let |shm| fall out of scope.
+static void DropShareMemoryAndVideoFrameDoneNotifier(
+    std::unique_ptr<base::SharedMemory> shm,
+    std::unique_ptr<VideoFrameDoneNotifier> notifier) {
+  // Just let |shm| and |notifier| fall out of scope.
 }
 
 void GpuArcVideoEncodeAccelerator::Encode(
     mojo::ScopedHandle handle,
     std::vector<::arc::VideoFramePlane> planes,
     int64_t timestamp,
-    bool force_keyframe) {
+    bool force_keyframe,
+    const EncodeCallback& callback) {
   DVLOGF(2) << "timestamp=" << timestamp;
   if (!accelerator_) {
     DLOG(ERROR) << "Accelerator is not initialized.";
     return;
   }
 
+  auto notifier = base::MakeUnique<VideoFrameDoneNotifier>(callback);
+
   if (planes.empty()) {  // EOS
     accelerator_->Encode(media::VideoFrame::CreateEOSFrame(), force_keyframe);
     return;
@@ -148,19 +169,23 @@
       shm_memory + aligned_offset, allocation_size, shm_handle,
       planes[0].offset, base::TimeDelta::FromMicroseconds(timestamp));
 
-  // Wrap |shm| in a callback and add it as a destruction observer, so it
-  // stays alive and mapped until |frame| goes out of scope.
+  // Wrap |shm| and |notifier| in a callback and add it as a destruction
+  // observer. When the |frame| goes out of scope, it unmaps and releases
+  // the shared memory as well as notifies |client_| about the end of processing
+  // the |frame|.
   frame->AddDestructionObserver(
-      base::Bind(&DropSharedMemory, base::Passed(&shm)));
+      base::Bind(&DropShareMemoryAndVideoFrameDoneNotifier, base::Passed(&shm),
+                 base::Passed(&notifier)));
+
   accelerator_->Encode(frame, force_keyframe);
 }
 
-void GpuArcVideoEncodeAccelerator::UseOutputBitstreamBuffer(
-    int32_t bitstream_buffer_id,
+void GpuArcVideoEncodeAccelerator::UseBitstreamBuffer(
     mojo::ScopedHandle shmem_fd,
     uint32_t offset,
-    uint32_t size) {
-  DVLOGF(2) << "id=" << bitstream_buffer_id;
+    uint32_t size,
+    const UseBitstreamBufferCallback& callback) {
+  DVLOGF(2) << "serial=" << bitstream_buffer_serial_;
   if (!accelerator_) {
     DLOG(ERROR) << "Accelerator is not initialized.";
     return;
@@ -178,8 +203,12 @@
   base::UnguessableToken guid = base::UnguessableToken::Create();
   base::SharedMemoryHandle shm_handle(base::FileDescriptor(fd.release(), true),
                                       0u, guid);
-  accelerator_->UseOutputBitstreamBuffer(
-      media::BitstreamBuffer(bitstream_buffer_id, shm_handle, size, offset));
+  use_bitstream_cbs_[bitstream_buffer_serial_] = callback;
+  accelerator_->UseOutputBitstreamBuffer(media::BitstreamBuffer(
+      bitstream_buffer_serial_, shm_handle, size, offset));
+
+  // Mask against 30 bits to avoid (undefined) wraparound on signed integer.
+  bitstream_buffer_serial_ = (bitstream_buffer_serial_ + 1) & 0x3FFFFFFF;
 }
 
 void GpuArcVideoEncodeAccelerator::RequestEncodingParametersChange(
diff --git a/chrome/gpu/gpu_arc_video_encode_accelerator.h b/chrome/gpu/gpu_arc_video_encode_accelerator.h
index f388d94..e3ef4db 100644
--- a/chrome/gpu/gpu_arc_video_encode_accelerator.h
+++ b/chrome/gpu/gpu_arc_video_encode_accelerator.h
@@ -57,11 +57,12 @@
   void Encode(mojo::ScopedHandle fd,
               std::vector<::arc::VideoFramePlane> planes,
               int64_t timestamp,
-              bool force_keyframe) override;
-  void UseOutputBitstreamBuffer(int32_t bitstream_buffer_id,
-                                mojo::ScopedHandle shmem_fd,
-                                uint32_t offset,
-                                uint32_t size) override;
+              bool force_keyframe,
+              const EncodeCallback& callback) override;
+  void UseBitstreamBuffer(mojo::ScopedHandle shmem_fd,
+                          uint32_t offset,
+                          uint32_t size,
+                          const UseBitstreamBufferCallback& callback) override;
   void RequestEncodingParametersChange(uint32_t bitrate,
                                        uint32_t framerate) override;
 
@@ -76,6 +77,8 @@
   gfx::Size coded_size_;
   gfx::Size visible_size_;
   VideoPixelFormat input_pixel_format_;
+  int32_t bitstream_buffer_serial_;
+  std::unordered_map<uint32_t, UseBitstreamBufferCallback> use_bitstream_cbs_;
 
   DISALLOW_COPY_AND_ASSIGN(GpuArcVideoEncodeAccelerator);
 };
diff --git a/components/arc/common/video_encode_accelerator.mojom b/components/arc/common/video_encode_accelerator.mojom
index 5f819a0..98fe048 100644
--- a/components/arc/common/video_encode_accelerator.mojom
+++ b/components/arc/common/video_encode_accelerator.mojom
@@ -99,8 +99,7 @@
   GetSupportedProfiles@0() => (array<VideoEncodeProfile> profiles);
 
   // Initializes the video encoder with specific configuration.  Called once per
-  // encoder construction.  This call returns true iff initialization is
-  // successful.
+  // encoder construction.
   // Parameters:
   //  |input_format| is the pixel format of the input frames.
   //  |visible_size| is the resolution of the input frames.
@@ -110,6 +109,9 @@
   //  in bits per second.
   //  |client| is the client of this video encoder. The client must be valid
   //  during the lifetime of this accelerator.
+  // Callback:
+  //  Called with true iff initialization is successful. The client should not
+  //  invoke any other methods before the callback.
   Initialize@1(VideoPixelFormat input_format,
                Size visible_size,
                StorageType input_storage,
@@ -125,24 +127,30 @@
   //  |planes| is arrays of offset and stride of planes in the video frame.
   //  |timestamp| the timestamp of the video frame(in microseconds).
   //  |force_keyframe| forces the encoding of a keyframe for this frame.
+  // Callback:
+  //  Called when the frame has been processed and no longer used by this
+  //  accelerator.
   Encode@2(handle frame_fd,
            array<VideoFramePlane> planes,
            int64 timestamp,
-           bool force_keyframe);
+           bool force_keyframe) => ();
 
-  // Sends a bitstream buffer to the encoder for storing future encoded output.
-  // Each call here will cause the shared memory buffer to be filled once, then
-  // returned with VideoEncodeClient::BitstreamBufferReady().
+  // Sends a bitstream buffer to the encoder for storing encoded output. The
+  // shared memory buffer will be filled with the encoded bitstream, and the
+  // callback will be called.
   // Parameters:
   //  |bitstream_buffer_id| is the id of the bitstream buffer. It is used to
   //  identify the bitstream in VideoEncodeClient::BitstreamBufferReady().
   //  |shmem_fd| is the file descriptor of the shared memory.
   //  |offset| and |size| define the region in the shared memory to be used
   //  as the bitstream buffer.
-  UseOutputBitstreamBuffer@3(int32 bitstream_buffer_id,
-                             handle shmem_fd,
-                             uint32 offset,
-                             uint32 size);
+  // Callback:
+  //  Called when the encoded data has been filled in the bitstream buffer.
+  //  |payload_size| is the byte size of the used portion of the buffer.
+  //  |key_frame| is true if this delivered frame is a keyframe.
+  //  |timestamp| is the same timestamp as the one passed to Encode().
+  UseBitstreamBuffer@3(handle shmem_fd, uint32 offset, uint32 size)
+      => (uint32 payload_size, bool key_frame, int64 timestamp);
 
   // Requests a change to the encoding parameters. This is only a request,
   // fulfilled on a best-effort basis.
@@ -177,18 +185,6 @@
                             Size input_coded_size,
                             uint32 output_buffer_size);
 
-  // Callback to deliver encoded bitstream buffers. Ownership of the buffer is
-  // transferred back to the VideoEncodeClient once this callback is made.
-  // Parameters:
-  //  |bitstream_buffer_id| is the id of the buffer that is ready.
-  //  |payload_size| is the byte size of the used portion of the buffer.
-  //  |key_frame| is true if this delivered frame is a keyframe.
-  //  |timestamp| is the same timestamp as the one passed to Encode().
-  BitstreamBufferReady@1(int32 bitstream_buffer_id,
-                         uint32 payload_size,
-                         bool key_frame,
-                         int64 timestamp);
-
   // Error notification callback. Note that errors in
   // VideoEncodeAccelerator::Initialize() will not be reported here, but will
   // instead be indicated by a false return value there.
diff --git a/content/common/message_port_message.h b/content/common/message_port_message.h
index c65764e..dc9a554 100644
--- a/content/common/message_port_message.h
+++ b/content/common/message_port_message.h
@@ -6,7 +6,7 @@
 #define CONTENT_COMMON_MESSAGE_PORT_MESSAGE_H_
 
 #include <vector>
-#include "mojo/public/cpp/bindings/array_traits_carray.h"
+#include "mojo/public/cpp/bindings/array_traits_span.h"
 #include "mojo/public/cpp/system/message_pipe.h"
 
 namespace content {
diff --git a/device/gamepad/public/interfaces/gamepad_struct_traits.h b/device/gamepad/public/interfaces/gamepad_struct_traits.h
index 20b136b..531f6bb 100644
--- a/device/gamepad/public/interfaces/gamepad_struct_traits.h
+++ b/device/gamepad/public/interfaces/gamepad_struct_traits.h
@@ -9,7 +9,7 @@
 
 #include "device/gamepad/public/cpp/gamepad.h"
 #include "device/gamepad/public/interfaces/gamepad.mojom.h"
-#include "mojo/public/cpp/bindings/array_traits_carray.h"
+#include "mojo/public/cpp/bindings/array_traits_span.h"
 #include "mojo/public/cpp/bindings/struct_traits.h"
 
 namespace mojo {
diff --git a/ios/chrome/browser/content_suggestions/content_suggestions_coordinator.mm b/ios/chrome/browser/content_suggestions/content_suggestions_coordinator.mm
index 817732d2..c076489 100644
--- a/ios/chrome/browser/content_suggestions/content_suggestions_coordinator.mm
+++ b/ios/chrome/browser/content_suggestions/content_suggestions_coordinator.mm
@@ -491,10 +491,11 @@
 - (void)openNewTabWithURL:(const GURL&)URL incognito:(BOOL)incognito {
   // TODO(crbug.com/691979): Add metrics.
 
+  // Open the tab in background if it is non-incognito only.
   [self.URLLoader webPageOrderedOpen:URL
                             referrer:web::Referrer()
                          inIncognito:incognito
-                        inBackground:NO
+                        inBackground:!incognito
                             appendTo:kCurrentTab];
 }
 
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_footer_item.mm b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_footer_item.mm
index 185be52..96695b37 100644
--- a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_footer_item.mm
+++ b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_footer_item.mm
@@ -4,7 +4,7 @@
 
 #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_footer_item.h"
 
-#import "ios/chrome/browser/ui/material_components/activity_indicator.h"
+#import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h"
 #import "ios/chrome/browser/ui/util/constraints_ui_util.h"
 #import "ios/third_party/material_components_ios/src/components/ActivityIndicator/src/MaterialActivityIndicator.h"
 
@@ -82,7 +82,7 @@
   self = [super initWithFrame:frame];
   if (self) {
     _activityIndicator = [[MDCActivityIndicator alloc] init];
-    _activityIndicator.cycleColors = ActivityIndicatorBrandedCycleColors();
+    _activityIndicator.cycleColors = @[ [[MDCPalette cr_bluePalette] tint500] ];
     _activityIndicator.translatesAutoresizingMaskIntoConstraints = NO;
     _button = [UIButton buttonWithType:UIButtonTypeSystem];
     _button.translatesAutoresizingMaskIntoConstraints = NO;
diff --git a/media/base/pipeline.h b/media/base/pipeline.h
index b39ae20..1423afae 100644
--- a/media/base/pipeline.h
+++ b/media/base/pipeline.h
@@ -34,7 +34,6 @@
     // Executed whenever an error occurs except when the error occurs during
     // Start/Seek/Resume or Suspend. Those errors are reported via |seek_cb|
     // and |suspend_cb| respectively.
-    // NOTE: The client is responsible for calling Pipeline::Stop().
     virtual void OnError(PipelineStatus status) = 0;
 
     // Executed whenever the media reaches the end.
diff --git a/media/base/pipeline_impl.cc b/media/base/pipeline_impl.cc
index 2028019..ecf1574 100644
--- a/media/base/pipeline_impl.cc
+++ b/media/base/pipeline_impl.cc
@@ -222,8 +222,8 @@
     std::unique_ptr<TextRenderer> text_renderer,
     base::WeakPtr<PipelineImpl> weak_pipeline) {
   DCHECK(media_task_runner_->BelongsToCurrentThread());
-  DCHECK(state_ == kCreated || state_ == kStopped)
-      << "Received start in unexpected state: " << state_;
+  DCHECK_EQ(kCreated, state_) << "Received start in unexpected state: "
+                              << state_;
 
   SetState(kStarting);
 
@@ -232,6 +232,7 @@
   DCHECK(!text_renderer_);
   DCHECK(!renderer_ended_);
   DCHECK(!text_renderer_ended_);
+  DCHECK(!weak_pipeline_);
   demuxer_ = demuxer;
   {
     base::AutoLock auto_lock(shared_state_lock_);
@@ -1274,16 +1275,18 @@
   // Else report error via the client interface.
   if (!seek_cb_.is_null()) {
     base::ResetAndReturn(&seek_cb_).Run(error);
-    return;
-  }
-
-  if (!suspend_cb_.is_null()) {
+  } else if (!suspend_cb_.is_null()) {
     base::ResetAndReturn(&suspend_cb_).Run(error);
-    return;
+  } else {
+    DCHECK(client_);
+    client_->OnError(error);
   }
 
-  DCHECK(client_);
-  client_->OnError(error);
+  // Any kind of error stops the pipeline.
+  //
+  // TODO (tguilbert): Move this out to PipelineController to make the state
+  // changes more consistent. See crbug.com/695734.
+  Stop();
 }
 
 void PipelineImpl::OnEnded() {
diff --git a/media/base/pipeline_impl.h b/media/base/pipeline_impl.h
index 73ee91f..e5c9de3 100644
--- a/media/base/pipeline_impl.h
+++ b/media/base/pipeline_impl.h
@@ -29,7 +29,7 @@
 // Here's a state diagram that describes the lifetime of this object.
 //
 //   [ *Created ]                       [ Any State ]
-//         | Start()                         | Stop()
+//         | Start()                         | Stop() / SetError()
 //         V                                 V
 //   [ Starting ]                       [ Stopping ]
 //         |                                 |
@@ -55,9 +55,9 @@
 // a chance to preroll. From then on the normal Seek() transitions are carried
 // out and we start playing the media.
 //
-// If Stop() is ever called, this object will transition to "Stopped" state.
-// Pipeline::Stop() is never called from withing PipelineImpl. It's |client_|'s
-// responsibility to call stop when appropriate.
+// If any error ever happens, this object will transition to the "Error" state
+// from any state. If Stop() is ever called, this object will transition to
+// "Stopped" state.
 //
 // TODO(sandersd): It should be possible to pass through Suspended when going
 // from InitDemuxer to InitRenderer, thereby eliminating the Resuming state.
diff --git a/media/base/pipeline_impl_unittest.cc b/media/base/pipeline_impl_unittest.cc
index 9db941b9..8e81bd2d 100644
--- a/media/base/pipeline_impl_unittest.cc
+++ b/media/base/pipeline_impl_unittest.cc
@@ -37,6 +37,8 @@
 using ::testing::CreateFunctor;
 using ::testing::DeleteArg;
 using ::testing::DoAll;
+// TODO(scherkus): Remove InSequence after refactoring Pipeline.
+using ::testing::InSequence;
 using ::testing::Invoke;
 using ::testing::InvokeWithoutArgs;
 using ::testing::Mock;
@@ -422,6 +424,7 @@
 TEST_F(PipelineImplTest, NoStreams) {
   EXPECT_CALL(*demuxer_, Initialize(_, _, _))
       .WillOnce(PostCallback<1>(PIPELINE_OK));
+  EXPECT_CALL(*demuxer_, Stop());
   EXPECT_CALL(callbacks_, OnMetadata(_));
 
   StartPipelineAndExpect(PIPELINE_ERROR_COULD_NOT_RENDER);
@@ -533,9 +536,8 @@
   // Initialize then seek!
   StartPipelineAndExpect(PIPELINE_OK);
 
-  // Pipeline::Client is supposed to call Pipeline::Stop() after errors.
-  EXPECT_CALL(callbacks_, OnError(_)).WillOnce(Stop(pipeline_.get()));
   EXPECT_CALL(*demuxer_, Stop());
+  EXPECT_CALL(callbacks_, OnError(_));
   OnDemuxerError();
   base::RunLoop().RunUntilIdle();
 
@@ -699,8 +701,7 @@
 
   pipeline_->Seek(seek_time, base::Bind(&CallbackHelper::OnSeek,
                                         base::Unretained(&callbacks_)));
-  EXPECT_CALL(callbacks_, OnSeek(PIPELINE_ERROR_READ))
-      .WillOnce(Stop(pipeline_.get()));
+  EXPECT_CALL(callbacks_, OnSeek(PIPELINE_ERROR_READ));
   base::RunLoop().RunUntilIdle();
 }
 
@@ -753,8 +754,7 @@
 
   pipeline_->Seek(seek_time, base::Bind(&CallbackHelper::OnSeek,
                                         base::Unretained(&callbacks_)));
-  EXPECT_CALL(callbacks_, OnSeek(PIPELINE_ERROR_READ))
-      .WillOnce(Stop(pipeline_.get()));
+  EXPECT_CALL(callbacks_, OnSeek(PIPELINE_ERROR_READ));
   base::RunLoop().RunUntilIdle();
 }
 
@@ -934,8 +934,7 @@
       } else {
         EXPECT_CALL(*demuxer_, Initialize(_, _, _))
             .WillOnce(PostCallback<1>(DEMUXER_ERROR_COULD_NOT_OPEN));
-        EXPECT_CALL(callbacks_, OnStart(DEMUXER_ERROR_COULD_NOT_OPEN))
-            .WillOnce(Stop(pipeline_.get()));
+        EXPECT_CALL(callbacks_, OnStart(DEMUXER_ERROR_COULD_NOT_OPEN));
       }
 
       EXPECT_CALL(*demuxer_, Stop());
@@ -958,8 +957,7 @@
       } else {
         EXPECT_CALL(*renderer_, Initialize(_, _, _))
             .WillOnce(PostCallback<2>(PIPELINE_ERROR_INITIALIZATION_FAILED));
-        EXPECT_CALL(callbacks_, OnStart(PIPELINE_ERROR_INITIALIZATION_FAILED))
-            .WillOnce(Stop(pipeline_.get()));
+        EXPECT_CALL(callbacks_, OnStart(PIPELINE_ERROR_INITIALIZATION_FAILED));
       }
 
       EXPECT_CALL(callbacks_, OnMetadata(_));
@@ -1010,8 +1008,7 @@
                 SetError(&renderer_client_, PIPELINE_ERROR_READ),
                 RunClosure<0>()));
         EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING));
-        EXPECT_CALL(callbacks_, OnSeek(PIPELINE_ERROR_READ))
-            .WillOnce(Stop(pipeline_.get()));
+        EXPECT_CALL(callbacks_, OnSeek(PIPELINE_ERROR_READ));
       }
       return;
     }
@@ -1031,8 +1028,7 @@
       } else {
         EXPECT_CALL(*demuxer_, Seek(_, _))
             .WillOnce(RunCallback<1>(PIPELINE_ERROR_READ));
-        EXPECT_CALL(callbacks_, OnSeek(PIPELINE_ERROR_READ))
-            .WillOnce(Stop(pipeline_.get()));
+        EXPECT_CALL(callbacks_, OnSeek(PIPELINE_ERROR_READ));
       }
       return;
     }
@@ -1072,8 +1068,7 @@
       } else {
         EXPECT_CALL(*demuxer_, Seek(_, _))
             .WillOnce(RunCallback<1>(PIPELINE_ERROR_READ));
-        EXPECT_CALL(callbacks_, OnResume(PIPELINE_ERROR_READ))
-            .WillOnce(Stop(pipeline_.get()));
+        EXPECT_CALL(callbacks_, OnResume(PIPELINE_ERROR_READ));
       }
     } else if (state != kSuspended && state != kSuspending) {
       NOTREACHED() << "State not supported: " << state;
@@ -1090,8 +1085,7 @@
       case kError:
         if (expect_errors) {
           EXPECT_CALL(*demuxer_, Stop());
-          EXPECT_CALL(callbacks_, OnError(PIPELINE_ERROR_READ))
-              .WillOnce(Stop(pipeline_.get()));
+          EXPECT_CALL(callbacks_, OnError(PIPELINE_ERROR_READ));
         }
         renderer_client_->OnError(PIPELINE_ERROR_READ);
         break;
diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc
index b552a9b5..68b41bce 100644
--- a/media/blink/webmediaplayer_impl.cc
+++ b/media/blink/webmediaplayer_impl.cc
@@ -1333,9 +1333,6 @@
     SetNetworkState(PipelineErrorToNetworkState(status));
   }
 
-  // PipelineController::Stop() is idempotent.
-  pipeline_controller_.Stop();
-
   UpdatePlayState();
 }
 
diff --git a/media/filters/pipeline_controller.cc b/media/filters/pipeline_controller.cc
index aad3e4f9..e5d0245 100644
--- a/media/filters/pipeline_controller.cc
+++ b/media/filters/pipeline_controller.cc
@@ -45,7 +45,7 @@
                                bool is_streaming,
                                bool is_static) {
   DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK_EQ(state_, State::STOPPED);
+  DCHECK(state_ == State::CREATED);
   DCHECK(demuxer);
 
   // Once the pipeline is started, we want to call the seeked callback but
@@ -247,18 +247,12 @@
 }
 
 void PipelineController::Stop() {
-  if (state_ == State::STOPPED)
-    return;
-
-  demuxer_ = nullptr;
-  waiting_for_seek_ = false;
-  pending_seeked_cb_ = false;
-  pending_time_updated_ = false;
-  pending_seek_ = false;
-  pending_suspend_ = false;
-  pending_resume_ = false;
-  state_ = State::STOPPED;
-
+  // For the moment, Stop() is only called on WMPI destruction, and updating the
+  // state of |this| is not relevant. Eventually, Start()/Stop() will be called
+  // in order to swap between demuxer types, and this will need to be adressed.
+  //
+  // TODO(tguilbert): Clarify the appropriate state changes when Stop() is
+  // called. See crbug.com/695734.
   pipeline_->Stop();
 }
 
diff --git a/media/filters/pipeline_controller.h b/media/filters/pipeline_controller.h
index e8fce793..79cb14b 100644
--- a/media/filters/pipeline_controller.h
+++ b/media/filters/pipeline_controller.h
@@ -30,7 +30,7 @@
 class MEDIA_EXPORT PipelineController {
  public:
   enum class State {
-    STOPPED,
+    CREATED,
     STARTING,
     PLAYING,
     SEEKING,
@@ -169,7 +169,7 @@
   bool is_static_ = true;
 
   // Tracks the current state of |pipeline_|.
-  State state_ = State::STOPPED;
+  State state_ = State::CREATED;
 
   // Indicates that a seek has occurred. When set, a seeked callback will be
   // issued at the next stable state.
diff --git a/mojo/public/cpp/bindings/BUILD.gn b/mojo/public/cpp/bindings/BUILD.gn
index 067523a..3d5dccb6 100644
--- a/mojo/public/cpp/bindings/BUILD.gn
+++ b/mojo/public/cpp/bindings/BUILD.gn
@@ -22,7 +22,7 @@
     "$interfaces_bindings_gen_dir/pipe_control_messages.mojom.cc",
     "$interfaces_bindings_gen_dir/pipe_control_messages.mojom.h",
     "array_data_view.h",
-    "array_traits_carray.h",
+    "array_traits_span.h",
     "array_traits_stl.h",
     "associated_binding.h",
     "associated_binding_set.h",
diff --git a/mojo/public/cpp/bindings/array_traits_carray.h b/mojo/public/cpp/bindings/array_traits_carray.h
deleted file mode 100644
index e4458ec..0000000
--- a/mojo/public/cpp/bindings/array_traits_carray.h
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef MOJO_PUBLIC_CPP_BINDINGS_ARRAY_TRAITS_CARRAY_H_
-#define MOJO_PUBLIC_CPP_BINDINGS_ARRAY_TRAITS_CARRAY_H_
-
-#include <cstddef>
-
-#include "mojo/public/cpp/bindings/array_traits.h"
-
-namespace mojo {
-
-template <typename T>
-class CArray {
- public:
-  constexpr CArray() noexcept : size_(0), data_(nullptr) {}
-  constexpr CArray(T* data, size_t size) noexcept : size_(size), data_(data) {}
-  template <size_t N>
-  constexpr CArray(T (&array)[N]) noexcept : size_(N), data_(array) {}
-
-  constexpr size_t size() const noexcept { return size_; }
-  constexpr T* data() const noexcept { return data_; }
-
-  constexpr CArray subspan(size_t pos, size_t count) const {
-    // Note: ideally this would DCHECK, but it requires fairly horrible
-    // contortions.
-    return CArray(data_ + pos, count);
-  }
-
- private:
-  size_t size_;
-  T* data_;
-};
-
-// TODO(dcheng): Not sure if this is needed. Maybe code should just use
-// CArray<const T> rather than ConstCArray<T>?
-template <typename T>
-class ConstCArray {
- public:
-  constexpr ConstCArray() noexcept : size_(0), data_(nullptr) {}
-  constexpr ConstCArray(const T* data, size_t size) noexcept
-      : size_(size), data_(data) {}
-  template <size_t N>
-  constexpr ConstCArray(const T (&array)[N]) noexcept
-      : size_(N), data_(array) {}
-
-  constexpr size_t size() const noexcept { return size_; }
-  constexpr const T* data() const noexcept { return data_; }
-
-  constexpr ConstCArray subspan(size_t pos, size_t count) const {
-    // Note: ideally this would DCHECK, but it requires fairly horrible
-    // contortions.
-    return ConstCArray(data_ + pos, count);
-  }
-
- private:
-  size_t size_;
-  const T* data_;
-};
-
-template <typename T>
-struct ArrayTraits<CArray<T>> {
-  using Element = T;
-
-  static bool IsNull(const CArray<T>& input) { return !input.data(); }
-
-  static void SetToNull(CArray<T>* output) { *output = CArray<T>(); }
-
-  static size_t GetSize(const CArray<T>& input) { return input.size(); }
-
-  static T* GetData(CArray<T>& input) { return input.data(); }
-
-  static const T* GetData(const CArray<T>& input) { return input.data(); }
-
-  static T& GetAt(CArray<T>& input, size_t index) {
-    return input.data()[index];
-  }
-
-  static const T& GetAt(const CArray<T>& input, size_t index) {
-    return input.data()[index];
-  }
-
-  static bool Resize(CArray<T>& input, size_t size) {
-    if (size > input.size())
-      return false;
-    input = input.subspan(0, size);
-    return true;
-  }
-};
-
-template <typename T>
-struct ArrayTraits<ConstCArray<T>> {
-  using Element = T;
-
-  static bool IsNull(const ConstCArray<T>& input) { return !input.data(); }
-
-  static void SetToNull(ConstCArray<T>* output) { *output = ConstCArray<T>(); }
-
-  static size_t GetSize(const ConstCArray<T>& input) { return input.size(); }
-
-  static const T* GetData(const ConstCArray<T>& input) { return input.data(); }
-
-  static const T& GetAt(const ConstCArray<T>& input, size_t index) {
-    return input.data()[index];
-  }
-};
-
-}  // namespace mojo
-
-#endif  // MOJO_PUBLIC_CPP_BINDINGS_ARRAY_TRAITS_CARRAY_H_
diff --git a/mojo/public/cpp/bindings/array_traits_span.h b/mojo/public/cpp/bindings/array_traits_span.h
new file mode 100644
index 0000000..dca82da5
--- /dev/null
+++ b/mojo/public/cpp/bindings/array_traits_span.h
@@ -0,0 +1,54 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_ARRAY_TRAITS_CARRAY_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_ARRAY_TRAITS_CARRAY_H_
+
+#include <cstddef>
+
+#include "base/containers/span.h"
+#include "mojo/public/cpp/bindings/array_traits.h"
+
+namespace mojo {
+
+// TODO(dcheng): Remove these type aliases.
+template <typename T>
+using CArray = base::Span<T>;
+
+template <typename T>
+using ConstCArray = base::Span<const T>;
+
+template <typename T>
+struct ArrayTraits<base::Span<T>> {
+  using Element = T;
+
+  static bool IsNull(const base::Span<T>& input) { return !input.data(); }
+
+  static void SetToNull(base::Span<T>* output) { *output = base::Span<T>(); }
+
+  static size_t GetSize(const base::Span<T>& input) { return input.size(); }
+
+  static T* GetData(base::Span<T>& input) { return input.data(); }
+
+  static const T* GetData(const base::Span<T>& input) { return input.data(); }
+
+  static T& GetAt(base::Span<T>& input, size_t index) {
+    return input.data()[index];
+  }
+
+  static const T& GetAt(const base::Span<T>& input, size_t index) {
+    return input.data()[index];
+  }
+
+  static bool Resize(base::Span<T>& input, size_t size) {
+    if (size > input.size())
+      return false;
+    input = input.subspan(0, size);
+    return true;
+  }
+};
+
+}  // namespace mojo
+
+#endif  // MOJO_PUBLIC_CPP_BINDINGS_ARRAY_TRAITS_CARRAY_H_
diff --git a/mojo/public/cpp/bindings/lib/array_serialization.h b/mojo/public/cpp/bindings/lib/array_serialization.h
index fcb6e1b5..8323b5f 100644
--- a/mojo/public/cpp/bindings/lib/array_serialization.h
+++ b/mojo/public/cpp/bindings/lib/array_serialization.h
@@ -116,8 +116,11 @@
 
   static_assert(std::is_same<Element, DataElement>::value,
                 "Incorrect array serializer");
-  static_assert(std::is_same<Element, typename Traits::Element>::value,
-                "Incorrect array serializer");
+  static_assert(
+      std::is_same<
+          Element,
+          typename std::remove_const<typename Traits::Element>::type>::value,
+      "Incorrect array serializer");
 
   static void SerializeElements(UserTypeIterator* input,
                                 Buffer* buf,
diff --git a/mojo/public/cpp/bindings/lib/serialization.h b/mojo/public/cpp/bindings/lib/serialization.h
index 8572f132..f5e89e2 100644
--- a/mojo/public/cpp/bindings/lib/serialization.h
+++ b/mojo/public/cpp/bindings/lib/serialization.h
@@ -8,7 +8,7 @@
 #include <string.h>
 
 #include "base/numerics/safe_math.h"
-#include "mojo/public/cpp/bindings/array_traits_carray.h"
+#include "mojo/public/cpp/bindings/array_traits_span.h"
 #include "mojo/public/cpp/bindings/array_traits_stl.h"
 #include "mojo/public/cpp/bindings/lib/array_serialization.h"
 #include "mojo/public/cpp/bindings/lib/buffer.h"
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index 7f2de04..27a41f4 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -13652,7 +13652,7 @@
             {
               "gpu": "8086:0d26",
               "hidpi": "1",
-              "os": "Mac-10.11.6"
+              "os": "Mac-10.12.5"
             },
             {
               "gpu": "none",
@@ -13668,6 +13668,7 @@
             },
             {
               "gpu": "8086:0a2e",
+              "hidpi": 0,
               "os": "Mac-10.12.5"
             }
           ],
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 1d28bc8..38a269d 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -1740,7 +1740,7 @@
 crbug.com/626703 virtual/threaded/transitions/transition-end-event-multiple-03.html [ Pass Failure ]
 
 # ====== New tests from wpt-importer added here ======
-crbug.com/626703 external/wpt/beacon/headers/header-content-type.html [ Failure ]
+crbug.com/626703 external/wpt/beacon/headers/header-content-type.html [ Pass Failure Timeout ]
 crbug.com/626703 [ Win ] external/wpt/css/css-ui-3/outline-004.html [ Failure ]
 crbug.com/626703 [ Win ] external/wpt/css/css-ui-3/text-overflow-001.html [ Pass Failure ]
 crbug.com/626703 [ Win ] external/wpt/css/css-ui-3/text-overflow-002.html [ Pass Failure ]
diff --git a/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp b/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp
index 1b09ade..49df87e 100644
--- a/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp
+++ b/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp
@@ -41,16 +41,13 @@
 }
 
 ContentSecurityPolicyHashAlgorithm ConvertHashAlgorithmToCSPHashAlgorithm(
-    HashAlgorithm algorithm) {
+    IntegrityAlgorithm algorithm) {
   switch (algorithm) {
-    case kHashAlgorithmSha1:
-      // Sha1 is not supported.
-      return kContentSecurityPolicyHashAlgorithmNone;
-    case kHashAlgorithmSha256:
+    case IntegrityAlgorithm::kSha256:
       return kContentSecurityPolicyHashAlgorithmSha256;
-    case kHashAlgorithmSha384:
+    case IntegrityAlgorithm::kSha384:
       return kContentSecurityPolicyHashAlgorithmSha384;
-    case kHashAlgorithmSha512:
+    case IntegrityAlgorithm::kSha512:
       return kContentSecurityPolicyHashAlgorithmSha512;
   }
   NOTREACHED();
@@ -214,7 +211,7 @@
     const IntegrityMetadataSet& hashes) const {
   if (!directive || hashes.IsEmpty())
     return false;
-  for (const std::pair<WTF::String, HashAlgorithm>& hash : hashes) {
+  for (const std::pair<String, IntegrityAlgorithm>& hash : hashes) {
     // Convert the hash from integrity metadata format to CSP format.
     CSPHashValue csp_hash;
     csp_hash.first = ConvertHashAlgorithmToCSPHashAlgorithm(hash.second);
diff --git a/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicyTest.cpp b/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicyTest.cpp
index fc2898f..dc8ce5e 100644
--- a/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicyTest.cpp
+++ b/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicyTest.cpp
@@ -398,7 +398,7 @@
   KURL url(NullURL(), "https://example.test");
   IntegrityMetadataSet integrity_metadata;
   integrity_metadata.insert(
-      IntegrityMetadata("1234", kHashAlgorithmSha384).ToPair());
+      IntegrityMetadata("1234", IntegrityAlgorithm::kSha384).ToPair());
   csp->BindToExecutionContext(execution_context.Get());
   // Enforce
   Persistent<ContentSecurityPolicy> policy = ContentSecurityPolicy::Create();
@@ -570,7 +570,7 @@
   KURL url(NullURL(), "https://example.test");
   IntegrityMetadataSet integrity_metadata;
   integrity_metadata.insert(
-      IntegrityMetadata("1234", kHashAlgorithmSha384).ToPair());
+      IntegrityMetadata("1234", IntegrityAlgorithm::kSha384).ToPair());
   csp->BindToExecutionContext(execution_context.Get());
   // Enforce
   Persistent<ContentSecurityPolicy> policy = ContentSecurityPolicy::Create();
diff --git a/third_party/WebKit/Source/devtools/front_end/color_picker/Contrast.js b/third_party/WebKit/Source/devtools/front_end/color_picker/Contrast.js
index ea0e71cb..ce9ee17 100644
--- a/third_party/WebKit/Source/devtools/front_end/color_picker/Contrast.js
+++ b/third_party/WebKit/Source/devtools/front_end/color_picker/Contrast.js
@@ -186,11 +186,22 @@
     this._contrastValueBubble.title = Common.UIString('Click to toggle contrast ratio details');
     this._contrastValueBubble.addEventListener('mousedown', this._toggleContrastDetails.bind(this), true);
 
+    /** @type {!AnchorBox} */
+    this._contrastValueBubbleBoxInWindow = new AnchorBox(0, 0, 0, 0);
+
     this._contrastDetails = new ColorPicker.ContrastDetails(
         this._contrastInfo, contentElement, toggleMainColorPickerCallback, this._update.bind(this));
 
     this._width = 0;
     this._height = 0;
+
+    this._contrastRatioLineThrottler = new Common.Throttler(0);
+    this._drawContrastRatioLineBound = this._drawContrastRatioLine.bind(this);
+
+    /** @type {?number} */
+    this._hueForCurrentLine = null;
+    /** @type {?number} */
+    this._alphaForCurrentLine = null;
   }
 
   /**
@@ -215,10 +226,10 @@
    * @param {number} y
    */
   moveAwayFrom(x, y) {
-    var bubble = this._contrastValueBubble;
-    if (!bubble.boxInWindow().contains(x, y))
+    if (!this._contrastValueBubbleBoxInWindow.contains(x, y))
       return;
 
+    var bubble = this._contrastValueBubble;
     if (bubble.offsetWidth > ((bubble.offsetParent.offsetWidth / 2) - 10))
       bubble.classList.toggle('contrast-info-top');
     else
@@ -230,13 +241,13 @@
       return;
 
     this._contrastValue.textContent = this._contrastInfo.contrastRatio().toFixed(2);
+    this._contrastValueBubbleBoxInWindow = this._contrastValueBubble.boxInWindow();
 
     var AA = this._contrastInfo.contrastRatioThreshold('AA');
     if (!AA)
       return;
 
-    // TODO(aboxhall): only redraw line if hue value changes
-    this._drawContrastRatioLine(AA, this._width, this._height);
+    this._contrastRatioLineThrottler.schedule(this._drawContrastRatioLineBound);
 
     var passesAA = this._contrastInfo.contrastRatio() >= AA;
     this._contrastValueBubble.classList.toggle('contrast-fail', !passesAA);
@@ -247,9 +258,10 @@
   /**
    * @param {number} width
    * @param {number} height
-   * @param {!AnchorBox} draggerBox
+   * @param {number} dragX
+   * @param {number} dragY
    */
-  show(width, height, draggerBox) {
+  show(width, height, dragX, dragY) {
     if (this._contrastInfo.contrastRatio() === null) {
       this.hide();
       return;
@@ -260,9 +272,6 @@
     this._update();
 
     this._contrastValueBubble.classList.remove('hidden');
-
-    var dragX = draggerBox.x + (draggerBox.width / 2);
-    var dragY = draggerBox.y + (draggerBox.height / 2);
     this.moveAwayFrom(dragX, dragY);
   }
 
@@ -281,19 +290,14 @@
   }
 
   /**
-   * @param {number} requiredContrast
-   * @param {number} width
-   * @param {number} height
+   * @return {!Promise}
    */
-  _drawContrastRatioLine(requiredContrast, width, height) {
-    // TODO(aboxhall): throttle this to avoid being called in rapid succession when using eyedropper
-    if (!width || !height)
-      return;
-
-    var hsva = this._contrastInfo.hsva();
-    var bgColor = this._contrastInfo.bgColor();
-    if (!hsva || !bgColor)
-      return;
+  _drawContrastRatioLine() {
+    var width = this._width;
+    var height = this._height;
+    var requiredContrast = this._contrastInfo.contrastRatioThreshold('AA');
+    if (!width || !height || !requiredContrast)
+      return Promise.resolve();
 
     const dS = 0.02;
     const epsilon = 0.002;
@@ -302,6 +306,13 @@
     const V = 2;
     const A = 3;
 
+    var hsva = this._contrastInfo.hsva();
+    var bgColor = this._contrastInfo.bgColor();
+    if (!hsva || !bgColor)
+      return Promise.resolve();
+    if (hsva[H] === this._hueForCurrentLine && hsva[A] === this._alphaForCurrentLine)
+      return Promise.resolve();
+
     var fgRGBA = [];
     Common.Color.hsva2rgba(hsva, fgRGBA);
     var bgRGBA = bgColor.rgba();
@@ -339,8 +350,8 @@
 
         if (Math.abs(dLuminance) < (onAxis ? epsilon / 10 : epsilon))
           return x;
-        else
-          x += (index === V ? -dLuminance : dLuminance);
+
+        x += (index === V ? -dLuminance : dLuminance);
       }
       return null;
     }
@@ -372,6 +383,10 @@
     }
 
     this._contrastRatioLine.setAttribute('d', pathBuilder.join(' '));
+    this._hueForCurrentLine = hsva[H];
+    this._alphaForCurrentLine = hsva[A];
+
+    return Promise.resolve();
   }
 };
 
diff --git a/third_party/WebKit/Source/devtools/front_end/color_picker/Spectrum.js b/third_party/WebKit/Source/devtools/front_end/color_picker/Spectrum.js
index 78493e7..d3f66ef 100644
--- a/third_party/WebKit/Source/devtools/front_end/color_picker/Spectrum.js
+++ b/third_party/WebKit/Source/devtools/front_end/color_picker/Spectrum.js
@@ -52,6 +52,8 @@
     this._colorDragElement = this._colorElement.createChild('div', 'spectrum-sat fill')
                                  .createChild('div', 'spectrum-val fill')
                                  .createChild('div', 'spectrum-dragger');
+    this._dragX = 0;
+    this._dragY = 0;
 
     if (Runtime.experiments.isEnabled('colorContrastRatio')) {
       var boundToggleColorPicker = this._toggleColorPicker.bind(this);
@@ -649,15 +651,15 @@
     var alpha = this._hsv[3];
 
     // Where to show the little circle that displays your current selected color.
-    var dragX = s * this.dragWidth;
-    var dragY = this.dragHeight - (v * this.dragHeight);
+    this._dragX = s * this.dragWidth;
+    this._dragY = this.dragHeight - (v * this.dragHeight);
 
-    dragX = Math.max(
+    var dragX = Math.max(
         -this._colorDragElementHeight,
-        Math.min(this.dragWidth - this._colorDragElementHeight, dragX - this._colorDragElementHeight));
-    dragY = Math.max(
+        Math.min(this.dragWidth - this._colorDragElementHeight, this._dragX - this._colorDragElementHeight));
+    var dragY = Math.max(
         -this._colorDragElementHeight,
-        Math.min(this.dragHeight - this._colorDragElementHeight, dragY - this._colorDragElementHeight));
+        Math.min(this.dragHeight - this._colorDragElementHeight, this._dragY - this._colorDragElementHeight));
 
     this._colorDragElement.positionAt(dragX, dragY);
 
@@ -699,7 +701,7 @@
     this._colorElement.style.backgroundColor = /** @type {string} */ (h.asString(Common.Color.Format.RGB));
     if (this._contrastOverlay) {
       if (this.dragWidth)
-        this._contrastOverlay.show(this.dragWidth, this.dragHeight, this._colorDragElement.boxInWindow());
+        this._contrastOverlay.show(this.dragWidth, this.dragHeight, this._dragX, this._dragY);
       else
         this._contrastOverlay.hide();
     }
diff --git a/third_party/WebKit/Source/platform/bindings/TraceWrapperReference.md b/third_party/WebKit/Source/platform/bindings/TraceWrapperReference.md
index 5e0bfc6..e292bb3 100644
--- a/third_party/WebKit/Source/platform/bindings/TraceWrapperReference.md
+++ b/third_party/WebKit/Source/platform/bindings/TraceWrapperReference.md
@@ -148,7 +148,6 @@
 ```c++
 class SomeDOMObject : public ScriptWrappable {
  public:
-  SomeDOMObject() : other_wrappable_(this, nullptr) {}
   DECLARE_VIRTUAL_TRACE_WRAPPERS();
 
  private:
@@ -188,59 +187,36 @@
 ```
 
 Note that this is different to Oilpan which can just trace the whole collection.
-Whenever an element is added through ``append()`` the value needs to be
-constructed using ``TraceWrapperMember``, e.g.
+``TraceWrapperMember`` can be constructed in place, so  using ``append`` and
+friends will work out of the box, e.g.
 
 ```c++
 void SomeDOMObject::AppendNewValue(OtherWrappable* newValue) {
-  other_wrappables_.append(TraceWrapperMember(this, newValue));
+  other_wrappables_.append(newValue);
 }
 ```
 
-The compiler will throw an error for each ommitted ``TraceWrapperMember``
+The compiler will throw an error for each omitted ``TraceWrapperMember``
 construction.
 
-### Corner-case: Pre-sized containers
+### Swapping ``HeapVector`` containing ``TraceWrapperMember`` and ``Member``
 
-Containers know how to construct an empty ``TraceWrapperMember`` slot. This
-allows simple creation of containers at the cost of loosing the compile-time
-check for assigning a raw value.
+It is possible to swap two ``HeapVectors`` containing ``TraceWrapperMember`` and
+``Member`` by using ``blink::swap``. The underlying swap will avoid copies and
+write barriers if possible.
 
 ```c++
-class SomeDOMObject : public ScriptWrappable {
- public:
-  SomeDOMObject() {
-    other_wrappables_.resize(5);
-  }
+// Swap two wrapper traced heap vectors.
+HeapVector<TraceWrapperMember<Wrappable>> a;
+HeapVector<TraceWrapperMember<Wrappable>> b;
+blink::swap(a, b);
 
-  void writeAt(int i, OtherWrappable* other) {
-    other_wrappables_[i] = other;
-  }
-
-  DECLARE_VIRTUAL_TRACE_WRAPPERS();
- private:
-  HeapVector<TraceWrapperMember<OtherWrappable>> other_wrappables_;
-};
-
-DEFINE_TRACE_WRAPPERS(SomeDOMObject) {
-  for (auto other : other_wrappables_)
-    visitor->TraceWrappers(other);
-}
+// Swap in a non-traced heap vector into a wrapper traced one.
+HeapVector<TraceWrapperMember<Wrappable>> c;
+HeapVector<Member<Wrappable>> temporary;
+blink::swap(c, temporary);
 ```
 
-In this example, the compiler will not warn you on
-``other_wrappables_[i] = other``, but an assertion will throw at runtime as long
-as there exists a test covering that branch.
-
-The correct assignment looks like
-
-```c++
-other_wrappables_[i] = TraceWrapperMember<OtherWrappable>(this, other);
-```
-
-Note that the assertion that triggers when the annotation is not present does
-not require wrapper tracing to be enabled.
-
 ## Tracing through non-``ScriptWrappable`` types
 
 Sometimes it is necessary to trace through types that do not inherit from
@@ -261,17 +237,15 @@
 ## Explicit write barriers
 
 Sometimes it is necessary to stick with the regular types and issue the write
-barriers explicitly. For example, if memory footprint is really important and
-it's not possible to use ``TraceWrapperMember`` which adds another pointer
-field. In this case, tracing needs to be adjusted to tell the system that all
-barriers will be done manually.
+barriers explicitly. In this case, tracing needs to be adjusted to tell the
+system that all barriers will be done manually.
 
 ```c++
 class ManualWrappable : public ScriptWrappable {
  public:
   void setNew(OtherWrappable* newValue) {
     other_wrappable_ = newValue;
-    SriptWrappableVisitor::WriteBarrier(this, other_wrappable_);
+    SriptWrappableVisitor::WriteBarrier(other_wrappable_);
   }
 
   DECLARE_VIRTUAL_TRACE_WRAPPERS();
diff --git a/third_party/WebKit/Source/platform/loader/SubresourceIntegrity.cpp b/third_party/WebKit/Source/platform/loader/SubresourceIntegrity.cpp
index e9d3b40..f705c0bf 100644
--- a/third_party/WebKit/Source/platform/loader/SubresourceIntegrity.cpp
+++ b/third_party/WebKit/Source/platform/loader/SubresourceIntegrity.cpp
@@ -65,29 +65,26 @@
   console_error_messages_.clear();
 }
 
-HashAlgorithm SubresourceIntegrity::GetPrioritizedHashFunction(
-    HashAlgorithm algorithm1,
-    HashAlgorithm algorithm2) {
-  const HashAlgorithm kWeakerThanSha384[] = {kHashAlgorithmSha256};
-  const HashAlgorithm kWeakerThanSha512[] = {kHashAlgorithmSha256,
-                                             kHashAlgorithmSha384};
-
-  DCHECK_NE(algorithm1, kHashAlgorithmSha1);
-  DCHECK_NE(algorithm2, kHashAlgorithmSha1);
+IntegrityAlgorithm SubresourceIntegrity::GetPrioritizedHashFunction(
+    IntegrityAlgorithm algorithm1,
+    IntegrityAlgorithm algorithm2) {
+  const IntegrityAlgorithm kWeakerThanSha384[] = {IntegrityAlgorithm::kSha256};
+  const IntegrityAlgorithm kWeakerThanSha512[] = {IntegrityAlgorithm::kSha256,
+                                                  IntegrityAlgorithm::kSha384};
 
   if (algorithm1 == algorithm2)
     return algorithm1;
 
-  const HashAlgorithm* weaker_algorithms = 0;
+  const IntegrityAlgorithm* weaker_algorithms = 0;
   size_t length = 0;
   switch (algorithm1) {
-    case kHashAlgorithmSha256:
+    case IntegrityAlgorithm::kSha256:
       break;
-    case kHashAlgorithmSha384:
+    case IntegrityAlgorithm::kSha384:
       weaker_algorithms = kWeakerThanSha384;
       length = WTF_ARRAY_LENGTH(kWeakerThanSha384);
       break;
-    case kHashAlgorithmSha512:
+    case IntegrityAlgorithm::kSha512:
       weaker_algorithms = kWeakerThanSha512;
       length = WTF_ARRAY_LENGTH(kWeakerThanSha512);
       break;
@@ -171,7 +168,7 @@
   if (!metadata_set.size())
     return true;
 
-  HashAlgorithm strongest_algorithm = kHashAlgorithmSha256;
+  IntegrityAlgorithm strongest_algorithm = IntegrityAlgorithm::kSha256;
   for (const IntegrityMetadata& metadata : metadata_set) {
     strongest_algorithm =
         GetPrioritizedHashFunction(metadata.Algorithm(), strongest_algorithm);
@@ -182,9 +179,20 @@
     if (metadata.Algorithm() != strongest_algorithm)
       continue;
 
+    blink::HashAlgorithm hash_algo = kHashAlgorithmSha256;
+    switch (metadata.Algorithm()) {
+      case IntegrityAlgorithm::kSha256:
+        hash_algo = kHashAlgorithmSha256;
+        break;
+      case IntegrityAlgorithm::kSha384:
+        hash_algo = kHashAlgorithmSha384;
+        break;
+      case IntegrityAlgorithm::kSha512:
+        hash_algo = kHashAlgorithmSha512;
+        break;
+    }
     digest.clear();
-    bool digest_success =
-        ComputeDigest(metadata.Algorithm(), content, size, digest);
+    bool digest_success = ComputeDigest(hash_algo, content, size, digest);
 
     if (digest_success) {
       Vector<char> hash_vector;
@@ -237,17 +245,19 @@
 SubresourceIntegrity::AlgorithmParseResult SubresourceIntegrity::ParseAlgorithm(
     const UChar*& position,
     const UChar* end,
-    HashAlgorithm& algorithm) {
+    IntegrityAlgorithm& algorithm) {
   // Any additions or subtractions from this struct should also modify the
   // respective entries in the kAlgorithmMap array in checkDigest() as well
   // as the array in algorithmToString().
   static const struct {
     const char* prefix;
-    HashAlgorithm algorithm;
-  } kSupportedPrefixes[] = {
-      {"sha256", kHashAlgorithmSha256}, {"sha-256", kHashAlgorithmSha256},
-      {"sha384", kHashAlgorithmSha384}, {"sha-384", kHashAlgorithmSha384},
-      {"sha512", kHashAlgorithmSha512}, {"sha-512", kHashAlgorithmSha512}};
+    IntegrityAlgorithm algorithm;
+  } kSupportedPrefixes[] = {{"sha256", IntegrityAlgorithm::kSha256},
+                            {"sha-256", IntegrityAlgorithm::kSha256},
+                            {"sha384", IntegrityAlgorithm::kSha384},
+                            {"sha-384", IntegrityAlgorithm::kSha384},
+                            {"sha512", IntegrityAlgorithm::kSha512},
+                            {"sha-512", IntegrityAlgorithm::kSha512}};
 
   const UChar* begin = position;
 
@@ -327,7 +337,7 @@
   // in order.
   while (position < end) {
     WTF::String digest;
-    HashAlgorithm algorithm;
+    IntegrityAlgorithm algorithm;
 
     SkipWhile<UChar, IsASCIISpace>(position, end);
     current_integrity_end = position;
diff --git a/third_party/WebKit/Source/platform/loader/SubresourceIntegrity.h b/third_party/WebKit/Source/platform/loader/SubresourceIntegrity.h
index 11bb2d02e..32f890f 100644
--- a/third_party/WebKit/Source/platform/loader/SubresourceIntegrity.h
+++ b/third_party/WebKit/Source/platform/loader/SubresourceIntegrity.h
@@ -6,7 +6,6 @@
 #define SubresourceIntegrity_h
 
 #include "base/gtest_prod_util.h"
-#include "platform/Crypto.h"
 #include "platform/PlatformExport.h"
 #include "platform/loader/fetch/IntegrityMetadata.h"
 #include "platform/wtf/Allocator.h"
@@ -98,10 +97,11 @@
     kAlgorithmUnknown
   };
 
-  static HashAlgorithm GetPrioritizedHashFunction(HashAlgorithm, HashAlgorithm);
+  static IntegrityAlgorithm GetPrioritizedHashFunction(IntegrityAlgorithm,
+                                                       IntegrityAlgorithm);
   static AlgorithmParseResult ParseAlgorithm(const UChar*& begin,
                                              const UChar* end,
-                                             HashAlgorithm&);
+                                             IntegrityAlgorithm&);
   static bool ParseDigest(const UChar*& begin,
                           const UChar* end,
                           String& digest);
diff --git a/third_party/WebKit/Source/platform/loader/SubresourceIntegrityTest.cpp b/third_party/WebKit/Source/platform/loader/SubresourceIntegrityTest.cpp
index 030c3e7..4f545e8 100644
--- a/third_party/WebKit/Source/platform/loader/SubresourceIntegrityTest.cpp
+++ b/third_party/WebKit/Source/platform/loader/SubresourceIntegrityTest.cpp
@@ -89,12 +89,13 @@
         MockFetchContext::Create(MockFetchContext::kShouldLoadNewResource);
   }
 
-  void ExpectAlgorithm(const String& text, HashAlgorithm expected_algorithm) {
+  void ExpectAlgorithm(const String& text,
+                       IntegrityAlgorithm expected_algorithm) {
     Vector<UChar> characters;
     text.AppendTo(characters);
     const UChar* position = characters.data();
     const UChar* end = characters.end();
-    HashAlgorithm algorithm;
+    IntegrityAlgorithm algorithm;
 
     EXPECT_EQ(SubresourceIntegrity::kAlgorithmValid,
               SubresourceIntegrity::ParseAlgorithm(position, end, algorithm));
@@ -110,7 +111,7 @@
     const UChar* position = characters.data();
     const UChar* begin = characters.data();
     const UChar* end = characters.end();
-    HashAlgorithm algorithm;
+    IntegrityAlgorithm algorithm;
 
     EXPECT_EQ(expected_result,
               SubresourceIntegrity::ParseAlgorithm(position, end, algorithm));
@@ -141,7 +142,7 @@
 
   void ExpectParse(const char* integrity_attribute,
                    const char* expected_digest,
-                   HashAlgorithm expected_algorithm) {
+                   IntegrityAlgorithm expected_algorithm) {
     IntegrityMetadataSet metadata_set;
 
     EXPECT_EQ(SubresourceIntegrity::kIntegrityParseValidResult,
@@ -281,44 +282,44 @@
 };
 
 TEST_F(SubresourceIntegrityTest, Prioritization) {
-  EXPECT_EQ(kHashAlgorithmSha256,
+  EXPECT_EQ(IntegrityAlgorithm::kSha256,
             SubresourceIntegrity::GetPrioritizedHashFunction(
-                kHashAlgorithmSha256, kHashAlgorithmSha256));
-  EXPECT_EQ(kHashAlgorithmSha384,
+                IntegrityAlgorithm::kSha256, IntegrityAlgorithm::kSha256));
+  EXPECT_EQ(IntegrityAlgorithm::kSha384,
             SubresourceIntegrity::GetPrioritizedHashFunction(
-                kHashAlgorithmSha384, kHashAlgorithmSha384));
-  EXPECT_EQ(kHashAlgorithmSha512,
+                IntegrityAlgorithm::kSha384, IntegrityAlgorithm::kSha384));
+  EXPECT_EQ(IntegrityAlgorithm::kSha512,
             SubresourceIntegrity::GetPrioritizedHashFunction(
-                kHashAlgorithmSha512, kHashAlgorithmSha512));
+                IntegrityAlgorithm::kSha512, IntegrityAlgorithm::kSha512));
 
-  EXPECT_EQ(kHashAlgorithmSha384,
+  EXPECT_EQ(IntegrityAlgorithm::kSha384,
             SubresourceIntegrity::GetPrioritizedHashFunction(
-                kHashAlgorithmSha384, kHashAlgorithmSha256));
-  EXPECT_EQ(kHashAlgorithmSha512,
+                IntegrityAlgorithm::kSha384, IntegrityAlgorithm::kSha256));
+  EXPECT_EQ(IntegrityAlgorithm::kSha512,
             SubresourceIntegrity::GetPrioritizedHashFunction(
-                kHashAlgorithmSha512, kHashAlgorithmSha256));
-  EXPECT_EQ(kHashAlgorithmSha512,
+                IntegrityAlgorithm::kSha512, IntegrityAlgorithm::kSha256));
+  EXPECT_EQ(IntegrityAlgorithm::kSha512,
             SubresourceIntegrity::GetPrioritizedHashFunction(
-                kHashAlgorithmSha512, kHashAlgorithmSha384));
+                IntegrityAlgorithm::kSha512, IntegrityAlgorithm::kSha384));
 
-  EXPECT_EQ(kHashAlgorithmSha384,
+  EXPECT_EQ(IntegrityAlgorithm::kSha384,
             SubresourceIntegrity::GetPrioritizedHashFunction(
-                kHashAlgorithmSha256, kHashAlgorithmSha384));
-  EXPECT_EQ(kHashAlgorithmSha512,
+                IntegrityAlgorithm::kSha256, IntegrityAlgorithm::kSha384));
+  EXPECT_EQ(IntegrityAlgorithm::kSha512,
             SubresourceIntegrity::GetPrioritizedHashFunction(
-                kHashAlgorithmSha256, kHashAlgorithmSha512));
-  EXPECT_EQ(kHashAlgorithmSha512,
+                IntegrityAlgorithm::kSha256, IntegrityAlgorithm::kSha512));
+  EXPECT_EQ(IntegrityAlgorithm::kSha512,
             SubresourceIntegrity::GetPrioritizedHashFunction(
-                kHashAlgorithmSha384, kHashAlgorithmSha512));
+                IntegrityAlgorithm::kSha384, IntegrityAlgorithm::kSha512));
 }
 
 TEST_F(SubresourceIntegrityTest, ParseAlgorithm) {
-  ExpectAlgorithm("sha256-", kHashAlgorithmSha256);
-  ExpectAlgorithm("sha384-", kHashAlgorithmSha384);
-  ExpectAlgorithm("sha512-", kHashAlgorithmSha512);
-  ExpectAlgorithm("sha-256-", kHashAlgorithmSha256);
-  ExpectAlgorithm("sha-384-", kHashAlgorithmSha384);
-  ExpectAlgorithm("sha-512-", kHashAlgorithmSha512);
+  ExpectAlgorithm("sha256-", IntegrityAlgorithm::kSha256);
+  ExpectAlgorithm("sha384-", IntegrityAlgorithm::kSha384);
+  ExpectAlgorithm("sha512-", IntegrityAlgorithm::kSha512);
+  ExpectAlgorithm("sha-256-", IntegrityAlgorithm::kSha256);
+  ExpectAlgorithm("sha-384-", IntegrityAlgorithm::kSha384);
+  ExpectAlgorithm("sha-512-", IntegrityAlgorithm::kSha512);
 
   ExpectAlgorithmFailure("sha1-", SubresourceIntegrity::kAlgorithmUnknown);
   ExpectAlgorithmFailure("sha-1-", SubresourceIntegrity::kAlgorithmUnknown);
@@ -357,70 +358,70 @@
   ExpectEmptyParseResult("ni:///sha256-abcdefg");
   ExpectEmptyParseResult("notsha256atall-abcdefg");
 
-  ExpectParse(
-      "sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=",
-      "BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=", kHashAlgorithmSha256);
+  ExpectParse("sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=",
+              "BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=",
+              IntegrityAlgorithm::kSha256);
 
-  ExpectParse(
-      "sha-256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=",
-      "BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=", kHashAlgorithmSha256);
+  ExpectParse("sha-256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=",
+              "BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=",
+              IntegrityAlgorithm::kSha256);
 
-  ExpectParse(
-      "     sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=     ",
-      "BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=", kHashAlgorithmSha256);
+  ExpectParse("     sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=     ",
+              "BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=",
+              IntegrityAlgorithm::kSha256);
 
   ExpectParse(
       "sha384-XVVXBGoYw6AJOh9J-Z8pBDMVVPfkBpngexkA7JqZu8d5GENND6TEIup_tA1v5GPr",
       "XVVXBGoYw6AJOh9J+Z8pBDMVVPfkBpngexkA7JqZu8d5GENND6TEIup/tA1v5GPr",
-      kHashAlgorithmSha384);
+      IntegrityAlgorithm::kSha384);
 
   ExpectParse(
       "sha-384-XVVXBGoYw6AJOh9J_Z8pBDMVVPfkBpngexkA7JqZu8d5GENND6TEIup_"
       "tA1v5GPr",
       "XVVXBGoYw6AJOh9J/Z8pBDMVVPfkBpngexkA7JqZu8d5GENND6TEIup/tA1v5GPr",
-      kHashAlgorithmSha384);
+      IntegrityAlgorithm::kSha384);
 
   ExpectParse(
       "sha512-tbUPioKbVBplr0b1ucnWB57SJWt4x9dOE0Vy2mzCXvH3FepqDZ-"
       "07yMK81ytlg0MPaIrPAjcHqba5csorDWtKg==",
       "tbUPioKbVBplr0b1ucnWB57SJWt4x9dOE0Vy2mzCXvH3FepqDZ+"
       "07yMK81ytlg0MPaIrPAjcHqba5csorDWtKg==",
-      kHashAlgorithmSha512);
+      IntegrityAlgorithm::kSha512);
 
   ExpectParse(
       "sha-512-tbUPioKbVBplr0b1ucnWB57SJWt4x9dOE0Vy2mzCXvH3FepqDZ-"
       "07yMK81ytlg0MPaIrPAjcHqba5csorDWtKg==",
       "tbUPioKbVBplr0b1ucnWB57SJWt4x9dOE0Vy2mzCXvH3FepqDZ+"
       "07yMK81ytlg0MPaIrPAjcHqba5csorDWtKg==",
-      kHashAlgorithmSha512);
+      IntegrityAlgorithm::kSha512);
 
   ExpectParse(
       "sha-512-tbUPioKbVBplr0b1ucnWB57SJWt4x9dOE0Vy2mzCXvH3FepqDZ-"
       "07yMK81ytlg0MPaIrPAjcHqba5csorDWtKg==?ct=application/javascript",
       "tbUPioKbVBplr0b1ucnWB57SJWt4x9dOE0Vy2mzCXvH3FepqDZ+"
       "07yMK81ytlg0MPaIrPAjcHqba5csorDWtKg==",
-      kHashAlgorithmSha512);
+      IntegrityAlgorithm::kSha512);
 
   ExpectParse(
       "sha-512-tbUPioKbVBplr0b1ucnWB57SJWt4x9dOE0Vy2mzCXvH3FepqDZ-"
       "07yMK81ytlg0MPaIrPAjcHqba5csorDWtKg==?ct=application/xhtml+xml",
       "tbUPioKbVBplr0b1ucnWB57SJWt4x9dOE0Vy2mzCXvH3FepqDZ+"
       "07yMK81ytlg0MPaIrPAjcHqba5csorDWtKg==",
-      kHashAlgorithmSha512);
+      IntegrityAlgorithm::kSha512);
 
   ExpectParse(
       "sha-512-tbUPioKbVBplr0b1ucnWB57SJWt4x9dOE0Vy2mzCXvH3FepqDZ-"
       "07yMK81ytlg0MPaIrPAjcHqba5csorDWtKg==?foo=bar?ct=application/xhtml+xml",
       "tbUPioKbVBplr0b1ucnWB57SJWt4x9dOE0Vy2mzCXvH3FepqDZ+"
       "07yMK81ytlg0MPaIrPAjcHqba5csorDWtKg==",
-      kHashAlgorithmSha512);
+      IntegrityAlgorithm::kSha512);
 
   ExpectParse(
       "sha-512-tbUPioKbVBplr0b1ucnWB57SJWt4x9dOE0Vy2mzCXvH3FepqDZ-"
       "07yMK81ytlg0MPaIrPAjcHqba5csorDWtKg==?ct=application/xhtml+xml?foo=bar",
       "tbUPioKbVBplr0b1ucnWB57SJWt4x9dOE0Vy2mzCXvH3FepqDZ+"
       "07yMK81ytlg0MPaIrPAjcHqba5csorDWtKg==",
-      kHashAlgorithmSha512);
+      IntegrityAlgorithm::kSha512);
 
   ExpectParse(
       "sha-512-tbUPioKbVBplr0b1ucnWB57SJWt4x9dOE0Vy2mzCXvH3FepqDZ-"
@@ -428,7 +429,7 @@
       "xhtml+xml?foo=bar",
       "tbUPioKbVBplr0b1ucnWB57SJWt4x9dOE0Vy2mzCXvH3FepqDZ+"
       "07yMK81ytlg0MPaIrPAjcHqba5csorDWtKg==",
-      kHashAlgorithmSha512);
+      IntegrityAlgorithm::kSha512);
 
   ExpectParseMultipleHashes("", 0, 0);
   ExpectParseMultipleHashes("    ", 0, 0);
@@ -436,10 +437,10 @@
   const IntegrityMetadata valid_sha384_and_sha512[] = {
       IntegrityMetadata(
           "XVVXBGoYw6AJOh9J+Z8pBDMVVPfkBpngexkA7JqZu8d5GENND6TEIup/tA1v5GPr",
-          kHashAlgorithmSha384),
+          IntegrityAlgorithm::kSha384),
       IntegrityMetadata("tbUPioKbVBplr0b1ucnWB57SJWt4x9dOE0Vy2mzCXvH3FepqDZ+"
                         "07yMK81ytlg0MPaIrPAjcHqba5csorDWtKg==",
-                        kHashAlgorithmSha512),
+                        IntegrityAlgorithm::kSha512),
   };
   ExpectParseMultipleHashes(
       "sha384-XVVXBGoYw6AJOh9J+Z8pBDMVVPfkBpngexkA7JqZu8d5GENND6TEIup/tA1v5GPr "
@@ -449,8 +450,8 @@
 
   const IntegrityMetadata valid_sha256_and_sha256[] = {
       IntegrityMetadata("BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=",
-                        kHashAlgorithmSha256),
-      IntegrityMetadata("deadbeef", kHashAlgorithmSha256),
+                        IntegrityAlgorithm::kSha256),
+      IntegrityMetadata("deadbeef", IntegrityAlgorithm::kSha256),
   };
   ExpectParseMultipleHashes(
       "sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE= sha256-deadbeef",
@@ -458,7 +459,7 @@
 
   const IntegrityMetadata valid_sha256_and_invalid_sha256[] = {
       IntegrityMetadata("BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=",
-                        kHashAlgorithmSha256),
+                        IntegrityAlgorithm::kSha256),
   };
   ExpectParseMultipleHashes(
       "sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE= sha256-!!!!",
@@ -467,46 +468,48 @@
 
   const IntegrityMetadata invalid_sha256_and_valid_sha256[] = {
       IntegrityMetadata("BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=",
-                        kHashAlgorithmSha256),
+                        IntegrityAlgorithm::kSha256),
   };
   ExpectParseMultipleHashes(
       "sha256-!!! sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=",
       invalid_sha256_and_valid_sha256,
       WTF_ARRAY_LENGTH(invalid_sha256_and_valid_sha256));
 
-  ExpectParse(
-      "sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=?foo=bar",
-      "BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=", kHashAlgorithmSha256);
+  ExpectParse("sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=?foo=bar",
+              "BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=",
+              IntegrityAlgorithm::kSha256);
 
   ExpectParse(
       "sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=?foo=bar?baz=foz",
-      "BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=", kHashAlgorithmSha256);
+      "BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=",
+      IntegrityAlgorithm::kSha256);
 
-  ExpectParse(
-      "sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=?",
-      "BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=", kHashAlgorithmSha256);
-  ExpectParse(
-      "sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=?foo=bar",
-      "BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=", kHashAlgorithmSha256);
+  ExpectParse("sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=?",
+              "BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=",
+              IntegrityAlgorithm::kSha256);
+  ExpectParse("sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=?foo=bar",
+              "BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=",
+              IntegrityAlgorithm::kSha256);
   ExpectParse(
       "sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=?foo=bar?baz=foz",
-      "BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=", kHashAlgorithmSha256);
-  ExpectParse(
-      "sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=?foo",
-      "BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=", kHashAlgorithmSha256);
-  ExpectParse(
-      "sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=?foo=bar?",
-      "BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=", kHashAlgorithmSha256);
-  ExpectParse(
-      "sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=?foo:bar",
-      "BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=", kHashAlgorithmSha256);
+      "BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=",
+      IntegrityAlgorithm::kSha256);
+  ExpectParse("sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=?foo",
+              "BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=",
+              IntegrityAlgorithm::kSha256);
+  ExpectParse("sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=?foo=bar?",
+              "BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=",
+              IntegrityAlgorithm::kSha256);
+  ExpectParse("sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=?foo:bar",
+              "BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=",
+              IntegrityAlgorithm::kSha256);
 }
 
 TEST_F(SubresourceIntegrityTest, ParsingBase64) {
   ExpectParse(
       "sha384-XVVXBGoYw6AJOh9J+Z8pBDMVVPfkBpngexkA7JqZu8d5GENND6TEIup/tA1v5GPr",
       "XVVXBGoYw6AJOh9J+Z8pBDMVVPfkBpngexkA7JqZu8d5GENND6TEIup/tA1v5GPr",
-      kHashAlgorithmSha384);
+      IntegrityAlgorithm::kSha384);
 }
 
 // Tests that SubresourceIntegrity::CheckSubresourceIntegrity behaves correctly
diff --git a/third_party/WebKit/Source/platform/loader/fetch/IntegrityMetadata.cpp b/third_party/WebKit/Source/platform/loader/fetch/IntegrityMetadata.cpp
index baf90d6..f1a8c63 100644
--- a/third_party/WebKit/Source/platform/loader/fetch/IntegrityMetadata.cpp
+++ b/third_party/WebKit/Source/platform/loader/fetch/IntegrityMetadata.cpp
@@ -7,14 +7,14 @@
 namespace blink {
 
 IntegrityMetadata::IntegrityMetadata(WTF::String digest,
-                                     HashAlgorithm algorithm)
+                                     IntegrityAlgorithm algorithm)
     : digest_(digest), algorithm_(algorithm) {}
 
-IntegrityMetadata::IntegrityMetadata(std::pair<WTF::String, HashAlgorithm> pair)
+IntegrityMetadata::IntegrityMetadata(IntegrityMetadataPair pair)
     : digest_(pair.first), algorithm_(pair.second) {}
 
-std::pair<WTF::String, HashAlgorithm> IntegrityMetadata::ToPair() const {
-  return std::pair<WTF::String, HashAlgorithm>(digest_, algorithm_);
+IntegrityMetadataPair IntegrityMetadata::ToPair() const {
+  return IntegrityMetadataPair(digest_, algorithm_);
 }
 
 bool IntegrityMetadata::SetsEqual(const IntegrityMetadataSet& set1,
diff --git a/third_party/WebKit/Source/platform/loader/fetch/IntegrityMetadata.h b/third_party/WebKit/Source/platform/loader/fetch/IntegrityMetadata.h
index 900a3d9..30c68db 100644
--- a/third_party/WebKit/Source/platform/loader/fetch/IntegrityMetadata.h
+++ b/third_party/WebKit/Source/platform/loader/fetch/IntegrityMetadata.h
@@ -5,7 +5,6 @@
 #ifndef IntegrityMetadata_h
 #define IntegrityMetadata_h
 
-#include "platform/Crypto.h"
 #include "platform/PlatformExport.h"
 #include "platform/wtf/HashSet.h"
 #include "platform/wtf/StringHasher.h"
@@ -15,20 +14,21 @@
 namespace blink {
 
 class IntegrityMetadata;
+enum class IntegrityAlgorithm : uint8_t;
 
-using IntegrityMetadataPair = std::pair<WTF::String, HashAlgorithm>;
+using IntegrityMetadataPair = std::pair<String, IntegrityAlgorithm>;
 using IntegrityMetadataSet = WTF::HashSet<IntegrityMetadataPair>;
 
 class PLATFORM_EXPORT IntegrityMetadata {
  public:
   IntegrityMetadata() {}
-  IntegrityMetadata(WTF::String digest, HashAlgorithm);
-  IntegrityMetadata(std::pair<WTF::String, HashAlgorithm>);
+  IntegrityMetadata(String digest, IntegrityAlgorithm);
+  IntegrityMetadata(IntegrityMetadataPair);
 
-  WTF::String Digest() const { return digest_; }
-  void SetDigest(const WTF::String& digest) { digest_ = digest; }
-  HashAlgorithm Algorithm() const { return algorithm_; }
-  void SetAlgorithm(HashAlgorithm algorithm) { algorithm_ = algorithm; }
+  String Digest() const { return digest_; }
+  void SetDigest(const String& digest) { digest_ = digest; }
+  IntegrityAlgorithm Algorithm() const { return algorithm_; }
+  void SetAlgorithm(IntegrityAlgorithm algorithm) { algorithm_ = algorithm; }
 
   IntegrityMetadataPair ToPair() const;
 
@@ -36,8 +36,8 @@
                         const IntegrityMetadataSet& set2);
 
  private:
-  WTF::String digest_;
-  HashAlgorithm algorithm_;
+  String digest_;
+  IntegrityAlgorithm algorithm_;
 };
 
 enum class ResourceIntegrityDisposition : uint8_t {
@@ -46,6 +46,24 @@
   kPassed
 };
 
+enum class IntegrityAlgorithm : uint8_t { kSha256, kSha384, kSha512 };
+
 }  // namespace blink
 
+namespace WTF {
+
+template <>
+struct DefaultHash<blink::IntegrityAlgorithm> {
+  STATIC_ONLY(DefaultHash);
+  typedef IntHash<blink::IntegrityAlgorithm> Hash;
+};
+
+template <>
+struct HashTraits<blink::IntegrityAlgorithm>
+    : UnsignedWithZeroKeyHashTraits<blink::IntegrityAlgorithm> {
+  STATIC_ONLY(HashTraits);
+};
+
+}  // namespace WTF
+
 #endif