diff --git a/DEPS b/DEPS
index b199f53..eb807fb 100644
--- a/DEPS
+++ b/DEPS
@@ -45,7 +45,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': '1fbe1ff2e1bf792bc378aba9c99c6b4e27f49db7',
+  'v8_revision': 'ecf9147d2b8322eefdeb737df265c3c47b2432ac',
   # 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.
@@ -97,7 +97,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling catapult
   # and whatever else without interference from each other.
-  'catapult_revision': '703485470a88380b828a6ec8f75e0fe11e371e17',
+  'catapult_revision': 'b233ea0e0e23e18000a6e7b6c7232cb67dbee7de',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
diff --git a/android_webview/browser/aw_contents.cc b/android_webview/browser/aw_contents.cc
index f423c897..5776088 100644
--- a/android_webview/browser/aw_contents.cc
+++ b/android_webview/browser/aw_contents.cc
@@ -941,12 +941,9 @@
     return ScopedJavaLocalRef<jbyteArray>();
 
   base::Pickle pickle;
-  if (!WriteToPickle(*web_contents_, &pickle)) {
-    return ScopedJavaLocalRef<jbyteArray>();
-  } else {
-    return base::android::ToJavaByteArray(
-        env, reinterpret_cast<const uint8_t*>(pickle.data()), pickle.size());
-  }
+  WriteToPickle(*web_contents_, &pickle);
+  return base::android::ToJavaByteArray(
+      env, reinterpret_cast<const uint8_t*>(pickle.data()), pickle.size());
 }
 
 jboolean AwContents::RestoreFromOpaqueState(
diff --git a/android_webview/browser/state_serializer.cc b/android_webview/browser/state_serializer.cc
index 3da314f..49223a4 100644
--- a/android_webview/browser/state_serializer.cc
+++ b/android_webview/browser/state_serializer.cc
@@ -36,12 +36,11 @@
 
 }  // namespace
 
-bool WriteToPickle(const content::WebContents& web_contents,
+void WriteToPickle(const content::WebContents& web_contents,
                    base::Pickle* pickle) {
   DCHECK(pickle);
 
-  if (!internal::WriteHeaderToPickle(pickle))
-    return false;
+  internal::WriteHeaderToPickle(pickle);
 
   const content::NavigationController& controller =
       web_contents.GetController();
@@ -51,24 +50,17 @@
   DCHECK_GE(selected_entry, -1);  // -1 is valid
   DCHECK_LT(selected_entry, entry_count);
 
-  if (!pickle->WriteInt(entry_count))
-    return false;
-
-  if (!pickle->WriteInt(selected_entry))
-    return false;
-
+  pickle->WriteInt(entry_count);
+  pickle->WriteInt(selected_entry);
   for (int i = 0; i < entry_count; ++i) {
-    if (!internal::WriteNavigationEntryToPickle(*controller.GetEntryAtIndex(i),
-                                                pickle))
-      return false;
+    internal::WriteNavigationEntryToPickle(*controller.GetEntryAtIndex(i),
+                                           pickle);
   }
 
   // Please update AW_STATE_VERSION and IsSupportedVersion() if serialization
   // format is changed.
   // Make sure the serialization format is updated in a backwards compatible
   // way.
-
-  return true;
 }
 
 bool RestoreFromPickle(base::PickleIterator* iterator,
@@ -135,12 +127,12 @@
 
 namespace internal {
 
-bool WriteHeaderToPickle(base::Pickle* pickle) {
-  return WriteHeaderToPickle(AW_STATE_VERSION, pickle);
+void WriteHeaderToPickle(base::Pickle* pickle) {
+  WriteHeaderToPickle(AW_STATE_VERSION, pickle);
 }
 
-bool WriteHeaderToPickle(uint32_t state_version, base::Pickle* pickle) {
-  return pickle->WriteUInt32(state_version);
+void WriteHeaderToPickle(uint32_t state_version, base::Pickle* pickle) {
+  pickle->WriteUInt32(state_version);
 }
 
 uint32_t RestoreHeaderFromPickle(base::PickleIterator* iterator) {
@@ -160,71 +152,50 @@
          state_version == internal::AW_STATE_VERSION_DATA_URL;
 }
 
-bool WriteNavigationEntryToPickle(const content::NavigationEntry& entry,
+void WriteNavigationEntryToPickle(const content::NavigationEntry& entry,
                                   base::Pickle* pickle) {
-  return WriteNavigationEntryToPickle(AW_STATE_VERSION, entry, pickle);
+  WriteNavigationEntryToPickle(AW_STATE_VERSION, entry, pickle);
 }
 
-bool WriteNavigationEntryToPickle(uint32_t state_version,
+void WriteNavigationEntryToPickle(uint32_t state_version,
                                   const content::NavigationEntry& entry,
                                   base::Pickle* pickle) {
   DCHECK(IsSupportedVersion(state_version));
-  if (!pickle->WriteString(entry.GetURL().spec()))
-    return false;
-
-  if (!pickle->WriteString(entry.GetVirtualURL().spec()))
-    return false;
+  pickle->WriteString(entry.GetURL().spec());
+  pickle->WriteString(entry.GetVirtualURL().spec());
 
   const content::Referrer& referrer = entry.GetReferrer();
-  if (!pickle->WriteString(referrer.url.spec()))
-    return false;
-  if (!pickle->WriteInt(static_cast<int>(referrer.policy)))
-    return false;
+  pickle->WriteString(referrer.url.spec());
+  pickle->WriteInt(static_cast<int>(referrer.policy));
 
-  if (!pickle->WriteString16(entry.GetTitle()))
-    return false;
-
-  if (!pickle->WriteString(entry.GetPageState().ToEncodedData()))
-    return false;
-
-  if (!pickle->WriteBool(static_cast<int>(entry.GetHasPostData())))
-    return false;
-
-  if (!pickle->WriteString(entry.GetOriginalRequestURL().spec()))
-    return false;
-
-  if (!pickle->WriteString(entry.GetBaseURLForDataURL().spec()))
-    return false;
+  pickle->WriteString16(entry.GetTitle());
+  pickle->WriteString(entry.GetPageState().ToEncodedData());
+  pickle->WriteBool(static_cast<int>(entry.GetHasPostData()));
+  pickle->WriteString(entry.GetOriginalRequestURL().spec());
+  pickle->WriteString(entry.GetBaseURLForDataURL().spec());
 
   if (state_version >= internal::AW_STATE_VERSION_DATA_URL) {
     const char* data = nullptr;
     size_t size = 0;
-    scoped_refptr<const base::RefCountedString> s = entry.GetDataURLAsString();
+    const scoped_refptr<const base::RefCountedString>& s =
+        entry.GetDataURLAsString();
     if (s) {
       data = s->front_as<char>();
       size = s->size();
     }
     // Even when |entry.GetDataForDataURL()| is null we still need to write a
     // zero-length entry to ensure the fields all line up when read back in.
-    if (!pickle->WriteData(data, size))
-      return false;
+    pickle->WriteData(data, size);
   }
 
-  if (!pickle->WriteBool(static_cast<int>(entry.GetIsOverridingUserAgent())))
-    return false;
-
-  if (!pickle->WriteInt64(entry.GetTimestamp().ToInternalValue()))
-    return false;
-
-  if (!pickle->WriteInt(entry.GetHttpStatusCode()))
-    return false;
+  pickle->WriteBool(static_cast<int>(entry.GetIsOverridingUserAgent()));
+  pickle->WriteInt64(entry.GetTimestamp().ToInternalValue());
+  pickle->WriteInt(entry.GetHttpStatusCode());
 
   // Please update AW_STATE_VERSION and IsSupportedVersion() if serialization
   // format is changed.
   // Make sure the serialization format is updated in a backwards compatible
   // way.
-
-  return true;
 }
 
 bool RestoreNavigationEntryFromPickle(base::PickleIterator* iterator,
diff --git a/android_webview/browser/state_serializer.h b/android_webview/browser/state_serializer.h
index 6745135..a07bbd2 100644
--- a/android_webview/browser/state_serializer.h
+++ b/android_webview/browser/state_serializer.h
@@ -29,8 +29,8 @@
 // success.
 
 // Note that |pickle| may be changed even if function returns false.
-bool WriteToPickle(const content::WebContents& web_contents,
-                   base::Pickle* pickle) WARN_UNUSED_RESULT;
+void WriteToPickle(const content::WebContents& web_contents,
+                   base::Pickle* pickle);
 
 // |web_contents| will not be modified if function returns false.
 bool RestoreFromPickle(base::PickleIterator* iterator,
@@ -44,17 +44,16 @@
 // Functions below are individual helper functions called by functions above.
 // They are broken up for unit testing, and should not be called out side of
 // tests.
-bool WriteHeaderToPickle(base::Pickle* pickle) WARN_UNUSED_RESULT;
-bool WriteHeaderToPickle(uint32_t state_version,
-                         base::Pickle* pickle) WARN_UNUSED_RESULT;
+void WriteHeaderToPickle(base::Pickle* pickle);
+void WriteHeaderToPickle(uint32_t state_version, base::Pickle* pickle);
 uint32_t RestoreHeaderFromPickle(base::PickleIterator* iterator)
     WARN_UNUSED_RESULT;
 bool IsSupportedVersion(uint32_t state_version) WARN_UNUSED_RESULT;
-bool WriteNavigationEntryToPickle(const content::NavigationEntry& entry,
-                                  base::Pickle* pickle) WARN_UNUSED_RESULT;
-bool WriteNavigationEntryToPickle(uint32_t state_version,
+void WriteNavigationEntryToPickle(const content::NavigationEntry& entry,
+                                  base::Pickle* pickle);
+void WriteNavigationEntryToPickle(uint32_t state_version,
                                   const content::NavigationEntry& entry,
-                                  base::Pickle* pickle) WARN_UNUSED_RESULT;
+                                  base::Pickle* pickle);
 bool RestoreNavigationEntryFromPickle(base::PickleIterator* iterator,
                                       content::NavigationEntry* entry)
     WARN_UNUSED_RESULT;
diff --git a/android_webview/browser/state_serializer_unittest.cc b/android_webview/browser/state_serializer_unittest.cc
index 31454df..0c306802 100644
--- a/android_webview/browser/state_serializer_unittest.cc
+++ b/android_webview/browser/state_serializer_unittest.cc
@@ -66,8 +66,7 @@
 
 TEST(AndroidWebViewStateSerializerTest, TestHeaderSerialization) {
   base::Pickle pickle;
-  bool result = internal::WriteHeaderToPickle(&pickle);
-  EXPECT_TRUE(result);
+  internal::WriteHeaderToPickle(&pickle);
 
   base::PickleIterator iterator(pickle);
   uint32_t version = internal::RestoreHeaderFromPickle(&iterator);
@@ -76,9 +75,7 @@
 
 TEST(AndroidWebViewStateSerializerTest, TestLegacyVersionHeaderSerialization) {
   base::Pickle pickle;
-  bool result = internal::WriteHeaderToPickle(
-      internal::AW_STATE_VERSION_INITIAL, &pickle);
-  EXPECT_TRUE(result);
+  internal::WriteHeaderToPickle(internal::AW_STATE_VERSION_INITIAL, &pickle);
 
   base::PickleIterator iterator(pickle);
   uint32_t version = internal::RestoreHeaderFromPickle(&iterator);
@@ -88,8 +85,7 @@
 TEST(AndroidWebViewStateSerializerTest,
      TestUnsupportedVersionHeaderSerialization) {
   base::Pickle pickle;
-  bool result = internal::WriteHeaderToPickle(20000101, &pickle);
-  EXPECT_TRUE(result);
+  internal::WriteHeaderToPickle(20000101, &pickle);
 
   base::PickleIterator iterator(pickle);
   uint32_t version = internal::RestoreHeaderFromPickle(&iterator);
@@ -106,13 +102,13 @@
   std::unique_ptr<content::NavigationEntry> entry(CreateNavigationEntry());
 
   base::Pickle pickle;
-  bool result = internal::WriteNavigationEntryToPickle(*entry, &pickle);
-  EXPECT_TRUE(result);
+  internal::WriteNavigationEntryToPickle(*entry, &pickle);
 
   std::unique_ptr<content::NavigationEntry> copy(
       content::NavigationEntry::Create());
   base::PickleIterator iterator(pickle);
-  result = internal::RestoreNavigationEntryFromPickle(&iterator, copy.get());
+  bool result =
+      internal::RestoreNavigationEntryFromPickle(&iterator, copy.get());
   EXPECT_TRUE(result);
 
   EXPECT_EQ(entry->GetURL(), copy->GetURL());
@@ -143,14 +139,13 @@
   std::unique_ptr<content::NavigationEntry> entry(CreateNavigationEntry());
 
   base::Pickle pickle;
-  bool result = internal::WriteNavigationEntryToPickle(
-      internal::AW_STATE_VERSION_INITIAL, *entry, &pickle);
-  EXPECT_TRUE(result);
+  internal::WriteNavigationEntryToPickle(internal::AW_STATE_VERSION_INITIAL,
+                                         *entry, &pickle);
 
   std::unique_ptr<content::NavigationEntry> copy(
       content::NavigationEntry::Create());
   base::PickleIterator iterator(pickle);
-  result = internal::RestoreNavigationEntryFromPickle(
+  bool result = internal::RestoreNavigationEntryFromPickle(
       internal::AW_STATE_VERSION_INITIAL, &iterator, copy.get());
   EXPECT_TRUE(result);
 
@@ -183,13 +178,13 @@
   EXPECT_FALSE(entry->GetDataURLAsString());
 
   base::Pickle pickle;
-  bool result = internal::WriteNavigationEntryToPickle(*entry, &pickle);
-  EXPECT_TRUE(result);
+  internal::WriteNavigationEntryToPickle(*entry, &pickle);
 
   std::unique_ptr<content::NavigationEntry> copy(
       content::NavigationEntry::Create());
   base::PickleIterator iterator(pickle);
-  result = internal::RestoreNavigationEntryFromPickle(&iterator, copy.get());
+  bool result =
+      internal::RestoreNavigationEntryFromPickle(&iterator, copy.get());
   EXPECT_TRUE(result);
   EXPECT_FALSE(entry->GetDataURLAsString());
 }
@@ -212,13 +207,13 @@
   }
 
   base::Pickle pickle;
-  bool result = internal::WriteNavigationEntryToPickle(*entry, &pickle);
-  EXPECT_TRUE(result);
+  internal::WriteNavigationEntryToPickle(*entry, &pickle);
 
   std::unique_ptr<content::NavigationEntry> copy(
       content::NavigationEntry::Create());
   base::PickleIterator iterator(pickle);
-  result = internal::RestoreNavigationEntryFromPickle(&iterator, copy.get());
+  bool result =
+      internal::RestoreNavigationEntryFromPickle(&iterator, copy.get());
   EXPECT_TRUE(result);
   EXPECT_EQ(huge_data_url, copy->GetDataURLAsString()->data());
 }
diff --git a/ash/resources/vector_icons/BUILD.gn b/ash/resources/vector_icons/BUILD.gn
index 6b15187..3490f03 100644
--- a/ash/resources/vector_icons/BUILD.gn
+++ b/ash/resources/vector_icons/BUILD.gn
@@ -86,6 +86,8 @@
     "notification_screenshare.1x.icon",
     "notification_screenshare.icon",
     "notification_settings.icon",
+    "notification_sms_sync.1x.icon",
+    "notification_sms_sync.icon",
     "notification_supervised.icon",
     "notification_timer.icon",
     "palette_action_capture_region.1x.icon",
diff --git a/ash/resources/vector_icons/notification_sms_sync.1x.icon b/ash/resources/vector_icons/notification_sms_sync.1x.icon
new file mode 100644
index 0000000..7c57390
--- /dev/null
+++ b/ash/resources/vector_icons/notification_sms_sync.1x.icon
@@ -0,0 +1,34 @@
+// 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.
+
+CANVAS_DIMENSIONS, 18,
+MOVE_TO, 14.6f, 2,
+R_CUBIC_TO, 0.77f, 0, 1.4f, 0.63f, 1.4f, 1.4f,
+R_V_LINE_TO, 8.4f,
+R_CUBIC_TO, 0, 0.77f, -0.63f, 1.2f, -1.4f, 1.2f,
+H_LINE_TO, 4.75f,
+LINE_TO, 2, 16,
+R_LINE_TO, 0.01f, -12.6f,
+R_CUBIC_TO, 0, -0.77f, 0.62f, -1.4f, 1.39f, -1.4f,
+R_H_LINE_TO, 11.2f,
+CLOSE,
+MOVE_TO, 6.5f, 6,
+R_LINE_TO, -3, 2.5f,
+R_LINE_TO, 3, 2.5f,
+V_LINE_TO, 9,
+H_LINE_TO, 10,
+V_LINE_TO, 8,
+H_LINE_TO, 6.5f,
+V_LINE_TO, 6,
+CLOSE,
+R_MOVE_TO, 8, 0.5f,
+R_LINE_TO, -3, -2.5f,
+R_V_LINE_TO, 2,
+H_LINE_TO, 8,
+R_V_LINE_TO, 1,
+R_H_LINE_TO, 3.5f,
+R_V_LINE_TO, 2,
+R_LINE_TO, 3, -2.5f,
+CLOSE,
+END
diff --git a/ash/resources/vector_icons/notification_sms_sync.icon b/ash/resources/vector_icons/notification_sms_sync.icon
new file mode 100644
index 0000000..d20a3f3
--- /dev/null
+++ b/ash/resources/vector_icons/notification_sms_sync.icon
@@ -0,0 +1,34 @@
+// 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.
+
+CANVAS_DIMENSIONS, 36,
+MOVE_TO, 29.2f, 4,
+CUBIC_TO, 30.74f, 4, 32, 5.26f, 32, 6.8f,
+R_V_LINE_TO, 16.8f,
+R_CUBIC_TO, 0, 1.54f, -1.26f, 2.4f, -2.8f, 2.4f,
+H_LINE_TO, 9.5f,
+LINE_TO, 4, 32,
+R_LINE_TO, 0.01f, -25.2f,
+CUBIC_TO, 4.01f, 5.26f, 5.26f, 4, 6.8f, 4,
+R_H_LINE_TO, 22.4f,
+CLOSE,
+MOVE_TO, 13, 12,
+R_LINE_TO, -6, 5.5f,
+R_LINE_TO, 6, 5.5f,
+R_V_LINE_TO, -4,
+R_H_LINE_TO, 8,
+R_V_LINE_TO, -3,
+R_H_LINE_TO, -8,
+R_V_LINE_TO, -4,
+CLOSE,
+R_MOVE_TO, 16, 0.5f,
+LINE_TO, 23, 7,
+R_V_LINE_TO, 4,
+R_H_LINE_TO, -8,
+R_V_LINE_TO, 3,
+R_H_LINE_TO, 8,
+R_V_LINE_TO, 4,
+R_LINE_TO, 6, -5.5f,
+CLOSE,
+END
diff --git a/ash/system/network/sms_observer.cc b/ash/system/network/sms_observer.cc
index 622bc59e..3c48142 100644
--- a/ash/system/network/sms_observer.cc
+++ b/ash/system/network/sms_observer.cc
@@ -34,16 +34,17 @@
   const char kNotificationId[] = "chrome://network/sms";
   std::unique_ptr<message_center::Notification> notification;
 
-  notification = base::MakeUnique<message_center::Notification>(
+  notification = system_notifier::CreateSystemNotification(
       message_center::NOTIFICATION_TYPE_SIMPLE,
       kNotificationId + std::to_string(message_id),
       base::ASCIIToUTF16(message_number), base::ASCIIToUTF16(message_text),
-      gfx::Image(gfx::CreateVectorIcon(
-          ash::kSystemMenuSmsIcon, ash::kMenuIconSize, ash::kMenuIconColor)),
+      gfx::Image(gfx::CreateVectorIcon(kSystemMenuSmsIcon, kMenuIconSize,
+                                       kMenuIconColor)),
       base::string16(), GURL(),
       message_center::NotifierId(message_center::NotifierId::APPLICATION,
-                                 ash::system_notifier::kNotifierSms),
-      message_center::RichNotificationData(), nullptr);
+                                 system_notifier::kNotifierSms),
+      message_center::RichNotificationData(), nullptr, kNotificationSmsSyncIcon,
+      message_center::SystemNotificationWarningLevel::NORMAL);
   message_center->AddNotification(std::move(notification));
 }
 
diff --git a/base/debug/activity_tracker.cc b/base/debug/activity_tracker.cc
index 89c611cc..8177689 100644
--- a/base/debug/activity_tracker.cc
+++ b/base/debug/activity_tracker.cc
@@ -1133,12 +1133,8 @@
     const GlobalActivityTracker::ModuleInfo& info,
     PersistentMemoryAllocator* allocator) {
   Pickle pickler;
-  bool okay =
-      pickler.WriteString(info.file) && pickler.WriteString(info.debug_file);
-  if (!okay) {
-    NOTREACHED();
-    return nullptr;
-  }
+  pickler.WriteString(info.file);
+  pickler.WriteString(info.debug_file);
   size_t required_size = offsetof(ModuleInfoRecord, pickle) + pickler.size();
   ModuleInfoRecord* record = allocator->New<ModuleInfoRecord>(required_size);
   if (!record)
diff --git a/base/metrics/field_trial.cc b/base/metrics/field_trial.cc
index 751d280..e51a330c 100644
--- a/base/metrics/field_trial.cc
+++ b/base/metrics/field_trial.cc
@@ -65,25 +65,19 @@
 const size_t kFieldTrialAllocationSize = 128 << 10;  // 128 KiB
 
 // Writes out string1 and then string2 to pickle.
-bool WriteStringPair(Pickle* pickle,
+void WriteStringPair(Pickle* pickle,
                      const StringPiece& string1,
                      const StringPiece& string2) {
-  if (!pickle->WriteString(string1))
-    return false;
-  if (!pickle->WriteString(string2))
-    return false;
-  return true;
+  pickle->WriteString(string1);
+  pickle->WriteString(string2);
 }
 
 // Writes out the field trial's contents (via trial_state) to the pickle. The
 // format of the pickle looks like:
 // TrialName, GroupName, ParamKey1, ParamValue1, ParamKey2, ParamValue2, ...
 // If there are no parameters, then it just ends at GroupName.
-bool PickleFieldTrial(const FieldTrial::State& trial_state, Pickle* pickle) {
-  if (!WriteStringPair(pickle, *trial_state.trial_name,
-                       *trial_state.group_name)) {
-    return false;
-  }
+void PickleFieldTrial(const FieldTrial::State& trial_state, Pickle* pickle) {
+  WriteStringPair(pickle, *trial_state.trial_name, *trial_state.group_name);
 
   // Get field trial params.
   std::map<std::string, std::string> params;
@@ -91,11 +85,8 @@
       *trial_state.trial_name, *trial_state.group_name, &params);
 
   // Write params to pickle.
-  for (const auto& param : params) {
-    if (!WriteStringPair(pickle, param.first, param.second))
-      return false;
-  }
-  return true;
+  for (const auto& param : params)
+    WriteStringPair(pickle, param.first, param.second);
 }
 
 // Created a time value based on |year|, |month| and |day_of_month| parameters.
@@ -1358,10 +1349,7 @@
     return;
 
   Pickle pickle;
-  if (!PickleFieldTrial(trial_state, &pickle)) {
-    NOTREACHED();
-    return;
-  }
+  PickleFieldTrial(trial_state, &pickle);
 
   size_t total_size = sizeof(FieldTrial::FieldTrialEntry) + pickle.size();
   FieldTrial::FieldTrialRef ref = allocator->Allocate(
diff --git a/base/metrics/histogram.cc b/base/metrics/histogram.cc
index b600359..1e76364 100644
--- a/base/metrics/histogram.cc
+++ b/base/metrics/histogram.cc
@@ -631,14 +631,14 @@
   return false;
 }
 
-bool Histogram::SerializeInfoImpl(Pickle* pickle) const {
+void Histogram::SerializeInfoImpl(Pickle* pickle) const {
   DCHECK(bucket_ranges()->HasValidChecksum());
-  return pickle->WriteString(histogram_name()) &&
-      pickle->WriteInt(flags()) &&
-      pickle->WriteInt(declared_min()) &&
-      pickle->WriteInt(declared_max()) &&
-      pickle->WriteUInt32(bucket_count()) &&
-      pickle->WriteUInt32(bucket_ranges()->checksum());
+  pickle->WriteString(histogram_name());
+  pickle->WriteInt(flags());
+  pickle->WriteInt(declared_min());
+  pickle->WriteInt(declared_max());
+  pickle->WriteUInt32(bucket_count());
+  pickle->WriteUInt32(bucket_ranges()->checksum());
 }
 
 // TODO(bcwhite): Remove minimum/maximum parameters from here and call chain.
@@ -1292,17 +1292,13 @@
                 meta,
                 logged_meta) {}
 
-bool CustomHistogram::SerializeInfoImpl(Pickle* pickle) const {
-  if (!Histogram::SerializeInfoImpl(pickle))
-    return false;
+void CustomHistogram::SerializeInfoImpl(Pickle* pickle) const {
+  Histogram::SerializeInfoImpl(pickle);
 
   // Serialize ranges. First and last ranges are alwasy 0 and INT_MAX, so don't
   // write them.
-  for (uint32_t i = 1; i < bucket_ranges()->bucket_count(); ++i) {
-    if (!pickle->WriteInt(bucket_ranges()->range(i)))
-      return false;
-  }
-  return true;
+  for (uint32_t i = 1; i < bucket_ranges()->bucket_count(); ++i)
+    pickle->WriteInt(bucket_ranges()->range(i));
 }
 
 double CustomHistogram::GetBucketSize(Count current, uint32_t i) const {
diff --git a/base/metrics/histogram.h b/base/metrics/histogram.h
index 6bac0814..a0942a5 100644
--- a/base/metrics/histogram.h
+++ b/base/metrics/histogram.h
@@ -247,7 +247,7 @@
             HistogramSamples::Metadata* logged_meta);
 
   // HistogramBase implementation:
-  bool SerializeInfoImpl(base::Pickle* pickle) const override;
+  void SerializeInfoImpl(base::Pickle* pickle) const override;
 
   // Method to override to skip the display of the i'th bucket if it's empty.
   virtual bool PrintEmptyBucket(uint32_t index) const;
@@ -541,7 +541,7 @@
                   HistogramSamples::Metadata* logged_meta);
 
   // HistogramBase implementation:
-  bool SerializeInfoImpl(base::Pickle* pickle) const override;
+  void SerializeInfoImpl(base::Pickle* pickle) const override;
 
   double GetBucketSize(Count current, uint32_t i) const override;
 
diff --git a/base/metrics/histogram_base.cc b/base/metrics/histogram_base.cc
index 5e9de6f..3171f37 100644
--- a/base/metrics/histogram_base.cc
+++ b/base/metrics/histogram_base.cc
@@ -91,10 +91,9 @@
   Add(value ? 1 : 0);
 }
 
-bool HistogramBase::SerializeInfo(Pickle* pickle) const {
-  if (!pickle->WriteInt(GetHistogramType()))
-    return false;
-  return SerializeInfoImpl(pickle);
+void HistogramBase::SerializeInfo(Pickle* pickle) const {
+  pickle->WriteInt(GetHistogramType());
+  SerializeInfoImpl(pickle);
 }
 
 uint32_t HistogramBase::FindCorruption(const HistogramSamples& samples) const {
diff --git a/base/metrics/histogram_base.h b/base/metrics/histogram_base.h
index 45e5126..f6c8de5 100644
--- a/base/metrics/histogram_base.h
+++ b/base/metrics/histogram_base.h
@@ -179,7 +179,7 @@
   // Serialize the histogram info into |pickle|.
   // Note: This only serializes the construction arguments of the histogram, but
   // does not serialize the samples.
-  bool SerializeInfo(base::Pickle* pickle) const;
+  void SerializeInfo(base::Pickle* pickle) const;
 
   // Try to find out data corruption from histogram and the samples.
   // The returned value is a combination of Inconsistency enum.
@@ -231,7 +231,7 @@
   enum ReportActivity { HISTOGRAM_CREATED, HISTOGRAM_LOOKUP };
 
   // Subclasses should implement this function to make SerializeInfo work.
-  virtual bool SerializeInfoImpl(base::Pickle* pickle) const = 0;
+  virtual void SerializeInfoImpl(base::Pickle* pickle) const = 0;
 
   // Writes information about the construction parameters in |params|.
   virtual void GetParameters(DictionaryValue* params) const = 0;
diff --git a/base/metrics/histogram_base_unittest.cc b/base/metrics/histogram_base_unittest.cc
index 1eb8fd4..abf4d2a 100644
--- a/base/metrics/histogram_base_unittest.cc
+++ b/base/metrics/histogram_base_unittest.cc
@@ -50,7 +50,7 @@
       HistogramBase::kIPCSerializationSourceFlag));
 
   Pickle pickle;
-  ASSERT_TRUE(histogram->SerializeInfo(&pickle));
+  histogram->SerializeInfo(&pickle);
 
   PickleIterator iter(pickle);
   HistogramBase* deserialized = DeserializeHistogramInfo(&iter);
@@ -75,7 +75,7 @@
       HistogramBase::kIPCSerializationSourceFlag);
 
   Pickle pickle;
-  ASSERT_TRUE(histogram->SerializeInfo(&pickle));
+  histogram->SerializeInfo(&pickle);
 
   PickleIterator iter(pickle);
   HistogramBase* deserialized = DeserializeHistogramInfo(&iter);
@@ -97,7 +97,7 @@
       "TestHistogram", HistogramBase::kIPCSerializationSourceFlag);
 
   Pickle pickle;
-  ASSERT_TRUE(histogram->SerializeInfo(&pickle));
+  histogram->SerializeInfo(&pickle);
 
   PickleIterator iter(pickle);
   HistogramBase* deserialized = DeserializeHistogramInfo(&iter);
@@ -124,7 +124,7 @@
       "TestHistogram", ranges, HistogramBase::kIPCSerializationSourceFlag);
 
   Pickle pickle;
-  ASSERT_TRUE(histogram->SerializeInfo(&pickle));
+  histogram->SerializeInfo(&pickle);
 
   PickleIterator iter(pickle);
   HistogramBase* deserialized = DeserializeHistogramInfo(&iter);
@@ -146,7 +146,7 @@
       "TestHistogram", HistogramBase::kIPCSerializationSourceFlag);
 
   Pickle pickle;
-  ASSERT_TRUE(histogram->SerializeInfo(&pickle));
+  histogram->SerializeInfo(&pickle);
 
   PickleIterator iter(pickle);
   HistogramBase* deserialized = DeserializeHistogramInfo(&iter);
diff --git a/base/metrics/histogram_samples.cc b/base/metrics/histogram_samples.cc
index 019cc5ab..f12cdc9 100644
--- a/base/metrics/histogram_samples.cc
+++ b/base/metrics/histogram_samples.cc
@@ -214,11 +214,9 @@
   DCHECK(success);
 }
 
-bool HistogramSamples::Serialize(Pickle* pickle) const {
-  if (!pickle->WriteInt64(sum()))
-    return false;
-  if (!pickle->WriteInt(redundant_count()))
-    return false;
+void HistogramSamples::Serialize(Pickle* pickle) const {
+  pickle->WriteInt64(sum());
+  pickle->WriteInt(redundant_count());
 
   HistogramBase::Sample min;
   int64_t max;
@@ -226,12 +224,10 @@
   for (std::unique_ptr<SampleCountIterator> it = Iterator(); !it->Done();
        it->Next()) {
     it->Get(&min, &max, &count);
-    if (!pickle->WriteInt(min) || !pickle->WriteInt64(max) ||
-        !pickle->WriteInt(count)) {
-      return false;
-    }
+    pickle->WriteInt(min);
+    pickle->WriteInt64(max);
+    pickle->WriteInt(count);
   }
-  return true;
 }
 
 bool HistogramSamples::AccumulateSingleSample(HistogramBase::Sample value,
diff --git a/base/metrics/histogram_samples.h b/base/metrics/histogram_samples.h
index 3efb05d..d1f95a4 100644
--- a/base/metrics/histogram_samples.h
+++ b/base/metrics/histogram_samples.h
@@ -144,7 +144,7 @@
   virtual void Subtract(const HistogramSamples& other);
 
   virtual std::unique_ptr<SampleCountIterator> Iterator() const = 0;
-  virtual bool Serialize(Pickle* pickle) const;
+  virtual void Serialize(Pickle* pickle) const;
 
   // Accessor fuctions.
   uint64_t id() const { return meta_->id; }
diff --git a/base/metrics/persistent_histogram_allocator.cc b/base/metrics/persistent_histogram_allocator.cc
index d871706..46e5773 100644
--- a/base/metrics/persistent_histogram_allocator.cc
+++ b/base/metrics/persistent_histogram_allocator.cc
@@ -733,8 +733,7 @@
   // FactoryGet() which will create the histogram in the global persistent-
   // histogram allocator if such is set.
   base::Pickle pickle;
-  if (!histogram->SerializeInfo(&pickle))
-    return nullptr;
+  histogram->SerializeInfo(&pickle);
   PickleIterator iter(pickle);
   existing = DeserializeHistogramInfo(&iter);
   if (!existing)
diff --git a/base/metrics/sparse_histogram.cc b/base/metrics/sparse_histogram.cc
index e9bacd1..ef9945a 100644
--- a/base/metrics/sparse_histogram.cc
+++ b/base/metrics/sparse_histogram.cc
@@ -169,8 +169,9 @@
   WriteAsciiImpl(true, "\n", output);
 }
 
-bool SparseHistogram::SerializeInfoImpl(Pickle* pickle) const {
-  return pickle->WriteString(histogram_name()) && pickle->WriteInt(flags());
+void SparseHistogram::SerializeInfoImpl(Pickle* pickle) const {
+  pickle->WriteString(histogram_name());
+  pickle->WriteInt(flags());
 }
 
 SparseHistogram::SparseHistogram(const std::string& name)
diff --git a/base/metrics/sparse_histogram.h b/base/metrics/sparse_histogram.h
index 66e9825..9733e57e 100644
--- a/base/metrics/sparse_histogram.h
+++ b/base/metrics/sparse_histogram.h
@@ -59,7 +59,7 @@
 
  protected:
   // HistogramBase implementation:
-  bool SerializeInfoImpl(base::Pickle* pickle) const override;
+  void SerializeInfoImpl(base::Pickle* pickle) const override;
 
  private:
   // Clients should always use FactoryGet to create SparseHistogram.
diff --git a/base/pickle.cc b/base/pickle.cc
index 2b278bc6..9c25c3bd 100644
--- a/base/pickle.cc
+++ b/base/pickle.cc
@@ -288,28 +288,24 @@
   return *this;
 }
 
-bool Pickle::WriteString(const StringPiece& value) {
-  if (!WriteInt(static_cast<int>(value.size())))
-    return false;
-
-  return WriteBytes(value.data(), static_cast<int>(value.size()));
+void Pickle::WriteString(const StringPiece& value) {
+  WriteInt(static_cast<int>(value.size()));
+  WriteBytes(value.data(), static_cast<int>(value.size()));
 }
 
-bool Pickle::WriteString16(const StringPiece16& value) {
-  if (!WriteInt(static_cast<int>(value.size())))
-    return false;
-
-  return WriteBytes(value.data(),
-                    static_cast<int>(value.size()) * sizeof(char16));
+void Pickle::WriteString16(const StringPiece16& value) {
+  WriteInt(static_cast<int>(value.size()));
+  WriteBytes(value.data(), static_cast<int>(value.size()) * sizeof(char16));
 }
 
-bool Pickle::WriteData(const char* data, int length) {
-  return length >= 0 && WriteInt(length) && WriteBytes(data, length);
+void Pickle::WriteData(const char* data, int length) {
+  CHECK_GE(length, 0);
+  WriteInt(length);
+  WriteBytes(data, length);
 }
 
-bool Pickle::WriteBytes(const void* data, int length) {
+void Pickle::WriteBytes(const void* data, int length) {
   WriteBytesCommon(data, length);
-  return true;
 }
 
 void Pickle::Reserve(size_t length) {
diff --git a/base/pickle.h b/base/pickle.h
index ce2b81f..4fe98d42 100644
--- a/base/pickle.h
+++ b/base/pickle.h
@@ -186,36 +186,28 @@
   // Pickle, it is important to read them in the order in which they were added
   // to the Pickle.
 
-  bool WriteBool(bool value) {
-    return WriteInt(value ? 1 : 0);
-  }
-  bool WriteInt(int value) {
-    return WritePOD(value);
-  }
-  bool WriteLong(long value) {
+  void WriteBool(bool value) { WriteInt(value ? 1 : 0); }
+  void WriteInt(int value) { WritePOD(value); }
+  void WriteLong(long value) {
     // Always write long as a 64-bit value to ensure compatibility between
     // 32-bit and 64-bit processes.
-    return WritePOD(static_cast<int64_t>(value));
+    WritePOD(static_cast<int64_t>(value));
   }
-  bool WriteUInt16(uint16_t value) { return WritePOD(value); }
-  bool WriteUInt32(uint32_t value) { return WritePOD(value); }
-  bool WriteInt64(int64_t value) { return WritePOD(value); }
-  bool WriteUInt64(uint64_t value) { return WritePOD(value); }
-  bool WriteFloat(float value) {
-    return WritePOD(value);
-  }
-  bool WriteDouble(double value) {
-    return WritePOD(value);
-  }
-  bool WriteString(const StringPiece& value);
-  bool WriteString16(const StringPiece16& value);
+  void WriteUInt16(uint16_t value) { WritePOD(value); }
+  void WriteUInt32(uint32_t value) { WritePOD(value); }
+  void WriteInt64(int64_t value) { WritePOD(value); }
+  void WriteUInt64(uint64_t value) { WritePOD(value); }
+  void WriteFloat(float value) { WritePOD(value); }
+  void WriteDouble(double value) { WritePOD(value); }
+  void WriteString(const StringPiece& value);
+  void WriteString16(const StringPiece16& value);
   // "Data" is a blob with a length. When you read it out you will be given the
   // length. See also WriteBytes.
-  bool WriteData(const char* data, int length);
+  void WriteData(const char* data, int length);
   // "Bytes" is a blob with no length. The caller must specify the length both
   // when reading and writing. It is normally used to serialize PoD types of a
   // known size. See also WriteData.
-  bool WriteBytes(const void* data, int length);
+  void WriteBytes(const void* data, int length);
 
   // WriteAttachment appends |attachment| to the pickle. It returns
   // false iff the set is full or if the Pickle implementation does not support
diff --git a/base/pickle_unittest.cc b/base/pickle_unittest.cc
index ba242e4..dedb819 100644
--- a/base/pickle_unittest.cc
+++ b/base/pickle_unittest.cc
@@ -112,21 +112,21 @@
 TEST(PickleTest, EncodeDecode) {
   Pickle pickle;
 
-  EXPECT_TRUE(pickle.WriteBool(testbool1));
-  EXPECT_TRUE(pickle.WriteBool(testbool2));
-  EXPECT_TRUE(pickle.WriteInt(testint));
-  EXPECT_TRUE(pickle.WriteLong(testlong));
-  EXPECT_TRUE(pickle.WriteUInt16(testuint16));
-  EXPECT_TRUE(pickle.WriteUInt32(testuint32));
-  EXPECT_TRUE(pickle.WriteInt64(testint64));
-  EXPECT_TRUE(pickle.WriteUInt64(testuint64));
-  EXPECT_TRUE(pickle.WriteFloat(testfloat));
-  EXPECT_TRUE(pickle.WriteDouble(testdouble));
-  EXPECT_TRUE(pickle.WriteString(teststring));
-  EXPECT_TRUE(pickle.WriteString16(teststring16));
-  EXPECT_TRUE(pickle.WriteString(testrawstring));
-  EXPECT_TRUE(pickle.WriteString16(testrawstring16));
-  EXPECT_TRUE(pickle.WriteData(testdata, testdatalen));
+  pickle.WriteBool(testbool1);
+  pickle.WriteBool(testbool2);
+  pickle.WriteInt(testint);
+  pickle.WriteLong(testlong);
+  pickle.WriteUInt16(testuint16);
+  pickle.WriteUInt32(testuint32);
+  pickle.WriteInt64(testint64);
+  pickle.WriteUInt64(testuint64);
+  pickle.WriteFloat(testfloat);
+  pickle.WriteDouble(testdouble);
+  pickle.WriteString(teststring);
+  pickle.WriteString16(teststring16);
+  pickle.WriteString(testrawstring);
+  pickle.WriteString16(testrawstring16);
+  pickle.WriteData(testdata, testdatalen);
   VerifyResult(pickle);
 
   // test copy constructor
@@ -146,7 +146,7 @@
   Pickle pickle;
   // Under the hood long is always written as a 64-bit value, so simulate a
   // 64-bit long even on 32-bit architectures by explicitly writing an int64_t.
-  EXPECT_TRUE(pickle.WriteInt64(testint64));
+  pickle.WriteInt64(testint64);
 
   PickleIterator iter(pickle);
   long outlong;
@@ -197,7 +197,7 @@
 
 TEST(PickleTest, ZeroLenStr) {
   Pickle pickle;
-  EXPECT_TRUE(pickle.WriteString(std::string()));
+  pickle.WriteString(std::string());
 
   PickleIterator iter(pickle);
   std::string outstr;
@@ -207,7 +207,7 @@
 
 TEST(PickleTest, ZeroLenStr16) {
   Pickle pickle;
-  EXPECT_TRUE(pickle.WriteString16(string16()));
+  pickle.WriteString16(string16());
 
   PickleIterator iter(pickle);
   std::string outstr;
@@ -217,7 +217,7 @@
 
 TEST(PickleTest, BadLenStr) {
   Pickle pickle;
-  EXPECT_TRUE(pickle.WriteInt(-2));
+  pickle.WriteInt(-2);
 
   PickleIterator iter(pickle);
   std::string outstr;
@@ -226,7 +226,7 @@
 
 TEST(PickleTest, BadLenStr16) {
   Pickle pickle;
-  EXPECT_TRUE(pickle.WriteInt(-1));
+  pickle.WriteInt(-1);
 
   PickleIterator iter(pickle);
   string16 outstr;
@@ -240,7 +240,7 @@
 
   Pickle pickle(sizeof(CustomHeader));
 
-  EXPECT_TRUE(pickle.WriteString("Goooooooooooogle"));
+  pickle.WriteString("Goooooooooooogle");
 
   const char* pickle_data = static_cast<const char*>(pickle.data());
 
@@ -317,8 +317,8 @@
 
 TEST(PickleTest, FindNext) {
   Pickle pickle;
-  EXPECT_TRUE(pickle.WriteInt(1));
-  EXPECT_TRUE(pickle.WriteString("Domo"));
+  pickle.WriteInt(1);
+  pickle.WriteString("Domo");
 
   const char* start = reinterpret_cast<const char*>(pickle.data());
   const char* end = start + pickle.size();
@@ -376,8 +376,8 @@
   PickleIterator iter(pickle);
   EXPECT_FALSE(iter.GetReadPointerAndAdvance(1));
 
-  EXPECT_TRUE(pickle.WriteInt(1));
-  EXPECT_TRUE(pickle.WriteInt(2));
+  pickle.WriteInt(1);
+  pickle.WriteInt(2);
   int bytes = sizeof(int) * 2;
 
   EXPECT_TRUE(PickleIterator(pickle).GetReadPointerAndAdvance(0));
@@ -459,7 +459,7 @@
 TEST(PickleTest, EvilLengths) {
   Pickle source;
   std::string str(100000, 'A');
-  EXPECT_TRUE(source.WriteData(str.c_str(), 100000));
+  source.WriteData(str.c_str(), 100000);
   // ReadString16 used to have its read buffer length calculation wrong leading
   // to out-of-bounds reading.
   PickleIterator iter(source);
@@ -469,7 +469,7 @@
   // And check we didn't break ReadString16.
   str16 = (wchar_t) 'A';
   Pickle str16_pickle;
-  EXPECT_TRUE(str16_pickle.WriteString16(str16));
+  str16_pickle.WriteString16(str16);
   iter = PickleIterator(str16_pickle);
   EXPECT_TRUE(iter.ReadString16(&str16));
   EXPECT_EQ(1U, str16.length());
@@ -477,7 +477,7 @@
   // Check we don't fail in a length check with invalid String16 size.
   // (1<<31) * sizeof(char16) == 0, so this is particularly evil.
   Pickle bad_len;
-  EXPECT_TRUE(bad_len.WriteInt(1 << 31));
+  bad_len.WriteInt(1 << 31);
   iter = PickleIterator(bad_len);
   EXPECT_FALSE(iter.ReadString16(&str16));
 }
@@ -485,7 +485,7 @@
 // Check we can write zero bytes of data and 'data' can be NULL.
 TEST(PickleTest, ZeroLength) {
   Pickle pickle;
-  EXPECT_TRUE(pickle.WriteData(NULL, 0));
+  pickle.WriteData(NULL, 0);
 
   PickleIterator iter(pickle);
   const char* outdata;
@@ -499,7 +499,7 @@
 TEST(PickleTest, ReadBytes) {
   Pickle pickle;
   int data = 0x7abcd;
-  EXPECT_TRUE(pickle.WriteBytes(&data, sizeof(data)));
+  pickle.WriteBytes(&data, sizeof(data));
 
   PickleIterator iter(pickle);
   const char* outdata_char = NULL;
diff --git a/cc/BUILD.gn b/cc/BUILD.gn
index 56d68f26..65d2b69 100644
--- a/cc/BUILD.gn
+++ b/cc/BUILD.gn
@@ -282,6 +282,8 @@
     "trees/element_id.h",
     "trees/frame_rate_counter.cc",
     "trees/frame_rate_counter.h",
+    "trees/image_animation_controller.cc",
+    "trees/image_animation_controller.h",
     "trees/latency_info_swap_promise.cc",
     "trees/latency_info_swap_promise.h",
     "trees/latency_info_swap_promise_monitor.cc",
@@ -410,6 +412,8 @@
     "test/fake_output_surface.h",
     "test/fake_output_surface_client.cc",
     "test/fake_output_surface_client.h",
+    "test/fake_paint_image_generator.cc",
+    "test/fake_paint_image_generator.h",
     "test/fake_painted_scrollbar_layer.cc",
     "test/fake_painted_scrollbar_layer.h",
     "test/fake_picture_layer.cc",
@@ -485,8 +489,6 @@
     "test/stub_layer_tree_host_client.h",
     "test/stub_layer_tree_host_single_thread_client.cc",
     "test/stub_layer_tree_host_single_thread_client.h",
-    "test/stub_paint_image_generator.cc",
-    "test/stub_paint_image_generator.h",
     "test/task_graph_runner_test_template.cc",
     "test/task_graph_runner_test_template.h",
     "test/test_context_provider.cc",
@@ -645,6 +647,7 @@
     "tiles/tile_priority_unittest.cc",
     "trees/blocking_task_runner_unittest.cc",
     "trees/damage_tracker_unittest.cc",
+    "trees/image_animation_controller_unittest.cc",
     "trees/layer_tree_frame_sink_unittest.cc",
     "trees/layer_tree_host_common_unittest.cc",
     "trees/layer_tree_host_impl_unittest.cc",
diff --git a/cc/benchmarks/rasterize_and_record_benchmark_impl.cc b/cc/benchmarks/rasterize_and_record_benchmark_impl.cc
index c0690b68..e28e367 100644
--- a/cc/benchmarks/rasterize_and_record_benchmark_impl.cc
+++ b/cc/benchmarks/rasterize_and_record_benchmark_impl.cc
@@ -60,7 +60,7 @@
 
       PlaybackImageProvider image_provider(false, PaintImageIdFlatSet(), {},
                                            image_decode_cache,
-                                           gfx::ColorSpace());
+                                           gfx::ColorSpace(), {});
       RasterSource::PlaybackSettings settings;
       settings.image_provider = &image_provider;
 
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc
index f81e710..e640106 100644
--- a/cc/layers/picture_layer_impl.cc
+++ b/cc/layers/picture_layer_impl.cc
@@ -20,6 +20,7 @@
 #include "cc/debug/debug_colors.h"
 #include "cc/layers/append_quads_data.h"
 #include "cc/layers/solid_color_layer_impl.h"
+#include "cc/paint/display_item_list.h"
 #include "cc/tiles/tile_manager.h"
 #include "cc/tiles/tiling_set_raster_queue_all.h"
 #include "cc/trees/layer_tree_impl.h"
@@ -119,6 +120,9 @@
   if (twin_layer_)
     twin_layer_->twin_layer_ = nullptr;
   layer_tree_impl()->UnregisterPictureLayerImpl(this);
+
+  // Unregister for all images on the current raster source.
+  UnregisterAnimatedImages();
 }
 
 void PictureLayerImpl::SetLayerMaskType(Layer::LayerMaskType mask_type) {
@@ -598,11 +602,27 @@
       << " bounds " << bounds().ToString() << " pile "
       << raster_source->GetSize().ToString();
 
+  // We have an updated recording if the DisplayItemList in the new RasterSource
+  // is different.
+  const bool recording_updated =
+      !raster_source_ || raster_source_->GetDisplayItemList() !=
+                             raster_source->GetDisplayItemList();
+
+  // Unregister for all images on the current raster source, if the recording
+  // was updated.
+  if (recording_updated)
+    UnregisterAnimatedImages();
+
   // The |raster_source_| is initially null, so have to check for that for the
   // first frame.
   bool could_have_tilings = raster_source_.get() && CanHaveTilings();
   raster_source_.swap(raster_source);
 
+  // Register images from the new raster source, if the recording was updated.
+  // TODO(khushalsagar): UMA the number of animated images in layer?
+  if (recording_updated)
+    RegisterAnimatedImages();
+
   // The |new_invalidation| must be cleared before updating tilings since they
   // access the invalidation through the PictureLayerTilingClient interface.
   invalidation_.Clear();
@@ -746,6 +766,26 @@
   return GetScaledEnclosingRectInTargetSpace(MaximumTilingContentsScale());
 }
 
+bool PictureLayerImpl::ShouldAnimate(PaintImage::Id paint_image_id) const {
+  DCHECK(raster_source_);
+
+  // Only animate images for layers which HasValidTilePriorities. This check is
+  // important for 2 reasons:
+  // 1) It avoids doing additional work for layers we don't plan to rasterize
+  //    and/or draw. The updated state will be pulled by the animation system
+  //    if the draw properties change.
+  // 2) It eliminates considering layers on the recycle tree. Once the pending
+  //    tree is activated, the layers on the recycle tree remain registered as
+  //    animation drivers, but should not drive animations since they don't have
+  //    updated draw properties.
+  //
+  //  Additionally only animate images which are on-screen, animations are
+  //  paused once they are not visible.
+  return HasValidTilePriorities() &&
+         raster_source_->GetRectForImage(paint_image_id)
+             .Intersects(visible_layer_rect());
+}
+
 gfx::Size PictureLayerImpl::CalculateTileSize(
     const gfx::Size& content_bounds) const {
   int max_texture_size =
@@ -1502,4 +1542,38 @@
                    "Invalidation", invalidation.ToString());
 }
 
+void PictureLayerImpl::RegisterAnimatedImages() {
+  if (!raster_source_ || !raster_source_->GetDisplayItemList())
+    return;
+
+  auto* controller = layer_tree_impl()->image_animation_controller();
+  if (!controller)
+    return;
+
+  const auto& metadata = raster_source_->GetDisplayItemList()
+                             ->discardable_image_map()
+                             .animated_images_metadata();
+  for (const auto& data : metadata) {
+    // Only update the metadata from updated recordings received from a commit.
+    if (layer_tree_impl()->IsSyncTree())
+      controller->UpdateAnimatedImage(data);
+    controller->RegisterAnimationDriver(data.paint_image_id, this);
+  }
+}
+
+void PictureLayerImpl::UnregisterAnimatedImages() {
+  if (!raster_source_ || !raster_source_->GetDisplayItemList())
+    return;
+
+  auto* controller = layer_tree_impl()->image_animation_controller();
+  if (!controller)
+    return;
+
+  const auto& metadata = raster_source_->GetDisplayItemList()
+                             ->discardable_image_map()
+                             .animated_images_metadata();
+  for (const auto& data : metadata)
+    controller->UnregisterAnimationDriver(data.paint_image_id, this);
+}
+
 }  // namespace cc
diff --git a/cc/layers/picture_layer_impl.h b/cc/layers/picture_layer_impl.h
index 62cdcff..10ebaed 100644
--- a/cc/layers/picture_layer_impl.h
+++ b/cc/layers/picture_layer_impl.h
@@ -20,6 +20,7 @@
 #include "cc/tiles/picture_layer_tiling.h"
 #include "cc/tiles/picture_layer_tiling_set.h"
 #include "cc/tiles/tiling_set_eviction_queue.h"
+#include "cc/trees/image_animation_controller.h"
 
 namespace cc {
 
@@ -27,8 +28,10 @@
 class MicroBenchmarkImpl;
 class Tile;
 
-class CC_EXPORT PictureLayerImpl : public LayerImpl,
-                                   public PictureLayerTilingClient {
+class CC_EXPORT PictureLayerImpl
+    : public LayerImpl,
+      public PictureLayerTilingClient,
+      public ImageAnimationController::AnimationDriver {
  public:
   static std::unique_ptr<PictureLayerImpl>
   Create(LayerTreeImpl* tree_impl, int id, Layer::LayerMaskType mask_type) {
@@ -63,6 +66,9 @@
   bool RequiresHighResToDraw() const override;
   gfx::Rect GetEnclosingRectInTargetSpace() const override;
 
+  // ImageAnimationController::AnimationDriver overrides.
+  bool ShouldAnimate(PaintImage::Id paint_image_id) const override;
+
   void set_gpu_raster_max_texture_size(gfx::Size gpu_raster_max_texture_size) {
     gpu_raster_max_texture_size_ = gpu_raster_max_texture_size;
   }
@@ -107,6 +113,8 @@
 
   bool RasterSourceUsesLCDTextForTesting() const { return can_use_lcd_text_; }
 
+  const Region& InvalidationForTesting() const { return invalidation_; }
+
  protected:
   PictureLayerImpl(LayerTreeImpl* tree_impl,
                    int id,
@@ -136,6 +144,9 @@
   float MaximumTilingContentsScale() const;
   std::unique_ptr<PictureLayerTilingSet> CreatePictureLayerTilingSet();
 
+  void RegisterAnimatedImages();
+  void UnregisterAnimatedImages();
+
   PictureLayerImpl* twin_layer_;
 
   std::unique_ptr<PictureLayerTilingSet> tilings_;
diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc
index f80d13ca..465463d 100644
--- a/cc/layers/picture_layer_impl_unittest.cc
+++ b/cc/layers/picture_layer_impl_unittest.cc
@@ -29,6 +29,7 @@
 #include "cc/test/fake_recording_source.h"
 #include "cc/test/geometry_test_utils.h"
 #include "cc/test/layer_test_common.h"
+#include "cc/test/skia_common.h"
 #include "cc/test/test_layer_tree_host_base.h"
 #include "cc/test/test_task_graph_runner.h"
 #include "cc/test/test_web_graphics_context_3d.h"
@@ -84,6 +85,7 @@
     settings.create_low_res_tiling = true;
     settings.resource_settings.buffer_to_texture_target_map =
         viz::DefaultBufferToTextureTargetMapForTesting();
+    settings.enable_image_animations = true;
     return settings;
   }
 
@@ -5199,5 +5201,59 @@
   }
 }
 
+TEST_F(PictureLayerImplTest, AnimatedImages) {
+  gfx::Size layer_bounds(1000, 1000);
+
+  // Set up a raster source with 2 animated images.
+  auto recording_source = FakeRecordingSource::CreateRecordingSource(
+      gfx::Rect(layer_bounds), layer_bounds);
+  std::vector<FrameMetadata> frames = {
+      FrameMetadata(true, base::TimeDelta::FromMilliseconds(1)),
+      FrameMetadata(true, base::TimeDelta::FromMilliseconds(1))};
+  PaintImage image1 = CreateAnimatedImage(gfx::Size(200, 200), frames);
+  PaintImage image2 = CreateAnimatedImage(gfx::Size(200, 200), frames);
+  recording_source->add_draw_image(image1, gfx::Point(100, 100));
+  recording_source->add_draw_image(image2, gfx::Point(500, 500));
+  recording_source->Rerecord();
+  scoped_refptr<RasterSource> raster_source =
+      recording_source->CreateRasterSource();
+
+  // All images should be registered on the pending layer.
+  SetupPendingTree(raster_source, gfx::Size(), Region(gfx::Rect(layer_bounds)));
+  auto* controller = host_impl()->image_animation_controller();
+  EXPECT_EQ(controller->GetDriversForTesting(image1.stable_id())
+                .count(pending_layer()),
+            1u);
+  EXPECT_EQ(controller->GetDriversForTesting(image2.stable_id())
+                .count(pending_layer()),
+            1u);
+
+  // Make only the first image visible and verify that only this image is
+  // animated.
+  gfx::Rect visible_rect(0, 0, 300, 300);
+  pending_layer()->set_visible_layer_rect(visible_rect);
+  EXPECT_TRUE(pending_layer()->ShouldAnimate(image1.stable_id()));
+  EXPECT_FALSE(pending_layer()->ShouldAnimate(image2.stable_id()));
+
+  // Now activate and make sure the active layer is registered as well.
+  ActivateTree();
+  active_layer()->set_visible_layer_rect(visible_rect);
+  EXPECT_EQ(controller->GetDriversForTesting(image1.stable_id())
+                .count(active_layer()),
+            1u);
+  EXPECT_EQ(controller->GetDriversForTesting(image2.stable_id())
+                .count(active_layer()),
+            1u);
+
+  // Once activated, only the active layer should drive animations for these
+  // images. Since DrawProperties are not updated on the recycle tree, it has
+  // stale state for visibility of images.
+  ASSERT_EQ(old_pending_layer()->visible_layer_rect(), visible_rect);
+  EXPECT_FALSE(old_pending_layer()->ShouldAnimate(image1.stable_id()));
+  EXPECT_FALSE(old_pending_layer()->ShouldAnimate(image2.stable_id()));
+  EXPECT_TRUE(active_layer()->ShouldAnimate(image1.stable_id()));
+  EXPECT_FALSE(active_layer()->ShouldAnimate(image2.stable_id()));
+}
+
 }  // namespace
 }  // namespace cc
diff --git a/cc/layers/recording_source_unittest.cc b/cc/layers/recording_source_unittest.cc
index 002ec5c..82c424f 100644
--- a/cc/layers/recording_source_unittest.cc
+++ b/cc/layers/recording_source_unittest.cc
@@ -111,7 +111,8 @@
     std::vector<const DrawImage*> images;
     raster_source->GetDiscardableImagesInRect(gfx::Rect(130, 0, 128, 128),
                                               &images);
-    DrawImage image(*images[0], scale, DefaultColorSpace());
+    DrawImage image(*images[0], scale, PaintImage::kDefaultFrameIndex,
+                    DefaultColorSpace());
     EXPECT_EQ(1u, images.size());
     EXPECT_FLOAT_EQ(scale, image.scale().width());
     EXPECT_FLOAT_EQ(scale, image.scale().height());
diff --git a/cc/paint/discardable_image_map.h b/cc/paint/discardable_image_map.h
index b3113020..d3b66aa 100644
--- a/cc/paint/discardable_image_map.h
+++ b/cc/paint/discardable_image_map.h
@@ -30,7 +30,7 @@
 // rect and get back a list of DrawImages in that rect.
 class CC_PAINT_EXPORT DiscardableImageMap {
  public:
-  struct AnimatedImageMetadata {
+  struct CC_PAINT_EXPORT AnimatedImageMetadata {
     AnimatedImageMetadata(PaintImage::Id paint_image_id,
                           PaintImage::CompletionState completion_state,
                           std::vector<FrameMetadata> frames,
diff --git a/cc/paint/discardable_image_map_unittest.cc b/cc/paint/discardable_image_map_unittest.cc
index fcfc074..0e8a6d20e 100644
--- a/cc/paint/discardable_image_map_unittest.cc
+++ b/cc/paint/discardable_image_map_unittest.cc
@@ -9,6 +9,7 @@
 #include <memory>
 
 #include "base/memory/ref_counted.h"
+#include "base/test/gtest_util.h"
 #include "base/values.h"
 #include "cc/base/region.h"
 #include "cc/paint/paint_flags.h"
@@ -60,7 +61,8 @@
     image_map.GetDiscardableImagesInRect(rect, &draw_image_ptrs);
     std::vector<DrawImage> draw_images;
     for (const auto* image : draw_image_ptrs)
-      draw_images.push_back(DrawImage(*image, 1.f, target_color_space));
+      draw_images.push_back(DrawImage(
+          *image, 1.f, PaintImage::kDefaultFrameIndex, target_color_space));
 
     std::vector<PositionScaleDrawImage> position_draw_images;
     for (DrawImage& image : image_map.images_rtree_.Search(rect)) {
@@ -698,11 +700,16 @@
   FakeContentLayerClient content_layer_client;
   content_layer_client.set_bounds(visible_rect.size());
 
+  std::vector<FrameMetadata> frames = {
+      FrameMetadata(true, base::TimeDelta::FromMilliseconds(2)),
+      FrameMetadata(true, base::TimeDelta::FromMilliseconds(3))};
+
   gfx::Size image_size(100, 100);
   PaintImage static_image = CreateDiscardablePaintImage(image_size);
   PaintImage animated_loop_none =
-      CreateAnimatedImage(image_size, {FrameMetadata()}, kAnimationNone);
-  PaintImage animation_loop_infinite = CreateAnimatedImage(image_size);
+      CreateAnimatedImage(image_size, frames, kAnimationNone);
+  PaintImage animation_loop_infinite =
+      CreateAnimatedImage(image_size, frames, 1u);
 
   PaintFlags flags;
   content_layer_client.add_draw_image(static_image, gfx::Point(0, 0), flags);
@@ -727,6 +734,17 @@
             animation_loop_infinite.GetFrameMetadata());
   EXPECT_EQ(animated_images_metadata[0].repetition_count,
             animation_loop_infinite.repetition_count());
+
+  std::vector<const DrawImage*> images;
+  display_list->discardable_image_map().GetDiscardableImagesInRect(visible_rect,
+                                                                   &images);
+  ASSERT_EQ(images.size(), 3u);
+  EXPECT_EQ(images[0]->paint_image(), static_image);
+  EXPECT_DCHECK_DEATH(images[0]->frame_index());
+  EXPECT_EQ(images[1]->paint_image(), animated_loop_none);
+  EXPECT_DCHECK_DEATH(images[1]->frame_index());
+  EXPECT_EQ(images[2]->paint_image(), animation_loop_infinite);
+  EXPECT_DCHECK_DEATH(images[2]->frame_index());
 }
 
 class DiscardableImageMapColorSpaceTest
diff --git a/cc/paint/draw_image.cc b/cc/paint/draw_image.cc
index 7b7314b..a1a78af 100644
--- a/cc/paint/draw_image.cc
+++ b/cc/paint/draw_image.cc
@@ -32,16 +32,19 @@
                      const SkIRect& src_rect,
                      SkFilterQuality filter_quality,
                      const SkMatrix& matrix,
+                     base::Optional<size_t> frame_index,
                      const base::Optional<gfx::ColorSpace>& color_space)
     : paint_image_(std::move(image)),
       src_rect_(src_rect),
       filter_quality_(filter_quality),
+      frame_index_(frame_index),
       target_color_space_(color_space) {
   matrix_is_decomposable_ = ExtractScale(matrix, &scale_);
 }
 
 DrawImage::DrawImage(const DrawImage& other,
                      float scale_adjustment,
+                     size_t frame_index,
                      const gfx::ColorSpace& color_space)
     : paint_image_(other.paint_image_),
       src_rect_(other.src_rect_),
@@ -49,6 +52,7 @@
       scale_(SkSize::Make(other.scale_.width() * scale_adjustment,
                           other.scale_.height() * scale_adjustment)),
       matrix_is_decomposable_(other.matrix_is_decomposable_),
+      frame_index_(frame_index),
       target_color_space_(color_space) {}
 
 DrawImage::DrawImage(const DrawImage& other) = default;
diff --git a/cc/paint/draw_image.h b/cc/paint/draw_image.h
index 58c46d9..81c45d1 100644
--- a/cc/paint/draw_image.h
+++ b/cc/paint/draw_image.h
@@ -25,11 +25,13 @@
             const SkIRect& src_rect,
             SkFilterQuality filter_quality,
             const SkMatrix& matrix,
+            base::Optional<size_t> frame_index = base::nullopt,
             const base::Optional<gfx::ColorSpace>& color_space = base::nullopt);
   // Constructs a DrawImage from |other| by adjusting its scale and setting a
   // new color_space.
   DrawImage(const DrawImage& other,
             float scale_adjustment,
+            size_t frame_index,
             const gfx::ColorSpace& color_space);
   DrawImage(const DrawImage& other);
   DrawImage(DrawImage&& other);
@@ -50,7 +52,11 @@
     return *target_color_space_;
   }
   PaintImage::FrameKey frame_key() const {
-    return paint_image_.GetKeyForFrame(paint_image_.frame_index());
+    return paint_image_.GetKeyForFrame(frame_index());
+  }
+  size_t frame_index() const {
+    DCHECK(frame_index_.has_value());
+    return frame_index_.value();
   }
 
  private:
@@ -59,6 +65,7 @@
   SkFilterQuality filter_quality_;
   SkSize scale_;
   bool matrix_is_decomposable_;
+  base::Optional<size_t> frame_index_;
   base::Optional<gfx::ColorSpace> target_color_space_;
 };
 
diff --git a/cc/paint/paint_image.cc b/cc/paint/paint_image.cc
index b18eb20..f941d60 100644
--- a/cc/paint/paint_image.cc
+++ b/cc/paint/paint_image.cc
@@ -18,6 +18,9 @@
 base::AtomicSequenceNumber s_next_content_id_;
 }  // namespace
 
+const int PaintImage::kNonLazyStableId = -1;
+const size_t PaintImage::kDefaultFrameIndex = 0u;
+
 PaintImage::PaintImage() = default;
 PaintImage::PaintImage(const PaintImage& other) = default;
 PaintImage::PaintImage(PaintImage&& other) = default;
@@ -118,7 +121,8 @@
 
 bool PaintImage::Decode(void* memory,
                         SkImageInfo* info,
-                        sk_sp<SkColorSpace> color_space) const {
+                        sk_sp<SkColorSpace> color_space,
+                        size_t frame_index) const {
   // We only support decode to supported decode size.
   DCHECK(info->dimensions() == GetSupportedDecodeSize(info->dimensions()));
 
@@ -129,13 +133,15 @@
   // requested size into the space of the original image. For now, fallback to
   // DecodeFromSkImage().
   if (paint_image_generator_ && subset_rect_.IsEmpty())
-    return DecodeFromGenerator(memory, info, std::move(color_space));
-  return DecodeFromSkImage(memory, info, std::move(color_space));
+    return DecodeFromGenerator(memory, info, std::move(color_space),
+                               frame_index);
+  return DecodeFromSkImage(memory, info, std::move(color_space), frame_index);
 }
 
 bool PaintImage::DecodeFromGenerator(void* memory,
                                      SkImageInfo* info,
-                                     sk_sp<SkColorSpace> color_space) const {
+                                     sk_sp<SkColorSpace> color_space,
+                                     size_t frame_index) const {
   DCHECK(subset_rect_.IsEmpty());
 
   // First convert the info to have the requested color space, since the decoder
@@ -151,7 +157,7 @@
 
     bool result = paint_image_generator_->GetPixels(n32info, n32memory.get(),
                                                     n32info.minRowBytes(),
-                                                    frame_index(), unique_id());
+                                                    frame_index, unique_id());
     if (!result)
       return false;
 
@@ -172,13 +178,14 @@
   }
 
   return paint_image_generator_->GetPixels(*info, memory, info->minRowBytes(),
-                                           frame_index(), unique_id());
+                                           frame_index, unique_id());
 }
 
 bool PaintImage::DecodeFromSkImage(void* memory,
                                    SkImageInfo* info,
-                                   sk_sp<SkColorSpace> color_space) const {
-  auto image = GetSkImage();
+                                   sk_sp<SkColorSpace> color_space,
+                                   size_t frame_index) const {
+  auto image = GetSkImageForFrame(frame_index);
   DCHECK(image);
   if (color_space) {
     image =
@@ -196,7 +203,7 @@
 
 bool PaintImage::ShouldAnimate() const {
   return animation_type_ == AnimationType::ANIMATED &&
-         repetition_count_ != kAnimationNone;
+         repetition_count_ != kAnimationNone && FrameCount() > 1;
 }
 
 PaintImage::FrameKey PaintImage::GetKeyForFrame(size_t frame_index) const {
@@ -230,6 +237,19 @@
              : 1u;
 }
 
+sk_sp<SkImage> PaintImage::GetSkImageForFrame(size_t index) const {
+  DCHECK_LT(index, FrameCount());
+
+  if (index == frame_index_)
+    return GetSkImage();
+
+  sk_sp<SkImage> image = SkImage::MakeFromGenerator(
+      base::MakeUnique<SkiaPaintImageGenerator>(paint_image_generator_, index));
+  if (!subset_rect_.IsEmpty())
+    image = image->makeSubset(gfx::RectToSkIRect(subset_rect_));
+  return image;
+}
+
 std::string PaintImage::ToString() const {
   std::ostringstream str;
   str << "sk_image_: " << sk_image_ << " paint_record_: " << paint_record_
diff --git a/cc/paint/paint_image.h b/cc/paint/paint_image.h
index 9eeff94..83e237b 100644
--- a/cc/paint/paint_image.h
+++ b/cc/paint/paint_image.h
@@ -39,11 +39,11 @@
   // An id that can be used for all non-lazy images. Note that if an image is
   // not lazy, it does not mean that this id must be used; one can still use
   // GetNextId to generate a stable id for such images.
-  static const Id kNonLazyStableId = -1;
+  static const Id kNonLazyStableId;
 
   // The default frame index to use if no index is provided. For multi-frame
   // images, this would imply the first frame of the animation.
-  static const size_t kDefaultFrameIndex = 0;
+  static const size_t kDefaultFrameIndex;
 
   class CC_PAINT_EXPORT FrameKey {
    public:
@@ -53,6 +53,7 @@
 
     uint64_t hash() const { return hash_; }
     std::string ToString() const;
+    size_t frame_index() const { return frame_index_; }
 
    private:
     ContentId content_id_;
@@ -112,7 +113,8 @@
   // is texture backed.
   bool Decode(void* memory,
               SkImageInfo* info,
-              sk_sp<SkColorSpace> color_space) const;
+              sk_sp<SkColorSpace> color_space,
+              size_t frame_index) const;
 
   Id stable_id() const { return id_; }
   const sk_sp<SkImage>& GetSkImage() const;
@@ -142,6 +144,9 @@
   // Returns the total number of frames known to exist in this image.
   size_t FrameCount() const;
 
+  // Returns an SkImage for the frame at |index|.
+  sk_sp<SkImage> GetSkImageForFrame(size_t index) const;
+
   std::string ToString() const;
 
  private:
@@ -151,10 +156,12 @@
 
   bool DecodeFromGenerator(void* memory,
                            SkImageInfo* info,
-                           sk_sp<SkColorSpace> color_space) const;
+                           sk_sp<SkColorSpace> color_space,
+                           size_t frame_index) const;
   bool DecodeFromSkImage(void* memory,
                          SkImageInfo* info,
-                         sk_sp<SkColorSpace> color_space) const;
+                         sk_sp<SkColorSpace> color_space,
+                         size_t frame_index) const;
 
   sk_sp<SkImage> sk_image_;
 
diff --git a/cc/paint/paint_image_builder.cc b/cc/paint/paint_image_builder.cc
index 399ac0b..da6387db 100644
--- a/cc/paint/paint_image_builder.cc
+++ b/cc/paint/paint_image_builder.cc
@@ -43,6 +43,13 @@
     DCHECK(!paint_image_.sk_image_);
     DCHECK(!paint_image_.paint_record_);
   }
+
+  if (paint_image_.ShouldAnimate()) {
+    DCHECK(paint_image_.paint_image_generator_)
+        << "Animated images must provide a generator";
+    for (const auto& frame : paint_image_.GetFrameMetadata())
+      DCHECK_GT(frame.duration, base::TimeDelta());
+  }
 #endif
 
   return std::move(paint_image_);
diff --git a/cc/paint/paint_image_unittest.cc b/cc/paint/paint_image_unittest.cc
index 0fe9a4ff..d3f743b 100644
--- a/cc/paint/paint_image_unittest.cc
+++ b/cc/paint/paint_image_unittest.cc
@@ -5,6 +5,8 @@
 #include "cc/paint/paint_image.h"
 
 #include "base/test/gtest_util.h"
+#include "cc/paint/paint_image_builder.h"
+#include "cc/test/fake_paint_image_generator.h"
 #include "cc/test/skia_common.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -31,4 +33,42 @@
   EXPECT_DCHECK_DEATH(image.MakeSubset(gfx::Rect()));
 }
 
+TEST(PaintImageTest, DecodesCorrectFrames) {
+  std::vector<FrameMetadata> frames = {
+      FrameMetadata(true, base::TimeDelta::FromMilliseconds(2)),
+      FrameMetadata(true, base::TimeDelta::FromMilliseconds(3))};
+  sk_sp<FakePaintImageGenerator> generator =
+      sk_make_sp<FakePaintImageGenerator>(SkImageInfo::MakeN32Premul(10, 10),
+                                          frames);
+  PaintImage image = PaintImageBuilder()
+                         .set_id(PaintImage::GetNextId())
+                         .set_paint_image_generator(generator)
+                         .set_frame_index(0u)
+                         .TakePaintImage();
+
+  // The recorded index is 0u but ask for 1u frame.
+  SkImageInfo info = SkImageInfo::MakeN32Premul(10, 10);
+  std::vector<size_t> memory(info.getSafeSize(info.minRowBytes()));
+  image.Decode(memory.data(), &info, nullptr, 1u);
+  ASSERT_EQ(generator->frames_decoded().size(), 1u);
+  EXPECT_EQ(generator->frames_decoded().count(1u), 1u);
+  generator->reset_frames_decoded();
+
+  // Subsetted.
+  PaintImage subset_image = image.MakeSubset(gfx::Rect(0, 0, 5, 5));
+  SkImageInfo subset_info = info.makeWH(5, 5);
+  subset_image.Decode(memory.data(), &subset_info, nullptr, 1u);
+  ASSERT_EQ(generator->frames_decoded().size(), 1u);
+  EXPECT_EQ(generator->frames_decoded().count(1u), 1u);
+  generator->reset_frames_decoded();
+
+  // Not N32 color type.
+  info.makeColorType(kRGB_565_SkColorType);
+  memory = std::vector<size_t>(info.getSafeSize(info.minRowBytes()));
+  image.Decode(memory.data(), &info, nullptr, 1u);
+  ASSERT_EQ(generator->frames_decoded().size(), 1u);
+  EXPECT_EQ(generator->frames_decoded().count(1u), 1u);
+  generator->reset_frames_decoded();
+}
+
 }  // namespace cc
diff --git a/cc/raster/playback_image_provider.cc b/cc/raster/playback_image_provider.cc
index d6856fd..86bc53b 100644
--- a/cc/raster/playback_image_provider.cc
+++ b/cc/raster/playback_image_provider.cc
@@ -22,12 +22,14 @@
     PaintImageIdFlatSet images_to_skip,
     std::vector<DrawImage> at_raster_images,
     ImageDecodeCache* cache,
-    const gfx::ColorSpace& target_color_space)
+    const gfx::ColorSpace& target_color_space,
+    base::flat_map<PaintImage::Id, size_t> image_to_current_frame_index)
     : skip_all_images_(skip_all_images),
       images_to_skip_(std::move(images_to_skip)),
       at_raster_images_(std::move(at_raster_images)),
       cache_(cache),
-      target_color_space_(target_color_space) {
+      target_color_space_(target_color_space),
+      image_to_current_frame_index_(std::move(image_to_current_frame_index)) {
   DCHECK(cache_);
 }
 
@@ -77,8 +79,14 @@
                          SkSize::Make(1.f, 1.f), draw_image.filter_quality()));
   }
 
-  DrawImage adjusted_image(draw_image, 1.f, target_color_space_);
+  const auto& it = image_to_current_frame_index_.find(paint_image.stable_id());
+  size_t frame_index = it == image_to_current_frame_index_.end()
+                           ? paint_image.frame_index()
+                           : it->second;
+
+  DrawImage adjusted_image(draw_image, 1.f, frame_index, target_color_space_);
   auto decoded_draw_image = cache_->GetDecodedImageForDraw(adjusted_image);
+
   return ScopedDecodedDrawImage(
       decoded_draw_image,
       base::BindOnce(&UnrefImageFromCache, std::move(adjusted_image), cache_));
diff --git a/cc/raster/playback_image_provider.h b/cc/raster/playback_image_provider.h
index bb2fc34..ddd2633c 100644
--- a/cc/raster/playback_image_provider.h
+++ b/cc/raster/playback_image_provider.h
@@ -5,6 +5,7 @@
 #ifndef CC_RASTER_PLAYBACK_IMAGE_PROVIDER_H_
 #define CC_RASTER_PLAYBACK_IMAGE_PROVIDER_H_
 
+#include "base/containers/flat_map.h"
 #include "cc/cc_export.h"
 #include "cc/paint/image_id.h"
 #include "cc/paint/image_provider.h"
@@ -21,11 +22,13 @@
 //    only be used for lazy generated images.
 class CC_EXPORT PlaybackImageProvider : public ImageProvider {
  public:
-  PlaybackImageProvider(bool skip_all_images,
-                        PaintImageIdFlatSet images_to_skip,
-                        std::vector<DrawImage> at_raster_images,
-                        ImageDecodeCache* cache,
-                        const gfx::ColorSpace& taget_color_space);
+  PlaybackImageProvider(
+      bool skip_all_images,
+      PaintImageIdFlatSet images_to_skip,
+      std::vector<DrawImage> at_raster_images,
+      ImageDecodeCache* cache,
+      const gfx::ColorSpace& taget_color_space,
+      base::flat_map<PaintImage::Id, size_t> image_to_current_frame_index);
   ~PlaybackImageProvider() override;
 
   void BeginRaster() override;
@@ -46,6 +49,7 @@
   std::vector<ImageProvider::ScopedDecodedDrawImage> decoded_at_raster_;
   ImageDecodeCache* cache_;
   gfx::ColorSpace target_color_space_;
+  base::flat_map<PaintImage::Id, size_t> image_to_current_frame_index_;
 
   DISALLOW_COPY_AND_ASSIGN(PlaybackImageProvider);
 };
diff --git a/cc/raster/playback_image_provider_unittest.cc b/cc/raster/playback_image_provider_unittest.cc
index 42d7783..153b484 100644
--- a/cc/raster/playback_image_provider_unittest.cc
+++ b/cc/raster/playback_image_provider_unittest.cc
@@ -30,6 +30,7 @@
 
   DecodedDrawImage GetDecodedImageForDraw(
       const DrawImage& draw_image) override {
+    last_image_ = draw_image;
     images_decoded_++;
     refed_image_count_++;
     return CreateDecode();
@@ -44,15 +45,17 @@
 
   int refed_image_count() const { return refed_image_count_; }
   int images_decoded() const { return images_decoded_; }
+  const DrawImage& last_image() { return last_image_; }
 
  private:
   int refed_image_count_ = 0;
   int images_decoded_ = 0;
+  DrawImage last_image_;
 };
 
 TEST(PlaybackImageProviderTest, SkipsAllImages) {
   MockDecodeCache cache;
-  PlaybackImageProvider provider(true, {}, {}, &cache, gfx::ColorSpace());
+  PlaybackImageProvider provider(true, {}, {}, &cache, gfx::ColorSpace(), {});
   provider.BeginRaster();
 
   SkIRect rect = SkIRect::MakeWH(10, 10);
@@ -77,7 +80,7 @@
   MockDecodeCache cache;
   PaintImage skip_image = CreateDiscardablePaintImage(gfx::Size(10, 10));
   PlaybackImageProvider provider(false, {skip_image.stable_id()}, {}, &cache,
-                                 gfx::ColorSpace());
+                                 gfx::ColorSpace(), {});
   provider.BeginRaster();
 
   SkIRect rect = SkIRect::MakeWH(10, 10);
@@ -90,7 +93,7 @@
 
 TEST(PlaybackImageProviderTest, RefAndUnrefDecode) {
   MockDecodeCache cache;
-  PlaybackImageProvider provider(false, {}, {}, &cache, gfx::ColorSpace());
+  PlaybackImageProvider provider(false, {}, {}, &cache, gfx::ColorSpace(), {});
   provider.BeginRaster();
 
   {
@@ -120,7 +123,7 @@
       size, nullptr, rect, kMedium_SkFilterQuality, matrix);
 
   PlaybackImageProvider provider(false, {}, {draw_image1, draw_image2}, &cache,
-                                 gfx::ColorSpace());
+                                 gfx::ColorSpace(), {});
 
   EXPECT_EQ(cache.refed_image_count(), 0);
   provider.BeginRaster();
@@ -132,5 +135,29 @@
   EXPECT_EQ(cache.images_decoded(), 2);
 }
 
+TEST(PlaybackImageProviderTest, SwapsGivenFrames) {
+  MockDecodeCache cache;
+  std::vector<FrameMetadata> frames = {
+      FrameMetadata(true, base::TimeDelta::FromMilliseconds(2)),
+      FrameMetadata(true, base::TimeDelta::FromMilliseconds(3))};
+  PaintImage image = CreateAnimatedImage(gfx::Size(10, 10), frames);
+
+  base::flat_map<PaintImage::Id, size_t> image_to_frame;
+  image_to_frame[image.stable_id()] = 1u;
+  PlaybackImageProvider provider(false, {}, {}, &cache, gfx::ColorSpace(),
+                                 image_to_frame);
+  provider.BeginRaster();
+
+  SkIRect rect = SkIRect::MakeWH(10, 10);
+  SkMatrix matrix = SkMatrix::I();
+  DrawImage draw_image(image, rect, kMedium_SkFilterQuality, matrix);
+  provider.GetDecodedDrawImage(draw_image);
+  ASSERT_TRUE(cache.last_image().paint_image());
+  ASSERT_EQ(cache.last_image().paint_image(), image);
+  ASSERT_EQ(cache.last_image().frame_index(), 1u);
+
+  provider.EndRaster();
+}
+
 }  // namespace
 }  // namespace cc
diff --git a/cc/raster/raster_source_unittest.cc b/cc/raster/raster_source_unittest.cc
index b6de90c..b89083e 100644
--- a/cc/raster/raster_source_unittest.cc
+++ b/cc/raster/raster_source_unittest.cc
@@ -215,7 +215,8 @@
     std::vector<const DrawImage*> images;
     raster->GetDiscardableImagesInRect(gfx::Rect(0, 0, 256, 256), &images);
     EXPECT_EQ(1u, images.size());
-    DrawImage image(*images[0], 1.f, target_color_space);
+    DrawImage image(*images[0], 1.f, PaintImage::kDefaultFrameIndex,
+                    target_color_space);
     EXPECT_EQ(discardable_image[0][0], images[0]->paint_image());
     EXPECT_EQ(target_color_space, image.target_color_space());
   }
@@ -225,7 +226,8 @@
     std::vector<const DrawImage*> images;
     raster->GetDiscardableImagesInRect(gfx::Rect(260, 260, 256, 256), &images);
     EXPECT_EQ(1u, images.size());
-    DrawImage image(*images[0], 1.f, target_color_space);
+    DrawImage image(*images[0], 1.f, PaintImage::kDefaultFrameIndex,
+                    target_color_space);
     EXPECT_EQ(discardable_image[1][1], images[0]->paint_image());
     EXPECT_EQ(target_color_space, image.target_color_space());
   }
diff --git a/cc/scheduler/scheduler_state_machine.cc b/cc/scheduler/scheduler_state_machine.cc
index 494ecabe..f101af6 100644
--- a/cc/scheduler/scheduler_state_machine.cc
+++ b/cc/scheduler/scheduler_state_machine.cc
@@ -592,6 +592,8 @@
 
   // Only perform impl side invalidation after the frame ends so that we wait
   // for any commit to happen before invalidating.
+  // TODO(khushalsagar): Invalidate at the beginning of the frame if there is no
+  // commit request from the main thread.
   if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE)
     return false;
 
diff --git a/cc/test/fake_paint_image_generator.cc b/cc/test/fake_paint_image_generator.cc
new file mode 100644
index 0000000..bf0412d
--- /dev/null
+++ b/cc/test/fake_paint_image_generator.cc
@@ -0,0 +1,44 @@
+// 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 <cc/test/fake_paint_image_generator.h>
+
+namespace cc {
+
+FakePaintImageGenerator::FakePaintImageGenerator(
+    const SkImageInfo& info,
+    std::vector<FrameMetadata> frames)
+    : PaintImageGenerator(info, std::move(frames)),
+      image_backing_memory_(info.getSafeSize(info.minRowBytes()), 0),
+      image_pixmap_(info, image_backing_memory_.data(), info.minRowBytes()) {}
+
+FakePaintImageGenerator::~FakePaintImageGenerator() = default;
+
+sk_sp<SkData> FakePaintImageGenerator::GetEncodedData() const {
+  return nullptr;
+}
+
+bool FakePaintImageGenerator::GetPixels(const SkImageInfo& info,
+                                        void* pixels,
+                                        size_t row_bytes,
+                                        size_t frame_index,
+                                        uint32_t lazy_pixel_ref) {
+  frames_decoded_.insert(frame_index);
+  return true;
+}
+
+bool FakePaintImageGenerator::QueryYUV8(SkYUVSizeInfo* info,
+                                        SkYUVColorSpace* color_space) const {
+  return false;
+}
+
+bool FakePaintImageGenerator::GetYUV8Planes(const SkYUVSizeInfo& info,
+                                            void* planes[3],
+                                            size_t frame_index,
+                                            uint32_t lazy_pixel_ref) {
+  NOTREACHED();
+  return false;
+}
+
+}  // namespace cc
diff --git a/cc/test/fake_paint_image_generator.h b/cc/test/fake_paint_image_generator.h
new file mode 100644
index 0000000..c8f4491
--- /dev/null
+++ b/cc/test/fake_paint_image_generator.h
@@ -0,0 +1,46 @@
+// 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 CC_TEST_FAKE_PAINT_IMAGE_GENERATOR_H_
+#define CC_TEST_FAKE_PAINT_IMAGE_GENERATOR_H_
+
+#include "base/containers/flat_set.h"
+#include "cc/paint/paint_image_generator.h"
+
+namespace cc {
+
+class FakePaintImageGenerator : public PaintImageGenerator {
+ public:
+  explicit FakePaintImageGenerator(const SkImageInfo& info,
+                                   std::vector<FrameMetadata> frames = {
+                                       FrameMetadata()});
+  ~FakePaintImageGenerator() override;
+
+  sk_sp<SkData> GetEncodedData() const override;
+  bool GetPixels(const SkImageInfo& info,
+                 void* pixels,
+                 size_t row_bytes,
+                 size_t frame_index,
+                 uint32_t lazy_pixel_ref) override;
+  bool QueryYUV8(SkYUVSizeInfo* info,
+                 SkYUVColorSpace* color_space) const override;
+  bool GetYUV8Planes(const SkYUVSizeInfo& info,
+                     void* planes[3],
+                     size_t frame_index,
+                     uint32_t lazy_pixel_ref) override;
+
+  const base::flat_set<size_t>& frames_decoded() const {
+    return frames_decoded_;
+  }
+  void reset_frames_decoded() { frames_decoded_.clear(); }
+
+ private:
+  std::vector<uint8_t> image_backing_memory_;
+  SkPixmap image_pixmap_;
+  base::flat_set<size_t> frames_decoded_;
+};
+
+}  // namespace cc
+
+#endif  // CC_TEST_FAKE_PAINT_IMAGE_GENERATOR_H_
diff --git a/cc/test/fake_tile_manager_client.cc b/cc/test/fake_tile_manager_client.cc
index 8325acc..28bd304 100644
--- a/cc/test/fake_tile_manager_client.cc
+++ b/cc/test/fake_tile_manager_client.cc
@@ -29,4 +29,10 @@
   return gfx::ColorSpace();
 }
 
+size_t FakeTileManagerClient::GetFrameIndexForImage(
+    const PaintImage& paint_image,
+    WhichTree tree) const {
+  return paint_image.frame_index();
+}
+
 }  // namespace cc
diff --git a/cc/test/fake_tile_manager_client.h b/cc/test/fake_tile_manager_client.h
index 3597d79..c618a39dc 100644
--- a/cc/test/fake_tile_manager_client.h
+++ b/cc/test/fake_tile_manager_client.h
@@ -29,6 +29,8 @@
   void SetIsLikelyToRequireADraw(bool is_likely_to_require_a_draw) override {}
   gfx::ColorSpace GetRasterColorSpace() const override;
   void RequestImplSideInvalidationForCheckerImagedTiles() override {}
+  size_t GetFrameIndexForImage(const PaintImage& paint_image,
+                               WhichTree tree) const override;
 };
 
 }  // namespace cc
diff --git a/cc/test/skia_common.cc b/cc/test/skia_common.cc
index 2effb65..0219b14 100644
--- a/cc/test/skia_common.cc
+++ b/cc/test/skia_common.cc
@@ -11,7 +11,7 @@
 #include "cc/paint/draw_image.h"
 #include "cc/paint/paint_canvas.h"
 #include "cc/paint/paint_image_builder.h"
-#include "cc/test/stub_paint_image_generator.h"
+#include "cc/test/fake_paint_image_generator.h"
 #include "third_party/skia/include/core/SkImageGenerator.h"
 #include "third_party/skia/include/core/SkPixmap.h"
 #include "ui/gfx/geometry/rect.h"
@@ -19,30 +19,6 @@
 
 namespace cc {
 
-namespace {
-
-class TestImageGenerator : public StubPaintImageGenerator {
- public:
-  explicit TestImageGenerator(const SkImageInfo& info)
-      : StubPaintImageGenerator(info),
-        image_backing_memory_(info.getSafeSize(info.minRowBytes()), 0),
-        image_pixmap_(info, image_backing_memory_.data(), info.minRowBytes()) {}
-
-  bool GetPixels(const SkImageInfo& info,
-                 void* pixels,
-                 size_t rowBytes,
-                 size_t frame_index,
-                 uint32_t lazy_pixel_ref) override {
-    return image_pixmap_.readPixels(info, pixels, rowBytes, 0, 0);
-  }
-
- private:
-  std::vector<uint8_t> image_backing_memory_;
-  SkPixmap image_pixmap_;
-};
-
-}  // anonymous namespace
-
 void DrawDisplayList(unsigned char* buffer,
                      const gfx::Rect& layer_rect,
                      scoped_refptr<const DisplayItemList> list) {
@@ -71,7 +47,7 @@
 }
 
 sk_sp<PaintImageGenerator> CreatePaintImageGenerator(const gfx::Size& size) {
-  return sk_make_sp<TestImageGenerator>(
+  return sk_make_sp<FakePaintImageGenerator>(
       SkImageInfo::MakeN32Premul(size.width(), size.height()));
 }
 
@@ -79,7 +55,7 @@
                                        sk_sp<SkColorSpace> color_space) {
   return PaintImageBuilder()
       .set_id(PaintImage::GetNextId())
-      .set_paint_image_generator(sk_make_sp<TestImageGenerator>(
+      .set_paint_image_generator(sk_make_sp<FakePaintImageGenerator>(
           SkImageInfo::MakeN32Premul(size.width(), size.height(), color_space)))
       .TakePaintImage();
 }
@@ -98,13 +74,16 @@
 
 PaintImage CreateAnimatedImage(const gfx::Size& size,
                                std::vector<FrameMetadata> frames,
-                               int repetition_count) {
+                               int repetition_count,
+                               size_t frame_index) {
   return PaintImageBuilder()
       .set_id(PaintImage::GetNextId())
-      .set_paint_image_generator(sk_make_sp<TestImageGenerator>(
-          SkImageInfo::MakeN32Premul(size.width(), size.height())))
+      .set_paint_image_generator(sk_make_sp<FakePaintImageGenerator>(
+          SkImageInfo::MakeN32Premul(size.width(), size.height()),
+          std::move(frames)))
       .set_animation_type(PaintImage::AnimationType::ANIMATED)
       .set_repetition_count(repetition_count)
+      .set_frame_index(frame_index)
       .TakePaintImage();
 }
 
diff --git a/cc/test/skia_common.h b/cc/test/skia_common.h
index 4cc4429e..b0c3241 100644
--- a/cc/test/skia_common.h
+++ b/cc/test/skia_common.h
@@ -45,8 +45,9 @@
 
 PaintImage CreateAnimatedImage(
     const gfx::Size& size,
-    std::vector<FrameMetadata> frames = {FrameMetadata()},
-    int repetition_count = kAnimationLoopInfinite);
+    std::vector<FrameMetadata> frames,
+    int repetition_count = kAnimationLoopInfinite,
+    size_t frame_index = PaintImage::kDefaultFrameIndex);
 
 }  // namespace cc
 
diff --git a/cc/test/stub_paint_image_generator.cc b/cc/test/stub_paint_image_generator.cc
deleted file mode 100644
index dce8372..0000000
--- a/cc/test/stub_paint_image_generator.cc
+++ /dev/null
@@ -1,33 +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.
-
-#include "cc/test/stub_paint_image_generator.h"
-
-namespace cc {
-
-sk_sp<SkData> StubPaintImageGenerator::GetEncodedData() const {
-  return nullptr;
-}
-
-bool StubPaintImageGenerator::GetPixels(const SkImageInfo& info,
-                                        void* pixels,
-                                        size_t row_bytes,
-                                        size_t frame_index,
-                                        uint32_t lazy_pixel_ref) {
-  return false;
-}
-
-bool StubPaintImageGenerator::QueryYUV8(SkYUVSizeInfo* info,
-                                        SkYUVColorSpace* color_space) const {
-  return false;
-}
-
-bool StubPaintImageGenerator::GetYUV8Planes(const SkYUVSizeInfo& info,
-                                            void* planes[3],
-                                            size_t frame_index,
-                                            uint32_t lazy_pixel_ref) {
-  return false;
-}
-
-}  // namespace cc
diff --git a/cc/test/stub_paint_image_generator.h b/cc/test/stub_paint_image_generator.h
deleted file mode 100644
index 0d566cd2..0000000
--- a/cc/test/stub_paint_image_generator.h
+++ /dev/null
@@ -1,33 +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.
-
-#ifndef CC_TEST_STUB_PAINT_IMAGE_GENERATOR_H_
-#define CC_TEST_STUB_PAINT_IMAGE_GENERATOR_H_
-
-#include "cc/paint/paint_image_generator.h"
-
-namespace cc {
-
-class StubPaintImageGenerator : public PaintImageGenerator {
- public:
-  explicit StubPaintImageGenerator(const SkImageInfo& info)
-      : PaintImageGenerator(info) {}
-
-  sk_sp<SkData> GetEncodedData() const override;
-  bool GetPixels(const SkImageInfo& info,
-                 void* pixels,
-                 size_t row_bytes,
-                 size_t frame_index,
-                 uint32_t lazy_pixel_ref) override;
-  bool QueryYUV8(SkYUVSizeInfo* info,
-                 SkYUVColorSpace* color_space) const override;
-  bool GetYUV8Planes(const SkYUVSizeInfo& info,
-                     void* planes[3],
-                     size_t frame_index,
-                     uint32_t lazy_pixel_ref) override;
-};
-
-}  // namespace cc
-
-#endif  // CC_TEST_STUB_PAINT_IMAGE_GENERATOR_H_
diff --git a/cc/tiles/checker_image_tracker.cc b/cc/tiles/checker_image_tracker.cc
index ccdfd3f..d1f221a1 100644
--- a/cc/tiles/checker_image_tracker.cc
+++ b/cc/tiles/checker_image_tracker.cc
@@ -362,6 +362,7 @@
   decode_state->filter_quality =
       std::max(decode_state->filter_quality, draw_image.filter_quality());
   decode_state->color_space = draw_image.target_color_space();
+  decode_state->frame_index = draw_image.frame_index();
 }
 
 void CheckerImageTracker::ScheduleNextImageDecode() {
@@ -400,7 +401,7 @@
         it->second.filter_quality,
         SkMatrix::MakeScale(it->second.scale.width(),
                             it->second.scale.height()),
-        it->second.color_space);
+        it->second.frame_index, it->second.color_space);
     outstanding_image_decode_.emplace(candidate);
     break;
   }
diff --git a/cc/tiles/checker_image_tracker.h b/cc/tiles/checker_image_tracker.h
index 095c868f..f415f86 100644
--- a/cc/tiles/checker_image_tracker.h
+++ b/cc/tiles/checker_image_tracker.h
@@ -130,6 +130,7 @@
     SkFilterQuality filter_quality = kNone_SkFilterQuality;
     SkSize scale = SkSize::MakeEmpty();
     gfx::ColorSpace color_space;
+    size_t frame_index = PaintImage::kDefaultFrameIndex;
   };
 
   // Wrapper to unlock an image decode requested from the ImageController on
diff --git a/cc/tiles/checker_image_tracker_unittest.cc b/cc/tiles/checker_image_tracker_unittest.cc
index ef0fcddd..504a16f9 100644
--- a/cc/tiles/checker_image_tracker_unittest.cc
+++ b/cc/tiles/checker_image_tracker_unittest.cc
@@ -121,7 +121,8 @@
                          .set_is_multipart(is_multipart)
                          .TakePaintImage(),
                      SkIRect::MakeWH(dimension, dimension),
-                     kNone_SkFilterQuality, SkMatrix::I(), gfx::ColorSpace());
+                     kNone_SkFilterQuality, SkMatrix::I(),
+                     PaintImage::kDefaultFrameIndex, gfx::ColorSpace());
   }
 
   bool ShouldCheckerImage(const DrawImage& draw_image, WhichTree tree) {
@@ -433,7 +434,8 @@
           .set_paint_image_generator(CreatePaintImageGenerator(image_size))
           .TakePaintImage(),
       SkIRect::MakeWH(image_size.width(), image_size.height()),
-      kNone_SkFilterQuality, SkMatrix::I(), gfx::ColorSpace());
+      kNone_SkFilterQuality, SkMatrix::I(), PaintImage::kDefaultFrameIndex,
+      gfx::ColorSpace());
   EXPECT_FALSE(
       ShouldCheckerImage(completed_paint_image, WhichTree::PENDING_TREE));
 }
@@ -460,10 +462,12 @@
   SetUpTracker(true);
 
   DrawImage image = CreateImage(ImageType::CHECKERABLE);
-  DrawImage scaled_image1(image, 0.5f, gfx::ColorSpace());
+  DrawImage scaled_image1(image, 0.5f, PaintImage::kDefaultFrameIndex,
+                          gfx::ColorSpace());
   DrawImage scaled_image2 =
       DrawImage(image.paint_image(), image.src_rect(), kHigh_SkFilterQuality,
-                SkMatrix::MakeScale(1.8f), gfx::ColorSpace());
+                SkMatrix::MakeScale(1.8f), PaintImage::kDefaultFrameIndex,
+                gfx::ColorSpace());
 
   std::vector<DrawImage> draw_images = {scaled_image1, scaled_image2};
   CheckerImageTracker::ImageDecodeQueue image_decode_queue =
@@ -538,7 +542,7 @@
   DrawImage image = CreateImage(ImageType::CHECKERABLE);
   image = DrawImage(image.paint_image(), SkIRect::MakeWH(200, 200),
                     image.filter_quality(), SkMatrix::I(),
-                    image.target_color_space());
+                    PaintImage::kDefaultFrameIndex, image.target_color_space());
   EXPECT_FALSE(ShouldCheckerImage(image, WhichTree::PENDING_TREE));
 }
 
diff --git a/cc/tiles/decoded_image_tracker.cc b/cc/tiles/decoded_image_tracker.cc
index 00cf27a..ebe3cc0 100644
--- a/cc/tiles/decoded_image_tracker.cc
+++ b/cc/tiles/decoded_image_tracker.cc
@@ -29,10 +29,8 @@
   gfx::ColorSpace target_color_space;
 
   auto image_bounds = SkIRect::MakeWH(image.width(), image.height());
-  // TODO(khushalsagar): Eliminate the use of an incorrect id here and have all
-  // call-sites provide PaintImage to the ImageController.
   DrawImage draw_image(image, image_bounds, kNone_SkFilterQuality,
-                       SkMatrix::I(), target_color_space);
+                       SkMatrix::I(), image.frame_index(), target_color_space);
   image_controller_->QueueImageDecode(
       draw_image, base::Bind(&DecodedImageTracker::ImageDecodeFinished,
                              base::Unretained(this), callback));
diff --git a/cc/tiles/gpu_image_decode_cache.cc b/cc/tiles/gpu_image_decode_cache.cc
index c96aeff1..6c2028f 100644
--- a/cc/tiles/gpu_image_decode_cache.cc
+++ b/cc/tiles/gpu_image_decode_cache.cc
@@ -121,7 +121,8 @@
 // if not, decodes to a compatible temporary pixmap and then converts that into
 // the |target_pixmap|.
 bool DrawAndScaleImage(const DrawImage& draw_image, SkPixmap* target_pixmap) {
-  const SkImage* image = draw_image.paint_image().GetSkImage().get();
+  sk_sp<SkImage> image =
+      draw_image.paint_image().GetSkImageForFrame(draw_image.frame_index());
   if (image->dimensions() == target_pixmap->bounds().size() ||
       target_pixmap->info().colorType() == kN32_SkColorType) {
     // If no scaling is occurring, or if the target colortype is already N32,
@@ -210,7 +211,7 @@
     TRACE_EVENT2("cc", "ImageDecodeTaskImpl::RunOnWorkerThread", "mode", "gpu",
                  "source_prepare_tiles_id", tracing_info_.prepare_tiles_id);
     devtools_instrumentation::ScopedImageDecodeTask image_decode_task(
-        image_.paint_image().GetSkImage().get(),
+        &image_.paint_image(),
         devtools_instrumentation::ScopedImageDecodeTask::kGpu,
         ImageDecodeCache::ToScopedTaskType(tracing_info_.task_type));
     cache_->DecodeImage(image_, tracing_info_.task_type);
@@ -1178,7 +1179,8 @@
         // TODO(crbug.com/649167): Params should not have changed since initial
         // sizing. Somehow this still happens. We should investigate and re-add
         // DCHECKs here to enforce this.
-        SkImage* image = draw_image.paint_image().GetSkImage().get();
+        sk_sp<SkImage> image = draw_image.paint_image().GetSkImageForFrame(
+            draw_image.frame_index());
         if (!image->getDeferredTextureImageData(
                 *context_threadsafe_proxy_.get(), &image_data->upload_params, 1,
                 backing_memory->data(), nullptr, color_type_)) {
@@ -1283,7 +1285,8 @@
   auto params = SkImage::DeferredTextureImageUsageParams(
       SkMatrix::I(), CalculateDesiredFilterQuality(draw_image),
       upload_scale_mip_level);
-  SkImage* image = draw_image.paint_image().GetSkImage().get();
+  sk_sp<SkImage> image =
+      draw_image.paint_image().GetSkImageForFrame(draw_image.frame_index());
   size_t data_size = image->getDeferredTextureImageData(
       *context_threadsafe_proxy_.get(), &params, 1, nullptr, nullptr,
       color_type_);
diff --git a/cc/tiles/gpu_image_decode_cache_unittest.cc b/cc/tiles/gpu_image_decode_cache_unittest.cc
index 61c4e0b..56b5d1f 100644
--- a/cc/tiles/gpu_image_decode_cache_unittest.cc
+++ b/cc/tiles/gpu_image_decode_cache_unittest.cc
@@ -6,6 +6,7 @@
 
 #include "cc/paint/draw_image.h"
 #include "cc/paint/paint_image_builder.h"
+#include "cc/test/fake_paint_image_generator.h"
 #include "cc/test/skia_common.h"
 #include "cc/test/test_context_provider.h"
 #include "cc/test/test_tile_task_runner.h"
@@ -56,7 +57,7 @@
   DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
                        quality,
                        CreateMatrix(SkSize::Make(1.5f, 1.5f), is_decomposable),
-                       DefaultColorSpace());
+                       PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult result =
       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(result.need_unref);
@@ -65,7 +66,7 @@
   DrawImage another_draw_image(
       image, SkIRect::MakeWH(image.width(), image.height()), quality,
       CreateMatrix(SkSize::Make(1.5f, 1.5f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult another_result = cache.GetTaskForImageAndRef(
       another_draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(another_result.need_unref);
@@ -89,7 +90,7 @@
   DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
                        quality,
                        CreateMatrix(SkSize::Make(1.5f, 1.5f), is_decomposable),
-                       DefaultColorSpace());
+                       PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult result =
       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(result.need_unref);
@@ -98,7 +99,7 @@
   DrawImage another_draw_image(
       image, SkIRect::MakeWH(image.width(), image.height()), quality,
       CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult another_result = cache.GetTaskForImageAndRef(
       another_draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(another_result.need_unref);
@@ -120,7 +121,8 @@
   SkMatrix matrix = CreateMatrix(SkSize::Make(0.4f, 0.4f), is_decomposable);
 
   DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
-                       kHigh_SkFilterQuality, matrix, DefaultColorSpace());
+                       kHigh_SkFilterQuality, matrix,
+                       PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult result =
       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(result.need_unref);
@@ -128,7 +130,8 @@
 
   DrawImage another_draw_image(
       image, SkIRect::MakeWH(image.width(), image.height()),
-      kLow_SkFilterQuality, matrix, DefaultColorSpace());
+      kLow_SkFilterQuality, matrix, PaintImage::kDefaultFrameIndex,
+      DefaultColorSpace());
   ImageDecodeCache::TaskResult another_result = cache.GetTaskForImageAndRef(
       another_draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(another_result.need_unref);
@@ -152,7 +155,7 @@
   DrawImage first_draw_image(
       first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
       quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult first_result = cache.GetTaskForImageAndRef(
       first_draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(first_result.need_unref);
@@ -163,7 +166,7 @@
       second_image,
       SkIRect::MakeWH(second_image.width(), second_image.height()), quality,
       CreateMatrix(SkSize::Make(0.25f, 0.25f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult second_result = cache.GetTaskForImageAndRef(
       second_draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(second_result.need_unref);
@@ -190,7 +193,7 @@
   DrawImage first_draw_image(
       first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
       quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult first_result = cache.GetTaskForImageAndRef(
       first_draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(first_result.need_unref);
@@ -204,7 +207,7 @@
   DrawImage second_draw_image(
       first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
       quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult second_result = cache.GetTaskForImageAndRef(
       second_draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(second_result.need_unref);
@@ -214,7 +217,7 @@
   DrawImage third_draw_image(
       first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
       quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult third_result = cache.GetTaskForImageAndRef(
       third_draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(third_result.need_unref);
@@ -238,7 +241,7 @@
   DrawImage first_draw_image(
       first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
       quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult first_result = cache.GetTaskForImageAndRef(
       first_draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(first_result.need_unref);
@@ -247,7 +250,7 @@
   DrawImage second_draw_image(
       first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
       quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult second_result = cache.GetTaskForImageAndRef(
       second_draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(second_result.need_unref);
@@ -257,7 +260,7 @@
   DrawImage third_draw_image(
       first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
       quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult third_result = cache.GetTaskForImageAndRef(
       third_draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(third_result.need_unref);
@@ -283,7 +286,8 @@
   PaintImage first_image = CreateDiscardablePaintImage(gfx::Size(100, 100));
   DrawImage first_draw_image(
       first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
-      kLow_SkFilterQuality, matrix, DefaultColorSpace());
+      kLow_SkFilterQuality, matrix, PaintImage::kDefaultFrameIndex,
+      DefaultColorSpace());
   ImageDecodeCache::TaskResult first_result = cache.GetTaskForImageAndRef(
       first_draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(first_result.need_unref);
@@ -296,7 +300,8 @@
 
   DrawImage second_draw_image(
       first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
-      kHigh_SkFilterQuality, matrix, DefaultColorSpace());
+      kHigh_SkFilterQuality, matrix, PaintImage::kDefaultFrameIndex,
+      DefaultColorSpace());
   ImageDecodeCache::TaskResult second_result = cache.GetTaskForImageAndRef(
       second_draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(second_result.need_unref);
@@ -320,7 +325,7 @@
   DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
                        quality,
                        CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
-                       DefaultColorSpace());
+                       PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult result =
       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(result.need_unref);
@@ -364,7 +369,7 @@
   DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
                        quality,
                        CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
-                       DefaultColorSpace());
+                       PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult result =
       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(result.need_unref);
@@ -408,7 +413,7 @@
   DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
                        quality,
                        CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
-                       DefaultColorSpace());
+                       PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult result =
       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(result.need_unref);
@@ -442,7 +447,7 @@
   DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
                        quality,
                        CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
-                       DefaultColorSpace());
+                       PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult result =
       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(result.need_unref);
@@ -487,7 +492,7 @@
   DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
                        quality,
                        CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
-                       DefaultColorSpace());
+                       PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult result =
       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(result.need_unref);
@@ -536,7 +541,7 @@
   DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
                        quality,
                        CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
-                       DefaultColorSpace());
+                       PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult result =
       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(result.need_unref);
@@ -568,7 +573,7 @@
   DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
                        quality,
                        CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
-                       DefaultColorSpace());
+                       PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult result =
       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(result.need_unref);
@@ -603,7 +608,7 @@
   DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
                        quality,
                        CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
-                       DefaultColorSpace());
+                       PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult result =
       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(result.need_unref);
@@ -641,7 +646,7 @@
   DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
                        quality,
                        CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
-                       DefaultColorSpace());
+                       PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   ImageDecodeCache::TaskResult result =
       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -673,7 +678,7 @@
   DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
                        kLow_SkFilterQuality,
                        CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
-                       DefaultColorSpace());
+                       PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult result =
       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(result.need_unref);
@@ -685,7 +690,7 @@
   DrawImage larger_draw_image(
       image, SkIRect::MakeWH(image.width(), image.height()), quality,
       CreateMatrix(SkSize::Make(1.5f, 1.5f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult larger_result = cache.GetTaskForImageAndRef(
       larger_draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(larger_result.need_unref);
@@ -732,7 +737,8 @@
 
   PaintImage image = CreateDiscardablePaintImage(gfx::Size(100, 100));
   DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
-                       kLow_SkFilterQuality, matrix, DefaultColorSpace());
+                       kLow_SkFilterQuality, matrix,
+                       PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult result =
       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(result.need_unref);
@@ -743,7 +749,8 @@
 
   DrawImage higher_quality_draw_image(
       image, SkIRect::MakeWH(image.width(), image.height()),
-      kHigh_SkFilterQuality, matrix, DefaultColorSpace());
+      kHigh_SkFilterQuality, matrix, PaintImage::kDefaultFrameIndex,
+      DefaultColorSpace());
   ImageDecodeCache::TaskResult hq_result = cache.GetTaskForImageAndRef(
       higher_quality_draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(hq_result.need_unref);
@@ -792,7 +799,7 @@
   DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
                        quality,
                        CreateMatrix(SkSize::Make(-0.5f, 0.5f), is_decomposable),
-                       DefaultColorSpace());
+                       PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult result =
       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(result.need_unref);
@@ -829,7 +836,7 @@
   DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
                        quality,
                        CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
-                       DefaultColorSpace());
+                       PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult result =
       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(result.need_unref);
@@ -870,7 +877,7 @@
   DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
                        quality,
                        CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
-                       DefaultColorSpace());
+                       PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   ImageDecodeCache::TaskResult result =
       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -915,7 +922,7 @@
   DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
                        quality,
                        CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
-                       DefaultColorSpace());
+                       PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   // Must hold context lock before calling GetDecodedImageForDraw /
   // DrawWithImageFinished.
@@ -949,7 +956,7 @@
   DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
                        quality,
                        CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
-                       DefaultColorSpace());
+                       PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   // Must hold context lock before calling GetDecodedImageForDraw /
   // DrawWithImageFinished.
@@ -989,7 +996,7 @@
   DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
                        quality,
                        CreateMatrix(SkSize::Make(0.f, 0.f), is_decomposable),
-                       DefaultColorSpace());
+                       PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   ImageDecodeCache::TaskResult result =
       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1017,7 +1024,7 @@
   DrawImage draw_image(
       image, SkIRect::MakeXYWH(150, 150, image.width(), image.height()),
       quality, CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   ImageDecodeCache::TaskResult result =
       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1045,7 +1052,7 @@
   DrawImage draw_image(
       image, SkIRect::MakeXYWH(0, 0, image.width(), image.height()), quality,
       CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   ImageDecodeCache::TaskResult result =
       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1073,8 +1080,7 @@
   DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
                        quality,
                        CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
-                       DefaultColorSpace());
-
+                       PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   {
     ImageDecodeCache::TaskResult result = cache.GetTaskForImageAndRef(
         draw_image, ImageDecodeCache::TracingInfo());
@@ -1138,7 +1144,7 @@
   DrawImage first_draw_image(
       first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
       quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult first_result = cache.GetTaskForImageAndRef(
       first_draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(first_result.need_unref);
@@ -1153,7 +1159,7 @@
   DrawImage second_draw_image(
       first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
       quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult second_result = cache.GetTaskForImageAndRef(
       second_draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(second_result.need_unref);
@@ -1193,7 +1199,7 @@
   DrawImage first_draw_image(
       first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
       quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult first_result = cache.GetTaskForImageAndRef(
       first_draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(first_result.need_unref);
@@ -1212,7 +1218,7 @@
   DrawImage second_draw_image(
       first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
       quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult second_result = cache.GetTaskForImageAndRef(
       second_draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(second_result.need_unref);
@@ -1240,7 +1246,8 @@
   // Create an image with kLow_FilterQuality.
   DrawImage low_draw_image(image,
                            SkIRect::MakeWH(image.width(), image.height()),
-                           kLow_SkFilterQuality, matrix, DefaultColorSpace());
+                           kLow_SkFilterQuality, matrix,
+                           PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult low_result = cache.GetTaskForImageAndRef(
       low_draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(low_result.need_unref);
@@ -1250,7 +1257,8 @@
   // should get a new task/ref.
   DrawImage medium_draw_image(
       image, SkIRect::MakeWH(image.width(), image.height()),
-      kMedium_SkFilterQuality, matrix, DefaultColorSpace());
+      kMedium_SkFilterQuality, matrix, PaintImage::kDefaultFrameIndex,
+      DefaultColorSpace());
   ImageDecodeCache::TaskResult medium_result = cache.GetTaskForImageAndRef(
       medium_draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(medium_result.need_unref);
@@ -1260,7 +1268,8 @@
   // Get the same image at kHigh_FilterQuality. We should re-use medium.
   DrawImage large_draw_image(
       image, SkIRect::MakeWH(image.width(), image.height()),
-      kHigh_SkFilterQuality, matrix, DefaultColorSpace());
+      kHigh_SkFilterQuality, matrix, PaintImage::kDefaultFrameIndex,
+      DefaultColorSpace());
   ImageDecodeCache::TaskResult large_result = cache.GetTaskForImageAndRef(
       large_draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(large_result.need_unref);
@@ -1290,7 +1299,7 @@
   DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
                        quality,
                        CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
-                       DefaultColorSpace());
+                       PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult result =
       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(result.need_unref);
@@ -1312,7 +1321,7 @@
   DrawImage draw_image_mips(
       image, SkIRect::MakeWH(image.width(), image.height()), quality,
       CreateMatrix(SkSize::Make(0.6f, 0.6f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   DecodedDrawImage decoded_draw_image =
       cache.GetDecodedImageForDraw(draw_image_mips);
   cache.DrawWithImageFinished(draw_image_mips, decoded_draw_image);
@@ -1328,7 +1337,8 @@
   bool is_decomposable = true;
   SkMatrix matrix = CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable);
   DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
-                       kLow_SkFilterQuality, matrix, DefaultColorSpace());
+                       kLow_SkFilterQuality, matrix,
+                       PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult result =
       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(result.need_unref);
@@ -1396,7 +1406,8 @@
   bool is_decomposable = true;
   SkMatrix matrix = CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable);
   DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
-                       kLow_SkFilterQuality, matrix, DefaultColorSpace());
+                       kLow_SkFilterQuality, matrix,
+                       PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   ImageDecodeCache::TaskResult result =
       cache.GetOutOfRasterDecodeTaskForImageAndRef(draw_image);
@@ -1427,7 +1438,7 @@
   DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
                        quality,
                        CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
-                       DefaultColorSpace());
+                       PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult result =
       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(result.need_unref);
@@ -1479,13 +1490,13 @@
   DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
                        quality,
                        CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
-                       DefaultColorSpace());
+                       PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   PaintImage image2 = CreateDiscardablePaintImage(gfx::Size(100, 100));
   DrawImage draw_image2(
       image2, SkIRect::MakeWH(image2.width(), image2.height()), quality,
       CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   // Add an image to the cache and un-ref it.
   {
@@ -1564,7 +1575,7 @@
     DrawImage draw_image(
         image, SkIRect::MakeWH(image.width(), image.height()), quality,
         CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
-        DefaultColorSpace());
+        PaintImage::kDefaultFrameIndex, DefaultColorSpace());
     ImageDecodeCache::TaskResult result = cache.GetTaskForImageAndRef(
         draw_image, ImageDecodeCache::TracingInfo());
     EXPECT_TRUE(result.need_unref);
@@ -1598,7 +1609,7 @@
   DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
                        quality,
                        CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
-                       DefaultColorSpace());
+                       PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult result =
       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(result.need_unref);
@@ -1637,7 +1648,7 @@
   DrawImage first_draw_image(
       first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
       quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
-      color_space_a);
+      PaintImage::kDefaultFrameIndex, color_space_a);
   ImageDecodeCache::TaskResult first_result = cache.GetTaskForImageAndRef(
       first_draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(first_result.need_unref);
@@ -1646,7 +1657,7 @@
   DrawImage second_draw_image(
       first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
       quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
-      color_space_b);
+      PaintImage::kDefaultFrameIndex, color_space_b);
   ImageDecodeCache::TaskResult second_result = cache.GetTaskForImageAndRef(
       second_draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(second_result.need_unref);
@@ -1656,7 +1667,7 @@
   DrawImage third_draw_image(
       first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
       quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
-      color_space_a);
+      PaintImage::kDefaultFrameIndex, color_space_a);
   ImageDecodeCache::TaskResult third_result = cache.GetTaskForImageAndRef(
       third_draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(third_result.need_unref);
@@ -1685,7 +1696,7 @@
     DrawImage draw_image(
         image, SkIRect::MakeWH(image.width(), image.height()), quality,
         CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
-        DefaultColorSpace());
+        PaintImage::kDefaultFrameIndex, DefaultColorSpace());
     frame_keys.push_back(draw_image.frame_key());
     ImageDecodeCache::TaskResult result = cache.GetTaskForImageAndRef(
         draw_image, ImageDecodeCache::TracingInfo());
@@ -1707,6 +1718,64 @@
   }
 }
 
+TEST_P(GpuImageDecodeCacheTest, CacheDecodesExpectedFrames) {
+  auto context_provider = TestContextProvider::Create();
+  context_provider->BindToCurrentThread();
+  TestGpuImageDecodeCache cache(context_provider.get(), GetParam());
+
+  std::vector<FrameMetadata> frames = {
+      FrameMetadata(true, base::TimeDelta::FromMilliseconds(2)),
+      FrameMetadata(true, base::TimeDelta::FromMilliseconds(3)),
+      FrameMetadata(true, base::TimeDelta::FromMilliseconds(4)),
+      FrameMetadata(true, base::TimeDelta::FromMilliseconds(5)),
+  };
+  sk_sp<FakePaintImageGenerator> generator =
+      sk_make_sp<FakePaintImageGenerator>(SkImageInfo::MakeN32Premul(10, 10),
+                                          frames);
+  PaintImage image = PaintImageBuilder()
+                         .set_id(PaintImage::GetNextId())
+                         .set_paint_image_generator(generator)
+                         .set_frame_index(0u)
+                         .TakePaintImage();
+
+  viz::ContextProvider::ScopedContextLock context_lock(context_provider.get());
+
+  bool is_decomposable = true;
+  SkFilterQuality quality = kHigh_SkFilterQuality;
+  DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
+                       quality,
+                       CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
+                       1u, DefaultColorSpace());
+  auto decoded_image = cache.GetDecodedImageForDraw(draw_image);
+  ASSERT_TRUE(decoded_image.image());
+  ASSERT_EQ(generator->frames_decoded().size(), 1u);
+  EXPECT_EQ(generator->frames_decoded().count(1u), 1u);
+  generator->reset_frames_decoded();
+  cache.DrawWithImageFinished(draw_image, decoded_image);
+
+  // Scaled.
+  DrawImage scaled_draw_image(draw_image, 0.5f, 2u,
+                              draw_image.target_color_space());
+  decoded_image = cache.GetDecodedImageForDraw(scaled_draw_image);
+  ASSERT_TRUE(decoded_image.image());
+  ASSERT_EQ(generator->frames_decoded().size(), 1u);
+  EXPECT_EQ(generator->frames_decoded().count(2u), 1u);
+  generator->reset_frames_decoded();
+  cache.DrawWithImageFinished(scaled_draw_image, decoded_image);
+
+  // Subset.
+  DrawImage subset_draw_image(
+      image, SkIRect::MakeWH(5, 5), quality,
+      CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable), 3u,
+      DefaultColorSpace());
+  decoded_image = cache.GetDecodedImageForDraw(subset_draw_image);
+  ASSERT_TRUE(decoded_image.image());
+  ASSERT_EQ(generator->frames_decoded().size(), 1u);
+  EXPECT_EQ(generator->frames_decoded().count(3u), 1u);
+  generator->reset_frames_decoded();
+  cache.DrawWithImageFinished(subset_draw_image, decoded_image);
+}
+
 INSTANTIATE_TEST_CASE_P(GpuImageDecodeCacheTests,
                         GpuImageDecodeCacheTest,
                         ::testing::Values(kN32_SkColorType,
diff --git a/cc/tiles/image_controller_unittest.cc b/cc/tiles/image_controller_unittest.cc
index fd4d809..081c46c 100644
--- a/cc/tiles/image_controller_unittest.cc
+++ b/cc/tiles/image_controller_unittest.cc
@@ -228,7 +228,8 @@
 DrawImage CreateDiscardableDrawImage(gfx::Size size) {
   return DrawImage(CreateDiscardablePaintImage(size),
                    SkIRect::MakeWH(size.width(), size.height()),
-                   kNone_SkFilterQuality, SkMatrix::I(), gfx::ColorSpace());
+                   kNone_SkFilterQuality, SkMatrix::I(),
+                   PaintImage::kDefaultFrameIndex, gfx::ColorSpace());
 }
 
 class ImageControllerTest : public testing::Test {
@@ -317,12 +318,13 @@
 
   SkBitmap bitmap;
   bitmap.allocN32Pixels(1, 1);
-  DrawImage image = DrawImage(PaintImageBuilder()
-                                  .set_id(PaintImage::GetNextId())
-                                  .set_image(SkImage::MakeFromBitmap(bitmap))
-                                  .TakePaintImage(),
-                              SkIRect::MakeWH(1, 1), kNone_SkFilterQuality,
-                              SkMatrix::I(), gfx::ColorSpace());
+  DrawImage image =
+      DrawImage(PaintImageBuilder()
+                    .set_id(PaintImage::GetNextId())
+                    .set_image(SkImage::MakeFromBitmap(bitmap))
+                    .TakePaintImage(),
+                SkIRect::MakeWH(1, 1), kNone_SkFilterQuality, SkMatrix::I(),
+                PaintImage::kDefaultFrameIndex, gfx::ColorSpace());
 
   ImageController::ImageDecodeRequestId expected_id =
       controller()->QueueImageDecode(
diff --git a/cc/tiles/software_image_decode_cache.cc b/cc/tiles/software_image_decode_cache.cc
index 786fefa..def638c7 100644
--- a/cc/tiles/software_image_decode_cache.cc
+++ b/cc/tiles/software_image_decode_cache.cc
@@ -596,7 +596,8 @@
                  "SoftwareImageDecodeCache::GetOriginalSizeImageDecode - "
                  "decode");
     bool result = paint_image.Decode(decoded_pixels->data(), &decoded_info,
-                                     key.target_color_space().ToSkColorSpace());
+                                     key.target_color_space().ToSkColorSpace(),
+                                     key.frame_key().frame_index());
     if (!result) {
       decoded_pixels->Unlock();
       return nullptr;
@@ -619,7 +620,8 @@
   // so. We could also subrect scaled images.
   SkIRect exact_size_rect = SkIRect::MakeWH(image.width(), image.height());
   DrawImage exact_size_draw_image(image, exact_size_rect, kNone_SkFilterQuality,
-                                  SkMatrix::I(), key.target_color_space());
+                                  SkMatrix::I(), key.frame_key().frame_index(),
+                                  key.target_color_space());
   ImageKey exact_size_key =
       ImageKey::FromDrawImage(exact_size_draw_image, color_type_);
 
@@ -693,7 +695,8 @@
                 key.target_size().width(), key.target_size().height())));
 
   DrawImage exact_size_draw_image(image, exact_size_rect, kNone_SkFilterQuality,
-                                  SkMatrix::I(), key.target_color_space());
+                                  SkMatrix::I(), key.frame_key().frame_index(),
+                                  key.target_color_space());
   ImageKey exact_size_key =
       ImageKey::FromDrawImage(exact_size_draw_image, color_type_);
 
diff --git a/cc/tiles/software_image_decode_cache_perftest.cc b/cc/tiles/software_image_decode_cache_perftest.cc
index fd9f4e8..02fb946 100644
--- a/cc/tiles/software_image_decode_cache_perftest.cc
+++ b/cc/tiles/software_image_decode_cache_perftest.cc
@@ -62,7 +62,7 @@
                   .set_image(CreateImage(rect.width(), rect.height()))
                   .TakePaintImage(),
               subrect, quality,
-              CreateMatrix(SkSize::Make(scale.first, scale.second)),
+              CreateMatrix(SkSize::Make(scale.first, scale.second)), 0u,
               gfx::ColorSpace());
         }
       }
diff --git a/cc/tiles/software_image_decode_cache_unittest.cc b/cc/tiles/software_image_decode_cache_unittest.cc
index 52499201f..807902cd 100644
--- a/cc/tiles/software_image_decode_cache_unittest.cc
+++ b/cc/tiles/software_image_decode_cache_unittest.cc
@@ -6,6 +6,7 @@
 
 #include "cc/paint/draw_image.h"
 #include "cc/paint/paint_image_builder.h"
+#include "cc/test/fake_paint_image_generator.h"
 #include "cc/test/skia_common.h"
 #include "cc/test/test_tile_task_runner.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -51,7 +52,7 @@
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       kNone_SkFilterQuality,
       CreateMatrix(SkSize::Make(0.5f, 1.5f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   auto key = ImageDecodeCacheKey::FromDrawImage(draw_image, kN32_SkColorType);
   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
@@ -72,7 +73,7 @@
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       kLow_SkFilterQuality,
       CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   auto key = ImageDecodeCacheKey::FromDrawImage(draw_image, kN32_SkColorType);
   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
@@ -90,7 +91,7 @@
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       kMedium_SkFilterQuality,
       CreateMatrix(SkSize::Make(0.75f, 0.75f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   auto key = ImageDecodeCacheKey::FromDrawImage(draw_image, kN32_SkColorType);
   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
@@ -108,7 +109,7 @@
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       kLow_SkFilterQuality,
       CreateMatrix(SkSize::Make(0.5f, 1.5f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   auto key =
       ImageDecodeCacheKey::FromDrawImage(draw_image, kARGB_4444_SkColorType);
@@ -127,7 +128,7 @@
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       kHigh_SkFilterQuality,
       CreateMatrix(SkSize::Make(1.5f, 1.5f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   auto key =
       ImageDecodeCacheKey::FromDrawImage(draw_image, kARGB_4444_SkColorType);
@@ -146,7 +147,7 @@
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       kLow_SkFilterQuality,
       CreateMatrix(SkSize::Make(1.5f, 1.5f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   auto key = ImageDecodeCacheKey::FromDrawImage(draw_image, kN32_SkColorType);
   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
@@ -165,7 +166,7 @@
   DrawImage draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(0.5f, 0.4f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   auto key = ImageDecodeCacheKey::FromDrawImage(draw_image, kN32_SkColorType);
   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
@@ -184,7 +185,7 @@
   DrawImage draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(1.5f, 1.5f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   auto key = ImageDecodeCacheKey::FromDrawImage(draw_image, kN32_SkColorType);
   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
@@ -203,7 +204,7 @@
   DrawImage draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   auto key = ImageDecodeCacheKey::FromDrawImage(draw_image, kN32_SkColorType);
   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
@@ -223,7 +224,7 @@
   DrawImage draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(1.001f, 1.001f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   auto key = ImageDecodeCacheKey::FromDrawImage(draw_image, kN32_SkColorType);
   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
@@ -243,7 +244,7 @@
   DrawImage draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(0.999f, 0.999f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   auto key = ImageDecodeCacheKey::FromDrawImage(draw_image, kN32_SkColorType);
   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
@@ -263,7 +264,7 @@
   DrawImage draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(0.5f, 1.5f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   auto key = ImageDecodeCacheKey::FromDrawImage(draw_image, kN32_SkColorType);
   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
@@ -283,7 +284,7 @@
   DrawImage draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(1.5f, 1.5f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   auto key = ImageDecodeCacheKey::FromDrawImage(draw_image, kN32_SkColorType);
   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
@@ -302,7 +303,7 @@
   DrawImage draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   auto key = ImageDecodeCacheKey::FromDrawImage(draw_image, kN32_SkColorType);
   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
@@ -321,7 +322,7 @@
   DrawImage draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(0.75f, 0.75f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   auto key = ImageDecodeCacheKey::FromDrawImage(draw_image, kN32_SkColorType);
   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
@@ -340,7 +341,7 @@
   DrawImage draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   auto key = ImageDecodeCacheKey::FromDrawImage(draw_image, kN32_SkColorType);
   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
@@ -359,7 +360,7 @@
   DrawImage draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(0.49f, 0.49f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   auto key = ImageDecodeCacheKey::FromDrawImage(draw_image, kN32_SkColorType);
   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
@@ -378,7 +379,7 @@
   DrawImage draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(0.1f, 0.1f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   auto key = ImageDecodeCacheKey::FromDrawImage(draw_image, kN32_SkColorType);
   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
@@ -397,7 +398,7 @@
   DrawImage draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(0.01f, 0.01f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   auto key = ImageDecodeCacheKey::FromDrawImage(draw_image, kN32_SkColorType);
   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
@@ -417,7 +418,7 @@
   DrawImage draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(0.5f, 0.2f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   auto key = ImageDecodeCacheKey::FromDrawImage(draw_image, kN32_SkColorType);
   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
@@ -436,7 +437,7 @@
   DrawImage draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(2.5f, 1.5f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   auto key = ImageDecodeCacheKey::FromDrawImage(draw_image, kN32_SkColorType);
   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
@@ -458,7 +459,7 @@
   DrawImage draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(0.45f, 0.45f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   auto key = ImageDecodeCacheKey::FromDrawImage(draw_image, kN32_SkColorType);
   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
@@ -478,7 +479,7 @@
   DrawImage draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(0.5f, 1.5f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   auto key = ImageDecodeCacheKey::FromDrawImage(draw_image, kN32_SkColorType);
   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
@@ -497,7 +498,7 @@
   DrawImage draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   auto key = ImageDecodeCacheKey::FromDrawImage(draw_image, kN32_SkColorType);
   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
@@ -517,7 +518,7 @@
   DrawImage draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(1.001f, 1.001f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   auto key = ImageDecodeCacheKey::FromDrawImage(draw_image, kN32_SkColorType);
   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
@@ -537,7 +538,7 @@
   DrawImage draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(0.999f, 0.999f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   auto key = ImageDecodeCacheKey::FromDrawImage(draw_image, kN32_SkColorType);
   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
@@ -556,7 +557,7 @@
   DrawImage draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(0.5f, 0.5), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   auto key = ImageDecodeCacheKey::FromDrawImage(draw_image, kN32_SkColorType);
   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
@@ -569,7 +570,7 @@
   DrawImage another_draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(1.5f, 1.5), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   auto another_key =
       ImageDecodeCacheKey::FromDrawImage(another_draw_image, kN32_SkColorType);
@@ -592,7 +593,7 @@
       paint_image,
       SkIRect::MakeXYWH(25, 35, paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   auto key = ImageDecodeCacheKey::FromDrawImage(draw_image, kN32_SkColorType);
   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
@@ -612,7 +613,7 @@
       paint_image,
       SkIRect::MakeXYWH(20, 30, paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   auto key = ImageDecodeCacheKey::FromDrawImage(draw_image, kN32_SkColorType);
   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
@@ -632,7 +633,7 @@
   DrawImage draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult result =
       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(result.need_unref);
@@ -641,7 +642,7 @@
   DrawImage another_draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult another_result = cache.GetTaskForImageAndRef(
       another_draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(another_result.need_unref);
@@ -662,7 +663,7 @@
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       kHigh_SkFilterQuality,
       CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult high_quality_result =
       cache.GetTaskForImageAndRef(high_quality_draw_image,
                                   ImageDecodeCache::TracingInfo());
@@ -673,7 +674,7 @@
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       kNone_SkFilterQuality,
       CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult none_quality_result =
       cache.GetTaskForImageAndRef(none_quality_draw_image,
                                   ImageDecodeCache::TracingInfo());
@@ -697,7 +698,7 @@
   DrawImage half_size_draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult half_size_result = cache.GetTaskForImageAndRef(
       half_size_draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(half_size_result.need_unref);
@@ -706,7 +707,7 @@
   DrawImage quarter_size_draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(0.25f, 0.25f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult quarter_size_result =
       cache.GetTaskForImageAndRef(quarter_size_draw_image,
                                   ImageDecodeCache::TracingInfo());
@@ -731,7 +732,7 @@
       first_paint_image,
       SkIRect::MakeWH(first_paint_image.width(), first_paint_image.height()),
       quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult first_result = cache.GetTaskForImageAndRef(
       first_draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(first_result.need_unref);
@@ -742,7 +743,7 @@
       second_paint_image,
       SkIRect::MakeWH(second_paint_image.width(), second_paint_image.height()),
       quality, CreateMatrix(SkSize::Make(0.25f, 0.25f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult second_result = cache.GetTaskForImageAndRef(
       second_draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(second_result.need_unref);
@@ -779,7 +780,7 @@
   DrawImage first_draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
-      color_space_b);
+      PaintImage::kDefaultFrameIndex, color_space_b);
   ImageDecodeCache::TaskResult first_result = cache.GetTaskForImageAndRef(
       first_draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(first_result.need_unref);
@@ -788,7 +789,7 @@
   DrawImage second_draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
-      color_space_c);
+      PaintImage::kDefaultFrameIndex, color_space_c);
   ImageDecodeCache::TaskResult second_result = cache.GetTaskForImageAndRef(
       second_draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(second_result.need_unref);
@@ -798,7 +799,7 @@
   DrawImage third_draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
-      color_space_b);
+      PaintImage::kDefaultFrameIndex, color_space_b);
   ImageDecodeCache::TaskResult third_result = cache.GetTaskForImageAndRef(
       third_draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(third_result.need_unref);
@@ -822,7 +823,7 @@
   DrawImage draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult result =
       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(result.need_unref);
@@ -851,7 +852,7 @@
   DrawImage draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult result =
       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(result.need_unref);
@@ -886,7 +887,7 @@
   DrawImage draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult result =
       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(result.need_unref);
@@ -927,7 +928,7 @@
   DrawImage draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult result =
       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(result.need_unref);
@@ -967,7 +968,7 @@
   DrawImage draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult result =
       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(result.need_unref);
@@ -1001,7 +1002,7 @@
       paint_image,
       SkIRect::MakeXYWH(20, 30, paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   ImageDecodeCache::TaskResult result =
       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
   EXPECT_TRUE(result.need_unref);
@@ -1033,7 +1034,7 @@
   DrawImage draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   DecodedDrawImage decoded_draw_image =
       cache.GetDecodedImageForDraw(draw_image);
@@ -1059,7 +1060,7 @@
   DrawImage draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   DecodedDrawImage decoded_draw_image =
       cache.GetDecodedImageForDraw(draw_image);
@@ -1091,7 +1092,7 @@
   DrawImage draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   DecodedDrawImage decoded_draw_image =
       cache.GetDecodedImageForDraw(draw_image);
@@ -1136,7 +1137,7 @@
   DrawImage draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   DecodedDrawImage decoded_draw_image =
       cache.GetDecodedImageForDraw(draw_image);
@@ -1181,7 +1182,7 @@
   DrawImage draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(0.f, 0.f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   ImageDecodeCache::TaskResult result =
       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1205,7 +1206,7 @@
       paint_image,
       SkIRect::MakeXYWH(150, 150, paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   ImageDecodeCache::TaskResult result =
       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1228,7 +1229,7 @@
   DrawImage draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   ImageDecodeCache::TaskResult result =
       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1256,7 +1257,7 @@
   PaintImage paint_image = CreatePaintImage(100, 100);
   DrawImage draw_image(paint_image, SkIRect::MakeXYWH(10, 10, 80, 80), quality,
                        CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
-                       DefaultColorSpace());
+                       PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   ImageDecodeCache::TaskResult result =
       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1289,7 +1290,7 @@
   PaintImage paint_image = CreatePaintImage(100, 100);
   DrawImage draw_image(paint_image, SkIRect::MakeXYWH(10, 10, 80, 80), quality,
                        CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
-                       DefaultColorSpace());
+                       PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   ImageDecodeCache::TaskResult result =
       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1320,7 +1321,7 @@
   DrawImage draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(1.5f, 1.5f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   ImageDecodeCache::TaskResult result =
       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1351,7 +1352,7 @@
   DrawImage draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   ImageDecodeCache::TaskResult result =
       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1382,7 +1383,7 @@
   DrawImage draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(0.75f, 0.75f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   ImageDecodeCache::TaskResult result =
       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1413,7 +1414,7 @@
   DrawImage draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   ImageDecodeCache::TaskResult result =
       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1444,7 +1445,7 @@
   DrawImage draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(0.49f, 0.49f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   ImageDecodeCache::TaskResult result =
       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1475,7 +1476,7 @@
   DrawImage draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(0.1f, 0.1f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   ImageDecodeCache::TaskResult result =
       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1506,7 +1507,7 @@
   DrawImage draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(0.01f, 0.01f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   ImageDecodeCache::TaskResult result =
       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1537,7 +1538,7 @@
   DrawImage draw_image(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(0.001f, 0.001f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   ImageDecodeCache::TaskResult result =
       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1561,11 +1562,11 @@
   DrawImage draw_image_50(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
   DrawImage draw_image_49(
       paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
       quality, CreateMatrix(SkSize::Make(0.49f, 0.49f), is_decomposable),
-      DefaultColorSpace());
+      PaintImage::kDefaultFrameIndex, DefaultColorSpace());
 
   ImageDecodeCache::TaskResult result_50 = cache.GetTaskForImageAndRef(
       draw_image_50, ImageDecodeCache::TracingInfo());
@@ -1612,7 +1613,7 @@
     DrawImage draw_image(
         paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
         quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
-        DefaultColorSpace());
+        PaintImage::kDefaultFrameIndex, DefaultColorSpace());
     ImageDecodeCache::TaskResult result = cache.GetTaskForImageAndRef(
         draw_image, ImageDecodeCache::TracingInfo());
     EXPECT_TRUE(result.need_unref);
@@ -1641,7 +1642,7 @@
     DrawImage draw_image(
         paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
         quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
-        DefaultColorSpace());
+        PaintImage::kDefaultFrameIndex, DefaultColorSpace());
     frame_keys.push_back(draw_image.frame_key());
     DecodedDrawImage decoded_draw_image =
         cache.GetDecodedImageForDraw(draw_image);
@@ -1664,5 +1665,58 @@
   }
 }
 
+TEST(SoftwareImageDecodeCacheTest, CacheDecodesExpectedFrames) {
+  TestSoftwareImageDecodeCache cache;
+  std::vector<FrameMetadata> frames = {
+      FrameMetadata(true, base::TimeDelta::FromMilliseconds(2)),
+      FrameMetadata(true, base::TimeDelta::FromMilliseconds(3)),
+      FrameMetadata(true, base::TimeDelta::FromMilliseconds(4)),
+      FrameMetadata(true, base::TimeDelta::FromMilliseconds(5)),
+  };
+  sk_sp<FakePaintImageGenerator> generator =
+      sk_make_sp<FakePaintImageGenerator>(SkImageInfo::MakeN32Premul(10, 10),
+                                          frames);
+  PaintImage image = PaintImageBuilder()
+                         .set_id(PaintImage::GetNextId())
+                         .set_paint_image_generator(generator)
+                         .set_frame_index(0u)
+                         .TakePaintImage();
+
+  bool is_decomposable = true;
+  SkFilterQuality quality = kHigh_SkFilterQuality;
+  DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
+                       quality,
+                       CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
+                       1u, DefaultColorSpace());
+  auto decoded_image = cache.GetDecodedImageForDraw(draw_image);
+  ASSERT_TRUE(decoded_image.image());
+  ASSERT_EQ(generator->frames_decoded().size(), 1u);
+  EXPECT_EQ(generator->frames_decoded().count(1u), 1u);
+  generator->reset_frames_decoded();
+  cache.DrawWithImageFinished(draw_image, decoded_image);
+
+  // Scaled.
+  DrawImage scaled_draw_image(draw_image, 0.5f, 2u,
+                              draw_image.target_color_space());
+  decoded_image = cache.GetDecodedImageForDraw(scaled_draw_image);
+  ASSERT_TRUE(decoded_image.image());
+  ASSERT_EQ(generator->frames_decoded().size(), 1u);
+  EXPECT_EQ(generator->frames_decoded().count(2u), 1u);
+  generator->reset_frames_decoded();
+  cache.DrawWithImageFinished(scaled_draw_image, decoded_image);
+
+  // Subset.
+  DrawImage subset_draw_image(
+      image, SkIRect::MakeWH(5, 5), quality,
+      CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable), 3u,
+      DefaultColorSpace());
+  decoded_image = cache.GetDecodedImageForDraw(subset_draw_image);
+  ASSERT_TRUE(decoded_image.image());
+  ASSERT_EQ(generator->frames_decoded().size(), 1u);
+  EXPECT_EQ(generator->frames_decoded().count(3u), 1u);
+  generator->reset_frames_decoded();
+  cache.DrawWithImageFinished(subset_draw_image, decoded_image);
+}
+
 }  // namespace
 }  // namespace cc
diff --git a/cc/tiles/tile_manager.cc b/cc/tiles/tile_manager.cc
index 618b973..21c016b 100644
--- a/cc/tiles/tile_manager.cc
+++ b/cc/tiles/tile_manager.cc
@@ -883,7 +883,8 @@
     const PrioritizedTile& prioritized_tile,
     const gfx::ColorSpace& raster_color_space,
     std::vector<DrawImage>* sync_decoded_images,
-    std::vector<PaintImage>* checkered_images) {
+    std::vector<PaintImage>* checkered_images,
+    base::flat_map<PaintImage::Id, size_t>* image_to_frame_index) {
   Tile* tile = prioritized_tile.tile();
   std::vector<const DrawImage*> images_in_tile;
   prioritized_tile.raster_source()->GetDiscardableImagesInRect(
@@ -891,8 +892,15 @@
   WhichTree tree = tile->tiling()->tree();
 
   for (const auto* original_draw_image : images_in_tile) {
+    size_t frame_index = client_->GetFrameIndexForImage(
+        original_draw_image->paint_image(), tree);
     DrawImage draw_image(*original_draw_image, tile->raster_transform().scale(),
-                         raster_color_space);
+                         frame_index, raster_color_space);
+    if (image_to_frame_index) {
+      (*image_to_frame_index)[draw_image.paint_image().stable_id()] =
+          frame_index;
+    }
+
     if (checker_image_tracker_.ShouldCheckerImage(
             draw_image, tree, tile->required_for_activation()))
       checkered_images->push_back(draw_image.paint_image());
@@ -913,9 +921,10 @@
   WhichTree tree = tile->tiling()->tree();
 
   for (const auto* original_draw_image : images_in_tile) {
+    size_t frame_index = client_->GetFrameIndexForImage(
+        original_draw_image->paint_image(), tree);
     DrawImage draw_image(*original_draw_image, tile->raster_transform().scale(),
-                         raster_color_space);
-
+                         frame_index, raster_color_space);
     if (checker_image_tracker_.ShouldCheckerImage(
             draw_image, tree, tile->required_for_activation())) {
       image_decode_queue->emplace_back(draw_image.paint_image(), decode_type);
@@ -1133,11 +1142,15 @@
       scheduled_draw_images_[tile->id()];
   sync_decoded_images.clear();
   PaintImageIdFlatSet images_to_skip;
+  base::flat_map<PaintImage::Id, size_t> image_id_to_current_frame_index;
   if (!skip_images) {
     std::vector<PaintImage> checkered_images;
     PartitionImagesForCheckering(prioritized_tile, color_space,
-                                 &sync_decoded_images, &checkered_images);
+                                 &sync_decoded_images, &checkered_images,
+                                 &image_id_to_current_frame_index);
     for (const auto& image : checkered_images) {
+      DCHECK(!image.ShouldAnimate());
+
       images_to_skip.insert(image.stable_id());
 
       // This can be the case for tiles on the active tree that will be replaced
@@ -1175,7 +1188,8 @@
       has_at_raster_images) {
     image_provider.emplace(skip_images, std::move(images_to_skip),
                            std::move(at_raster_images),
-                           image_controller_.cache(), color_space);
+                           image_controller_.cache(), color_space,
+                           std::move(image_id_to_current_frame_index));
   }
 
   return make_scoped_refptr(new RasterTaskImpl(
diff --git a/cc/tiles/tile_manager.h b/cc/tiles/tile_manager.h
index d9a7cbf..58de5f05 100644
--- a/cc/tiles/tile_manager.h
+++ b/cc/tiles/tile_manager.h
@@ -87,6 +87,9 @@
   // rasterized with missing images need to be invalidated.
   virtual void RequestImplSideInvalidationForCheckerImagedTiles() = 0;
 
+  virtual size_t GetFrameIndexForImage(const PaintImage& paint_image,
+                                       WhichTree tree) const = 0;
+
  protected:
   virtual ~TileManagerClient() {}
 };
@@ -357,10 +360,12 @@
   PrioritizedWorkToSchedule AssignGpuMemoryToTiles();
   void ScheduleTasks(PrioritizedWorkToSchedule work_to_schedule);
 
-  void PartitionImagesForCheckering(const PrioritizedTile& prioritized_tile,
-                                    const gfx::ColorSpace& raster_color_space,
-                                    std::vector<DrawImage>* sync_decoded_images,
-                                    std::vector<PaintImage>* checkered_images);
+  void PartitionImagesForCheckering(
+      const PrioritizedTile& prioritized_tile,
+      const gfx::ColorSpace& raster_color_space,
+      std::vector<DrawImage>* sync_decoded_images,
+      std::vector<PaintImage>* checkered_images,
+      base::flat_map<PaintImage::Id, size_t>* image_to_frame_index = nullptr);
   void AddCheckeredImagesToDecodeQueue(
       const PrioritizedTile& prioritized_tile,
       const gfx::ColorSpace& raster_color_space,
diff --git a/cc/tiles/tile_manager_unittest.cc b/cc/tiles/tile_manager_unittest.cc
index 02b1a75..71cf49c1 100644
--- a/cc/tiles/tile_manager_unittest.cc
+++ b/cc/tiles/tile_manager_unittest.cc
@@ -22,6 +22,7 @@
 #include "cc/test/fake_layer_tree_frame_sink.h"
 #include "cc/test/fake_layer_tree_frame_sink_client.h"
 #include "cc/test/fake_layer_tree_host_impl.h"
+#include "cc/test/fake_paint_image_generator.h"
 #include "cc/test/fake_picture_layer_impl.h"
 #include "cc/test/fake_picture_layer_tiling_client.h"
 #include "cc/test/fake_raster_source.h"
@@ -29,7 +30,6 @@
 #include "cc/test/fake_tile_manager.h"
 #include "cc/test/fake_tile_task_manager.h"
 #include "cc/test/skia_common.h"
-#include "cc/test/stub_paint_image_generator.h"
 #include "cc/test/test_layer_tree_host_base.h"
 #include "cc/test/test_task_graph_runner.h"
 #include "cc/test/test_tile_priorities.h"
@@ -2307,10 +2307,10 @@
 
 class CheckerImagingTileManagerTest : public TestLayerTreeHostBase {
  public:
-  class MockImageGenerator : public StubPaintImageGenerator {
+  class MockImageGenerator : public FakePaintImageGenerator {
    public:
     explicit MockImageGenerator(const gfx::Size& size)
-        : StubPaintImageGenerator(
+        : FakePaintImageGenerator(
               SkImageInfo::MakeN32Premul(size.width(), size.height())) {}
 
     MOCK_METHOD5(GetPixels,
diff --git a/cc/trees/image_animation_controller.cc b/cc/trees/image_animation_controller.cc
new file mode 100644
index 0000000..09e3023
--- /dev/null
+++ b/cc/trees/image_animation_controller.cc
@@ -0,0 +1,401 @@
+// 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 "cc/trees/image_animation_controller.h"
+
+#include "base/bind.h"
+#include "base/trace_event/trace_event.h"
+#include "cc/paint/image_animation_count.h"
+
+namespace cc {
+namespace {
+
+// The maximum number of time an animation can be delayed before it is reset to
+// start from the beginning, instead of fast-forwarding to catch up to the
+// desired frame.
+const base::TimeDelta kAnimationResyncCutoff = base::TimeDelta::FromMinutes(5);
+
+}  //  namespace
+
+ImageAnimationController::ImageAnimationController(
+    base::SingleThreadTaskRunner* task_runner,
+    base::Closure invalidation_callback)
+    : notifier_(task_runner, invalidation_callback) {}
+
+ImageAnimationController::~ImageAnimationController() = default;
+
+void ImageAnimationController::UpdateAnimatedImage(
+    const DiscardableImageMap::AnimatedImageMetadata& data) {
+  AnimationState& animation_state = animation_state_map_[data.paint_image_id];
+  animation_state.UpdateMetadata(data);
+}
+
+void ImageAnimationController::RegisterAnimationDriver(
+    PaintImage::Id paint_image_id,
+    AnimationDriver* driver) {
+  auto it = animation_state_map_.find(paint_image_id);
+  DCHECK(it != animation_state_map_.end());
+  it->second.AddDriver(driver);
+}
+
+void ImageAnimationController::UnregisterAnimationDriver(
+    PaintImage::Id paint_image_id,
+    AnimationDriver* driver) {
+  auto it = animation_state_map_.find(paint_image_id);
+  DCHECK(it != animation_state_map_.end());
+  it->second.RemoveDriver(driver);
+}
+
+const PaintImageIdFlatSet& ImageAnimationController::AnimateForSyncTree(
+    base::TimeTicks now) {
+  TRACE_EVENT0("cc", "ImageAnimationController::AnimateImagesForSyncTree");
+  DCHECK(images_animated_on_sync_tree_.empty());
+
+  notifier_.WillAnimate();
+  base::Optional<base::TimeTicks> next_invalidation_time;
+
+  for (auto id : active_animations_) {
+    auto it = animation_state_map_.find(id);
+    DCHECK(it != animation_state_map_.end());
+    AnimationState& state = it->second;
+
+    // Is anyone still interested in animating this image?
+    if (!state.ShouldAnimate())
+      continue;
+
+    // If we were able to advance this animation, invalidate it on the sync
+    // tree.
+    if (state.AdvanceFrame(now))
+      images_animated_on_sync_tree_.insert(id);
+
+    // Update the next invalidation time to the earliest time at which we need
+    // a frame to animate an image.
+    // Note its important to check ShouldAnimate() here again since advancing to
+    // a new frame on the sync tree means we might not need to animate this
+    // image any longer.
+    if (!state.ShouldAnimate())
+      continue;
+
+    DCHECK_GT(state.next_desired_frame_time(), now);
+    if (!next_invalidation_time.has_value()) {
+      next_invalidation_time.emplace(state.next_desired_frame_time());
+    } else {
+      next_invalidation_time = std::min(state.next_desired_frame_time(),
+                                        next_invalidation_time.value());
+    }
+  }
+
+  if (next_invalidation_time.has_value())
+    notifier_.Schedule(now, next_invalidation_time.value());
+  else
+    notifier_.Cancel();
+
+  return images_animated_on_sync_tree_;
+}
+
+void ImageAnimationController::UpdateStateFromDrivers(base::TimeTicks now) {
+  TRACE_EVENT0("cc", "UpdateStateFromAnimationDrivers");
+
+  base::Optional<base::TimeTicks> next_invalidation_time;
+  for (auto& it : animation_state_map_) {
+    AnimationState& state = it.second;
+    state.UpdateStateFromDrivers();
+
+    // If we don't need to animate this image anymore, remove it from the list
+    // of active animations.
+    // Note that by not updating the |next_invalidation_time| from this image
+    // here, we will cancel any pending invalidation scheduled for this image
+    // when updating the |notifier_| at the end of this loop.
+    if (!state.ShouldAnimate()) {
+      active_animations_.erase(it.first);
+      continue;
+    }
+
+    active_animations_.insert(it.first);
+    if (!next_invalidation_time.has_value()) {
+      next_invalidation_time.emplace(state.next_desired_frame_time());
+    } else {
+      next_invalidation_time = std::min(next_invalidation_time.value(),
+                                        state.next_desired_frame_time());
+    }
+  }
+
+  if (next_invalidation_time.has_value())
+    notifier_.Schedule(now, next_invalidation_time.value());
+  else
+    notifier_.Cancel();
+}
+
+void ImageAnimationController::DidActivate() {
+  TRACE_EVENT0("cc", "ImageAnimationController::WillActivate");
+
+  for (auto id : images_animated_on_sync_tree_) {
+    auto it = animation_state_map_.find(id);
+    DCHECK(it != animation_state_map_.end());
+    it->second.PushPendingToActive();
+  }
+
+  images_animated_on_sync_tree_.clear();
+}
+
+size_t ImageAnimationController::GetFrameIndexForImage(
+    PaintImage::Id paint_image_id,
+    WhichTree tree) const {
+  const auto& it = animation_state_map_.find(paint_image_id);
+  DCHECK(it != animation_state_map_.end());
+  return tree == WhichTree::PENDING_TREE ? it->second.pending_index()
+                                         : it->second.active_index();
+}
+
+const base::flat_set<ImageAnimationController::AnimationDriver*>&
+ImageAnimationController::GetDriversForTesting(
+    PaintImage::Id paint_image_id) const {
+  const auto& it = animation_state_map_.find(paint_image_id);
+  DCHECK(it != animation_state_map_.end());
+  return it->second.drivers_for_testing();
+}
+
+ImageAnimationController::AnimationState::AnimationState() = default;
+
+ImageAnimationController::AnimationState::AnimationState(
+    AnimationState&& other) = default;
+
+ImageAnimationController::AnimationState&
+ImageAnimationController::AnimationState::operator=(AnimationState&& other) =
+    default;
+
+ImageAnimationController::AnimationState::~AnimationState() {
+  DCHECK(drivers_.empty());
+}
+
+bool ImageAnimationController::AnimationState::ShouldAnimate() const {
+  DCHECK(repetitions_completed_ == 0 || is_complete());
+
+  // If we have no drivers for this image, no need to animate it.
+  if (!should_animate_from_drivers_)
+    return false;
+
+  switch (requested_repetitions_) {
+    case kAnimationLoopOnce:
+      if (repetitions_completed_ >= 1)
+        return false;
+      break;
+    case kAnimationNone:
+      NOTREACHED() << "We shouldn't be tracking kAnimationNone images";
+      break;
+    case kAnimationLoopInfinite:
+      break;
+    default:
+      if (requested_repetitions_ <= repetitions_completed_)
+        return false;
+  }
+
+  // If we have all data for this image and the policy allows it, we can
+  // continue animating it.
+  if (completion_state_ == PaintImage::CompletionState::DONE)
+    return true;
+
+  // If we have not yet received all data for this image, we can not advance to
+  // an incomplete frame.
+  if (!frames_[NextFrameIndex()].complete)
+    return false;
+
+  // If we don't have all data for this image, we can not trust the frame count
+  // and loop back to the first frame.
+  size_t last_frame_index = frames_.size() - 1;
+  if (pending_index_ == last_frame_index)
+    return false;
+
+  return true;
+}
+
+bool ImageAnimationController::AnimationState::AdvanceFrame(
+    base::TimeTicks now) {
+  DCHECK(ShouldAnimate());
+
+  // Start the animation from the first frame, if not yet started. We don't need
+  // an invalidation here since the pending/active tree should be displaying the
+  // first frame.
+  if (!animation_started_) {
+    DCHECK_EQ(pending_index_, 0u);
+    DCHECK_EQ(pending_index_, active_index_);
+
+    next_desired_frame_time_ = now + frames_[0].duration;
+    animation_started_ = true;
+    return false;
+  }
+
+  // Don't advance the animation if its not time yet to move to the next frame.
+  if (now < next_desired_frame_time_)
+    return false;
+
+  // If the animation is more than 5 min out of date, we don't bother catching
+  // up and start again from the current frame.
+  // Note that we don't need to invalidate this image since the active tree
+  // is already displaying the current frame.
+  if (now - next_desired_frame_time_ > kAnimationResyncCutoff) {
+    DCHECK_EQ(pending_index_, active_index_);
+    next_desired_frame_time_ = now + frames_[pending_index_].duration;
+    return false;
+  }
+
+  // Keep catching up the animation until we reach the frame we should be
+  // displaying now.
+  // TODO(khushalsagar): Avoid unnecessary iterations for skipping whole loops
+  // in the animations.
+  size_t last_frame_index = frames_.size() - 1;
+  while (next_desired_frame_time_ <= now && ShouldAnimate()) {
+    size_t next_frame_index = NextFrameIndex();
+    base::TimeTicks next_desired_frame_time =
+        next_desired_frame_time_ + frames_[next_frame_index].duration;
+
+    // The image may load more slowly than it's supposed to animate, so that by
+    // the time we reach the end of the first repetition, we're well behind.
+    // Start the animation from the first frame in this case, so that we don't
+    // skip frames (or whole iterations) trying to "catch up".  This is a
+    // tradeoff: It guarantees users see the whole animation the second time
+    // through and don't miss any repetitions, and is closer to what other
+    // browsers do; on the other hand, it makes animations "less accurate" for
+    // pages that try to sync an image and some other resource (e.g. audio),
+    // especially if users switch tabs (and thus stop drawing the animation,
+    // which will pause it) during that initial loop, then switch back later.
+    if (next_frame_index == 0u && repetitions_completed_ == 1 &&
+        next_desired_frame_time <= now) {
+      pending_index_ = 0u;
+      next_desired_frame_time_ = now + frames_[0].duration;
+      repetitions_completed_ = 0;
+      break;
+    }
+
+    pending_index_ = next_frame_index;
+    next_desired_frame_time_ = next_desired_frame_time;
+
+    // If we are advancing to the last frame and the image has been completely
+    // loaded (which means that the frame count is known to be accurate), we
+    // just finished a loop in the animation.
+    if (pending_index_ == last_frame_index && is_complete())
+      repetitions_completed_++;
+  }
+
+  return pending_index_ != active_index_;
+}
+
+void ImageAnimationController::AnimationState::UpdateMetadata(
+    const DiscardableImageMap::AnimatedImageMetadata& data) {
+  paint_image_id_ = data.paint_image_id;
+
+  DCHECK_NE(data.repetition_count, kAnimationNone);
+  requested_repetitions_ = data.repetition_count;
+
+  DCHECK(frames_.size() <= data.frames.size())
+      << "Updated recordings can only append frames";
+  frames_ = data.frames;
+  DCHECK_GT(frames_.size(), 1u);
+
+  DCHECK(completion_state_ != PaintImage::CompletionState::DONE ||
+         data.completion_state == PaintImage::CompletionState::DONE)
+      << "If the image was marked complete before, it can not be incomplete in "
+         "a new update";
+  completion_state_ = data.completion_state;
+
+  // Update the repetition count in case we have displayed the last frame and
+  // we now know the frame count to be accurate.
+  size_t last_frame_index = frames_.size() - 1;
+  if (pending_index_ == last_frame_index && is_complete() &&
+      repetitions_completed_ == 0)
+    repetitions_completed_++;
+}
+
+void ImageAnimationController::AnimationState::PushPendingToActive() {
+  active_index_ = pending_index_;
+}
+
+void ImageAnimationController::AnimationState::AddDriver(
+    AnimationDriver* driver) {
+  drivers_.insert(driver);
+}
+
+void ImageAnimationController::AnimationState::RemoveDriver(
+    AnimationDriver* driver) {
+  drivers_.erase(driver);
+}
+
+void ImageAnimationController::AnimationState::UpdateStateFromDrivers() {
+  should_animate_from_drivers_ = false;
+  for (auto* driver : drivers_) {
+    if (driver->ShouldAnimate(paint_image_id_)) {
+      should_animate_from_drivers_ = true;
+      break;
+    }
+  }
+}
+
+size_t ImageAnimationController::AnimationState::NextFrameIndex() const {
+  if (!animation_started_)
+    return 0u;
+  return (pending_index_ + 1) % frames_.size();
+}
+
+ImageAnimationController::DelayedNotifier::DelayedNotifier(
+    base::SingleThreadTaskRunner* task_runner,
+    base::Closure closure)
+    : task_runner_(task_runner),
+      closure_(std::move(closure)),
+      weak_factory_(this) {
+  DCHECK(task_runner_->BelongsToCurrentThread());
+}
+
+ImageAnimationController::DelayedNotifier::~DelayedNotifier() {
+  DCHECK(task_runner_->BelongsToCurrentThread());
+}
+
+void ImageAnimationController::DelayedNotifier::Schedule(
+    base::TimeTicks now,
+    base::TimeTicks notification_time) {
+  // If an animation is already pending, don't schedule another invalidation.
+  // We will schedule the next invalidation based on the latest animation state
+  // during AnimateForSyncTree.
+  if (animation_pending_)
+    return;
+
+  // The requested notification time can be in the past. For instance, if an
+  // animation was paused because the image became invisible.
+  if (notification_time < now)
+    notification_time = now;
+
+  // If we already have a notification scheduled to run at this time, no need to
+  // Cancel it.
+  if (pending_notification_time_.has_value() &&
+      notification_time == pending_notification_time_.value())
+    return;
+
+  // Cancel the pending notification since we the requested notification time
+  // has changed.
+  Cancel();
+
+  TRACE_EVENT2("cc", "ScheduleInvalidationForImageAnimation",
+               "notification_time", notification_time, "now", now);
+  pending_notification_time_.emplace(notification_time);
+  task_runner_->PostDelayedTask(
+      FROM_HERE,
+      base::Bind(&DelayedNotifier::Notify, weak_factory_.GetWeakPtr()),
+      notification_time - now);
+}
+
+void ImageAnimationController::DelayedNotifier::Cancel() {
+  pending_notification_time_.reset();
+  weak_factory_.InvalidateWeakPtrs();
+}
+
+void ImageAnimationController::DelayedNotifier::Notify() {
+  pending_notification_time_.reset();
+  animation_pending_ = true;
+  closure_.Run();
+}
+
+void ImageAnimationController::DelayedNotifier::WillAnimate() {
+  animation_pending_ = false;
+}
+
+}  // namespace cc
diff --git a/cc/trees/image_animation_controller.h b/cc/trees/image_animation_controller.h
new file mode 100644
index 0000000..f536021
--- /dev/null
+++ b/cc/trees/image_animation_controller.h
@@ -0,0 +1,224 @@
+// 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 CC_TREES_IMAGE_ANIMATION_CONTROLLER_H_
+#define CC_TREES_IMAGE_ANIMATION_CONTROLLER_H_
+
+#include "base/cancelable_callback.h"
+#include "base/containers/flat_map.h"
+#include "base/containers/flat_set.h"
+#include "base/memory/weak_ptr.h"
+#include "base/optional.h"
+#include "base/time/time.h"
+#include "cc/cc_export.h"
+#include "cc/paint/discardable_image_map.h"
+#include "cc/paint/image_id.h"
+#include "cc/paint/paint_image.h"
+#include "cc/paint/paint_image_generator.h"
+#include "cc/tiles/tile_priority.h"
+
+namespace cc {
+class PaintImage;
+
+// ImageAnimationController is responsible for tracking state for ticking image
+// animations in the compositor.
+//
+// 1) It receives the updated metadata for these images from new recordings
+//    received from the client using UpdateAnimatedImage. The controller tracks
+//    the frame index of an image used on a tree, and advances the animation to
+//    the desired frame each time a new sync tree is created.
+//
+// 2) An AnimationDriver can register itself for deciding whether the
+//    controller animates an image. The animation is paused if there are no
+//    registered drivers interested in animating it.
+//
+//  3) An animation is only advanced on the sync tree, which is requested to be
+//     created using the |invalidation_callback|. This effectively means that
+//     the frame of the image used remains consistent throughout the lifetime of
+//     a tree, guaranteeing that the image update is atomic.
+class CC_EXPORT ImageAnimationController {
+ public:
+  // AnimationDrivers are clients interested in driving image animations. An
+  // animation is ticked if there is at least one driver registered for which
+  // ShouldAnimate returns true. Once
+  // no drivers are registered for an image, or none of the registered drivers
+  // want us to animate, the animation is no longer ticked.
+  class CC_EXPORT AnimationDriver {
+   public:
+    virtual ~AnimationDriver() {}
+
+    // Returns true if the image should be animated.
+    virtual bool ShouldAnimate(PaintImage::Id paint_image_id) const = 0;
+  };
+
+  // |invalidation_callback| is the callback to trigger an invalidation and
+  // create a sync tree for advancing an image animation. The controller is
+  // guaranteed to receive a call to AnimateForSyncTree when the sync tree is
+  // created.
+  // |task_runner| is the thread on which the controller is used. The
+  // invalidation_callback can only be run on this thread.
+  ImageAnimationController(base::SingleThreadTaskRunner* task_runner,
+                           base::Closure invalidation_callback);
+  ~ImageAnimationController();
+
+  // Called to update the state for a PaintImage received in a new recording.
+  void UpdateAnimatedImage(
+      const DiscardableImageMap::AnimatedImageMetadata& data);
+
+  // Registers/Unregisters an animation driver interested in animating this
+  // image.
+  // Note that the state for this image must have been populated to the
+  // controller using UpdatePaintImage prior to registering any drivers.
+  void RegisterAnimationDriver(PaintImage::Id paint_image_id,
+                               AnimationDriver* driver);
+  void UnregisterAnimationDriver(PaintImage::Id paint_image_id,
+                                 AnimationDriver* driver);
+
+  // Called to advance the animations to the frame to be used on the sync tree.
+  // This should be called only once for a sync tree and must be followed with
+  // a call to DidActivate when this tree is activated.
+  // Returns the set of images that were animated and should be invalidated on
+  // this sync tree.
+  const PaintImageIdFlatSet& AnimateForSyncTree(base::TimeTicks now);
+
+  // Called whenever the ShouldAnimate response for a driver could have changed.
+  // For instance on a change in the visibility of the image, we would pause
+  // off-screen animations.
+  // This is called after every DrawProperties update and commit.
+  void UpdateStateFromDrivers(base::TimeTicks now);
+
+  // Called when the sync tree was activated and the animations' associated
+  // state should be pushed to the active tree.
+  void DidActivate();
+
+  // Returns the frame index to use for the given PaintImage and tree.
+  size_t GetFrameIndexForImage(PaintImage::Id paint_image_id,
+                               WhichTree tree) const;
+
+  const base::flat_set<AnimationDriver*>& GetDriversForTesting(
+      PaintImage::Id paint_image_id) const;
+
+ private:
+  class AnimationState {
+   public:
+    AnimationState();
+    AnimationState(AnimationState&& other);
+    AnimationState& operator=(AnimationState&& other);
+    ~AnimationState();
+
+    bool ShouldAnimate() const;
+    bool AdvanceFrame(base::TimeTicks now);
+    void UpdateMetadata(const DiscardableImageMap::AnimatedImageMetadata& data);
+    void PushPendingToActive();
+
+    void AddDriver(AnimationDriver* driver);
+    void RemoveDriver(AnimationDriver* driver);
+    void UpdateStateFromDrivers();
+
+    size_t pending_index() const { return pending_index_; }
+    size_t active_index() const { return active_index_; }
+    base::TimeTicks next_desired_frame_time() const {
+      return next_desired_frame_time_;
+    }
+    const base::flat_set<AnimationDriver*>& drivers_for_testing() const {
+      return drivers_;
+    }
+
+   private:
+    size_t NextFrameIndex() const;
+    bool is_complete() const {
+      return completion_state_ == PaintImage::CompletionState::DONE;
+    }
+
+    PaintImage::Id paint_image_id_ = PaintImage::kNonLazyStableId;
+
+    // The frame metadata received from the most updated recording with this
+    // PaintImage.
+    std::vector<FrameMetadata> frames_;
+
+    // The number of animation loops requested for this image. For a value > 0,
+    // this number represents the exact number of iterations requested. A few
+    // special cases are represented using constants defined in
+    // cc/paint/image_animation_count.h
+    int requested_repetitions_ = kAnimationNone;
+
+    // The number of loops the animation has finished so far.
+    int repetitions_completed_ = 0;
+
+    // A set of drivers interested in animating this image.
+    base::flat_set<AnimationDriver*> drivers_;
+
+    // The index being used on the active tree, if a recording with this image
+    // is still present.
+    size_t active_index_ = PaintImage::kDefaultFrameIndex;
+
+    // The index being displayed on the pending tree.
+    size_t pending_index_ = PaintImage::kDefaultFrameIndex;
+
+    // The time at which we would like to display the next frame. This can be in
+    // the past, for instance, if we pause the animation from the image becoming
+    // invisible.
+    base::TimeTicks next_desired_frame_time_;
+
+    // Set if there is at least one driver interested in animating this image,
+    // cached from the last update.
+    bool should_animate_from_drivers_ = false;
+
+    // Set if the animation has been started.
+    bool animation_started_ = false;
+
+    // Whether the image is known to be completely loaded in the most recent
+    // recording received.
+    PaintImage::CompletionState completion_state_ =
+        PaintImage::CompletionState::PARTIALLY_DONE;
+
+    DISALLOW_COPY_AND_ASSIGN(AnimationState);
+  };
+
+  class DelayedNotifier {
+   public:
+    DelayedNotifier(base::SingleThreadTaskRunner* task_runner,
+                    base::Closure closure);
+    ~DelayedNotifier();
+
+    void Schedule(base::TimeTicks now, base::TimeTicks notification_time);
+    void Cancel();
+    void WillAnimate();
+
+   private:
+    void Notify();
+
+    base::SingleThreadTaskRunner* task_runner_;
+    base::Closure closure_;
+
+    // Set if a notification is currently pending.
+    base::Optional<base::TimeTicks> pending_notification_time_;
+
+    // Set if the notification was dispatched and the resulting animation on the
+    // next sync tree is pending.
+    bool animation_pending_ = false;
+
+    base::WeakPtrFactory<DelayedNotifier> weak_factory_;
+  };
+
+  // The AnimationState for images is persisted until they are cleared on
+  // navigation. This is because while an image might not be painted anymore, if
+  // it moves out of the interest rect for instance, the state retained is
+  // necessary to resume the animation.
+  // TODO(khushalsagar): Implement clearing of state on navigations.
+  using AnimationStateMap = base::flat_map<PaintImage::Id, AnimationState>;
+  AnimationStateMap animation_state_map_;
+
+  // The set of currently active animations.
+  PaintImageIdFlatSet active_animations_;
+
+  // The set of images that were animated and invalidated on the last sync tree.
+  PaintImageIdFlatSet images_animated_on_sync_tree_;
+
+  DelayedNotifier notifier_;
+};
+
+}  // namespace cc
+
+#endif  // CC_TREES_IMAGE_ANIMATION_CONTROLLER_H_
diff --git a/cc/trees/image_animation_controller_unittest.cc b/cc/trees/image_animation_controller_unittest.cc
new file mode 100644
index 0000000..db983ea
--- /dev/null
+++ b/cc/trees/image_animation_controller_unittest.cc
@@ -0,0 +1,679 @@
+// 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 "cc/trees/image_animation_controller.h"
+
+#include "base/memory/ptr_util.h"
+#include "base/run_loop.h"
+#include "base/test/gtest_util.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace cc {
+
+class FakeAnimationDriver : public ImageAnimationController::AnimationDriver {
+ public:
+  FakeAnimationDriver() {}
+  ~FakeAnimationDriver() override {}
+
+  void set_should_animate(bool should_animate) {
+    should_animate_ = should_animate;
+  }
+
+  // ImageAnimationController::AnimationDriver implementation.
+  bool ShouldAnimate(PaintImage::Id paint_image_id) const override {
+    return should_animate_;
+  }
+
+ private:
+  bool should_animate_ = true;
+};
+
+class DelayTrackingTaskRunner : public base::SingleThreadTaskRunner {
+ public:
+  explicit DelayTrackingTaskRunner(base::SingleThreadTaskRunner* task_runner)
+      : task_runner_(task_runner) {}
+
+  bool PostDelayedTask(const base::Location& from_here,
+                       base::OnceClosure task,
+                       base::TimeDelta delay) override {
+    last_delay_.emplace(delay);
+    return task_runner_->PostTask(from_here, std::move(task));
+  }
+
+  bool RunsTasksInCurrentSequence() const override {
+    return task_runner_->RunsTasksInCurrentSequence();
+  }
+
+  bool PostNonNestableDelayedTask(const base::Location& from_here,
+                                  base::OnceClosure task,
+                                  base::TimeDelta delay) override {
+    last_delay_.emplace(delay);
+    return task_runner_->PostTask(from_here, std::move(task));
+  }
+
+  void VerifyDelay(base::TimeDelta expected) {
+    DCHECK(last_delay_.has_value());
+    EXPECT_EQ(last_delay_.value(), expected);
+    last_delay_.reset();
+  }
+
+  bool has_delay() const { return last_delay_.has_value(); }
+
+ private:
+  ~DelayTrackingTaskRunner() override = default;
+
+  base::Optional<base::TimeDelta> last_delay_;
+  base::SingleThreadTaskRunner* task_runner_;
+};
+
+class ImageAnimationControllerTest : public testing::Test {
+ public:
+  void SetUp() override {
+    task_runner_ =
+        new DelayTrackingTaskRunner(base::ThreadTaskRunnerHandle::Get().get());
+    base::Closure invalidation_callback =
+        base::Bind(&ImageAnimationControllerTest::RequestInvalidation,
+                   base::Unretained(this));
+    controller_ = base::MakeUnique<ImageAnimationController>(
+        task_runner_.get(), invalidation_callback);
+    now_ += base::TimeDelta::FromSeconds(10);
+  }
+
+  void TearDown() override { controller_.reset(); }
+
+  void LoopOnceNoDelay(PaintImage::Id paint_image_id,
+                       const std::vector<FrameMetadata>& frames,
+                       size_t num_of_frames_to_loop,
+                       int repetitions_completed) {
+    DCHECK_LE(num_of_frames_to_loop, frames.size());
+
+    invalidation_count_ = 0;
+    for (size_t i = 0; i < num_of_frames_to_loop; ++i) {
+      SCOPED_TRACE(i);
+
+      // Run the pending invalidation.
+      base::RunLoop().RunUntilIdle();
+      EXPECT_EQ(invalidation_count_, static_cast<int>(i + 1));
+
+      // Animate the image on the sync tree.
+      auto animated_images = controller_->AnimateForSyncTree(now_);
+      EXPECT_EQ(controller_->GetFrameIndexForImage(paint_image_id,
+                                                   WhichTree::PENDING_TREE),
+                i);
+      size_t active_index = i - 1;
+      if (i == 0u) {
+        // If we are displaying the first frame on the pending tree, then the
+        // active tree has the first frame as well if this is the first loop,
+        // otherwise it should be the last frame since we are starting a new
+        // loop.
+        if (repetitions_completed == 0)
+          active_index = 0u;
+        else
+          active_index = frames.size() - 1;
+      }
+
+      EXPECT_EQ(controller_->GetFrameIndexForImage(paint_image_id,
+                                                   WhichTree::ACTIVE_TREE),
+                active_index);
+
+      if (i == 0u && repetitions_completed == 0) {
+        // Starting the animation does not perform any invalidation.
+        EXPECT_EQ(animated_images.size(), 0u);
+      } else {
+        EXPECT_EQ(animated_images.size(), 1u);
+        EXPECT_EQ(animated_images.count(paint_image_id), 1u);
+      }
+
+      // Animating should schedule an invalidation for the next frame, until we
+      // reach the last frame.
+      if (i != num_of_frames_to_loop - 1)
+        task_runner_->VerifyDelay(frames[i].duration);
+
+      // Activate and advance time to the next frame.
+      controller_->DidActivate();
+      AdvanceNow(frames[i].duration);
+    }
+  }
+
+ protected:
+  void RequestInvalidation() { invalidation_count_++; }
+
+  void AdvanceNow(base::TimeDelta delta) { now_ += delta; }
+
+  base::TimeTicks now_;
+  int invalidation_count_ = 0;
+  std::unique_ptr<ImageAnimationController> controller_;
+  scoped_refptr<DelayTrackingTaskRunner> task_runner_;
+};
+
+TEST_F(ImageAnimationControllerTest, AnimationWithDelays) {
+  std::vector<FrameMetadata> frames = {
+      FrameMetadata(true, base::TimeDelta::FromMilliseconds(5)),
+      FrameMetadata(true, base::TimeDelta::FromMilliseconds(3)),
+      FrameMetadata(true, base::TimeDelta::FromMilliseconds(4))};
+
+  DiscardableImageMap::AnimatedImageMetadata data(
+      PaintImage::GetNextId(), PaintImage::CompletionState::DONE, frames,
+      kAnimationLoopInfinite);
+  controller_->UpdateAnimatedImage(data);
+  FakeAnimationDriver driver;
+  controller_->RegisterAnimationDriver(data.paint_image_id, &driver);
+  controller_->UpdateStateFromDrivers(now_);
+
+  // Display 2 loops in the animation.
+  LoopOnceNoDelay(data.paint_image_id, frames, frames.size(), 0);
+  LoopOnceNoDelay(data.paint_image_id, frames, frames.size(), 1);
+
+  // now_ is set to the time at which the first frame should be displayed for
+  // the third iteration. Add a delay that causes us to skip the first frame.
+  base::TimeDelta additional_delay = base::TimeDelta::FromMilliseconds(1);
+  AdvanceNow(data.frames[0].duration + additional_delay);
+  auto animated_images = controller_->AnimateForSyncTree(now_);
+  EXPECT_EQ(animated_images.size(), 1u);
+  EXPECT_EQ(animated_images.count(data.paint_image_id), 1u);
+
+  // The pending tree displays the second frame while the active tree has the
+  // third frame.
+  EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
+                                               WhichTree::PENDING_TREE),
+            1u);
+  EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
+                                               WhichTree::ACTIVE_TREE),
+            2u);
+
+  // Invalidation delay is based on the duration of the second frame and the
+  // delay in creating this sync tree.
+  task_runner_->VerifyDelay(frames[1].duration - additional_delay);
+  invalidation_count_ = 0;
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(invalidation_count_, 1);
+
+  // Activate and animate with a delay that causes us to skip another frame.
+  controller_->DidActivate();
+  EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
+                                               WhichTree::ACTIVE_TREE),
+            1u);
+  AdvanceNow(data.frames[1].duration + data.frames[2].duration);
+  animated_images = controller_->AnimateForSyncTree(now_);
+  EXPECT_EQ(animated_images.size(), 1u);
+  EXPECT_EQ(animated_images.count(data.paint_image_id), 1u);
+
+  // The pending tree displays the first frame, while the active tree has the
+  // second frame.
+  EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
+                                               WhichTree::PENDING_TREE),
+            0u);
+  EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
+                                               WhichTree::ACTIVE_TREE),
+            1u);
+
+  // Invalidation delay is based on the duration of the first frame and the
+  // initial additionaly delay.
+  task_runner_->VerifyDelay(frames[0].duration - additional_delay);
+  invalidation_count_ = 0;
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(invalidation_count_, 1);
+
+  controller_->UnregisterAnimationDriver(data.paint_image_id, &driver);
+}
+
+TEST_F(ImageAnimationControllerTest, DriversControlAnimationTicking) {
+  std::vector<FrameMetadata> first_image_frames = {
+      FrameMetadata(true, base::TimeDelta::FromMilliseconds(2)),
+      FrameMetadata(true, base::TimeDelta::FromMilliseconds(3))};
+  DiscardableImageMap::AnimatedImageMetadata first_data(
+      PaintImage::GetNextId(), PaintImage::CompletionState::DONE,
+      first_image_frames, kAnimationLoopOnce);
+  controller_->UpdateAnimatedImage(first_data);
+  FakeAnimationDriver first_driver;
+  controller_->RegisterAnimationDriver(first_data.paint_image_id,
+                                       &first_driver);
+
+  std::vector<FrameMetadata> second_image_frames = {
+      FrameMetadata(true, base::TimeDelta::FromMilliseconds(5)),
+      FrameMetadata(true, base::TimeDelta::FromMilliseconds(3))};
+  DiscardableImageMap::AnimatedImageMetadata second_data(
+      PaintImage::GetNextId(), PaintImage::CompletionState::DONE,
+      second_image_frames, kAnimationLoopOnce);
+  controller_->UpdateAnimatedImage(second_data);
+  FakeAnimationDriver second_driver;
+  controller_->RegisterAnimationDriver(second_data.paint_image_id,
+                                       &second_driver);
+
+  // Disable animating from all drivers, no invalidation request should be made.
+  first_driver.set_should_animate(false);
+  second_driver.set_should_animate(false);
+  controller_->UpdateStateFromDrivers(now_);
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(invalidation_count_, 0);
+
+  // Enable animating from the first driver, which should schedule an
+  // invalidation to advance this animation.
+  first_driver.set_should_animate(true);
+  controller_->UpdateStateFromDrivers(now_);
+  task_runner_->VerifyDelay(base::TimeDelta());
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(invalidation_count_, 1);
+
+  // Start animating the first image.
+  auto animated_images = controller_->AnimateForSyncTree(now_);
+  EXPECT_EQ(animated_images.size(), 0u);
+
+  // Invalidation should be scheduled for this image.
+  task_runner_->VerifyDelay(first_image_frames[0].duration);
+
+  // Now enable animating the second image instead.
+  second_driver.set_should_animate(true);
+  controller_->UpdateStateFromDrivers(now_);
+
+  // Invalidation is triggered to start with no delay since the second image has
+  // not started animating yet.
+  task_runner_->VerifyDelay(base::TimeDelta());
+
+  // Disable animating all images.
+  first_driver.set_should_animate(false);
+  second_driver.set_should_animate(false);
+  controller_->UpdateStateFromDrivers(now_);
+
+  // Any scheduled invalidation should be cancelled.
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(invalidation_count_, 1);
+
+  controller_->UnregisterAnimationDriver(first_data.paint_image_id,
+                                         &first_driver);
+  controller_->UnregisterAnimationDriver(second_data.paint_image_id,
+                                         &second_driver);
+}
+
+TEST_F(ImageAnimationControllerTest, RepetitionsRequested) {
+  std::vector<FrameMetadata> frames = {
+      FrameMetadata(true, base::TimeDelta::FromMilliseconds(2)),
+      FrameMetadata(true, base::TimeDelta::FromMilliseconds(3)),
+      FrameMetadata(true, base::TimeDelta::FromMilliseconds(4))};
+
+  DiscardableImageMap::AnimatedImageMetadata data(
+      PaintImage::GetNextId(), PaintImage::CompletionState::DONE, frames,
+      kAnimationLoopOnce);
+  controller_->UpdateAnimatedImage(data);
+  FakeAnimationDriver driver;
+  controller_->RegisterAnimationDriver(data.paint_image_id, &driver);
+  controller_->UpdateStateFromDrivers(now_);
+
+  // Finish a single loop in the animation.
+  LoopOnceNoDelay(data.paint_image_id, frames, frames.size(), 0);
+
+  // No invalidation should be scheduled now, since the requested number of
+  // loops have been completed.
+  invalidation_count_ = 0;
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(invalidation_count_, 0);
+  controller_->UnregisterAnimationDriver(data.paint_image_id, &driver);
+
+  // Now with a repetition count of 5.
+  data.paint_image_id = PaintImage::GetNextId();
+  data.repetition_count = 5;
+  controller_->UpdateAnimatedImage(data);
+  controller_->RegisterAnimationDriver(data.paint_image_id, &driver);
+  controller_->UpdateStateFromDrivers(now_);
+  for (int i = 0; i < data.repetition_count; ++i) {
+    LoopOnceNoDelay(data.paint_image_id, frames, frames.size(), i);
+
+    // Since we will be looping back to the first frame, the invalidation should
+    // have the delay of the last frame. Until we reach the end of requested
+    // iterations.
+    if (i < data.repetition_count - 1)
+      task_runner_->VerifyDelay(frames.back().duration);
+    invalidation_count_ = 0;
+  }
+
+  // No invalidation should be scheduled now, since the requested number of
+  // loops have been completed.
+  invalidation_count_ = 0;
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(invalidation_count_, 0);
+  controller_->UnregisterAnimationDriver(data.paint_image_id, &driver);
+
+  // Now with kAnimationLoopInfinite.
+  data.paint_image_id = PaintImage::GetNextId();
+  data.repetition_count = kAnimationLoopInfinite;
+  controller_->UpdateAnimatedImage(data);
+  controller_->RegisterAnimationDriver(data.paint_image_id, &driver);
+  controller_->UpdateStateFromDrivers(now_);
+  for (int i = 0; i < 7; ++i) {
+    LoopOnceNoDelay(data.paint_image_id, frames, frames.size(), i);
+
+    // Since we will be looping back to the first frame, the invalidation should
+    // have the delay of the last frame. Until we reach the end of requested
+    // iterations.
+    if (i < data.repetition_count - 1)
+      task_runner_->VerifyDelay(frames.back().duration);
+    invalidation_count_ = 0;
+  }
+
+  // We still have an invalidation scheduled since the image will keep looping
+  // till the drivers keep the animation active.
+  invalidation_count_ = 0;
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(invalidation_count_, 1);
+  controller_->UnregisterAnimationDriver(data.paint_image_id, &driver);
+
+  // Now try with a kAnimationNone image, which should result in a DCHECK
+  // failure.
+  data.paint_image_id = PaintImage::GetNextId();
+  data.repetition_count = kAnimationNone;
+  EXPECT_DCHECK_DEATH(controller_->UpdateAnimatedImage(data));
+}
+
+TEST_F(ImageAnimationControllerTest, DisplayCompleteFrameOnly) {
+  std::vector<FrameMetadata> frames = {
+      FrameMetadata(true, base::TimeDelta::FromMilliseconds(2)),
+      FrameMetadata(true, base::TimeDelta::FromMilliseconds(3)),
+      FrameMetadata(false, base::TimeDelta::FromMilliseconds(4))};
+
+  DiscardableImageMap::AnimatedImageMetadata data(
+      PaintImage::GetNextId(), PaintImage::CompletionState::PARTIALLY_DONE,
+      frames, kAnimationLoopInfinite);
+  controller_->UpdateAnimatedImage(data);
+  FakeAnimationDriver driver;
+  controller_->RegisterAnimationDriver(data.paint_image_id, &driver);
+  controller_->UpdateStateFromDrivers(now_);
+
+  // Advance until the second frame.
+  LoopOnceNoDelay(data.paint_image_id, frames, 2, 0);
+
+  // We have no invalidation scheduled since its not possible to animate the
+  // image further until the second frame is completed.
+  invalidation_count_ = 0;
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(invalidation_count_, 0);
+
+  // The frame is still incomplete but the image has been marked complete, which
+  // should push the animation forward.
+  data.completion_state = PaintImage::CompletionState::DONE;
+  controller_->UpdateAnimatedImage(data);
+  controller_->UpdateStateFromDrivers(now_);
+
+  // There is no delay for advancing to this frame since we advanced the time
+  // in the loop iteration above.
+  task_runner_->VerifyDelay(base::TimeDelta());
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(invalidation_count_, 1);
+
+  controller_->UnregisterAnimationDriver(data.paint_image_id, &driver);
+}
+
+TEST_F(ImageAnimationControllerTest, DontLoopPartiallyLoadedImages) {
+  std::vector<FrameMetadata> frames = {
+      FrameMetadata(true, base::TimeDelta::FromMilliseconds(2)),
+      FrameMetadata(true, base::TimeDelta::FromMilliseconds(3))};
+
+  DiscardableImageMap::AnimatedImageMetadata data(
+      PaintImage::GetNextId(), PaintImage::CompletionState::PARTIALLY_DONE,
+      frames, 2);
+  controller_->UpdateAnimatedImage(data);
+  FakeAnimationDriver driver;
+  controller_->RegisterAnimationDriver(data.paint_image_id, &driver);
+  controller_->UpdateStateFromDrivers(now_);
+
+  // Finish the first loop.
+  LoopOnceNoDelay(data.paint_image_id, frames, frames.size(), 0);
+
+  // We shouldn't be looping back to the first frame until the image is known to
+  // be completely loaded.
+  invalidation_count_ = 0;
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(invalidation_count_, 0);
+
+  // Now add another frame and mark the image complete. The animation should
+  // advance and we should see another repetition. This verifies that we don't
+  // mark loops complete on reaching the last frame until the image is
+  // completely loaded and the frame count is known to be accurate.
+  frames.push_back(FrameMetadata(true, base::TimeDelta::FromMilliseconds(4)));
+  data.completion_state = PaintImage::CompletionState::DONE;
+  data.frames = frames;
+  controller_->UpdateAnimatedImage(data);
+  controller_->UpdateStateFromDrivers(now_);
+
+  // The animation advances to the last frame. We don't have a delay since we
+  // already advanced to the desired time in the loop above.
+  task_runner_->VerifyDelay(base::TimeDelta());
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(invalidation_count_, 1);
+  auto animated_images = controller_->AnimateForSyncTree(now_);
+  EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
+                                               WhichTree::PENDING_TREE),
+            2u);
+  EXPECT_EQ(animated_images.size(), 1u);
+  EXPECT_EQ(animated_images.count(data.paint_image_id), 1u);
+  controller_->DidActivate();
+
+  // Advancing the animation scheduled an invalidation for the next iteration.
+  task_runner_->VerifyDelay(frames.back().duration);
+
+  // Perform another loop in the animation.
+  AdvanceNow(frames.back().duration);
+  LoopOnceNoDelay(data.paint_image_id, frames, frames.size(), 1);
+
+  // No invalidation should have been requested at the end of the second loop.
+  invalidation_count_ = 0;
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(invalidation_count_, 0);
+
+  controller_->UnregisterAnimationDriver(data.paint_image_id, &driver);
+}
+
+TEST_F(ImageAnimationControllerTest, DontAdvanceUntilDesiredTime) {
+  std::vector<FrameMetadata> frames = {
+      FrameMetadata(true, base::TimeDelta::FromMilliseconds(2)),
+      FrameMetadata(true, base::TimeDelta::FromMilliseconds(3))};
+
+  DiscardableImageMap::AnimatedImageMetadata data(
+      PaintImage::GetNextId(), PaintImage::CompletionState::DONE, frames,
+      kAnimationLoopOnce);
+  controller_->UpdateAnimatedImage(data);
+  FakeAnimationDriver driver;
+  controller_->RegisterAnimationDriver(data.paint_image_id, &driver);
+  controller_->UpdateStateFromDrivers(now_);
+
+  // Advance the first frame.
+  task_runner_->VerifyDelay(base::TimeDelta());
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(invalidation_count_, 1);
+  auto animated_images = controller_->AnimateForSyncTree(now_);
+  EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
+                                               WhichTree::PENDING_TREE),
+            0u);
+  EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
+                                               WhichTree::ACTIVE_TREE),
+            0u);
+  EXPECT_EQ(animated_images.size(), 0u);
+  controller_->DidActivate();
+
+  // We have an invalidation request for the second frame.
+  task_runner_->VerifyDelay(frames[0].duration);
+
+  // While there is still time for the second frame, we get a new sync tree. The
+  // animation is not advanced.
+  base::TimeDelta time_remaining = base::TimeDelta::FromMilliseconds(1);
+  AdvanceNow(frames[0].duration - time_remaining);
+  animated_images = controller_->AnimateForSyncTree(now_);
+  EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
+                                               WhichTree::PENDING_TREE),
+            0u);
+  EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
+                                               WhichTree::ACTIVE_TREE),
+            0u);
+  EXPECT_EQ(animated_images.size(), 0u);
+  controller_->DidActivate();
+
+  // We did not get another invalidation request because there is no change in
+  // the desired time and the previous request is still pending.
+  EXPECT_FALSE(task_runner_->has_delay());
+
+  // We have a sync tree before the invalidation task could run.
+  AdvanceNow(time_remaining);
+  animated_images = controller_->AnimateForSyncTree(now_);
+  EXPECT_EQ(animated_images.size(), 1u);
+  EXPECT_EQ(animated_images.count(data.paint_image_id), 1u);
+  EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
+                                               WhichTree::PENDING_TREE),
+            1u);
+  EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
+                                               WhichTree::ACTIVE_TREE),
+            0u);
+  controller_->DidActivate();
+
+  // We shouldn't have an invalidation because the animation was already
+  // advanced to the last frame and the previous one should have been cancelled.
+  invalidation_count_ = 0;
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(invalidation_count_, 0);
+
+  controller_->UnregisterAnimationDriver(data.paint_image_id, &driver);
+}
+
+TEST_F(ImageAnimationControllerTest, RestartAfterSyncCutoff) {
+  std::vector<FrameMetadata> frames = {
+      FrameMetadata(true, base::TimeDelta::FromMilliseconds(2)),
+      FrameMetadata(true, base::TimeDelta::FromMilliseconds(3))};
+
+  DiscardableImageMap::AnimatedImageMetadata data(
+      PaintImage::GetNextId(), PaintImage::CompletionState::DONE, frames,
+      kAnimationLoopOnce);
+  controller_->UpdateAnimatedImage(data);
+  FakeAnimationDriver driver;
+  controller_->RegisterAnimationDriver(data.paint_image_id, &driver);
+  controller_->UpdateStateFromDrivers(now_);
+
+  // Advance the first frame.
+  task_runner_->VerifyDelay(base::TimeDelta());
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(invalidation_count_, 1);
+  auto animated_images = controller_->AnimateForSyncTree(now_);
+  EXPECT_EQ(animated_images.size(), 0u);
+  EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
+                                               WhichTree::PENDING_TREE),
+            0u);
+  EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
+                                               WhichTree::ACTIVE_TREE),
+            0u);
+  controller_->DidActivate();
+
+  // Invalidation request for the second frame.
+  task_runner_->VerifyDelay(frames[0].duration);
+
+  // Advance the time by 10 min.
+  AdvanceNow(base::TimeDelta::FromMinutes(10));
+
+  // Animate again, it starts from the first frame. We don't see an
+  // invalidation, because that's the frame we are already displaying.
+  animated_images = controller_->AnimateForSyncTree(now_);
+  EXPECT_EQ(animated_images.size(), 0u);
+  EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
+                                               WhichTree::PENDING_TREE),
+            0u);
+  EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
+                                               WhichTree::ACTIVE_TREE),
+            0u);
+  controller_->DidActivate();
+
+  // New invalidation request since the desired invalidation time changed.
+  task_runner_->VerifyDelay(frames[0].duration);
+  invalidation_count_ = 0;
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(invalidation_count_, 1);
+
+  controller_->UnregisterAnimationDriver(data.paint_image_id, &driver);
+}
+
+TEST_F(ImageAnimationControllerTest, DontSkipLoopsToCatchUpAfterLoad) {
+  std::vector<FrameMetadata> frames = {
+      FrameMetadata(true, base::TimeDelta::FromMilliseconds(2)),
+      FrameMetadata(true, base::TimeDelta::FromMilliseconds(3)),
+      FrameMetadata(true, base::TimeDelta::FromMilliseconds(4)),
+      FrameMetadata(true, base::TimeDelta::FromMilliseconds(5))};
+
+  DiscardableImageMap::AnimatedImageMetadata data(
+      PaintImage::GetNextId(), PaintImage::CompletionState::PARTIALLY_DONE,
+      frames, kAnimationLoopInfinite);
+  controller_->UpdateAnimatedImage(data);
+  FakeAnimationDriver driver;
+  controller_->RegisterAnimationDriver(data.paint_image_id, &driver);
+  controller_->UpdateStateFromDrivers(now_);
+
+  // Perform the first loop while the image is partially loaded, until the third
+  // frame.
+  LoopOnceNoDelay(data.paint_image_id, frames, 3u, 0);
+
+  // The invalidation has been scheduled with a delay for the third frame's
+  // duration.
+  task_runner_->VerifyDelay(frames[2].duration);
+
+  // |now_| is set to the desired time for the fourth frame. Advance further so
+  // we would reach the time for the second frame.
+  AdvanceNow(frames[3].duration + frames[0].duration);
+
+  // Finish the image load.
+  data.completion_state = PaintImage::CompletionState::DONE;
+  controller_->UpdateAnimatedImage(data);
+  controller_->UpdateStateFromDrivers(now_);
+
+  // Invalidation is scheduled immediately because we are way past the desired
+  // time. We should start from the first frame after the image is loaded
+  // instead of skipping frames.
+  task_runner_->VerifyDelay(base::TimeDelta());
+  auto animated_images = controller_->AnimateForSyncTree(now_);
+  EXPECT_EQ(animated_images.size(), 1u);
+  EXPECT_EQ(animated_images.count(data.paint_image_id), 1u);
+  EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
+                                               WhichTree::PENDING_TREE),
+            0u);
+  EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
+                                               WhichTree::ACTIVE_TREE),
+            2u);
+  controller_->UnregisterAnimationDriver(data.paint_image_id, &driver);
+}
+
+TEST_F(ImageAnimationControllerTest, FinishRepetitionsDuringCatchUp) {
+  std::vector<FrameMetadata> frames = {
+      FrameMetadata(true, base::TimeDelta::FromMilliseconds(2)),
+      FrameMetadata(true, base::TimeDelta::FromMilliseconds(3)),
+      FrameMetadata(true, base::TimeDelta::FromMilliseconds(4))};
+
+  // The animation wants 3 loops.
+  DiscardableImageMap::AnimatedImageMetadata data(
+      PaintImage::GetNextId(), PaintImage::CompletionState::DONE, frames, 3);
+  controller_->UpdateAnimatedImage(data);
+  FakeAnimationDriver driver;
+  controller_->RegisterAnimationDriver(data.paint_image_id, &driver);
+  controller_->UpdateStateFromDrivers(now_);
+
+  // Finish 2 loops.
+  LoopOnceNoDelay(data.paint_image_id, frames, frames.size(), 0);
+  LoopOnceNoDelay(data.paint_image_id, frames, frames.size(), 1);
+
+  // now_ is set to the desired time for the first frame. Advance it so we would
+  // reach way beyond the third repeition.
+  AdvanceNow(base::TimeDelta::FromMinutes(1));
+
+  // Advance the animation, we should see the last frame since the desired
+  // repetition count will be reached during catch up.
+  invalidation_count_ = 0;
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(invalidation_count_, 1);
+  auto animated_images = controller_->AnimateForSyncTree(now_);
+  // No invalidation since the active tree is already at the last frame.
+  EXPECT_EQ(animated_images.size(), 0u);
+  EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
+                                               WhichTree::PENDING_TREE),
+            frames.size() - 1);
+  EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
+                                               WhichTree::ACTIVE_TREE),
+            frames.size() - 1);
+
+  controller_->UnregisterAnimationDriver(data.paint_image_id, &driver);
+}
+
+}  // namespace cc
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index e7605f17..3ce444d 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -67,6 +67,7 @@
 #include "cc/trees/draw_property_utils.h"
 #include "cc/trees/effect_node.h"
 #include "cc/trees/frame_rate_counter.h"
+#include "cc/trees/image_animation_controller.h"
 #include "cc/trees/latency_info_swap_promise_monitor.h"
 #include "cc/trees/layer_tree_frame_sink.h"
 #include "cc/trees/layer_tree_host_common.h"
@@ -270,6 +271,16 @@
       settings.top_controls_hide_threshold);
 
   tile_manager_.SetDecodedImageTracker(&decoded_image_tracker_);
+
+  if (settings_.enable_image_animations) {
+    // It is safe to use base::Unretained here since we will outlive the
+    // ImageAnimationController.
+    base::Closure invalidation_callback =
+        base::Bind(&LayerTreeHostImpl::RequestInvalidationForAnimatedImages,
+                   base::Unretained(this));
+    image_animation_controller_.emplace(GetTaskRunner(),
+                                        std::move(invalidation_callback));
+  }
 }
 
 LayerTreeHostImpl::~LayerTreeHostImpl() {
@@ -344,9 +355,6 @@
 }
 
 void LayerTreeHostImpl::UpdateSyncTreeAfterCommitOrImplSideInvalidation() {
-  sync_tree()->InvalidateRegionForImages(
-      tile_manager_.TakeImagesToInvalidateOnSyncTree());
-
   if (CommitToActiveTree()) {
     active_tree_->HandleScrollbarShowRequestsFromMain();
 
@@ -382,6 +390,20 @@
   // layer can or cannot use lcd text.  So, this is the cleanup pass to
   // determine if lcd state needs to switch due to draw properties.
   sync_tree()->UpdateCanUseLCDText();
+
+  // Defer invalidating images until UpdateDrawProperties is performed since
+  // that updates whether an image should be animated based on its visibility
+  // and the updated data for the image from the main frame.
+  PaintImageIdFlatSet images_to_invalidate =
+      tile_manager_.TakeImagesToInvalidateOnSyncTree();
+  if (image_animation_controller_.has_value()) {
+    const auto& animated_images =
+        image_animation_controller_.value().AnimateForSyncTree(
+            CurrentBeginFrameArgs().frame_time);
+    images_to_invalidate.insert(animated_images.begin(), animated_images.end());
+  }
+  sync_tree()->InvalidateRegionForImages(images_to_invalidate);
+
   // Start working on newly created tiles immediately if needed.
   // TODO(vmpstr): Investigate always having PrepareTiles issue
   // NotifyReadyToActivate, instead of handling it here.
@@ -1406,6 +1428,15 @@
   client_->NeedsImplSideInvalidation(needs_first_draw_on_activation);
 }
 
+size_t LayerTreeHostImpl::GetFrameIndexForImage(const PaintImage& paint_image,
+                                                WhichTree tree) const {
+  if (!paint_image.ShouldAnimate() || !image_animation_controller_.has_value())
+    return paint_image.frame_index();
+
+  return image_animation_controller_.value().GetFrameIndexForImage(
+      paint_image.stable_id(), tree);
+}
+
 void LayerTreeHostImpl::NotifyReadyToActivate() {
   pending_tree_raster_duration_timer_.reset();
   client_->NotifyReadyToActivate();
@@ -2206,8 +2237,17 @@
 
   UpdateViewportContainerSizes();
 
+  // Inform the ImageAnimationController and TileManager before dirtying tile
+  // priorities. Since these components cache tree specific state, these should
+  // be updated before DidModifyTilePriorities which can synchronously issue a
+  // PrepareTiles.
+  if (image_animation_controller_)
+    image_animation_controller_->DidActivate();
+  tile_manager_.DidActivateSyncTree();
+
   active_tree_->DidBecomeActive();
   client_->RenewTreePriority();
+
   // If we have any picture layers, then by activating we also modified tile
   // priorities.
   if (!active_tree_->picture_layers().empty())
@@ -4500,4 +4540,13 @@
     animation_controller->DidScrollUpdate();
 }
 
+void LayerTreeHostImpl::RequestInvalidationForAnimatedImages() {
+  DCHECK(image_animation_controller_);
+
+  // If we are animating an image, we want at least one draw of the active tree
+  // before a new tree is activated.
+  bool needs_first_draw_on_activation = true;
+  client_->NeedsImplSideInvalidation(needs_first_draw_on_activation);
+}
+
 }  // namespace cc
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h
index 250d679..0373670 100644
--- a/cc/trees/layer_tree_host_impl.h
+++ b/cc/trees/layer_tree_host_impl.h
@@ -59,6 +59,7 @@
 class DebugRectHistory;
 class EvictionTilePriorityQueue;
 class FrameRateCounter;
+class ImageAnimationController;
 class LayerImpl;
 class LayerTreeImpl;
 class MemoryHistory;
@@ -354,6 +355,8 @@
   void SetIsLikelyToRequireADraw(bool is_likely_to_require_a_draw) override;
   gfx::ColorSpace GetRasterColorSpace() const override;
   void RequestImplSideInvalidationForCheckerImagedTiles() override;
+  size_t GetFrameIndexForImage(const PaintImage& paint_image,
+                               WhichTree tree) const override;
 
   // ScrollbarAnimationControllerClient implementation.
   void PostDelayedScrollbarAnimationTask(const base::Closure& task,
@@ -417,6 +420,11 @@
   }
   ResourcePool* resource_pool() { return resource_pool_.get(); }
   ImageDecodeCache* image_decode_cache() { return image_decode_cache_.get(); }
+  ImageAnimationController* image_animation_controller() {
+    if (!image_animation_controller_.has_value())
+      return nullptr;
+    return &image_animation_controller_.value();
+  }
 
   virtual void WillBeginImplFrame(const viz::BeginFrameArgs& args);
   virtual void DidFinishImplFrame();
@@ -733,6 +741,9 @@
   // tree, because the active tree value always takes precedence for scrollbars.
   void PushScrollbarOpacitiesFromActiveToPending();
 
+  // Request an impl-side invalidation to animate an image.
+  void RequestInvalidationForAnimatedImages();
+
   using UIResourceMap = std::unordered_map<UIResourceId, UIResourceData>;
   UIResourceMap ui_resource_map_;
 
@@ -896,6 +907,8 @@
 
   ImplThreadPhase impl_thread_phase_;
 
+  base::Optional<ImageAnimationController> image_animation_controller_;
+
   DISALLOW_COPY_AND_ASSIGN(LayerTreeHostImpl);
 };
 
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc
index 67ab40aa..84dcd17 100644
--- a/cc/trees/layer_tree_host_unittest.cc
+++ b/cc/trees/layer_tree_host_unittest.cc
@@ -25,10 +25,12 @@
 #include "cc/layers/picture_layer.h"
 #include "cc/layers/solid_color_layer.h"
 #include "cc/layers/video_layer.h"
+#include "cc/paint/image_animation_count.h"
 #include "cc/resources/ui_resource_manager.h"
 #include "cc/test/fake_content_layer_client.h"
 #include "cc/test/fake_layer_tree_host_client.h"
 #include "cc/test/fake_output_surface.h"
+#include "cc/test/fake_paint_image_generator.h"
 #include "cc/test/fake_painted_scrollbar_layer.h"
 #include "cc/test/fake_picture_layer.h"
 #include "cc/test/fake_picture_layer_impl.h"
@@ -7841,7 +7843,8 @@
 
     image_ = DrawImage(CreateDiscardablePaintImage(gfx::Size(400, 400)),
                        SkIRect::MakeWH(400, 400), kNone_SkFilterQuality,
-                       SkMatrix::I(), gfx::ColorSpace());
+                       SkMatrix::I(), PaintImage::kDefaultFrameIndex,
+                       gfx::ColorSpace());
     auto callback =
         base::Bind(&LayerTreeHostTestQueueImageDecode::ImageDecodeFinished,
                    base::Unretained(this));
@@ -8041,5 +8044,86 @@
 
 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestDiscardAckAfterRelease);
 
+class LayerTreeHostTestImageAnimation : public LayerTreeHostTest {
+ public:
+  void BeginTest() override { PostSetNeedsCommitToMainThread(); }
+
+  void InitializeSettings(LayerTreeSettings* settings) override {
+    settings->enable_image_animations = true;
+  }
+
+  void SetupTree() override {
+    gfx::Size layer_size(1000, 500);
+    content_layer_client_.set_bounds(layer_size);
+    content_layer_client_.set_fill_with_nonsolid_color(true);
+    std::vector<FrameMetadata> frames = {
+        FrameMetadata(true, base::TimeDelta::FromSeconds(1)),
+        FrameMetadata(true, base::TimeDelta::FromSeconds(1)),
+        FrameMetadata(true, base::TimeDelta::FromSeconds(1))};
+    generator_ = sk_make_sp<FakePaintImageGenerator>(
+        SkImageInfo::MakeN32Premul(500, 500), frames);
+    PaintImage image =
+        PaintImageBuilder()
+            .set_id(PaintImage::GetNextId())
+            .set_paint_image_generator(generator_)
+            .set_frame_index(0u)
+            .set_animation_type(PaintImage::AnimationType::ANIMATED)
+            .set_repetition_count(kAnimationLoopOnce)
+            .TakePaintImage();
+    content_layer_client_.add_draw_image(image, gfx::Point(0, 0), PaintFlags());
+
+    layer_tree_host()->SetRootLayer(
+        FakePictureLayer::Create(&content_layer_client_));
+    layer_tree_host()->root_layer()->SetBounds(layer_size);
+    LayerTreeTest::SetupTree();
+  }
+
+  void WillPrepareToDrawOnThread(LayerTreeHostImpl* host_impl) override {
+    gfx::Rect image_rect(-1, -1, 502, 502);
+    auto* layer = static_cast<PictureLayerImpl*>(
+        host_impl->active_tree()->root_layer_for_testing());
+    switch (++draw_count_) {
+      case 1:
+        // First draw, everything is invalid.
+        EXPECT_EQ(layer->InvalidationForTesting().bounds(),
+                  gfx::Rect(layer->bounds()));
+        EXPECT_EQ(layer->update_rect(), gfx::Rect(layer->bounds()));
+        EXPECT_EQ(generator_->frames_decoded().size(), 1u);
+        EXPECT_EQ(generator_->frames_decoded().count(0u), 1u);
+        break;
+      case 2:
+        // Every frame after the first one should invalidate only the image.
+        EXPECT_EQ(layer->InvalidationForTesting().bounds(), image_rect);
+        EXPECT_EQ(layer->update_rect(), image_rect);
+        EXPECT_EQ(generator_->frames_decoded().size(), 2u);
+        EXPECT_EQ(generator_->frames_decoded().count(1u), 1u);
+        break;
+      case 3:
+        EXPECT_EQ(layer->InvalidationForTesting().bounds(), image_rect);
+        EXPECT_EQ(layer->update_rect(), image_rect);
+        EXPECT_EQ(generator_->frames_decoded().size(), 3u);
+        EXPECT_EQ(generator_->frames_decoded().count(2u), 1u);
+        break;
+      default:
+        // Only 3 draws should happen for 3 frames of the animate image.
+        NOTREACHED();
+    }
+
+    if (draw_count_ == 3)
+      EndTest();
+  }
+
+  void AfterTest() override {
+    EXPECT_EQ(generator_->frames_decoded().size(), 3u);
+  }
+
+ private:
+  FakeContentLayerClient content_layer_client_;
+  sk_sp<FakePaintImageGenerator> generator_;
+  int draw_count_ = 0;
+};
+
+MULTI_THREAD_TEST_F(LayerTreeHostTestImageAnimation);
+
 }  // namespace
 }  // namespace cc
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc
index fa1b7be..55b4dae 100644
--- a/cc/trees/layer_tree_impl.cc
+++ b/cc/trees/layer_tree_impl.cc
@@ -1119,6 +1119,11 @@
                      "layers_updated_count", layers_updated_count);
   }
 
+  if (image_animation_controller()) {
+    image_animation_controller()->UpdateStateFromDrivers(
+        host_impl_->CurrentBeginFrameArgs().frame_time);
+  }
+
   DCHECK(!needs_update_draw_properties_)
       << "CalcDrawProperties should not set_needs_update_draw_properties()";
   return true;
@@ -1328,6 +1333,10 @@
   return host_impl_->image_decode_cache();
 }
 
+ImageAnimationController* LayerTreeImpl::image_animation_controller() const {
+  return host_impl_->image_animation_controller();
+}
+
 FrameRateCounter* LayerTreeImpl::frame_rate_counter() const {
   return host_impl_->fps_counter();
 }
diff --git a/cc/trees/layer_tree_impl.h b/cc/trees/layer_tree_impl.h
index a4a3fed..38bf8c2 100644
--- a/cc/trees/layer_tree_impl.h
+++ b/cc/trees/layer_tree_impl.h
@@ -111,6 +111,7 @@
   LayerTreeResourceProvider* resource_provider() const;
   TileManager* tile_manager() const;
   ImageDecodeCache* image_decode_cache() const;
+  ImageAnimationController* image_animation_controller() const;
   FrameRateCounter* frame_rate_counter() const;
   MemoryHistory* memory_history() const;
   gfx::Size device_viewport_size() const;
diff --git a/cc/trees/layer_tree_settings.h b/cc/trees/layer_tree_settings.h
index 0b68410..804478ac 100644
--- a/cc/trees/layer_tree_settings.h
+++ b/cc/trees/layer_tree_settings.h
@@ -145,6 +145,9 @@
   // Whether to use out of process raster.  If true, whenever gpu raster
   // would have been used, out of process gpu raster will be used instead.
   bool enable_oop_rasterization = false;
+
+  // Whether images should be animated in the compositor.
+  bool enable_image_animations = false;
 };
 
 }  // namespace cc
diff --git a/chrome/browser/android/tab_state.cc b/chrome/browser/android/tab_state.cc
index 749d398..a78081ff 100644
--- a/chrome/browser/android/tab_state.cc
+++ b/chrome/browser/android/tab_state.cc
@@ -36,13 +36,13 @@
 
 namespace {
 
-bool WriteStateHeaderToPickle(bool off_the_record,
+void WriteStateHeaderToPickle(bool off_the_record,
                               int entry_count,
                               int current_entry_index,
                               base::Pickle* pickle) {
-  return pickle->WriteBool(off_the_record) &&
-      pickle->WriteInt(entry_count) &&
-      pickle->WriteInt(current_entry_index);
+  pickle->WriteBool(off_the_record);
+  pickle->WriteInt(entry_count);
+  pickle->WriteInt(current_entry_index);
 }
 
 // Migrates a pickled SerializedNavigationEntry from Android tab version 0 to
@@ -316,12 +316,8 @@
     const std::vector<content::NavigationEntry*>& navigations,
     int current_entry) {
   base::Pickle pickle;
-  if (!WriteStateHeaderToPickle(is_off_the_record, navigations.size(),
-                                current_entry, &pickle)) {
-    LOG(ERROR) << "Failed to serialize tab state (entry count=" <<
-        navigations.size() << ").";
-    return ScopedJavaLocalRef<jobject>();
-  }
+  WriteStateHeaderToPickle(is_off_the_record, navigations.size(),
+                           current_entry, &pickle);
 
   // Write out all of the NavigationEntrys.
   for (size_t i = 0; i < navigations.size(); ++i) {
diff --git a/chrome/browser/chromeos/drive/drive_integration_service.cc b/chrome/browser/chromeos/drive/drive_integration_service.cc
index f74dac0..f748c2a 100644
--- a/chrome/browser/chromeos/drive/drive_integration_service.cc
+++ b/chrome/browser/chromeos/drive/drive_integration_service.cc
@@ -255,7 +255,8 @@
 
   logger_.reset(new EventLogger);
   blocking_task_runner_ = base::CreateSequencedTaskRunnerWithTraits(
-      {base::MayBlock(), base::TaskPriority::USER_BLOCKING});
+      {base::MayBlock(), base::TaskPriority::USER_BLOCKING,
+       base::WithBaseSyncPrimitives()});
 
   ProfileOAuth2TokenService* oauth_service =
       ProfileOAuth2TokenServiceFactory::GetForProfile(profile);
diff --git a/chrome/browser/devtools/chrome_devtools_manager_delegate.cc b/chrome/browser/devtools/chrome_devtools_manager_delegate.cc
index 826a55c..fb9618a 100644
--- a/chrome/browser/devtools/chrome_devtools_manager_delegate.cc
+++ b/chrome/browser/devtools/chrome_devtools_manager_delegate.cc
@@ -6,6 +6,7 @@
 
 #include <utility>
 
+#include "base/json/json_writer.h"
 #include "base/memory/ptr_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
@@ -118,6 +119,12 @@
   }
 }
 
+std::string ToString(std::unique_ptr<base::DictionaryValue> value) {
+  std::string json;
+  base::JSONWriter::Write(*value, &json);
+  return json;
+}
+
 }  // namespace
 
 // static
@@ -347,7 +354,7 @@
   DevToolsWindow::OpenDevToolsWindow(agent_host, nullptr);
 }
 
-base::DictionaryValue* ChromeDevToolsManagerDelegate::HandleCommand(
+bool ChromeDevToolsManagerDelegate::HandleCommand(
     DevToolsAgentHost* agent_host,
     int session_id,
     base::DictionaryValue* command_dict) {
@@ -355,26 +362,44 @@
   std::string method;
   base::DictionaryValue* params = nullptr;
   if (!DevToolsProtocol::ParseCommand(command_dict, &id, &method, &params))
-    return nullptr;
+    return false;
 
   // Do not actually handle the enable/disable commands, just keep track of the
   // enable state.
-  if (method == chrome::devtools::Page::enable::kName)
+  if (method == chrome::devtools::Page::enable::kName) {
     TogglePageEnable(true /* enable */, agent_host);
-  if (method == chrome::devtools::Page::disable::kName)
+    return false;
+  }
+
+  if (method == chrome::devtools::Page::disable::kName) {
     TogglePageEnable(false /* enable */, agent_host);
+    return false;
+  }
 
-  auto* result = HandleBrowserCommand(id, method, params).release();
-  if (result)
-    return result;
+  auto result = HandleBrowserCommand(id, method, params);
+  if (result) {
+    agent_host->SendProtocolMessageToClient(session_id,
+                                            ToString(std::move(result)));
+    return true;
+  }
 
-  if (method == chrome::devtools::Page::setAdBlockingEnabled::kName)
-    return SetAdBlockingEnabled(agent_host, id, params).release();
+  if (method == chrome::devtools::Page::setAdBlockingEnabled::kName) {
+    result = SetAdBlockingEnabled(agent_host, id, params);
+    DCHECK(result);
+    agent_host->SendProtocolMessageToClient(session_id,
+                                            ToString(std::move(result)));
+    return true;
+  }
 
-  if (method == chrome::devtools::Target::setRemoteLocations::kName)
-    return SetRemoteLocations(agent_host, id, params).release();
+  if (method == chrome::devtools::Target::setRemoteLocations::kName) {
+    result = SetRemoteLocations(agent_host, id, params);
+    DCHECK(result);
+    agent_host->SendProtocolMessageToClient(session_id,
+                                            ToString(std::move(result)));
+    return true;
+  }
 
-  return nullptr;
+  return false;
 }
 
 std::string ChromeDevToolsManagerDelegate::GetTargetType(
diff --git a/chrome/browser/devtools/chrome_devtools_manager_delegate.h b/chrome/browser/devtools/chrome_devtools_manager_delegate.h
index 666dd6b..3c1b1d1 100644
--- a/chrome/browser/devtools/chrome_devtools_manager_delegate.h
+++ b/chrome/browser/devtools/chrome_devtools_manager_delegate.h
@@ -34,10 +34,9 @@
 
   // content::DevToolsManagerDelegate implementation.
   void Inspect(content::DevToolsAgentHost* agent_host) override;
-  base::DictionaryValue* HandleCommand(
-      content::DevToolsAgentHost* agent_host,
-      int session_id,
-      base::DictionaryValue* command_dict) override;
+  bool HandleCommand(content::DevToolsAgentHost* agent_host,
+                     int session_id,
+                     base::DictionaryValue* command_dict) override;
   std::string GetTargetType(content::WebContents* web_contents) override;
   std::string GetTargetTitle(content::WebContents* web_contents) override;
   scoped_refptr<content::DevToolsAgentHost> CreateNewTarget(
diff --git a/chrome/browser/ntp_snippets/download_suggestions_provider.cc b/chrome/browser/ntp_snippets/download_suggestions_provider.cc
index c14512ab..b50bf36 100644
--- a/chrome/browser/ntp_snippets/download_suggestions_provider.cc
+++ b/chrome/browser/ntp_snippets/download_suggestions_provider.cc
@@ -23,7 +23,6 @@
 #include "components/ntp_snippets/features.h"
 #include "components/ntp_snippets/pref_names.h"
 #include "components/ntp_snippets/pref_util.h"
-#include "components/offline_pages/core/offline_page_model_query.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
 #include "components/variations/variations_associated_data.h"
@@ -142,14 +141,6 @@
   return policy_controller->IsSupportedByDownload(client_id.name_space);
 }
 
-std::unique_ptr<OfflinePageModelQuery> BuildOfflinePageDownloadsQuery(
-    offline_pages::OfflinePageModel* model) {
-  OfflinePageModelQueryBuilder builder;
-  builder.RequireSupportedByDownload(
-      OfflinePageModelQuery::Requirement::INCLUDE_MATCHING);
-  return builder.Build(model->GetPolicyController());
-}
-
 }  // namespace
 
 DownloadSuggestionsProvider::DownloadSuggestionsProvider(
@@ -289,13 +280,10 @@
     // Offline pages which are not related to downloads are also queried here,
     // so that they can be returned if they happen to be dismissed (e.g. due to
     // a bug).
-    OfflinePageModelQueryBuilder query_builder;
-    offline_page_model_->GetPagesMatchingQuery(
-        query_builder.Build(offline_page_model_->GetPolicyController()),
-        base::Bind(&DownloadSuggestionsProvider::
-                       GetPagesMatchingQueryCallbackForGetDismissedSuggestions,
-                   weak_ptr_factory_.GetWeakPtr(),
-                   base::Passed(std::move(callback))));
+    offline_page_model_->GetAllPages(base::Bind(
+        &DownloadSuggestionsProvider::
+            GetPagesMatchingQueryCallbackForGetDismissedSuggestions,
+        weak_ptr_factory_.GetWeakPtr(), base::Passed(std::move(callback))));
   } else {
     GetPagesMatchingQueryCallbackForGetDismissedSuggestions(
         std::move(callback), std::vector<OfflinePageItem>());
@@ -496,8 +484,7 @@
 
   // If Offline Page model is not loaded yet, it will process our query once it
   // has finished loading.
-  offline_page_model_->GetPagesMatchingQuery(
-      BuildOfflinePageDownloadsQuery(offline_page_model_),
+  offline_page_model_->GetPagesSupportedByDownloads(
       base::Bind(&DownloadSuggestionsProvider::UpdateOfflinePagesCache,
                  weak_ptr_factory_.GetWeakPtr(), notify));
 }
diff --git a/chrome/browser/offline_pages/android/offline_page_bridge.cc b/chrome/browser/offline_pages/android/offline_page_bridge.cc
index 115ecca..9b70831 100644
--- a/chrome/browser/offline_pages/android/offline_page_bridge.cc
+++ b/chrome/browser/offline_pages/android/offline_page_bridge.cc
@@ -488,13 +488,9 @@
 
   std::string name_space = ConvertJavaStringToUTF8(env, j_namespace);
 
-  OfflinePageModelQueryBuilder builder;
-  builder.RequireNamespace(name_space);
-
-  offline_page_model_->GetPagesMatchingQuery(
-      builder.Build(offline_page_model_->GetPolicyController()),
-      base::Bind(&MultipleOfflinePageItemCallback, j_result_ref,
-                 j_callback_ref));
+  offline_page_model_->GetPagesByNamespace(
+      name_space, base::Bind(&MultipleOfflinePageItemCallback, j_result_ref,
+                             j_callback_ref));
 }
 
 void OfflinePageBridge::SelectPageForOnlineUrl(
diff --git a/chrome/browser/offline_pages/offline_page_utils.cc b/chrome/browser/offline_pages/offline_page_utils.cc
index 435fc437..1b0c631 100644
--- a/chrome/browser/offline_pages/offline_page_utils.cc
+++ b/chrome/browser/offline_pages/offline_page_utils.cc
@@ -325,11 +325,7 @@
       OfflinePageModelFactory::GetForBrowserContext(browser_context);
   if (!offline_page_model || begin_time > end_time)
     return false;
-  OfflinePageModelQueryBuilder builder;
-  builder.RequireRemovedOnCacheReset(
-      OfflinePageModelQuery::Requirement::INCLUDE_MATCHING);
-  offline_page_model->GetPagesMatchingQuery(
-      builder.Build(offline_page_model->GetPolicyController()),
+  offline_page_model->GetPagesRemovedOnCacheReset(
       base::Bind(&DoCalculateSizeBetween, callback, begin_time, end_time));
   return true;
 }
diff --git a/chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.cc b/chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.cc
index 55fc1b6..dcf9cbf4 100644
--- a/chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.cc
+++ b/chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.cc
@@ -84,18 +84,15 @@
   return result;
 }
 
-bool WriteDataToPickle(const std::map<base::string16, std::string>& data,
+void WriteDataToPickle(const std::map<base::string16, std::string>& data,
                        base::Pickle* pickle) {
   pickle->WriteUInt32(data.size());
   for (std::map<base::string16, std::string>::const_iterator it = data.begin();
        it != data.end();
        ++it) {
-    if (!pickle->WriteString16(it->first))
-      return false;
-    if (!pickle->WriteString(it->second))
-      return false;
+    pickle->WriteString16(it->first);
+    pickle->WriteString(it->second);
   }
-  return true;
 }
 
 }  // namespace
@@ -345,12 +342,9 @@
 
   if (custom_data_map.size() > 0) {
     base::Pickle pickle;
-    if (WriteDataToPickle(custom_data_map, &pickle)) {
-      scw.WritePickledData(pickle,
-                           ui::Clipboard::GetPepperCustomDataFormatType());
-    } else {
-      res = PP_ERROR_BADARGUMENT;
-    }
+    WriteDataToPickle(custom_data_map, &pickle);
+    scw.WritePickledData(pickle,
+                         ui::Clipboard::GetPepperCustomDataFormatType());
   }
 
   if (res != PP_OK) {
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index f9aec2cc..ecd587c 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -938,6 +938,8 @@
       "omnibox/chrome_omnibox_navigation_observer.h",
       "omnibox/clipboard_utils.cc",
       "omnibox/clipboard_utils.h",
+      "overlay/overlay_surface_embedder.cc",
+      "overlay/overlay_surface_embedder.h",
       "overlay/overlay_window.h",
       "page_info/page_info_dialog.cc",
       "page_info/page_info_dialog.h",
diff --git a/chrome/browser/ui/cocoa/page_info/page_info_bubble_controller.mm b/chrome/browser/ui/cocoa/page_info/page_info_bubble_controller.mm
index 432eb392..478d14d 100644
--- a/chrome/browser/ui/cocoa/page_info/page_info_bubble_controller.mm
+++ b/chrome/browser/ui/cocoa/page_info/page_info_bubble_controller.mm
@@ -736,7 +736,8 @@
     yPos = [self setYPositionOfView:permissionsView_ to:yPos];
   }
 
-  yPos = [self layoutViewAtRTLStart:siteSettingsButton_ withYPosition:yPos];
+  yPos = [self layoutViewAtRTLStart:siteSettingsButton_
+                      withYPosition:yPos + kSectionVerticalPadding];
 
   // Resize the height based on contents.
   [self setHeightOfView:siteSettingsSectionView_
@@ -1309,8 +1310,6 @@
                                              atPoint:controlOrigin];
       controlOrigin.y = rowBottomRight.y;
     }
-
-    controlOrigin.y += kPermissionsVerticalSpacing;
   }
 
   [permissionsView_ setFrameSize:NSMakeSize(NSWidth([permissionsView_ frame]),
diff --git a/chrome/browser/ui/overlay/overlay_surface_embedder.cc b/chrome/browser/ui/overlay/overlay_surface_embedder.cc
new file mode 100644
index 0000000..3cd6dd5
--- /dev/null
+++ b/chrome/browser/ui/overlay/overlay_surface_embedder.cc
@@ -0,0 +1,29 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/overlay/overlay_surface_embedder.h"
+
+#include "components/viz/common/surfaces/stub_surface_reference_factory.h"
+#include "ui/compositor/layer.h"
+
+OverlaySurfaceEmbedder::OverlaySurfaceEmbedder(OverlayWindow* window)
+    : window_(window) {
+  surface_layer_ = base::MakeUnique<ui::Layer>(ui::LAYER_TEXTURED);
+  surface_layer_->SetMasksToBounds(true);
+
+  // The frame provided by the parent window's layer needs to show through
+  // the surface layer.
+  surface_layer_->SetFillsBoundsOpaquely(false);
+  window_->GetLayer()->Add(surface_layer_.get());
+  ref_factory_ = new viz::StubSurfaceReferenceFactory();
+}
+
+OverlaySurfaceEmbedder::~OverlaySurfaceEmbedder() = default;
+
+void OverlaySurfaceEmbedder::SetPrimarySurfaceInfo(
+    const viz::SurfaceInfo& surface_info) {
+  // SurfaceInfo has information about the embedded surface.
+  surface_layer_->SetShowPrimarySurface(surface_info, ref_factory_);
+  surface_layer_->SetBounds(gfx::Rect(window_->GetBounds().size()));
+}
diff --git a/chrome/browser/ui/overlay/overlay_surface_embedder.h b/chrome/browser/ui/overlay/overlay_surface_embedder.h
new file mode 100644
index 0000000..6bbd032
--- /dev/null
+++ b/chrome/browser/ui/overlay/overlay_surface_embedder.h
@@ -0,0 +1,37 @@
+// 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 CHROME_BROWSER_UI_OVERLAY_OVERLAY_SURFACE_EMBEDDER_H_
+#define CHROME_BROWSER_UI_OVERLAY_OVERLAY_SURFACE_EMBEDDER_H_
+
+#include "chrome/browser/ui/overlay/overlay_window.h"
+#include "components/viz/common/surfaces/surface_reference_factory.h"
+
+namespace viz {
+class SurfaceInfo;
+}
+
+// Embed a surface into the OverlayWindow to show content. Responsible for
+// setting up the surface layers that contain content to show on the
+// OverlayWindow.
+class OverlaySurfaceEmbedder {
+ public:
+  explicit OverlaySurfaceEmbedder(OverlayWindow* window);
+  ~OverlaySurfaceEmbedder();
+
+  void SetPrimarySurfaceInfo(const viz::SurfaceInfo& surface_info);
+
+ private:
+  // The window which embeds the client.
+  std::unique_ptr<OverlayWindow> window_;
+
+  // Contains the client's content.
+  std::unique_ptr<ui::Layer> surface_layer_;
+
+  scoped_refptr<viz::SurfaceReferenceFactory> ref_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(OverlaySurfaceEmbedder);
+};
+
+#endif  // CHROME_BROWSER_UI_OVERLAY_OVERLAY_SURFACE_EMBEDDER_H_
diff --git a/chromeos/components/tether/ble_advertiser.cc b/chromeos/components/tether/ble_advertiser.cc
index 7660fd09..a25291c 100644
--- a/chromeos/components/tether/ble_advertiser.cc
+++ b/chromeos/components/tether/ble_advertiser.cc
@@ -111,6 +111,28 @@
   return false;
 }
 
+bool BleAdvertiser::AreAdvertisementsRegistered() {
+  for (const auto& advertisement : advertisements_) {
+    if (advertisement)
+      return true;
+  }
+
+  return false;
+}
+
+void BleAdvertiser::AddObserver(Observer* observer) {
+  observer_list_.AddObserver(observer);
+}
+
+void BleAdvertiser::RemoveObserver(Observer* observer) {
+  observer_list_.RemoveObserver(observer);
+}
+
+void BleAdvertiser::NotifyAllAdvertisementsUnregistered() {
+  for (auto& observer : observer_list_)
+    observer.OnAllAdvertisementsUnregistered();
+}
+
 void BleAdvertiser::SetEidGeneratorForTest(
     std::unique_ptr<cryptauth::ForegroundEidGenerator> test_eid_generator) {
   eid_generator_ = std::move(test_eid_generator);
@@ -149,6 +171,10 @@
 void BleAdvertiser::OnAdvertisementStopped(size_t index) {
   DCHECK(advertisements_[index] && advertisements_[index]->HasBeenStopped());
   advertisements_[index].reset();
+
+  if (!AreAdvertisementsRegistered())
+    NotifyAllAdvertisementsUnregistered();
+
   UpdateAdvertisements();
 }
 
diff --git a/chromeos/components/tether/ble_advertiser.h b/chromeos/components/tether/ble_advertiser.h
index ef7b8ee4..3cd8173 100644
--- a/chromeos/components/tether/ble_advertiser.h
+++ b/chromeos/components/tether/ble_advertiser.h
@@ -12,6 +12,7 @@
 #include "base/callback_forward.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
+#include "base/observer_list.h"
 #include "chromeos/components/tether/ble_constants.h"
 #include "components/cryptauth/foreground_eid_generator.h"
 #include "components/cryptauth/remote_device.h"
@@ -36,6 +37,14 @@
 // advertisement.
 class BleAdvertiser {
  public:
+  class Observer {
+   public:
+    virtual void OnAllAdvertisementsUnregistered() = 0;
+
+   protected:
+    virtual ~Observer() {}
+  };
+
   BleAdvertiser(scoped_refptr<device::BluetoothAdapter> adapter,
                 cryptauth::LocalDeviceDataProvider* local_device_data_provider,
                 cryptauth::RemoteBeaconSeedFetcher* remote_beacon_seed_fetcher);
@@ -46,6 +55,14 @@
   virtual bool StopAdvertisingToDevice(
       const cryptauth::RemoteDevice& remote_device);
 
+  bool AreAdvertisementsRegistered();
+
+  void AddObserver(Observer* observer);
+  void RemoveObserver(Observer* observer);
+
+ protected:
+  void NotifyAllAdvertisementsUnregistered();
+
  private:
   friend class BleAdvertiserTest;
 
@@ -83,6 +100,8 @@
              kMaxConcurrentAdvertisements>
       advertisements_;
 
+  base::ObserverList<Observer> observer_list_;
+
   base::WeakPtrFactory<BleAdvertiser> weak_ptr_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(BleAdvertiser);
diff --git a/chromeos/components/tether/ble_advertiser_unittest.cc b/chromeos/components/tether/ble_advertiser_unittest.cc
index 0c0a5950d..f16ab36 100644
--- a/chromeos/components/tether/ble_advertiser_unittest.cc
+++ b/chromeos/components/tether/ble_advertiser_unittest.cc
@@ -97,6 +97,24 @@
   size_t num_created_ = 0;
 };
 
+class TestObserver : public BleAdvertiser::Observer {
+ public:
+  TestObserver() {}
+  ~TestObserver() override {}
+
+  size_t num_times_all_advertisements_unregistered() {
+    return num_times_all_advertisements_unregistered_;
+  }
+
+  // BleAdvertiser::Observer:
+  void OnAllAdvertisementsUnregistered() override {
+    ++num_times_all_advertisements_unregistered_;
+  }
+
+ private:
+  size_t num_times_all_advertisements_unregistered_ = 0;
+};
+
 }  // namespace
 
 class BleAdvertiserTest : public testing::Test {
@@ -138,13 +156,17 @@
     ErrorTolerantBleAdvertisementImpl::Factory::SetInstanceForTesting(
         fake_advertisement_factory_.get());
 
+    test_observer_ = base::WrapUnique(new TestObserver());
+
     ble_advertiser_ = base::MakeUnique<BleAdvertiser>(
         mock_adapter_, mock_local_data_provider_.get(),
         mock_seed_fetcher_.get());
     ble_advertiser_->SetEidGeneratorForTest(std::move(eid_generator));
+    ble_advertiser_->AddObserver(test_observer_.get());
   }
 
   void TearDown() override {
+    ble_advertiser_->RemoveObserver(test_observer_.get());
     ErrorTolerantBleAdvertisementImpl::Factory::SetInstanceForTesting(nullptr);
   }
 
@@ -175,6 +197,8 @@
   std::unique_ptr<cryptauth::MockLocalDeviceDataProvider>
       mock_local_data_provider_;
 
+  std::unique_ptr<TestObserver> test_observer_;
+
   std::unique_ptr<FakeErrorTolerantBleAdvertisementFactory>
       fake_advertisement_factory_;
 
@@ -188,18 +212,21 @@
   mock_local_data_provider_->SetPublicKey(nullptr);
   EXPECT_FALSE(ble_advertiser_->StartAdvertisingToDevice(fake_devices_[0]));
   EXPECT_EQ(0u, fake_advertisement_factory_->num_created());
+  EXPECT_EQ(0u, test_observer_->num_times_all_advertisements_unregistered());
 }
 
 TEST_F(BleAdvertiserTest, EmptyPublicKey) {
   mock_local_data_provider_->SetPublicKey(base::MakeUnique<std::string>(""));
   EXPECT_FALSE(ble_advertiser_->StartAdvertisingToDevice(fake_devices_[0]));
   EXPECT_EQ(0u, fake_advertisement_factory_->num_created());
+  EXPECT_EQ(0u, test_observer_->num_times_all_advertisements_unregistered());
 }
 
 TEST_F(BleAdvertiserTest, NoBeaconSeeds) {
   mock_seed_fetcher_->SetSeedsForDevice(fake_devices_[0], nullptr);
   EXPECT_FALSE(ble_advertiser_->StartAdvertisingToDevice(fake_devices_[0]));
   EXPECT_EQ(0u, fake_advertisement_factory_->num_created());
+  EXPECT_EQ(0u, test_observer_->num_times_all_advertisements_unregistered());
 }
 
 TEST_F(BleAdvertiserTest, EmptyBeaconSeeds) {
@@ -208,12 +235,14 @@
 
   EXPECT_FALSE(ble_advertiser_->StartAdvertisingToDevice(fake_devices_[0]));
   EXPECT_EQ(0u, fake_advertisement_factory_->num_created());
+  EXPECT_EQ(0u, test_observer_->num_times_all_advertisements_unregistered());
 }
 
 TEST_F(BleAdvertiserTest, CannotGenerateAdvertisement) {
   mock_eid_generator_->set_advertisement(nullptr);
   EXPECT_FALSE(ble_advertiser_->StartAdvertisingToDevice(fake_devices_[0]));
   EXPECT_EQ(0u, fake_advertisement_factory_->num_created());
+  EXPECT_EQ(0u, test_observer_->num_times_all_advertisements_unregistered());
 }
 
 TEST_F(BleAdvertiserTest, AdvertisementRegisteredSuccessfully) {
@@ -223,9 +252,12 @@
   EXPECT_TRUE(ble_advertiser_->StartAdvertisingToDevice(fake_devices_[0]));
   EXPECT_EQ(1u, fake_advertisement_factory_->num_created());
   EXPECT_EQ(1u, fake_advertisement_factory_->active_advertisements().size());
+  EXPECT_TRUE(ble_advertiser_->AreAdvertisementsRegistered());
+  EXPECT_EQ(0u, test_observer_->num_times_all_advertisements_unregistered());
 
   // Now, unregister.
   EXPECT_TRUE(ble_advertiser_->StopAdvertisingToDevice(fake_devices_[0]));
+  EXPECT_TRUE(ble_advertiser_->AreAdvertisementsRegistered());
 
   // The advertisement should have been stopped, but it should not yet have
   // been removed.
@@ -237,6 +269,8 @@
   InvokeAdvertisementStoppedCallback(0u /* index */,
                                      fake_devices_[0].GetDeviceId());
   EXPECT_EQ(0u, fake_advertisement_factory_->active_advertisements().size());
+  EXPECT_FALSE(ble_advertiser_->AreAdvertisementsRegistered());
+  EXPECT_EQ(1u, test_observer_->num_times_all_advertisements_unregistered());
 }
 
 TEST_F(BleAdvertiserTest, AdvertisementRegisteredSuccessfully_TwoDevices) {
@@ -246,6 +280,8 @@
   EXPECT_TRUE(ble_advertiser_->StartAdvertisingToDevice(fake_devices_[0]));
   EXPECT_EQ(1u, fake_advertisement_factory_->num_created());
   EXPECT_EQ(1u, fake_advertisement_factory_->active_advertisements().size());
+  EXPECT_TRUE(ble_advertiser_->AreAdvertisementsRegistered());
+  EXPECT_EQ(0u, test_observer_->num_times_all_advertisements_unregistered());
 
   // Register device 1.
   mock_eid_generator_->set_advertisement(
@@ -253,6 +289,8 @@
   EXPECT_TRUE(ble_advertiser_->StartAdvertisingToDevice(fake_devices_[1]));
   EXPECT_EQ(2u, fake_advertisement_factory_->num_created());
   EXPECT_EQ(2u, fake_advertisement_factory_->active_advertisements().size());
+  EXPECT_TRUE(ble_advertiser_->AreAdvertisementsRegistered());
+  EXPECT_EQ(0u, test_observer_->num_times_all_advertisements_unregistered());
 
   // Unregister device 0.
   EXPECT_TRUE(ble_advertiser_->StopAdvertisingToDevice(fake_devices_[0]));
@@ -260,6 +298,8 @@
   InvokeAdvertisementStoppedCallback(0u /* index */,
                                      fake_devices_[0].GetDeviceId());
   EXPECT_EQ(1u, fake_advertisement_factory_->active_advertisements().size());
+  EXPECT_TRUE(ble_advertiser_->AreAdvertisementsRegistered());
+  EXPECT_EQ(0u, test_observer_->num_times_all_advertisements_unregistered());
 
   // Unregister device 1.
   EXPECT_TRUE(ble_advertiser_->StopAdvertisingToDevice(fake_devices_[1]));
@@ -267,6 +307,8 @@
   InvokeAdvertisementStoppedCallback(0u /* index */,
                                      fake_devices_[1].GetDeviceId());
   EXPECT_EQ(0u, fake_advertisement_factory_->active_advertisements().size());
+  EXPECT_FALSE(ble_advertiser_->AreAdvertisementsRegistered());
+  EXPECT_EQ(1u, test_observer_->num_times_all_advertisements_unregistered());
 }
 
 TEST_F(BleAdvertiserTest, TooManyDevicesRegistered) {
diff --git a/chromeos/components/tether/error_tolerant_ble_advertisement_impl.cc b/chromeos/components/tether/error_tolerant_ble_advertisement_impl.cc
index 752a2c6..da2a7b35 100644
--- a/chromeos/components/tether/error_tolerant_ble_advertisement_impl.cc
+++ b/chromeos/components/tether/error_tolerant_ble_advertisement_impl.cc
@@ -110,9 +110,9 @@
 }
 
 void ErrorTolerantBleAdvertisementImpl::UpdateRegistrationStatus() {
-  if (!advertisement_ && stop_callback_.is_null())
+  if (!advertisement_)
     AttemptRegistration();
-  else if (advertisement_ && !stop_callback_.is_null())
+  else if (advertisement_ && HasBeenStopped())
     AttemptUnregistration();
 }
 
@@ -124,8 +124,7 @@
 }
 
 void ErrorTolerantBleAdvertisementImpl::AttemptRegistration() {
-  // Should never attempt to register after Stop() has been called.
-  DCHECK(stop_callback_.is_null() && !unregistration_in_progress_);
+  DCHECK(!unregistration_in_progress_);
 
   if (registration_in_progress_)
     return;
diff --git a/chromeos/components/tether/initializer_impl.cc b/chromeos/components/tether/initializer_impl.cc
index d98054a..81acbcb0 100644
--- a/chromeos/components/tether/initializer_impl.cc
+++ b/chromeos/components/tether/initializer_impl.cc
@@ -8,7 +8,6 @@
 #include "chromeos/components/tether/active_host.h"
 #include "chromeos/components/tether/active_host_network_state_updater.h"
 #include "chromeos/components/tether/ble_advertisement_device_queue.h"
-#include "chromeos/components/tether/ble_advertiser.h"
 #include "chromeos/components/tether/ble_connection_manager.h"
 #include "chromeos/components/tether/crash_recovery_manager.h"
 #include "chromeos/components/tether/device_id_tether_network_guid_map.h"
@@ -168,6 +167,10 @@
   StartAsynchronousShutdown();
 }
 
+void InitializerImpl::OnAllAdvertisementsUnregistered() {
+  FinishAsynchronousShutdownIfPossible();
+}
+
 void InitializerImpl::OnPendingDisconnectRequestsComplete() {
   FinishAsynchronousShutdownIfPossible();
 }
@@ -276,6 +279,11 @@
 }
 
 bool InitializerImpl::IsAsyncShutdownRequired() {
+  // All of the asynchronous shutdown procedures depend on Bluetooth. If
+  // Bluetooth is off, there is no way to complete these tasks.
+  if (!adapter_->IsPowered())
+    return false;
+
   // If there are pending disconnection requests, they must be sent before the
   // component shuts down.
   if (disconnect_tethering_request_sender_ &&
@@ -289,6 +297,10 @@
     return true;
   }
 
+  // The BLE advertiser must unregister all of its advertisements.
+  if (ble_advertiser_ && ble_advertiser_->AreAdvertisementsRegistered())
+    return true;
+
   return false;
 }
 
@@ -308,6 +320,7 @@
   // asynchronous shutdowns, so start observering these objects. Once they
   // notify observers that they are finished shutting down, asynchronous
   // shutdown will complete.
+  ble_advertiser_->AddObserver(this);
   ble_scanner_->AddObserver(this);
   disconnect_tethering_request_sender_->AddObserver(this);
 
@@ -345,6 +358,7 @@
   if (IsAsyncShutdownRequired())
     return;
 
+  ble_advertiser_->RemoveObserver(this);
   ble_scanner_->RemoveObserver(this);
   disconnect_tethering_request_sender_->RemoveObserver(this);
 
diff --git a/chromeos/components/tether/initializer_impl.h b/chromeos/components/tether/initializer_impl.h
index b9070954..edbcf51 100644
--- a/chromeos/components/tether/initializer_impl.h
+++ b/chromeos/components/tether/initializer_impl.h
@@ -12,6 +12,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
 #include "base/time/default_clock.h"
+#include "chromeos/components/tether/ble_advertiser.h"
 #include "chromeos/components/tether/ble_scanner.h"
 #include "chromeos/components/tether/disconnect_tethering_request_sender.h"
 #include "chromeos/components/tether/initializer.h"
@@ -38,7 +39,6 @@
 
 class ActiveHost;
 class ActiveHostNetworkStateUpdater;
-class BleAdvertiser;
 class BleAdvertisementDeviceQueue;
 class BleConnectionManager;
 class CrashRecoveryManager;
@@ -66,6 +66,7 @@
 
 // Initializes the Tether Chrome OS component.
 class InitializerImpl : public Initializer,
+                        public BleAdvertiser::Observer,
                         public BleScanner::Observer,
                         public DisconnectTetheringRequestSender::Observer {
  public:
@@ -117,6 +118,9 @@
   // Initializer:
   void RequestShutdown() override;
 
+  // BleAdvertiser::Observer:
+  void OnAllAdvertisementsUnregistered() override;
+
   // BleScanner::Observer:
   void OnDiscoverySessionStateChanged(bool discovery_session_active) override;
 
diff --git a/components/cryptauth/BUILD.gn b/components/cryptauth/BUILD.gn
index 0f0214a..fc01780 100644
--- a/components/cryptauth/BUILD.gn
+++ b/components/cryptauth/BUILD.gn
@@ -39,8 +39,9 @@
     "cryptauth_service.h",
     "data_with_timestamp.cc",
     "data_with_timestamp.h",
-    "device_capability_manager.cc",
     "device_capability_manager.h",
+    "device_capability_manager_impl.cc",
+    "device_capability_manager_impl.h",
     "device_to_device_authenticator.cc",
     "device_to_device_authenticator.h",
     "device_to_device_initiator_helper.cc",
@@ -119,6 +120,8 @@
     "fake_cryptauth_gcm_manager.h",
     "fake_cryptauth_service.cc",
     "fake_cryptauth_service.h",
+    "fake_device_capability_manager.cc",
+    "fake_device_capability_manager.h",
     "fake_remote_device_provider.cc",
     "fake_remote_device_provider.h",
     "fake_secure_channel.cc",
@@ -165,7 +168,7 @@
     "cryptauth_enroller_impl_unittest.cc",
     "cryptauth_enrollment_manager_unittest.cc",
     "cryptauth_gcm_manager_impl_unittest.cc",
-    "device_capability_manager_unittest.cc",
+    "device_capability_manager_impl_unittest.cc",
     "device_to_device_authenticator_unittest.cc",
     "device_to_device_operations_unittest.cc",
     "device_to_device_secure_context_unittest.cc",
diff --git a/components/cryptauth/device_capability_manager.h b/components/cryptauth/device_capability_manager.h
index 71b0bc17..1a5ea97 100644
--- a/components/cryptauth/device_capability_manager.h
+++ b/components/cryptauth/device_capability_manager.h
@@ -5,12 +5,7 @@
 #ifndef COMPONENTS_CRYPTAUTH_DEVICE_CAPABILITY_MANAGER_H_
 #define COMPONENTS_CRYPTAUTH_DEVICE_CAPABILITY_MANAGER_H_
 
-#include "base/bind.h"
-#include "base/callback_forward.h"
-#include "base/containers/queue.h"
-#include "base/memory/ptr_util.h"
-#include "base/memory/weak_ptr.h"
-#include "components/cryptauth/cryptauth_client.h"
+#include "base/callback.h"
 #include "components/cryptauth/proto/cryptauth_api.pb.h"
 
 namespace cryptauth {
@@ -18,124 +13,33 @@
 // DeviceCapabilityManager sends requests to the back-end which enable/disable
 // device capabilities and finds devices which contain those capabilities. Here,
 // the term "capability" refers to the ability of a device to use a given
-// feature (e.g. EasyUnlock or Magic Tether).
+// feature (e.g. EasyUnlock or Instant Tethering).
 class DeviceCapabilityManager {
  public:
   // CAPABILITY_UNLOCK_KEY refers to EasyUnlock.
   enum class Capability { CAPABILITY_UNLOCK_KEY };
 
-  DeviceCapabilityManager(CryptAuthClientFactory* cryptauth_client_factory);
+  virtual ~DeviceCapabilityManager(){};
 
-  ~DeviceCapabilityManager();
-
-  // Enables or disables |capability| for the device corresponding to
-  // |public_key|. In error cases, |error_callback| is invoked with an error
-  // string.
-  void SetCapabilityEnabled(
+  virtual void SetCapabilityEnabled(
       const std::string& public_key,
       Capability capability,
       bool enabled,
       const base::Closure& success_callback,
-      const base::Callback<void(const std::string&)>& error_callback);
+      const base::Callback<void(const std::string&)>& error_callback) = 0;
 
-  // Fetches metadata about the device which are eligible for |capability|. In
-  // error cases, |error_callback| is invoked with an error string.
-  void FindEligibleDevicesForCapability(
+  virtual void FindEligibleDevicesForCapability(
       Capability capability,
       const base::Callback<void(const std::vector<ExternalDeviceInfo>&,
                                 const std::vector<IneligibleDevice>&)>&
           success_callback,
-      const base::Callback<void(const std::string&)>& error_callback);
+      const base::Callback<void(const std::string&)>& error_callback) = 0;
 
-  // Determines whether a device with |public_key| is promotable for
-  // |capability|. In error cases, |error_callback| is invoked with an error
-  // string.
-  void IsCapabilityPromotable(
+  virtual void IsCapabilityPromotable(
       const std::string& public_key,
       Capability capability,
       const base::Callback<void(bool)>& success_callback,
-      const base::Callback<void(const std::string&)>& error_callback);
-
- private:
-  enum class RequestType {
-    SET_CAPABILITY_ENABLED,
-    FIND_ELIGIBLE_DEVICES_FOR_CAPABILITY,
-    IS_CAPABILITY_PROMOTABLE
-  };
-
-  struct Request {
-    // Used for SET_CAPABILITY_ENABLED Requests.
-    Request(RequestType request_type,
-            Capability capability,
-            std::string public_key,
-            bool enabled,
-            const base::Closure& set_capability_callback,
-            const base::Callback<void(const std::string&)>& error_callback);
-
-    // Used for FIND_ELIGIBLE_DEVICES_FOR_CAPABILITY Requests.
-    Request(RequestType request_type,
-            Capability capability,
-            const base::Callback<void(const std::vector<ExternalDeviceInfo>&,
-                                      const std::vector<IneligibleDevice>&)>&
-                find_eligible_devices_callback,
-            const base::Callback<void(const std::string&)>& error_callback);
-
-    // Used for IS_CAPABILITY_PROMOTABLE Requests.
-    Request(RequestType request_type,
-            Capability capability,
-            std::string public_key,
-            const base::Callback<void(bool)> is_device_promotable_callback,
-            const base::Callback<void(const std::string&)>& error_callback);
-
-    ~Request();
-
-    // Defined for every request.
-    RequestType request_type;
-    base::Callback<void(const std::string&)> error_callback;
-    Capability capability;
-
-    // Defined for SET_CAPABILITY_ENABLED and IS_CAPABILITY_PROMOTABLE;
-    // otherwise, unused.
-    std::string public_key;
-
-    // Defined if |request_type_| is SET_CAPABILITY_ENABLED; otherwise, unused.
-    base::Closure set_capability_callback;
-    bool enabled;
-
-    // Defined if |request_type_| is FIND_ELIGIBLE_DEVICES_FOR_CAPABILITY;
-    // otherwise, unused.
-    base::Callback<void(const std::vector<ExternalDeviceInfo>&,
-                        const std::vector<IneligibleDevice>&)>
-        find_eligible_devices_callback;
-
-    // Defined if |request_type_| is IS_CAPABILITY_PROMOTABLE; otherwise,
-    // unused.
-    base::Callback<void(bool)> is_device_promotable_callback;
-  };
-
-  void CreateNewCryptAuthClient();
-
-  void ProcessSetCapabilityEnabledRequest();
-  void ProcessFindEligibleDevicesForCapability();
-  void ProcessIsCapabilityPromotableRequest();
-
-  void SetUnlockKeyCapability();
-  void FindEligibleUnlockDevices();
-  void IsDeviceUnlockPromotable();
-
-  void OnToggleEasyUnlockResponse(const ToggleEasyUnlockResponse& response);
-  void OnFindEligibleUnlockDevicesResponse(
-      const FindEligibleUnlockDevicesResponse& response);
-  void OnIsDeviceUnlockPromotableResponse(
-      const FindEligibleForPromotionResponse& response);
-  void OnErrorResponse(const std::string& response);
-  void ProcessRequestQueue();
-
-  std::unique_ptr<CryptAuthClient> current_cryptauth_client_;
-  std::unique_ptr<Request> current_request_;
-  base::queue<std::unique_ptr<Request>> pending_requests_;
-  CryptAuthClientFactory* crypt_auth_client_factory_;
-  base::WeakPtrFactory<DeviceCapabilityManager> weak_ptr_factory_;
+      const base::Callback<void(const std::string&)>& error_callback) = 0;
 };
 }  // namespace cryptauth
 
diff --git a/components/cryptauth/device_capability_manager.cc b/components/cryptauth/device_capability_manager_impl.cc
similarity index 68%
rename from components/cryptauth/device_capability_manager.cc
rename to components/cryptauth/device_capability_manager_impl.cc
index 1e33c58..e49121a 100644
--- a/components/cryptauth/device_capability_manager.cc
+++ b/components/cryptauth/device_capability_manager_impl.cc
@@ -2,21 +2,47 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "components/cryptauth/device_capability_manager.h"
+#include "components/cryptauth/device_capability_manager_impl.h"
 
 #include "base/logging.h"
 #include "components/cryptauth/proto/cryptauth_api.pb.h"
 
 namespace cryptauth {
 
-DeviceCapabilityManager::DeviceCapabilityManager(
+// static
+DeviceCapabilityManagerImpl::Factory*
+    DeviceCapabilityManagerImpl::Factory::factory_instance_ = nullptr;
+
+// static
+std::unique_ptr<DeviceCapabilityManager>
+DeviceCapabilityManagerImpl::Factory::NewInstance(
+    CryptAuthClientFactory* cryptauth_client_factory) {
+  if (!factory_instance_) {
+    factory_instance_ = new Factory();
+  }
+  return factory_instance_->BuildInstance(cryptauth_client_factory);
+}
+
+void DeviceCapabilityManagerImpl::Factory::SetInstanceForTesting(
+    Factory* factory) {
+  factory_instance_ = factory;
+}
+
+std::unique_ptr<DeviceCapabilityManager>
+DeviceCapabilityManagerImpl::Factory::BuildInstance(
+    CryptAuthClientFactory* cryptauth_client_factory) {
+  return base::WrapUnique(
+      new DeviceCapabilityManagerImpl(cryptauth_client_factory));
+}
+
+DeviceCapabilityManagerImpl::DeviceCapabilityManagerImpl(
     CryptAuthClientFactory* cryptauth_client_factory)
     : crypt_auth_client_factory_(cryptauth_client_factory),
       weak_ptr_factory_(this) {}
 
-DeviceCapabilityManager::~DeviceCapabilityManager() {}
+DeviceCapabilityManagerImpl::~DeviceCapabilityManagerImpl() {}
 
-void DeviceCapabilityManager::SetCapabilityEnabled(
+void DeviceCapabilityManagerImpl::SetCapabilityEnabled(
     const std::string& public_key,
     Capability capability,
     bool enabled,
@@ -28,7 +54,7 @@
   ProcessRequestQueue();
 }
 
-void DeviceCapabilityManager::FindEligibleDevicesForCapability(
+void DeviceCapabilityManagerImpl::FindEligibleDevicesForCapability(
     Capability capability,
     const base::Callback<void(const std::vector<ExternalDeviceInfo>&,
                               const std::vector<IneligibleDevice>&)>&
@@ -40,7 +66,7 @@
   ProcessRequestQueue();
 }
 
-void DeviceCapabilityManager::IsCapabilityPromotable(
+void DeviceCapabilityManagerImpl::IsCapabilityPromotable(
     const std::string& public_key,
     Capability capability,
     const base::Callback<void(bool)>& success_callback,
@@ -51,7 +77,7 @@
   ProcessRequestQueue();
 }
 
-DeviceCapabilityManager::Request::Request(
+DeviceCapabilityManagerImpl::Request::Request(
     RequestType request_type,
     Capability capability,
     std::string public_key,
@@ -65,7 +91,7 @@
       set_capability_callback(set_capability_callback),
       enabled(enabled) {}
 
-DeviceCapabilityManager::Request::Request(
+DeviceCapabilityManagerImpl::Request::Request(
     RequestType request_type,
     Capability capability,
     const base::Callback<void(const std::vector<ExternalDeviceInfo>&,
@@ -77,7 +103,7 @@
       capability(capability),
       find_eligible_devices_callback(find_eligible_devices_callback) {}
 
-DeviceCapabilityManager::Request::Request(
+DeviceCapabilityManagerImpl::Request::Request(
     RequestType request_type,
     Capability capability,
     std::string public_key,
@@ -89,29 +115,29 @@
       public_key(public_key),
       is_device_promotable_callback(is_device_promotable_callback) {}
 
-DeviceCapabilityManager::Request::~Request() {}
+DeviceCapabilityManagerImpl::Request::~Request() {}
 
-void DeviceCapabilityManager::CreateNewCryptAuthClient() {
+void DeviceCapabilityManagerImpl::CreateNewCryptAuthClient() {
   DCHECK(!current_cryptauth_client_);
   current_cryptauth_client_ = crypt_auth_client_factory_->CreateInstance();
 }
 
-void DeviceCapabilityManager::ProcessSetCapabilityEnabledRequest() {
+void DeviceCapabilityManagerImpl::ProcessSetCapabilityEnabledRequest() {
   DCHECK(current_request_->capability == Capability::CAPABILITY_UNLOCK_KEY);
   SetUnlockKeyCapability();
 }
 
-void DeviceCapabilityManager::ProcessFindEligibleDevicesForCapability() {
+void DeviceCapabilityManagerImpl::ProcessFindEligibleDevicesForCapability() {
   DCHECK(current_request_->capability == Capability::CAPABILITY_UNLOCK_KEY);
   FindEligibleUnlockDevices();
 }
 
-void DeviceCapabilityManager::ProcessIsCapabilityPromotableRequest() {
+void DeviceCapabilityManagerImpl::ProcessIsCapabilityPromotableRequest() {
   DCHECK(current_request_->capability == Capability::CAPABILITY_UNLOCK_KEY);
   IsDeviceUnlockPromotable();
 }
 
-void DeviceCapabilityManager::SetUnlockKeyCapability() {
+void DeviceCapabilityManagerImpl::SetUnlockKeyCapability() {
   CreateNewCryptAuthClient();
 
   ToggleEasyUnlockRequest request;
@@ -121,24 +147,25 @@
 
   current_cryptauth_client_->ToggleEasyUnlock(
       request,
-      base::Bind(&DeviceCapabilityManager::OnToggleEasyUnlockResponse,
+      base::Bind(&DeviceCapabilityManagerImpl::OnToggleEasyUnlockResponse,
                  weak_ptr_factory_.GetWeakPtr()),
-      base::Bind(&DeviceCapabilityManager::OnErrorResponse,
+      base::Bind(&DeviceCapabilityManagerImpl::OnErrorResponse,
                  weak_ptr_factory_.GetWeakPtr()));
 }
 
-void DeviceCapabilityManager::FindEligibleUnlockDevices() {
+void DeviceCapabilityManagerImpl::FindEligibleUnlockDevices() {
   CreateNewCryptAuthClient();
 
   current_cryptauth_client_->FindEligibleUnlockDevices(
       FindEligibleUnlockDevicesRequest(),
-      base::Bind(&DeviceCapabilityManager::OnFindEligibleUnlockDevicesResponse,
-                 weak_ptr_factory_.GetWeakPtr()),
-      base::Bind(&DeviceCapabilityManager::OnErrorResponse,
+      base::Bind(
+          &DeviceCapabilityManagerImpl::OnFindEligibleUnlockDevicesResponse,
+          weak_ptr_factory_.GetWeakPtr()),
+      base::Bind(&DeviceCapabilityManagerImpl::OnErrorResponse,
                  weak_ptr_factory_.GetWeakPtr()));
 }
 
-void DeviceCapabilityManager::IsDeviceUnlockPromotable() {
+void DeviceCapabilityManagerImpl::IsDeviceUnlockPromotable() {
   CreateNewCryptAuthClient();
 
   FindEligibleForPromotionRequest request;
@@ -146,13 +173,14 @@
 
   current_cryptauth_client_->FindEligibleForPromotion(
       request,
-      base::Bind(&DeviceCapabilityManager::OnIsDeviceUnlockPromotableResponse,
-                 weak_ptr_factory_.GetWeakPtr()),
-      base::Bind(&DeviceCapabilityManager::OnErrorResponse,
+      base::Bind(
+          &DeviceCapabilityManagerImpl::OnIsDeviceUnlockPromotableResponse,
+          weak_ptr_factory_.GetWeakPtr()),
+      base::Bind(&DeviceCapabilityManagerImpl::OnErrorResponse,
                  weak_ptr_factory_.GetWeakPtr()));
 }
 
-void DeviceCapabilityManager::OnToggleEasyUnlockResponse(
+void DeviceCapabilityManagerImpl::OnToggleEasyUnlockResponse(
     const ToggleEasyUnlockResponse& response) {
   current_cryptauth_client_.reset();
   current_request_->set_capability_callback.Run();
@@ -160,7 +188,7 @@
   ProcessRequestQueue();
 }
 
-void DeviceCapabilityManager::OnFindEligibleUnlockDevicesResponse(
+void DeviceCapabilityManagerImpl::OnFindEligibleUnlockDevicesResponse(
     const FindEligibleUnlockDevicesResponse& response) {
   current_cryptauth_client_.reset();
   current_request_->find_eligible_devices_callback.Run(
@@ -172,7 +200,7 @@
   ProcessRequestQueue();
 }
 
-void DeviceCapabilityManager::OnIsDeviceUnlockPromotableResponse(
+void DeviceCapabilityManagerImpl::OnIsDeviceUnlockPromotableResponse(
     const FindEligibleForPromotionResponse& response) {
   current_cryptauth_client_.reset();
   current_request_->is_device_promotable_callback.Run(
@@ -181,14 +209,14 @@
   ProcessRequestQueue();
 }
 
-void DeviceCapabilityManager::OnErrorResponse(const std::string& response) {
+void DeviceCapabilityManagerImpl::OnErrorResponse(const std::string& response) {
   current_cryptauth_client_.reset();
   current_request_->error_callback.Run(response);
   current_request_.reset();
   ProcessRequestQueue();
 }
 
-void DeviceCapabilityManager::ProcessRequestQueue() {
+void DeviceCapabilityManagerImpl::ProcessRequestQueue() {
   if (current_request_ || pending_requests_.empty())
     return;
 
diff --git a/components/cryptauth/device_capability_manager_impl.h b/components/cryptauth/device_capability_manager_impl.h
new file mode 100644
index 0000000..a6b16f9
--- /dev/null
+++ b/components/cryptauth/device_capability_manager_impl.h
@@ -0,0 +1,154 @@
+// 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 COMPONENTS_CRYPTAUTH_DEVICE_CAPABILITY_MANAGER_IMPL_H_
+#define COMPONENTS_CRYPTAUTH_DEVICE_CAPABILITY_MANAGER_IMPL_H_
+
+#include "base/bind.h"
+#include "base/callback_forward.h"
+#include "base/containers/queue.h"
+#include "base/memory/ptr_util.h"
+#include "base/memory/weak_ptr.h"
+#include "components/cryptauth/cryptauth_client.h"
+#include "components/cryptauth/device_capability_manager.h"
+#include "components/cryptauth/proto/cryptauth_api.pb.h"
+
+namespace cryptauth {
+
+using Capability = DeviceCapabilityManager::Capability;
+
+// Concrete DeviceCapabilityManager implementation.
+class DeviceCapabilityManagerImpl : public DeviceCapabilityManager {
+ public:
+  class Factory {
+   public:
+    static std::unique_ptr<DeviceCapabilityManager> NewInstance(
+        CryptAuthClientFactory* cryptauth_client_factory);
+
+    static void SetInstanceForTesting(Factory* factory);
+
+   protected:
+    virtual std::unique_ptr<DeviceCapabilityManager> BuildInstance(
+        CryptAuthClientFactory* cryptauth_client_factory);
+
+   private:
+    static Factory* factory_instance_;
+  };
+
+  DeviceCapabilityManagerImpl(CryptAuthClientFactory* cryptauth_client_factory);
+
+  ~DeviceCapabilityManagerImpl() override;
+
+  // Enables or disables |capability| for the device corresponding to
+  // |public_key|. In error cases, |error_callback| is invoked with an error
+  // string.
+  void SetCapabilityEnabled(
+      const std::string& public_key,
+      Capability capability,
+      bool enabled,
+      const base::Closure& success_callback,
+      const base::Callback<void(const std::string&)>& error_callback) override;
+
+  // Fetches metadata about the device which are eligible for |capability|. In
+  // error cases, |error_callback| is invoked with an error string.
+  void FindEligibleDevicesForCapability(
+      Capability capability,
+      const base::Callback<void(const std::vector<ExternalDeviceInfo>&,
+                                const std::vector<IneligibleDevice>&)>&
+          success_callback,
+      const base::Callback<void(const std::string&)>& error_callback) override;
+
+  // Determines whether a device with |public_key| is promotable for
+  // |capability|. In error cases, |error_callback| is invoked with an error
+  // string.
+  void IsCapabilityPromotable(
+      const std::string& public_key,
+      Capability capability,
+      const base::Callback<void(bool)>& success_callback,
+      const base::Callback<void(const std::string&)>& error_callback) override;
+
+ private:
+  enum class RequestType {
+    SET_CAPABILITY_ENABLED,
+    FIND_ELIGIBLE_DEVICES_FOR_CAPABILITY,
+    IS_CAPABILITY_PROMOTABLE
+  };
+
+  struct Request {
+    // Used for SET_CAPABILITY_ENABLED Requests.
+    Request(RequestType request_type,
+            Capability capability,
+            std::string public_key,
+            bool enabled,
+            const base::Closure& set_capability_callback,
+            const base::Callback<void(const std::string&)>& error_callback);
+
+    // Used for FIND_ELIGIBLE_DEVICES_FOR_CAPABILITY Requests.
+    Request(RequestType request_type,
+            Capability capability,
+            const base::Callback<void(const std::vector<ExternalDeviceInfo>&,
+                                      const std::vector<IneligibleDevice>&)>&
+                find_eligible_devices_callback,
+            const base::Callback<void(const std::string&)>& error_callback);
+
+    // Used for IS_CAPABILITY_PROMOTABLE Requests.
+    Request(RequestType request_type,
+            Capability capability,
+            std::string public_key,
+            const base::Callback<void(bool)> is_device_promotable_callback,
+            const base::Callback<void(const std::string&)>& error_callback);
+
+    ~Request();
+
+    // Defined for every request.
+    RequestType request_type;
+    base::Callback<void(const std::string&)> error_callback;
+    Capability capability;
+
+    // Defined for SET_CAPABILITY_ENABLED and IS_CAPABILITY_PROMOTABLE;
+    // otherwise, unused.
+    std::string public_key;
+
+    // Defined if |request_type_| is SET_CAPABILITY_ENABLED; otherwise, unused.
+    base::Closure set_capability_callback;
+    bool enabled;
+
+    // Defined if |request_type_| is FIND_ELIGIBLE_DEVICES_FOR_CAPABILITY;
+    // otherwise, unused.
+    base::Callback<void(const std::vector<ExternalDeviceInfo>&,
+                        const std::vector<IneligibleDevice>&)>
+        find_eligible_devices_callback;
+
+    // Defined if |request_type_| is IS_CAPABILITY_PROMOTABLE; otherwise,
+    // unused.
+    base::Callback<void(bool)> is_device_promotable_callback;
+  };
+
+  void CreateNewCryptAuthClient();
+
+  void ProcessSetCapabilityEnabledRequest();
+  void ProcessFindEligibleDevicesForCapability();
+  void ProcessIsCapabilityPromotableRequest();
+
+  void SetUnlockKeyCapability();
+  void FindEligibleUnlockDevices();
+  void IsDeviceUnlockPromotable();
+
+  void OnToggleEasyUnlockResponse(const ToggleEasyUnlockResponse& response);
+  void OnFindEligibleUnlockDevicesResponse(
+      const FindEligibleUnlockDevicesResponse& response);
+  void OnIsDeviceUnlockPromotableResponse(
+      const FindEligibleForPromotionResponse& response);
+  void OnErrorResponse(const std::string& response);
+  void ProcessRequestQueue();
+
+  std::unique_ptr<CryptAuthClient> current_cryptauth_client_;
+  std::unique_ptr<Request> current_request_;
+  base::queue<std::unique_ptr<Request>> pending_requests_;
+  CryptAuthClientFactory* crypt_auth_client_factory_;
+  base::WeakPtrFactory<DeviceCapabilityManagerImpl> weak_ptr_factory_;
+};
+}  // namespace cryptauth
+
+#endif  // COMPONENTS_CRYPTAUTH_DEVICE_CAPABILITY_MANAGER_IMPL_H_
diff --git a/components/cryptauth/device_capability_manager_unittest.cc b/components/cryptauth/device_capability_manager_impl_unittest.cc
similarity index 80%
rename from components/cryptauth/device_capability_manager_unittest.cc
rename to components/cryptauth/device_capability_manager_impl_unittest.cc
index 4f89d7e..f080bf9 100644
--- a/components/cryptauth/device_capability_manager_unittest.cc
+++ b/components/cryptauth/device_capability_manager_impl_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "components/cryptauth/device_capability_manager.h"
+#include "components/cryptauth/device_capability_manager_impl.h"
 
 #include <stddef.h>
 
@@ -51,11 +51,11 @@
 
 }  // namespace
 
-class DeviceCapabilityManagerTest
+class DeviceCapabilityManagerImplTest
     : public testing::Test,
       public MockCryptAuthClientFactory::Observer {
  public:
-  DeviceCapabilityManagerTest()
+  DeviceCapabilityManagerImplTest()
       : all_test_external_device_infos_(
             CreateExternalDeviceInfosForRemoteDevices(
                 cryptauth::GenerateTestRemoteDevices(5))),
@@ -72,20 +72,22 @@
         base::MakeUnique<MockCryptAuthClientFactory>(
             MockCryptAuthClientFactory::MockType::MAKE_NICE_MOCKS);
     mock_cryptauth_client_factory_->AddObserver(this);
-    device_capability_manager_ = base::MakeUnique<DeviceCapabilityManager>(
+    device_capability_manager_ = base::MakeUnique<DeviceCapabilityManagerImpl>(
         mock_cryptauth_client_factory_.get());
   }
 
   void OnCryptAuthClientCreated(MockCryptAuthClient* client) override {
     ON_CALL(*client, ToggleEasyUnlock(_, _, _))
-        .WillByDefault(
-            Invoke(this, &DeviceCapabilityManagerTest::MockToggleEasyUnlock));
+        .WillByDefault(Invoke(
+            this, &DeviceCapabilityManagerImplTest::MockToggleEasyUnlock));
     ON_CALL(*client, FindEligibleUnlockDevices(_, _, _))
         .WillByDefault(Invoke(
-            this, &DeviceCapabilityManagerTest::MockFindEligibleUnlockDevices));
+            this,
+            &DeviceCapabilityManagerImplTest::MockFindEligibleUnlockDevices));
     ON_CALL(*client, FindEligibleForPromotion(_, _, _))
         .WillByDefault(Invoke(
-            this, &DeviceCapabilityManagerTest::MockFindEligibleForPromotion));
+            this,
+            &DeviceCapabilityManagerImplTest::MockFindEligibleForPromotion));
   }
 
   // Mock CryptAuthClient::ToggleEasyUnlock() implementation.
@@ -160,37 +162,37 @@
     result_ineligible_devices_.clear();
   }
 
-  void SetCapabilityEnabled(DeviceCapabilityManager::Capability capability,
+  void SetCapabilityEnabled(DeviceCapabilityManagerImpl::Capability capability,
                             const ExternalDeviceInfo& device_info,
                             bool enable) {
     device_capability_manager_->SetCapabilityEnabled(
         device_info.public_key(), capability, enable,
-        base::Bind(&DeviceCapabilityManagerTest::
+        base::Bind(&DeviceCapabilityManagerImplTest::
                        TestSuccessSetCapabilityKeyUnlockCallback,
                    base::Unretained(this)),
-        base::Bind(&DeviceCapabilityManagerTest::TestErrorCallback,
+        base::Bind(&DeviceCapabilityManagerImplTest::TestErrorCallback,
                    base::Unretained(this)));
   }
 
   void FindEligibleDevicesForCapability(
-      DeviceCapabilityManager::Capability capability) {
+      DeviceCapabilityManagerImpl::Capability capability) {
     device_capability_manager_->FindEligibleDevicesForCapability(
-        DeviceCapabilityManager::Capability::CAPABILITY_UNLOCK_KEY,
-        base::Bind(&DeviceCapabilityManagerTest::
+        DeviceCapabilityManagerImpl::Capability::CAPABILITY_UNLOCK_KEY,
+        base::Bind(&DeviceCapabilityManagerImplTest::
                        TestSuccessFindEligibleUnlockDevicesCallback,
                    base::Unretained(this)),
-        base::Bind(&DeviceCapabilityManagerTest::TestErrorCallback,
+        base::Bind(&DeviceCapabilityManagerImplTest::TestErrorCallback,
                    base::Unretained(this)));
   }
 
-  void IsPromotableDevice(DeviceCapabilityManager::Capability capability,
+  void IsPromotableDevice(DeviceCapabilityManagerImpl::Capability capability,
                           const std::string& public_key) {
     device_capability_manager_->IsCapabilityPromotable(
         public_key, capability,
-        base::Bind(&DeviceCapabilityManagerTest::
+        base::Bind(&DeviceCapabilityManagerImplTest::
                        TestSuccessFindEligibleForPromotionDeviceCallback,
                    base::Unretained(this)),
-        base::Bind(&DeviceCapabilityManagerTest::TestErrorCallback,
+        base::Bind(&DeviceCapabilityManagerImplTest::TestErrorCallback,
                    base::Unretained(this)));
   }
 
@@ -265,7 +267,7 @@
   const std::vector<ExternalDeviceInfo> test_ineligible_external_devices_infos_;
 
   std::unique_ptr<MockCryptAuthClientFactory> mock_cryptauth_client_factory_;
-  std::unique_ptr<cryptauth::DeviceCapabilityManager>
+  std::unique_ptr<cryptauth::DeviceCapabilityManagerImpl>
       device_capability_manager_;
   CryptAuthClient::ToggleEasyUnlockCallback toggle_easy_unlock_callback_;
   CryptAuthClient::FindEligibleUnlockDevicesCallback
@@ -287,24 +289,26 @@
   bool result_eligible_for_promotion_;
 
  private:
-  DISALLOW_COPY_AND_ASSIGN(DeviceCapabilityManagerTest);
+  DISALLOW_COPY_AND_ASSIGN(DeviceCapabilityManagerImplTest);
 };
 
-TEST_F(DeviceCapabilityManagerTest, TestOrderUponMultipleRequests) {
+TEST_F(DeviceCapabilityManagerImplTest, TestOrderUponMultipleRequests) {
   SetCapabilityEnabled(
-      DeviceCapabilityManager::Capability::CAPABILITY_UNLOCK_KEY,
+      DeviceCapabilityManagerImpl::Capability::CAPABILITY_UNLOCK_KEY,
       test_eligible_external_devices_infos_[0], true /* enable */);
   FindEligibleDevicesForCapability(
-      DeviceCapabilityManager::Capability::CAPABILITY_UNLOCK_KEY);
-  IsPromotableDevice(DeviceCapabilityManager::Capability::CAPABILITY_UNLOCK_KEY,
-                     test_eligible_external_devices_infos_[0].public_key());
+      DeviceCapabilityManagerImpl::Capability::CAPABILITY_UNLOCK_KEY);
+  IsPromotableDevice(
+      DeviceCapabilityManagerImpl::Capability::CAPABILITY_UNLOCK_KEY,
+      test_eligible_external_devices_infos_[0].public_key());
   SetCapabilityEnabled(
-      DeviceCapabilityManager::Capability::CAPABILITY_UNLOCK_KEY,
+      DeviceCapabilityManagerImpl::Capability::CAPABILITY_UNLOCK_KEY,
       test_eligible_external_devices_infos_[1], true /* enable */);
   FindEligibleDevicesForCapability(
-      DeviceCapabilityManager::Capability::CAPABILITY_UNLOCK_KEY);
-  IsPromotableDevice(DeviceCapabilityManager::Capability::CAPABILITY_UNLOCK_KEY,
-                     test_eligible_external_devices_infos_[1].public_key());
+      DeviceCapabilityManagerImpl::Capability::CAPABILITY_UNLOCK_KEY);
+  IsPromotableDevice(
+      DeviceCapabilityManagerImpl::Capability::CAPABILITY_UNLOCK_KEY,
+      test_eligible_external_devices_infos_[1].public_key());
 
   InvokeSetCapabilityKeyUnlockCallback();
   EXPECT_EQ(kSuccessResult, GetResultAndReset());
@@ -331,15 +335,15 @@
   EXPECT_TRUE(GetEligibleForPromotionAndReset());
 }
 
-TEST_F(DeviceCapabilityManagerTest, TestMultipleSetUnlocksRequests) {
+TEST_F(DeviceCapabilityManagerImplTest, TestMultipleSetUnlocksRequests) {
   SetCapabilityEnabled(
-      DeviceCapabilityManager::Capability::CAPABILITY_UNLOCK_KEY,
+      DeviceCapabilityManagerImpl::Capability::CAPABILITY_UNLOCK_KEY,
       test_eligible_external_devices_infos_[0], true /* enable */);
   SetCapabilityEnabled(
-      DeviceCapabilityManager::Capability::CAPABILITY_UNLOCK_KEY,
+      DeviceCapabilityManagerImpl::Capability::CAPABILITY_UNLOCK_KEY,
       test_eligible_external_devices_infos_[1], true /* enable */);
   SetCapabilityEnabled(
-      DeviceCapabilityManager::Capability::CAPABILITY_UNLOCK_KEY,
+      DeviceCapabilityManagerImpl::Capability::CAPABILITY_UNLOCK_KEY,
       test_eligible_external_devices_infos_[2], true /* enable */);
 
   InvokeErrorCallback();
@@ -352,14 +356,14 @@
   EXPECT_EQ(kSuccessResult, GetResultAndReset());
 }
 
-TEST_F(DeviceCapabilityManagerTest,
+TEST_F(DeviceCapabilityManagerImplTest,
        TestMultipleFindEligibleForUnlockDevicesRequests) {
   FindEligibleDevicesForCapability(
-      DeviceCapabilityManager::Capability::CAPABILITY_UNLOCK_KEY);
+      DeviceCapabilityManagerImpl::Capability::CAPABILITY_UNLOCK_KEY);
   FindEligibleDevicesForCapability(
-      DeviceCapabilityManager::Capability::CAPABILITY_UNLOCK_KEY);
+      DeviceCapabilityManagerImpl::Capability::CAPABILITY_UNLOCK_KEY);
   FindEligibleDevicesForCapability(
-      DeviceCapabilityManager::Capability::CAPABILITY_UNLOCK_KEY);
+      DeviceCapabilityManagerImpl::Capability::CAPABILITY_UNLOCK_KEY);
 
   InvokeFindEligibleUnlockDevicesCallback(
       CreateFindEligibleUnlockDevicesResponse());
@@ -375,13 +379,16 @@
   VerifyDeviceEligibility();
 }
 
-TEST_F(DeviceCapabilityManagerTest, TestMultipleIsPromotableRequests) {
-  IsPromotableDevice(DeviceCapabilityManager::Capability::CAPABILITY_UNLOCK_KEY,
-                     test_eligible_external_devices_infos_[0].public_key());
-  IsPromotableDevice(DeviceCapabilityManager::Capability::CAPABILITY_UNLOCK_KEY,
-                     test_eligible_external_devices_infos_[1].public_key());
-  IsPromotableDevice(DeviceCapabilityManager::Capability::CAPABILITY_UNLOCK_KEY,
-                     test_eligible_external_devices_infos_[2].public_key());
+TEST_F(DeviceCapabilityManagerImplTest, TestMultipleIsPromotableRequests) {
+  IsPromotableDevice(
+      DeviceCapabilityManagerImpl::Capability::CAPABILITY_UNLOCK_KEY,
+      test_eligible_external_devices_infos_[0].public_key());
+  IsPromotableDevice(
+      DeviceCapabilityManagerImpl::Capability::CAPABILITY_UNLOCK_KEY,
+      test_eligible_external_devices_infos_[1].public_key());
+  IsPromotableDevice(
+      DeviceCapabilityManagerImpl::Capability::CAPABILITY_UNLOCK_KEY,
+      test_eligible_external_devices_infos_[2].public_key());
 
   InvokeFindEligibleForPromotionCallback(true /*eligible*/);
   EXPECT_EQ(kSuccessResult, GetResultAndReset());
@@ -395,14 +402,15 @@
   EXPECT_EQ(kErrorFindEligibleForPromotion, GetResultAndReset());
 }
 
-TEST_F(DeviceCapabilityManagerTest, TestOrderViaMultipleErrors) {
+TEST_F(DeviceCapabilityManagerImplTest, TestOrderViaMultipleErrors) {
   SetCapabilityEnabled(
-      DeviceCapabilityManager::Capability::CAPABILITY_UNLOCK_KEY,
+      DeviceCapabilityManagerImpl::Capability::CAPABILITY_UNLOCK_KEY,
       test_eligible_external_devices_infos_[0], true /* enable */);
   FindEligibleDevicesForCapability(
-      DeviceCapabilityManager::Capability::CAPABILITY_UNLOCK_KEY);
-  IsPromotableDevice(DeviceCapabilityManager::Capability::CAPABILITY_UNLOCK_KEY,
-                     test_eligible_external_devices_infos_[0].public_key());
+      DeviceCapabilityManagerImpl::Capability::CAPABILITY_UNLOCK_KEY);
+  IsPromotableDevice(
+      DeviceCapabilityManagerImpl::Capability::CAPABILITY_UNLOCK_KEY,
+      test_eligible_external_devices_infos_[0].public_key());
 
   InvokeErrorCallback();
   EXPECT_EQ(kErrorOnToggleEasyUnlockResult, GetResultAndReset());
diff --git a/components/cryptauth/fake_device_capability_manager.cc b/components/cryptauth/fake_device_capability_manager.cc
new file mode 100644
index 0000000..c8d7692
--- /dev/null
+++ b/components/cryptauth/fake_device_capability_manager.cc
@@ -0,0 +1,51 @@
+// 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 "components/cryptauth/fake_device_capability_manager.h"
+
+namespace cryptauth {
+
+FakeDeviceCapabilityManager::FakeDeviceCapabilityManager() {}
+
+FakeDeviceCapabilityManager::~FakeDeviceCapabilityManager() {}
+
+void FakeDeviceCapabilityManager::SetCapabilityEnabled(
+    const std::string& public_key,
+    Capability capability,
+    bool enabled,
+    const base::Closure& success_callback,
+    const base::Callback<void(const std::string&)>& error_callback) {
+  if (set_capability_enabled_error_code_.empty()) {
+    success_callback.Run();
+    return;
+  }
+  error_callback.Run(std::move(set_capability_enabled_error_code_));
+}
+
+void FakeDeviceCapabilityManager::FindEligibleDevicesForCapability(
+    Capability capability,
+    const base::Callback<void(const std::vector<ExternalDeviceInfo>&,
+                              const std::vector<IneligibleDevice>&)>&
+        success_callback,
+    const base::Callback<void(const std::string&)>& error_callback) {
+  if (find_eligible_devices_for_capability_error_code_.empty()) {
+    success_callback.Run(external_device_infos_, ineligible_devices_);
+    return;
+  }
+  error_callback.Run(find_eligible_devices_for_capability_error_code_);
+}
+
+void FakeDeviceCapabilityManager::IsCapabilityPromotable(
+    const std::string& public_key,
+    Capability capability,
+    const base::Callback<void(bool)>& success_callback,
+    const base::Callback<void(const std::string&)>& error_callback) {
+  if (is_capability_promotable_error_code_.empty()) {
+    success_callback.Run(true /* capability is promotable */);
+    return;
+  }
+  error_callback.Run(is_capability_promotable_error_code_);
+}
+
+}  // namespace cryptauth
\ No newline at end of file
diff --git a/components/cryptauth/fake_device_capability_manager.h b/components/cryptauth/fake_device_capability_manager.h
new file mode 100644
index 0000000..b0d35e42
--- /dev/null
+++ b/components/cryptauth/fake_device_capability_manager.h
@@ -0,0 +1,76 @@
+// 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 COMPONENTS_CRYPTAUTH_FAKE_DEVICE_CAPABILITY_MANAGER_H_
+#define COMPONENTS_CRYPTAUTH_FAKE_DEVICE_CAPABILITY_MANAGER_H_
+
+#include "base/callback.h"
+#include "components/cryptauth/device_capability_manager.h"
+#include "components/cryptauth/proto/cryptauth_api.pb.h"
+
+namespace cryptauth {
+
+using Capability = DeviceCapabilityManager::Capability;
+
+// Test double for Device Capability Manager.
+class FakeDeviceCapabilityManager : public cryptauth::DeviceCapabilityManager {
+ public:
+  FakeDeviceCapabilityManager();
+
+  ~FakeDeviceCapabilityManager() override;
+
+  void set_find_eligible_devices_for_capability_error_code(
+      std::string error_code) {
+    find_eligible_devices_for_capability_error_code_ = error_code;
+  }
+
+  void set_capability_enabled_error_code(std::string error_code) {
+    set_capability_enabled_error_code_ = error_code;
+    LOG(ERROR) << set_capability_enabled_error_code_;
+  }
+
+  void set_is_capability_promotable_error_code(std::string error_code) {
+    is_capability_promotable_error_code_ = error_code;
+  }
+
+  void set_external_device_info(
+      std::vector<ExternalDeviceInfo> external_device_infos) {
+    external_device_infos_ = external_device_infos;
+  }
+
+  void set_ineligible_devices(
+      std::vector<IneligibleDevice> ineligible_devices) {
+    ineligible_devices_ = ineligible_devices;
+  }
+
+  // cryptauth::DeviceCapabilityManager:
+  void SetCapabilityEnabled(
+      const std::string& public_key,
+      Capability capability,
+      bool enabled,
+      const base::Closure& success_callback,
+      const base::Callback<void(const std::string&)>& error_callback) override;
+
+  void FindEligibleDevicesForCapability(
+      Capability capability,
+      const base::Callback<void(const std::vector<ExternalDeviceInfo>&,
+                                const std::vector<IneligibleDevice>&)>&
+          success_callback,
+      const base::Callback<void(const std::string&)>& error_callback) override;
+
+  void IsCapabilityPromotable(
+      const std::string& public_key,
+      Capability capability,
+      const base::Callback<void(bool)>& success_callback,
+      const base::Callback<void(const std::string&)>& error_callback) override;
+
+  std::string set_capability_enabled_error_code_;
+  std::string find_eligible_devices_for_capability_error_code_;
+  std::string is_capability_promotable_error_code_;
+  std::vector<ExternalDeviceInfo> external_device_infos_;
+  std::vector<IneligibleDevice> ineligible_devices_;
+};
+}  // namespace cryptauth
+
+#endif  // COMPONENTS_CRYPTAUTH_FAKE_DEVICE_CAPABILITY_MANAGER_H_
diff --git a/components/metrics/persistent_system_profile.cc b/components/metrics/persistent_system_profile.cc
index 6c52550..fd7fe75 100644
--- a/components/metrics/persistent_system_profile.cc
+++ b/components/metrics/persistent_system_profile.cc
@@ -333,8 +333,8 @@
   DCHECK(!group.empty());
 
   base::Pickle pickler;
-  if (!pickler.WriteString(trial) || !pickler.WriteString(group))
-    return;
+  pickler.WriteString(trial);
+  pickler.WriteString(group);
 
   WriteToAll(kFieldTrialInfo,
              base::StringPiece(static_cast<const char*>(pickler.data()),
diff --git a/components/ntp_snippets/offline_pages/offline_pages_test_utils.cc b/components/ntp_snippets/offline_pages/offline_pages_test_utils.cc
index 22a406a..92bf0d2 100644
--- a/components/ntp_snippets/offline_pages/offline_pages_test_utils.cc
+++ b/components/ntp_snippets/offline_pages/offline_pages_test_utils.cc
@@ -10,8 +10,10 @@
 #include "base/guid.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
+#include "components/offline_pages/core/client_policy_controller.h"
 
 using offline_pages::ClientId;
+using offline_pages::ClientPolicyController;
 using offline_pages::MultipleOfflinePageItemCallback;
 using offline_pages::OfflinePageItem;
 using offline_pages::StubOfflinePageModel;
@@ -26,12 +28,24 @@
 
 FakeOfflinePageModel::~FakeOfflinePageModel() = default;
 
-void FakeOfflinePageModel::GetPagesMatchingQuery(
-    std::unique_ptr<offline_pages::OfflinePageModelQuery> query,
+void FakeOfflinePageModel::GetPagesByNamespace(
+    const std::string& name_space,
     const MultipleOfflinePageItemCallback& callback) {
   MultipleOfflinePageItemResult filtered_result;
   for (auto& item : items_) {
-    if (query->Matches(item)) {
+    if (item.client_id.name_space == name_space) {
+      filtered_result.emplace_back(item);
+    }
+  }
+  callback.Run(filtered_result);
+}
+
+void FakeOfflinePageModel::GetPagesSupportedByDownloads(
+    const MultipleOfflinePageItemCallback& callback) {
+  ClientPolicyController controller;
+  MultipleOfflinePageItemResult filtered_result;
+  for (auto& item : items_) {
+    if (controller.IsSupportedByDownload(item.client_id.name_space)) {
       filtered_result.emplace_back(item);
     }
   }
diff --git a/components/ntp_snippets/offline_pages/offline_pages_test_utils.h b/components/ntp_snippets/offline_pages/offline_pages_test_utils.h
index 61147b7..bbd1ed7 100644
--- a/components/ntp_snippets/offline_pages/offline_pages_test_utils.h
+++ b/components/ntp_snippets/offline_pages/offline_pages_test_utils.h
@@ -17,8 +17,11 @@
   FakeOfflinePageModel();
   ~FakeOfflinePageModel() override;
 
-  void GetPagesMatchingQuery(
-      std::unique_ptr<offline_pages::OfflinePageModelQuery> query,
+  void GetPagesByNamespace(
+      const std::string& name_space,
+      const offline_pages::MultipleOfflinePageItemCallback& callback) override;
+
+  void GetPagesSupportedByDownloads(
       const offline_pages::MultipleOfflinePageItemCallback& callback) override;
 
   void GetAllPages(
diff --git a/components/ntp_snippets/remote/prefetched_pages_tracker_impl.cc b/components/ntp_snippets/remote/prefetched_pages_tracker_impl.cc
index b05b465d7..dc8018c 100644
--- a/components/ntp_snippets/remote/prefetched_pages_tracker_impl.cc
+++ b/components/ntp_snippets/remote/prefetched_pages_tracker_impl.cc
@@ -9,20 +9,11 @@
 
 using offline_pages::OfflinePageItem;
 using offline_pages::OfflinePageModel;
-using offline_pages::OfflinePageModelQuery;
-using offline_pages::OfflinePageModelQueryBuilder;
 
 namespace ntp_snippets {
 
 namespace {
 
-std::unique_ptr<OfflinePageModelQuery> BuildPrefetchedPagesQuery(
-    OfflinePageModel* model) {
-  OfflinePageModelQueryBuilder builder;
-  builder.RequireNamespace(offline_pages::kSuggestedArticlesNamespace);
-  return builder.Build(model->GetPolicyController());
-}
-
 bool IsOfflineItemPrefetchedPage(const OfflinePageItem& offline_page_item) {
   return offline_page_item.client_id.name_space ==
          offline_pages::kSuggestedArticlesNamespace;
@@ -44,8 +35,8 @@
   DCHECK(offline_page_model_);
   // If Offline Page model is not loaded yet, it will process our query
   // once it has finished loading.
-  offline_page_model_->GetPagesMatchingQuery(
-      BuildPrefetchedPagesQuery(offline_page_model),
+  offline_page_model_->GetPagesByNamespace(
+      offline_pages::kSuggestedArticlesNamespace,
       base::Bind(&PrefetchedPagesTrackerImpl::Initialize,
                  weak_ptr_factory_.GetWeakPtr()));
 }
diff --git a/components/ntp_snippets/remote/prefetched_pages_tracker_impl_unittest.cc b/components/ntp_snippets/remote/prefetched_pages_tracker_impl_unittest.cc
index 440849a..83f29de2 100644
--- a/components/ntp_snippets/remote/prefetched_pages_tracker_impl_unittest.cc
+++ b/components/ntp_snippets/remote/prefetched_pages_tracker_impl_unittest.cc
@@ -31,17 +31,8 @@
  public:
   ~MockOfflinePageModel() override = default;
 
-  // GMock does not support movable-only types (unique_ptr in this case).
-  // Therefore, the call is redirected to a mock method without movable-only
-  // types.
-  void GetPagesMatchingQuery(
-      std::unique_ptr<OfflinePageModelQuery> query,
-      const MultipleOfflinePageItemCallback& callback) override {
-    GetPagesMatchingQuery(query.get(), callback);
-  }
-
-  MOCK_METHOD2(GetPagesMatchingQuery,
-               void(OfflinePageModelQuery* query,
+  MOCK_METHOD2(GetPagesByNamespace,
+               void(const std::string& name_space,
                     const MultipleOfflinePageItemCallback& callback));
 };
 
@@ -170,7 +161,9 @@
 
 TEST_F(PrefetchedPagesTrackerImplTest,
        ShouldReportAsNotInitializedBeforeInitialization) {
-  EXPECT_CALL(*mock_offline_page_model(), GetPagesMatchingQuery(_, _));
+  EXPECT_CALL(
+      *mock_offline_page_model(),
+      GetPagesByNamespace(offline_pages::kSuggestedArticlesNamespace, _));
   PrefetchedPagesTrackerImpl tracker(mock_offline_page_model());
   EXPECT_FALSE(tracker.IsInitialized());
 }
@@ -178,7 +171,9 @@
 TEST_F(PrefetchedPagesTrackerImplTest,
        ShouldReportAsInitializedAfterInitialization) {
   MultipleOfflinePageItemCallback offline_pages_callback;
-  EXPECT_CALL(*mock_offline_page_model(), GetPagesMatchingQuery(_, _))
+  EXPECT_CALL(
+      *mock_offline_page_model(),
+      GetPagesByNamespace(offline_pages::kSuggestedArticlesNamespace, _))
       .WillOnce(SaveArg<1>(&offline_pages_callback));
   PrefetchedPagesTrackerImpl tracker(mock_offline_page_model());
 
@@ -189,7 +184,9 @@
 
 TEST_F(PrefetchedPagesTrackerImplTest, ShouldCallCallbackAfterInitialization) {
   MultipleOfflinePageItemCallback offline_pages_callback;
-  EXPECT_CALL(*mock_offline_page_model(), GetPagesMatchingQuery(_, _))
+  EXPECT_CALL(
+      *mock_offline_page_model(),
+      GetPagesByNamespace(offline_pages::kSuggestedArticlesNamespace, _))
       .WillOnce(SaveArg<1>(&offline_pages_callback));
   PrefetchedPagesTrackerImpl tracker(mock_offline_page_model());
 
@@ -204,7 +201,9 @@
 TEST_F(PrefetchedPagesTrackerImplTest,
        ShouldCallMultipleCallbacksAfterInitialization) {
   MultipleOfflinePageItemCallback offline_pages_callback;
-  EXPECT_CALL(*mock_offline_page_model(), GetPagesMatchingQuery(_, _))
+  EXPECT_CALL(
+      *mock_offline_page_model(),
+      GetPagesByNamespace(offline_pages::kSuggestedArticlesNamespace, _))
       .WillOnce(SaveArg<1>(&offline_pages_callback));
   PrefetchedPagesTrackerImpl tracker(mock_offline_page_model());
 
@@ -223,7 +222,9 @@
 TEST_F(PrefetchedPagesTrackerImplTest,
        ShouldCallCallbackImmediatelyIfAlreadyInitialiazed) {
   MultipleOfflinePageItemCallback offline_pages_callback;
-  EXPECT_CALL(*mock_offline_page_model(), GetPagesMatchingQuery(_, _))
+  EXPECT_CALL(
+      *mock_offline_page_model(),
+      GetPagesByNamespace(offline_pages::kSuggestedArticlesNamespace, _))
       .WillOnce(SaveArg<1>(&offline_pages_callback));
   PrefetchedPagesTrackerImpl tracker(mock_offline_page_model());
   offline_pages_callback.Run(std::vector<OfflinePageItem>());
diff --git a/components/offline_pages/core/offline_page_model.h b/components/offline_pages/core/offline_page_model.h
index dd5a2b5f..561ae7fc 100644
--- a/components/offline_pages/core/offline_page_model.h
+++ b/components/offline_pages/core/offline_page_model.h
@@ -145,10 +145,6 @@
   virtual void DeletePagesByClientIds(const std::vector<ClientId>& client_ids,
                                       const DeletePageCallback& callback) = 0;
 
-  virtual void GetPagesMatchingQuery(
-      std::unique_ptr<OfflinePageModelQuery> query,
-      const MultipleOfflinePageItemCallback& callback) = 0;
-
   // Retrieves all pages associated with any of |client_ids|.
   virtual void GetPagesByClientIds(
       const std::vector<ClientId>& client_ids,
@@ -190,6 +186,19 @@
       URLSearchMode url_search_mode,
       const MultipleOfflinePageItemCallback& callback) = 0;
 
+  // Returns the offline pages that are removed when cache is reset.
+  virtual void GetPagesRemovedOnCacheReset(
+      const MultipleOfflinePageItemCallback& callback) = 0;
+
+  // Returns the offline pages that belong in |name_space|.
+  virtual void GetPagesByNamespace(
+      const std::string& name_space,
+      const MultipleOfflinePageItemCallback& callback) = 0;
+
+  // Returns the offline pages that are visible in download manager UI.
+  virtual void GetPagesSupportedByDownloads(
+      const MultipleOfflinePageItemCallback& callback) = 0;
+
   // Returns the policy controller.
   virtual ClientPolicyController* GetPolicyController() = 0;
 
diff --git a/components/offline_pages/core/offline_page_model_impl.cc b/components/offline_pages/core/offline_page_model_impl.cc
index b3923bbd..0a8f5fb 100644
--- a/components/offline_pages/core/offline_page_model_impl.cc
+++ b/components/offline_pages/core/offline_page_model_impl.cc
@@ -495,14 +495,6 @@
   DoDeletePagesByOfflineId(offline_ids, callback);
 }
 
-void OfflinePageModelImpl::GetPagesMatchingQuery(
-    std::unique_ptr<OfflinePageModelQuery> query,
-    const MultipleOfflinePageItemCallback& callback) {
-  RunWhenLoaded(base::Bind(
-      &OfflinePageModelImpl::GetPagesMatchingQueryWhenLoadDone,
-      weak_ptr_factory_.GetWeakPtr(), base::Passed(&query), callback));
-}
-
 void OfflinePageModelImpl::GetPagesMatchingQueryWhenLoadDone(
     std::unique_ptr<OfflinePageModelQuery> query,
     const MultipleOfflinePageItemCallback& callback) {
@@ -671,6 +663,39 @@
                  base::Passed(builder.Build(GetPolicyController())), callback));
 }
 
+void OfflinePageModelImpl::GetPagesRemovedOnCacheReset(
+    const MultipleOfflinePageItemCallback& callback) {
+  OfflinePageModelQueryBuilder builder;
+  builder.RequireRemovedOnCacheReset(
+      OfflinePageModelQuery::Requirement::INCLUDE_MATCHING);
+  RunWhenLoaded(
+      base::Bind(&OfflinePageModelImpl::GetPagesMatchingQueryWhenLoadDone,
+                 weak_ptr_factory_.GetWeakPtr(),
+                 base::Passed(builder.Build(GetPolicyController())), callback));
+}
+
+void OfflinePageModelImpl::GetPagesByNamespace(
+    const std::string& name_space,
+    const MultipleOfflinePageItemCallback& callback) {
+  OfflinePageModelQueryBuilder builder;
+  builder.RequireNamespace(name_space);
+  RunWhenLoaded(
+      base::Bind(&OfflinePageModelImpl::GetPagesMatchingQueryWhenLoadDone,
+                 weak_ptr_factory_.GetWeakPtr(),
+                 base::Passed(builder.Build(GetPolicyController())), callback));
+}
+
+void OfflinePageModelImpl::GetPagesSupportedByDownloads(
+    const MultipleOfflinePageItemCallback& callback) {
+  OfflinePageModelQueryBuilder builder;
+  builder.RequireSupportedByDownload(
+      OfflinePageModelQuery::Requirement::INCLUDE_MATCHING);
+  RunWhenLoaded(
+      base::Bind(&OfflinePageModelImpl::GetPagesMatchingQueryWhenLoadDone,
+                 weak_ptr_factory_.GetWeakPtr(),
+                 base::Passed(builder.Build(GetPolicyController())), callback));
+}
+
 void OfflinePageModelImpl::CheckMetadataConsistency() {
   DCHECK(is_loaded_);
 
diff --git a/components/offline_pages/core/offline_page_model_impl.h b/components/offline_pages/core/offline_page_model_impl.h
index 2f23ea8d..0a9a390 100644
--- a/components/offline_pages/core/offline_page_model_impl.h
+++ b/components/offline_pages/core/offline_page_model_impl.h
@@ -75,10 +75,6 @@
   void DeletePagesByClientIds(const std::vector<ClientId>& client_ids,
                               const DeletePageCallback& callback) override;
 
-  void GetPagesMatchingQuery(
-      std::unique_ptr<OfflinePageModelQuery> query,
-      const MultipleOfflinePageItemCallback& callback) override;
-
   void GetPagesByClientIds(
       const std::vector<ClientId>& client_ids,
       const MultipleOfflinePageItemCallback& callback) override;
@@ -104,6 +100,13 @@
       const GURL& url,
       URLSearchMode url_search_mode,
       const MultipleOfflinePageItemCallback& callback) override;
+  void GetPagesRemovedOnCacheReset(
+      const MultipleOfflinePageItemCallback& callback) override;
+  void GetPagesByNamespace(
+      const std::string& name_space,
+      const MultipleOfflinePageItemCallback& callback) override;
+  void GetPagesSupportedByDownloads(
+      const MultipleOfflinePageItemCallback& callback) override;
   ClientPolicyController* GetPolicyController() override;
 
   // Methods for testing only:
diff --git a/components/offline_pages/core/offline_page_model_impl_unittest.cc b/components/offline_pages/core/offline_page_model_impl_unittest.cc
index c5d11207..66204ad 100644
--- a/components/offline_pages/core/offline_page_model_impl_unittest.cc
+++ b/components/offline_pages/core/offline_page_model_impl_unittest.cc
@@ -1460,35 +1460,102 @@
   EXPECT_EQ(SavePageResult::STORE_FAILURE, result.first);
 }
 
-TEST_F(OfflinePageModelImplTest, GetPagesMatchingQuery) {
-  std::unique_ptr<OfflinePageTestArchiver> archiver(BuildArchiver(
-      kTestUrl, OfflinePageArchiver::ArchiverResult::SUCCESSFULLY_CREATED));
-  SavePageWithArchiverAsync(kTestUrl, kTestClientId1, kTestUrl2, "",
-                            std::move(archiver));
-  PumpLoop();
-
-  std::vector<ClientId> client_ids{kTestClientId1};
-  OfflinePageModelQueryBuilder builder;
-  builder.SetClientIds(OfflinePageModelQuery::Requirement::INCLUDE_MATCHING,
-                       client_ids);
+TEST_F(OfflinePageModelImplTest, GetPagesByNamespace) {
+  SavePage(kTestUrl, ClientId(kCCTNamespace, "123"));
+  SavePage(kTestUrl, ClientId(kDownloadNamespace, "456"));
+  base::FilePath archive_path(last_archiver_path());
+  SavePage(kTestUrl, ClientId(kNTPSuggestionsNamespace, "789"));
 
   MultipleOfflinePageItemResult offline_pages;
-  model()->GetPagesMatchingQuery(
-      builder.Build(model()->GetPolicyController()),
+  model()->GetPagesByNamespace(
+      kDownloadNamespace,
       base::Bind(&OfflinePageModelImplTest::OnGetMultipleOfflinePageItemsResult,
                  AsWeakPtr(), base::Unretained(&offline_pages)));
   PumpLoop();
 
   ASSERT_EQ(1UL, offline_pages.size());
   EXPECT_EQ(kTestUrl, offline_pages[0].url);
-  EXPECT_EQ(kTestClientId1.id, offline_pages[0].client_id.id);
-  EXPECT_EQ(kTestClientId1.name_space, offline_pages[0].client_id.name_space);
-  EXPECT_EQ(last_archiver_path(), offline_pages[0].file_path);
+  EXPECT_EQ("456", offline_pages[0].client_id.id);
+  EXPECT_EQ(kDownloadNamespace, offline_pages[0].client_id.name_space);
+  EXPECT_EQ(archive_path, offline_pages[0].file_path);
   EXPECT_EQ(kTestFileSize, offline_pages[0].file_size);
   EXPECT_EQ(0, offline_pages[0].access_count);
   EXPECT_EQ(0, offline_pages[0].flags);
   EXPECT_EQ(kTestTitle, offline_pages[0].title);
-  EXPECT_EQ(kTestUrl2, offline_pages[0].original_url);
+  EXPECT_EQ(GURL(), offline_pages[0].original_url);
+  EXPECT_EQ("", offline_pages[0].request_origin);
+}
+
+TEST_F(OfflinePageModelImplTest, GetPagesRemovedOnCacheReset) {
+  SavePage(kTestUrl, ClientId(kCCTNamespace, "123"));
+  base::FilePath archive_path(last_archiver_path());
+  SavePage(kTestUrl, ClientId(kDownloadNamespace, "456"));
+  SavePage(kTestUrl, ClientId(kNTPSuggestionsNamespace, "789"));
+
+  MultipleOfflinePageItemResult offline_pages;
+  model()->GetPagesRemovedOnCacheReset(
+      base::Bind(&OfflinePageModelImplTest::OnGetMultipleOfflinePageItemsResult,
+                 AsWeakPtr(), base::Unretained(&offline_pages)));
+  PumpLoop();
+
+  ASSERT_EQ(1UL, offline_pages.size());
+  EXPECT_EQ(kTestUrl, offline_pages[0].url);
+  EXPECT_EQ("123", offline_pages[0].client_id.id);
+  EXPECT_EQ(kCCTNamespace, offline_pages[0].client_id.name_space);
+  EXPECT_EQ(archive_path, offline_pages[0].file_path);
+  EXPECT_EQ(kTestFileSize, offline_pages[0].file_size);
+  EXPECT_EQ(0, offline_pages[0].access_count);
+  EXPECT_EQ(0, offline_pages[0].flags);
+  EXPECT_EQ(kTestTitle, offline_pages[0].title);
+  EXPECT_EQ(GURL(), offline_pages[0].original_url);
+  EXPECT_EQ("", offline_pages[0].request_origin);
+}
+
+TEST_F(OfflinePageModelImplTest, GetPagesSupportedByDownloads) {
+  SavePage(kTestUrl, ClientId(kCCTNamespace, "123"));
+  SavePage(kTestUrl, ClientId(kDownloadNamespace, "456"));
+  base::FilePath download_archive_path(last_archiver_path());
+  SavePage(kTestUrl, ClientId(kNTPSuggestionsNamespace, "789"));
+  base::FilePath ntp_suggestions_archive_path(last_archiver_path());
+
+  MultipleOfflinePageItemResult offline_pages;
+  model()->GetPagesSupportedByDownloads(
+      base::Bind(&OfflinePageModelImplTest::OnGetMultipleOfflinePageItemsResult,
+                 AsWeakPtr(), base::Unretained(&offline_pages)));
+  PumpLoop();
+
+  ASSERT_EQ(2UL, offline_pages.size());
+  int download_index = 0;
+  int ntp_suggestions_index = 1;
+  if (offline_pages[0].client_id.name_space != kDownloadNamespace) {
+    download_index = 1;
+    ntp_suggestions_index = 0;
+  }
+
+  EXPECT_EQ(kTestUrl, offline_pages[download_index].url);
+  EXPECT_EQ("456", offline_pages[download_index].client_id.id);
+  EXPECT_EQ(kDownloadNamespace,
+            offline_pages[download_index].client_id.name_space);
+  EXPECT_EQ(download_archive_path, offline_pages[download_index].file_path);
+  EXPECT_EQ(kTestFileSize, offline_pages[download_index].file_size);
+  EXPECT_EQ(0, offline_pages[download_index].access_count);
+  EXPECT_EQ(0, offline_pages[download_index].flags);
+  EXPECT_EQ(kTestTitle, offline_pages[download_index].title);
+  EXPECT_EQ(GURL(), offline_pages[download_index].original_url);
+  EXPECT_EQ("", offline_pages[download_index].request_origin);
+
+  EXPECT_EQ(kTestUrl, offline_pages[ntp_suggestions_index].url);
+  EXPECT_EQ("789", offline_pages[ntp_suggestions_index].client_id.id);
+  EXPECT_EQ(kNTPSuggestionsNamespace,
+            offline_pages[ntp_suggestions_index].client_id.name_space);
+  EXPECT_EQ(ntp_suggestions_archive_path,
+            offline_pages[ntp_suggestions_index].file_path);
+  EXPECT_EQ(kTestFileSize, offline_pages[ntp_suggestions_index].file_size);
+  EXPECT_EQ(0, offline_pages[ntp_suggestions_index].access_count);
+  EXPECT_EQ(0, offline_pages[ntp_suggestions_index].flags);
+  EXPECT_EQ(kTestTitle, offline_pages[ntp_suggestions_index].title);
+  EXPECT_EQ(GURL(), offline_pages[ntp_suggestions_index].original_url);
+  EXPECT_EQ("", offline_pages[ntp_suggestions_index].request_origin);
 }
 
 TEST(CommandLineFlagsTest, OfflineBookmarks) {
diff --git a/components/offline_pages/core/stub_offline_page_model.cc b/components/offline_pages/core/stub_offline_page_model.cc
index 5808083..ed0d3d71 100644
--- a/components/offline_pages/core/stub_offline_page_model.cc
+++ b/components/offline_pages/core/stub_offline_page_model.cc
@@ -24,9 +24,6 @@
 void StubOfflinePageModel::DeletePagesByClientIds(
     const std::vector<ClientId>& client_ids,
     const DeletePageCallback& callback) {}
-void StubOfflinePageModel::GetPagesMatchingQuery(
-    std::unique_ptr<OfflinePageModelQuery> query,
-    const MultipleOfflinePageItemCallback& callback) {}
 void StubOfflinePageModel::GetPagesByClientIds(
     const std::vector<ClientId>& client_ids,
     const MultipleOfflinePageItemCallback& callback) {}
@@ -51,6 +48,13 @@
 void StubOfflinePageModel::GetPagesByRequestOrigin(
     const std::string& origin,
     const MultipleOfflinePageItemCallback& callback) {}
+void StubOfflinePageModel::GetPagesRemovedOnCacheReset(
+    const MultipleOfflinePageItemCallback& callback) {}
+void StubOfflinePageModel::GetPagesByNamespace(
+    const std::string& name_space,
+    const MultipleOfflinePageItemCallback& callback) {}
+void StubOfflinePageModel::GetPagesSupportedByDownloads(
+    const MultipleOfflinePageItemCallback& callback) {}
 ClientPolicyController* StubOfflinePageModel::GetPolicyController() {
   return &policy_controller_;
 }
diff --git a/components/offline_pages/core/stub_offline_page_model.h b/components/offline_pages/core/stub_offline_page_model.h
index 11d9c9f..d68d0a0 100644
--- a/components/offline_pages/core/stub_offline_page_model.h
+++ b/components/offline_pages/core/stub_offline_page_model.h
@@ -35,9 +35,6 @@
                               const DeletePageCallback& callback) override;
   void DeletePagesByClientIds(const std::vector<ClientId>& client_ids,
                               const DeletePageCallback& callback) override;
-  void GetPagesMatchingQuery(
-      std::unique_ptr<OfflinePageModelQuery> query,
-      const MultipleOfflinePageItemCallback& callback) override;
   void GetPagesByClientIds(
       const std::vector<ClientId>& client_ids,
       const MultipleOfflinePageItemCallback& callback) override;
@@ -61,6 +58,13 @@
   void GetPagesByRequestOrigin(
       const std::string& origin,
       const MultipleOfflinePageItemCallback& callback) override;
+  void GetPagesRemovedOnCacheReset(
+      const MultipleOfflinePageItemCallback& callback) override;
+  void GetPagesByNamespace(
+      const std::string& name_space,
+      const MultipleOfflinePageItemCallback& callback) override;
+  void GetPagesSupportedByDownloads(
+      const MultipleOfflinePageItemCallback& callback) override;
   ClientPolicyController* GetPolicyController() override;
   bool is_loaded() const override;
   OfflineEventLogger* GetLogger() override;
diff --git a/content/browser/background_fetch/background_fetch_event_dispatcher.cc b/content/browser/background_fetch/background_fetch_event_dispatcher.cc
index d694845..ba5b9ca 100644
--- a/content/browser/background_fetch/background_fetch_event_dispatcher.cc
+++ b/content/browser/background_fetch/background_fetch_event_dispatcher.cc
@@ -199,8 +199,8 @@
       base::BindOnce(&BackgroundFetchEventDispatcher::DispatchEvent, event,
                      finished_closure, loaded_callback,
                      make_scoped_refptr(service_worker_version)),
-      base::Bind(&BackgroundFetchEventDispatcher::DidDispatchEvent, event,
-                 finished_closure, DispatchPhase::STARTING));
+      base::BindOnce(&BackgroundFetchEventDispatcher::DidDispatchEvent, event,
+                     finished_closure, DispatchPhase::STARTING));
 }
 
 void BackgroundFetchEventDispatcher::DispatchEvent(
@@ -210,8 +210,8 @@
     scoped_refptr<ServiceWorkerVersion> service_worker_version) {
   int request_id = service_worker_version->StartRequest(
       event,
-      base::Bind(&BackgroundFetchEventDispatcher::DidDispatchEvent, event,
-                 std::move(finished_closure), DispatchPhase::DISPATCHING));
+      base::BindOnce(&BackgroundFetchEventDispatcher::DidDispatchEvent, event,
+                     std::move(finished_closure), DispatchPhase::DISPATCHING));
 
   loaded_callback.Run(std::move(service_worker_version), request_id);
 }
diff --git a/content/browser/background_sync/background_sync_manager.cc b/content/browser/background_sync/background_sync_manager.cc
index 72fbea0..0904549a 100644
--- a/content/browser/background_sync/background_sync_manager.cc
+++ b/content/browser/background_sync/background_sync_manager.cc
@@ -146,11 +146,12 @@
   return parameters;
 }
 
-void OnSyncEventFinished(scoped_refptr<ServiceWorkerVersion> active_version,
-                         int request_id,
-                         const ServiceWorkerVersion::StatusCallback& callback,
-                         ServiceWorkerStatusCode status,
-                         base::Time dispatch_event_time) {
+void OnSyncEventFinished(
+    scoped_refptr<ServiceWorkerVersion> active_version,
+    int request_id,
+    const ServiceWorkerVersion::LegacyStatusCallback& callback,
+    ServiceWorkerStatusCode status,
+    base::Time dispatch_event_time) {
   if (!active_version->FinishRequest(request_id, status == SERVICE_WORKER_OK,
                                      dispatch_event_time)) {
     return;
@@ -263,7 +264,7 @@
     const std::string& tag,
     scoped_refptr<ServiceWorkerVersion> active_version,
     bool last_chance,
-    const ServiceWorkerVersion::StatusCallback& callback) {
+    const ServiceWorkerVersion::LegacyStatusCallback& callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   DispatchSyncEvent(
       tag, std::move(active_version),
@@ -756,7 +757,7 @@
     const std::string& tag,
     scoped_refptr<ServiceWorkerVersion> active_version,
     blink::mojom::BackgroundSyncEventLastChance last_chance,
-    const ServiceWorkerVersion::StatusCallback& callback) {
+    const ServiceWorkerVersion::LegacyStatusCallback& callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   DCHECK(active_version);
 
diff --git a/content/browser/background_sync/background_sync_manager.h b/content/browser/background_sync/background_sync_manager.h
index 0ab44ce..06fc25d 100644
--- a/content/browser/background_sync/background_sync_manager.h
+++ b/content/browser/background_sync/background_sync_manager.h
@@ -105,7 +105,7 @@
       const std::string& tag,
       scoped_refptr<ServiceWorkerVersion> active_version,
       bool last_chance,
-      const ServiceWorkerVersion::StatusCallback& callback);
+      const ServiceWorkerVersion::LegacyStatusCallback& callback);
 
  protected:
   explicit BackgroundSyncManager(
@@ -129,7 +129,7 @@
       const std::string& tag,
       scoped_refptr<ServiceWorkerVersion> active_version,
       blink::mojom::BackgroundSyncEventLastChance last_chance,
-      const ServiceWorkerVersion::StatusCallback& callback);
+      const ServiceWorkerVersion::LegacyStatusCallback& callback);
   virtual void ScheduleDelayedTask(base::OnceClosure callback,
                                    base::TimeDelta delay);
   virtual void HasMainFrameProviderHost(const GURL& origin,
diff --git a/content/browser/background_sync/background_sync_manager_unittest.cc b/content/browser/background_sync/background_sync_manager_unittest.cc
index e63aa5e..c9b9f65 100644
--- a/content/browser/background_sync/background_sync_manager_unittest.cc
+++ b/content/browser/background_sync/background_sync_manager_unittest.cc
@@ -85,7 +85,7 @@
 void DispatchSyncSuccessfulCallback(
     int* count,
     const scoped_refptr<ServiceWorkerVersion>& active_version,
-    const ServiceWorkerVersion::StatusCallback& callback) {
+    const ServiceWorkerVersion::LegacyStatusCallback& callback) {
   *count += 1;
   callback.Run(SERVICE_WORKER_OK);
 }
@@ -93,16 +93,16 @@
 void DispatchSyncFailedCallback(
     int* count,
     const scoped_refptr<ServiceWorkerVersion>& active_version,
-    const ServiceWorkerVersion::StatusCallback& callback) {
+    const ServiceWorkerVersion::LegacyStatusCallback& callback) {
   *count += 1;
   callback.Run(SERVICE_WORKER_ERROR_FAILED);
 }
 
 void DispatchSyncDelayedCallback(
     int* count,
-    ServiceWorkerVersion::StatusCallback* out_callback,
+    ServiceWorkerVersion::LegacyStatusCallback* out_callback,
     const scoped_refptr<ServiceWorkerVersion>& active_version,
-    const ServiceWorkerVersion::StatusCallback& callback) {
+    const ServiceWorkerVersion::LegacyStatusCallback& callback) {
   *count += 1;
   *out_callback = callback;
 }
@@ -447,7 +447,7 @@
       callback_registrations_;
   ServiceWorkerStatusCode callback_sw_status_code_ = SERVICE_WORKER_OK;
   int sync_events_called_ = 0;
-  ServiceWorkerVersion::StatusCallback sync_fired_callback_;
+  ServiceWorkerVersion::LegacyStatusCallback sync_fired_callback_;
 };
 
 TEST_F(BackgroundSyncManagerTest, Register) {
diff --git a/content/browser/browser_plugin/browser_plugin_guest.cc b/content/browser/browser_plugin/browser_plugin_guest.cc
index 8d822a4d..b2bc69be 100644
--- a/content/browser/browser_plugin/browser_plugin_guest.cc
+++ b/content/browser/browser_plugin/browser_plugin_guest.cc
@@ -627,10 +627,7 @@
   bool read_success = iter.ReadBytes(&data, remaining_bytes);
   CHECK(read_success)
       << "Unexpected failure reading remaining IPC::Message payload.";
-  bool write_success = new_msg->WriteBytes(data, remaining_bytes);
-  CHECK(write_success)
-      << "Unexpected failure writing remaining IPC::Message payload.";
-
+  new_msg->WriteBytes(data, remaining_bytes);
   return new_msg;
 }
 
diff --git a/content/browser/devtools/devtools_agent_host_impl.cc b/content/browser/devtools/devtools_agent_host_impl.cc
index 1aa569d..8b45608f 100644
--- a/content/browser/devtools/devtools_agent_host_impl.cc
+++ b/content/browser/devtools/devtools_agent_host_impl.cc
@@ -45,6 +45,7 @@
 const char DevToolsAgentHost::kTypeGuest[] = "webview";
 const char DevToolsAgentHost::kTypeOther[] = "other";
 int DevToolsAgentHostImpl::s_force_creation_count_ = 0;
+int DevToolsAgentHostImpl::s_last_session_id_ = 0;
 
 // static
 std::string DevToolsAgentHost::GetProtocolVersion() {
@@ -116,8 +117,7 @@
       ->GetDevToolsAgentHostForWorker(worker_process_id, worker_route_id);
 }
 
-DevToolsAgentHostImpl::DevToolsAgentHostImpl(const std::string& id)
-    : id_(id), last_session_id_(0) {
+DevToolsAgentHostImpl::DevToolsAgentHostImpl(const std::string& id) : id_(id) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 }
 
@@ -161,7 +161,7 @@
 void DevToolsAgentHostImpl::InnerAttachClient(DevToolsAgentHostClient* client) {
   scoped_refptr<DevToolsAgentHostImpl> protect(this);
   DevToolsSession* session =
-      new DevToolsSession(this, client, ++last_session_id_);
+      new DevToolsSession(this, client, ++s_last_session_id_);
   int session_id = session->session_id();
   sessions_.insert(session);
   session_by_id_[session_id] = session;
diff --git a/content/browser/devtools/devtools_agent_host_impl.h b/content/browser/devtools/devtools_agent_host_impl.h
index a0e6441..9db363b 100644
--- a/content/browser/devtools/devtools_agent_host_impl.h
+++ b/content/browser/devtools/devtools_agent_host_impl.h
@@ -80,13 +80,13 @@
   DevToolsSession* SessionByClient(DevToolsAgentHostClient* client);
 
   const std::string id_;
-  int last_session_id_;
   base::flat_set<DevToolsSession*> sessions_;
   base::flat_map<int, DevToolsSession*> session_by_id_;
   base::flat_map<DevToolsAgentHostClient*, std::unique_ptr<DevToolsSession>>
       session_by_client_;
   DevToolsIOContext io_context_;
   static int s_force_creation_count_;
+  static int s_last_session_id_;
 };
 
 class DevToolsMessageChunkProcessor {
diff --git a/content/browser/devtools/devtools_session.cc b/content/browser/devtools/devtools_session.cc
index 19ff3cd..023d489 100644
--- a/content/browser/devtools/devtools_session.cc
+++ b/content/browser/devtools/devtools_session.cc
@@ -80,12 +80,10 @@
   if (value && value->IsType(base::Value::Type::DICTIONARY) && delegate) {
     base::DictionaryValue* dict_value =
         static_cast<base::DictionaryValue*>(value.get());
-    std::unique_ptr<base::DictionaryValue> response(
-        delegate->HandleCommand(agent_host_, session_id_, dict_value));
-    if (response) {
-      SendResponse(std::move(response));
+
+    if (delegate->HandleCommand(agent_host_, session_id_, dict_value))
       return protocol::Response::kSuccess;
-    }
+
     if (delegate->HandleAsyncCommand(agent_host_, session_id_, dict_value,
                                      base::Bind(&DevToolsSession::SendResponse,
                                                 weak_factory_.GetWeakPtr()))) {
diff --git a/content/browser/frame_host/navigation_entry_impl.cc b/content/browser/frame_host/navigation_entry_impl.cc
index ac6821c..2e1780a 100644
--- a/content/browser/frame_host/navigation_entry_impl.cc
+++ b/content/browser/frame_host/navigation_entry_impl.cc
@@ -311,10 +311,10 @@
     DCHECK(base::StartsWith(data_url->front_as<char>(), url::kDataScheme,
                             base::CompareCase::SENSITIVE));
   }
-  data_url_as_string_ = data_url;
+  data_url_as_string_ = std::move(data_url);
 }
 
-const scoped_refptr<const base::RefCountedString>
+const scoped_refptr<const base::RefCountedString>&
 NavigationEntryImpl::GetDataURLAsString() const {
   return data_url_as_string_;
 }
diff --git a/content/browser/frame_host/navigation_entry_impl.h b/content/browser/frame_host/navigation_entry_impl.h
index b70a51f..6fea23b5 100644
--- a/content/browser/frame_host/navigation_entry_impl.h
+++ b/content/browser/frame_host/navigation_entry_impl.h
@@ -103,7 +103,7 @@
 #if defined(OS_ANDROID)
   void SetDataURLAsString(
       scoped_refptr<base::RefCountedString> data_url) override;
-  const scoped_refptr<const base::RefCountedString> GetDataURLAsString()
+  const scoped_refptr<const base::RefCountedString>& GetDataURLAsString()
       const override;
 #endif
   void SetReferrer(const Referrer& referrer) override;
diff --git a/content/browser/notifications/notification_event_dispatcher_impl.cc b/content/browser/notifications/notification_event_dispatcher_impl.cc
index 67a9d8b..217d3d7 100644
--- a/content/browser/notifications/notification_event_dispatcher_impl.cc
+++ b/content/browser/notifications/notification_event_dispatcher_impl.cc
@@ -208,7 +208,7 @@
     const NotificationDatabaseData& notification_database_data,
     const base::Optional<int>& action_index,
     const base::Optional<base::string16>& reply,
-    const ServiceWorkerVersion::StatusCallback& callback) {
+    const ServiceWorkerVersion::LegacyStatusCallback& callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   int request_id = service_worker->StartRequest(
       ServiceWorkerMetrics::EventType::NOTIFICATION_CLICK, callback);
@@ -231,7 +231,7 @@
     const scoped_refptr<PlatformNotificationContext>& notification_context,
     const ServiceWorkerRegistration* service_worker_registration,
     const NotificationDatabaseData& notification_database_data) {
-  ServiceWorkerVersion::StatusCallback status_callback = base::Bind(
+  ServiceWorkerVersion::LegacyStatusCallback status_callback = base::Bind(
       &ServiceWorkerNotificationEventFinished, dispatch_complete_callback);
   service_worker_registration->active_version()->RunAfterStartWorker(
       ServiceWorkerMetrics::EventType::NOTIFICATION_CLICK,
@@ -280,7 +280,7 @@
 void DispatchNotificationCloseEventOnWorker(
     const scoped_refptr<ServiceWorkerVersion>& service_worker,
     const NotificationDatabaseData& notification_database_data,
-    const ServiceWorkerVersion::StatusCallback& callback) {
+    const ServiceWorkerVersion::LegacyStatusCallback& callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   int request_id = service_worker->StartRequest(
       ServiceWorkerMetrics::EventType::NOTIFICATION_CLOSE, callback);
@@ -300,7 +300,7 @@
     const scoped_refptr<PlatformNotificationContext>& notification_context,
     const ServiceWorkerRegistration* service_worker_registration,
     const NotificationDatabaseData& notification_database_data) {
-  const ServiceWorkerVersion::StatusCallback dispatch_event_callback =
+  const ServiceWorkerVersion::LegacyStatusCallback dispatch_event_callback =
       base::Bind(&DeleteNotificationDataFromDatabase, notification_id,
                  notification_database_data.origin, notification_context,
                  dispatch_complete_callback);
diff --git a/content/browser/payments/payment_app_provider_impl.cc b/content/browser/payments/payment_app_provider_impl.cc
index 7b72610..9f6e027 100644
--- a/content/browser/payments/payment_app_provider_impl.cc
+++ b/content/browser/payments/payment_app_provider_impl.cc
@@ -38,8 +38,8 @@
         binding_(this),
         weak_ptr_factory_(this) {
     request_id_ = service_worker_version->StartRequest(
-        event_type, base::Bind(&RespondWithCallbacks::OnErrorStatus,
-                               weak_ptr_factory_.GetWeakPtr()));
+        event_type, base::BindOnce(&RespondWithCallbacks::OnErrorStatus,
+                                   weak_ptr_factory_.GetWeakPtr()));
   }
 
   RespondWithCallbacks(
@@ -51,8 +51,8 @@
         binding_(this),
         weak_ptr_factory_(this) {
     request_id_ = service_worker_version->StartRequest(
-        event_type, base::Bind(&RespondWithCallbacks::OnErrorStatus,
-                               weak_ptr_factory_.GetWeakPtr()));
+        event_type, base::BindOnce(&RespondWithCallbacks::OnErrorStatus,
+                                   weak_ptr_factory_.GetWeakPtr()));
   }
 
   payments::mojom::PaymentHandlerResponseCallbackPtr
@@ -215,7 +215,7 @@
 
   int event_finish_id = active_version->StartRequest(
       ServiceWorkerMetrics::EventType::CAN_MAKE_PAYMENT,
-      base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
+      base::BindOnce(&ServiceWorkerUtils::NoOpStatusCallback));
 
   // This object self-deletes after either success or error callback is invoked.
   RespondWithCallbacks* invocation_callbacks =
@@ -244,7 +244,7 @@
 
   int event_finish_id = active_version->StartRequest(
       ServiceWorkerMetrics::EventType::CAN_MAKE_PAYMENT,
-      base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
+      base::BindOnce(&ServiceWorkerUtils::NoOpStatusCallback));
 
   // This object self-deletes after either success or error callback is invoked.
   RespondWithCallbacks* invocation_callbacks = new RespondWithCallbacks(
@@ -276,7 +276,7 @@
 
   int event_finish_id = active_version->StartRequest(
       ServiceWorkerMetrics::EventType::PAYMENT_REQUEST,
-      base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
+      base::BindOnce(&ServiceWorkerUtils::NoOpStatusCallback));
 
   // This object self-deletes after either success or error callback is invoked.
   RespondWithCallbacks* invocation_callbacks =
diff --git a/content/browser/push_messaging/push_messaging_router.cc b/content/browser/push_messaging/push_messaging_router.cc
index 39867fc..ca37a7f 100644
--- a/content/browser/push_messaging/push_messaging_router.cc
+++ b/content/browser/push_messaging/push_messaging_router.cc
@@ -107,8 +107,8 @@
       base::BindOnce(&PushMessagingRouter::DeliverMessageToWorker,
                      make_scoped_refptr(version), service_worker_registration,
                      payload, deliver_message_callback),
-      base::Bind(&PushMessagingRouter::DeliverMessageEnd,
-                 deliver_message_callback, service_worker_registration));
+      base::BindOnce(&PushMessagingRouter::DeliverMessageEnd,
+                     deliver_message_callback, service_worker_registration));
 }
 
 // static
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
index 4c3ae74..7bcbc0b 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -2539,6 +2539,7 @@
     switches::kDisableWebGLImageChromium,
     switches::kDomAutomationController,
     switches::kEnableBrowserSideNavigation,
+    switches::kEnableCompositorImageAnimations,
     switches::kEnableDisplayList2dCanvas,
     switches::kEnableDistanceFieldText,
     switches::kEnableExperimentalCanvasFeatures,
diff --git a/content/browser/service_worker/browser_side_controller_service_worker.cc b/content/browser/service_worker/browser_side_controller_service_worker.cc
index 30eaea0e..c603b1f 100644
--- a/content/browser/service_worker/browser_side_controller_service_worker.cc
+++ b/content/browser/service_worker/browser_side_controller_service_worker.cc
@@ -143,11 +143,11 @@
       base::BindOnce(
           &BrowserSideControllerServiceWorker::DispatchFetchEventInternal,
           weak_factory_.GetWeakPtr(), internal_fetch_event_id, request,
-          base::Passed(&response_callback)),
-      base::Bind(
+          std::move(response_callback)),
+      base::BindOnce(
           &BrowserSideControllerServiceWorker::DidFailToStartWorker,
           weak_factory_.GetWeakPtr(),
-          base::Bind(
+          base::BindOnce(
               &BrowserSideControllerServiceWorker::DidFailToDispatchFetch,
               weak_factory_.GetWeakPtr(), internal_fetch_event_id, nullptr)));
 }
@@ -165,14 +165,15 @@
   // TODO(kinuko): No timeout support for now; support timeout.
   int fetch_event_id = receiver_version_->StartRequest(
       ServiceWorkerMetrics::EventType::FETCH_SUB_RESOURCE,
-      base::Bind(&BrowserSideControllerServiceWorker::DidFailToDispatchFetch,
-                 weak_factory_.GetWeakPtr(), internal_fetch_event_id,
-                 base::Passed(&response_callback)));
+      base::BindOnce(
+          &BrowserSideControllerServiceWorker::DidFailToDispatchFetch,
+          weak_factory_.GetWeakPtr(), internal_fetch_event_id,
+          std::move(response_callback)));
   int event_finish_id = receiver_version_->StartRequest(
       ServiceWorkerMetrics::EventType::FETCH_WAITUNTIL,
       // NoOp as the same error callback should be handled by the other
       // StartRequest above.
-      base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
+      base::BindOnce(&ServiceWorkerUtils::NoOpStatusCallback));
 
   response_callback_rawptr->set_fetch_event_id(fetch_event_id);
 
@@ -185,7 +186,7 @@
 }
 
 void BrowserSideControllerServiceWorker::DidFailToStartWorker(
-    const StatusCallback& callback,
+    StatusCallback callback,
     ServiceWorkerStatusCode status) {
   // TODO(kinuko): Should log the failures.
   DCHECK_NE(SERVICE_WORKER_OK, status);
diff --git a/content/browser/service_worker/browser_side_controller_service_worker.h b/content/browser/service_worker/browser_side_controller_service_worker.h
index b7d39444..3215943 100644
--- a/content/browser/service_worker/browser_side_controller_service_worker.h
+++ b/content/browser/service_worker/browser_side_controller_service_worker.h
@@ -40,13 +40,13 @@
 
  private:
   class ResponseCallback;
-  using StatusCallback = base::Callback<void(ServiceWorkerStatusCode)>;
+  using StatusCallback = base::OnceCallback<void(ServiceWorkerStatusCode)>;
 
   void DispatchFetchEventInternal(
       int internal_fetch_event_id,
       const ServiceWorkerFetchRequest& request,
       mojom::ServiceWorkerFetchResponseCallbackPtr response_callback);
-  void DidFailToStartWorker(const StatusCallback& callback,
+  void DidFailToStartWorker(StatusCallback callback,
                             ServiceWorkerStatusCode status);
   void DidFailToDispatchFetch(int internal_fetch_event_id,
                               std::unique_ptr<ResponseCallback> callback,
diff --git a/content/browser/service_worker/embedded_worker_instance.cc b/content/browser/service_worker/embedded_worker_instance.cc
index c7dfe86..01506aa6 100644
--- a/content/browser/service_worker/embedded_worker_instance.cc
+++ b/content/browser/service_worker/embedded_worker_instance.cc
@@ -337,11 +337,11 @@
   }
 
   void Start(std::unique_ptr<EmbeddedWorkerStartParams> params,
-             const StatusCallback& callback) {
+             StatusCallback callback) {
     DCHECK_CURRENTLY_ON(BrowserThread::IO);
     DCHECK(instance_->context_);
     state_ = ProcessAllocationState::ALLOCATING;
-    start_callback_ = callback;
+    start_callback_ = std::move(callback);
     is_installed_ = params->is_installed;
 
     if (!GetContentClient()->browser()->IsBrowserStartupComplete())
@@ -372,9 +372,9 @@
     TRACE_EVENT_NESTABLE_ASYNC_END1("ServiceWorker", "INITIALIZING_ON_RENDERER",
                                     task, "Status",
                                     ServiceWorkerStatusToString(status));
-    StatusCallback callback = task->start_callback_;
+    StatusCallback callback = std::move(task->start_callback_);
     task->start_callback_.Reset();
-    callback.Run(status);
+    std::move(callback).Run(status);
     // |task| may be destroyed.
   }
 
@@ -392,9 +392,9 @@
       TRACE_EVENT_NESTABLE_ASYNC_END1("ServiceWorker", "ALLOCATING_PROCESS",
                                       this, "Error",
                                       ServiceWorkerStatusToString(status));
-      StatusCallback callback = start_callback_;
+      StatusCallback callback = std::move(start_callback_);
       start_callback_.Reset();
-      instance_->OnStartFailed(callback, status);
+      instance_->OnStartFailed(std::move(callback), status);
       // |this| may be destroyed.
       return;
     }
@@ -426,9 +426,9 @@
 
     status = instance_->SendStartWorker(std::move(params));
     if (status != SERVICE_WORKER_OK) {
-      StatusCallback callback = start_callback_;
+      StatusCallback callback = std::move(start_callback_);
       start_callback_.Reset();
-      instance_->OnStartFailed(callback, status);
+      instance_->OnStartFailed(std::move(callback), status);
       // |this| may be destroyed.
     }
     TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("ServiceWorker",
@@ -477,10 +477,10 @@
     ProviderInfoGetter provider_info_getter,
     mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
     mojom::ServiceWorkerInstalledScriptsInfoPtr installed_scripts_info,
-    const StatusCallback& callback) {
+    StatusCallback callback) {
   restart_count_++;
   if (!context_) {
-    callback.Run(SERVICE_WORKER_ERROR_ABORT);
+    std::move(callback).Run(SERVICE_WORKER_ERROR_ABORT);
     // |this| may be destroyed by the callback.
     return;
   }
@@ -512,7 +512,7 @@
 
   inflight_start_task_.reset(
       new StartTask(this, params->script_url, std::move(request)));
-  inflight_start_task_->Start(std::move(params), callback);
+  inflight_start_task_->Start(std::move(params), std::move(callback));
 }
 
 void EmbeddedWorkerInstance::Stop() {
@@ -907,12 +907,12 @@
   thread_id_ = kInvalidEmbeddedWorkerThreadId;
 }
 
-void EmbeddedWorkerInstance::OnStartFailed(const StatusCallback& callback,
+void EmbeddedWorkerInstance::OnStartFailed(StatusCallback callback,
                                            ServiceWorkerStatusCode status) {
   EmbeddedWorkerStatus old_status = status_;
   ReleaseProcess();
   base::WeakPtr<EmbeddedWorkerInstance> weak_this = weak_factory_.GetWeakPtr();
-  callback.Run(status);
+  std::move(callback).Run(status);
   if (weak_this && old_status != EmbeddedWorkerStatus::STOPPED) {
     for (auto& observer : weak_this->listener_list_)
       observer.OnStopped(old_status);
diff --git a/content/browser/service_worker/embedded_worker_instance.h b/content/browser/service_worker/embedded_worker_instance.h
index 4c063323..ab558bd 100644
--- a/content/browser/service_worker/embedded_worker_instance.h
+++ b/content/browser/service_worker/embedded_worker_instance.h
@@ -54,7 +54,7 @@
     : public mojom::EmbeddedWorkerInstanceHost {
  public:
   class DevToolsProxy;
-  typedef base::Callback<void(ServiceWorkerStatusCode)> StatusCallback;
+  using StatusCallback = base::OnceCallback<void(ServiceWorkerStatusCode)>;
 
   // This enum is used in UMA histograms. Append-only.
   enum StartingPhase {
@@ -137,7 +137,7 @@
              ProviderInfoGetter provider_info_getter,
              mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
              mojom::ServiceWorkerInstalledScriptsInfoPtr installed_scripts_info,
-             const StatusCallback& callback);
+             StatusCallback callback);
 
   // Stops the worker. It is invalid to call this when the worker is not in
   // STARTING or RUNNING status.
@@ -291,8 +291,7 @@
 
   // Called back from StartTask when the startup sequence failed. Calls
   // ReleaseProcess() and invokes |callback| with |status|. May destroy |this|.
-  void OnStartFailed(const StatusCallback& callback,
-                     ServiceWorkerStatusCode status);
+  void OnStartFailed(StatusCallback callback, ServiceWorkerStatusCode status);
 
   // Returns the time elapsed since |step_time_| and updates |step_time_|
   // to the current time.
diff --git a/content/browser/service_worker/embedded_worker_instance_unittest.cc b/content/browser/service_worker/embedded_worker_instance_unittest.cc
index 6357e81..75906b8 100644
--- a/content/browser/service_worker/embedded_worker_instance_unittest.cc
+++ b/content/browser/service_worker/embedded_worker_instance_unittest.cc
@@ -37,10 +37,10 @@
 namespace {
 
 void SaveStatusAndCall(ServiceWorkerStatusCode* out,
-                       const base::Closure& callback,
+                       base::OnceClosure callback,
                        ServiceWorkerStatusCode status) {
   *out = status;
-  callback.Run();
+  std::move(callback).Run();
 }
 
 }  // namespace
@@ -151,7 +151,7 @@
     worker->Start(
         std::move(params), CreateProviderInfoGetter(), CreateEventDispatcher(),
         GetInstalledScriptsInfoPtr(),
-        base::Bind(&SaveStatusAndCall, &status, run_loop.QuitClosure()));
+        base::BindOnce(&SaveStatusAndCall, &status, run_loop.QuitClosure()));
     run_loop.Run();
     return status;
   }
@@ -306,7 +306,7 @@
   worker->Start(
       std::move(params), CreateProviderInfoGetter(), CreateEventDispatcher(),
       GetInstalledScriptsInfoPtr(),
-      base::Bind(&SaveStatusAndCall, &status, run_loop.QuitClosure()));
+      base::BindOnce(&SaveStatusAndCall, &status, run_loop.QuitClosure()));
   EXPECT_EQ(EmbeddedWorkerStatus::STARTING, worker->status());
   run_loop.Run();
   EXPECT_EQ(SERVICE_WORKER_OK, status);
@@ -364,7 +364,7 @@
     worker->Start(
         std::move(params), CreateProviderInfoGetter(), CreateEventDispatcher(),
         GetInstalledScriptsInfoPtr(),
-        base::Bind(&SaveStatusAndCall, &status, run_loop.QuitClosure()));
+        base::BindOnce(&SaveStatusAndCall, &status, run_loop.QuitClosure()));
     run_loop.Run();
     EXPECT_EQ(SERVICE_WORKER_OK, status);
     EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, worker->status());
@@ -390,7 +390,7 @@
     worker->Start(
         std::move(params), CreateProviderInfoGetter(), CreateEventDispatcher(),
         GetInstalledScriptsInfoPtr(),
-        base::Bind(&SaveStatusAndCall, &status, run_loop.QuitClosure()));
+        base::BindOnce(&SaveStatusAndCall, &status, run_loop.QuitClosure()));
     EXPECT_EQ(EmbeddedWorkerStatus::STARTING, worker->status());
     run_loop.Run();
     EXPECT_EQ(SERVICE_WORKER_OK, status);
@@ -472,7 +472,7 @@
     worker1->Start(
         std::move(params), CreateProviderInfoGetter(), CreateEventDispatcher(),
         GetInstalledScriptsInfoPtr(),
-        base::Bind(&SaveStatusAndCall, &status, run_loop.QuitClosure()));
+        base::BindOnce(&SaveStatusAndCall, &status, run_loop.QuitClosure()));
     run_loop.Run();
     EXPECT_EQ(SERVICE_WORKER_OK, status);
   }
@@ -486,7 +486,7 @@
     worker2->Start(
         std::move(params), CreateProviderInfoGetter(), CreateEventDispatcher(),
         GetInstalledScriptsInfoPtr(),
-        base::Bind(&SaveStatusAndCall, &status, run_loop.QuitClosure()));
+        base::BindOnce(&SaveStatusAndCall, &status, run_loop.QuitClosure()));
     run_loop.Run();
     EXPECT_EQ(SERVICE_WORKER_OK, status);
   }
@@ -522,10 +522,10 @@
   ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE;
   std::unique_ptr<EmbeddedWorkerStartParams> params =
       CreateStartParams(version_id, scope, url);
-  worker->Start(
-      std::move(params), CreateProviderInfoGetter(), CreateEventDispatcher(),
-      GetInstalledScriptsInfoPtr(),
-      base::Bind(&SaveStatusAndCall, &status, base::Bind(&base::DoNothing)));
+  worker->Start(std::move(params), CreateProviderInfoGetter(),
+                CreateEventDispatcher(), GetInstalledScriptsInfoPtr(),
+                base::BindOnce(&SaveStatusAndCall, &status,
+                               base::BindOnce(&base::DoNothing)));
   worker->Detach();
   base::RunLoop().RunUntilIdle();
 
@@ -556,10 +556,10 @@
   ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE;
   std::unique_ptr<EmbeddedWorkerStartParams> params =
       CreateStartParams(version_id, scope, url);
-  worker->Start(
-      std::move(params), CreateProviderInfoGetter(), CreateEventDispatcher(),
-      GetInstalledScriptsInfoPtr(),
-      base::Bind(&SaveStatusAndCall, &status, base::Bind(&base::DoNothing)));
+  worker->Start(std::move(params), CreateProviderInfoGetter(),
+                CreateEventDispatcher(), GetInstalledScriptsInfoPtr(),
+                base::BindOnce(&SaveStatusAndCall, &status,
+                               base::BindOnce(&base::DoNothing)));
   base::RunLoop().RunUntilIdle();
 
   ASSERT_EQ(2u, events_.size());
@@ -597,10 +597,10 @@
 
   std::unique_ptr<EmbeddedWorkerStartParams> params =
       CreateStartParams(version_id, scope, url);
-  worker->Start(
-      std::move(params), CreateProviderInfoGetter(), CreateEventDispatcher(),
-      GetInstalledScriptsInfoPtr(),
-      base::Bind(&SaveStatusAndCall, &status, base::Bind(&base::DoNothing)));
+  worker->Start(std::move(params), CreateProviderInfoGetter(),
+                CreateEventDispatcher(), GetInstalledScriptsInfoPtr(),
+                base::BindOnce(&SaveStatusAndCall, &status,
+                               base::BindOnce(&base::DoNothing)));
   worker->Stop();
   base::RunLoop().RunUntilIdle();
 
@@ -624,7 +624,7 @@
   worker->Start(
       std::move(params), CreateProviderInfoGetter(), CreateEventDispatcher(),
       GetInstalledScriptsInfoPtr(),
-      base::Bind(&SaveStatusAndCall, &status, run_loop->QuitClosure()));
+      base::BindOnce(&SaveStatusAndCall, &status, run_loop->QuitClosure()));
   run_loop->Run();
 
   EXPECT_EQ(SERVICE_WORKER_OK, status);
@@ -674,10 +674,10 @@
   std::unique_ptr<EmbeddedWorkerStartParams> params =
       CreateStartParams(version_id, scope, url);
   params->pause_after_download = true;
-  worker->Start(
-      std::move(params), CreateProviderInfoGetter(), CreateEventDispatcher(),
-      GetInstalledScriptsInfoPtr(),
-      base::Bind(&SaveStatusAndCall, &status, base::Bind(&base::DoNothing)));
+  worker->Start(std::move(params), CreateProviderInfoGetter(),
+                CreateEventDispatcher(), GetInstalledScriptsInfoPtr(),
+                base::BindOnce(&SaveStatusAndCall, &status,
+                               base::BindOnce(&base::DoNothing)));
   base::RunLoop().RunUntilIdle();
 
   // Make the worker stopping and attempt to send a resume after download
@@ -705,10 +705,10 @@
   ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE;
   std::unique_ptr<EmbeddedWorkerStartParams> params =
       CreateStartParams(version_id, scope, url);
-  worker->Start(
-      std::move(params), CreateProviderInfoGetter(), CreateEventDispatcher(),
-      GetInstalledScriptsInfoPtr(),
-      base::Bind(&SaveStatusAndCall, &status, base::Bind(&base::DoNothing)));
+  worker->Start(std::move(params), CreateProviderInfoGetter(),
+                CreateEventDispatcher(), GetInstalledScriptsInfoPtr(),
+                base::BindOnce(&SaveStatusAndCall, &status,
+                               base::BindOnce(&base::DoNothing)));
   base::RunLoop().RunUntilIdle();
 
   ASSERT_EQ(2u, events_.size());
@@ -742,7 +742,7 @@
   worker->Start(
       std::move(params), CreateProviderInfoGetter(), CreateEventDispatcher(),
       GetInstalledScriptsInfoPtr(),
-      base::Bind(&SaveStatusAndCall, &status, run_loop->QuitClosure()));
+      base::BindOnce(&SaveStatusAndCall, &status, run_loop->QuitClosure()));
   run_loop->Run();
 
   // The worker should be started.
@@ -774,7 +774,7 @@
   worker->Start(
       std::move(params), CreateProviderInfoGetter(), CreateEventDispatcher(),
       GetInstalledScriptsInfoPtr(),
-      base::Bind(&SaveStatusAndCall, &status, run_loop.QuitClosure()));
+      base::BindOnce(&SaveStatusAndCall, &status, run_loop.QuitClosure()));
   run_loop.Run();
 
   // Detach.
@@ -809,7 +809,7 @@
       CreateStartParams(version_id, pattern, url);
   worker->Start(std::move(params), CreateProviderInfoGetter(),
                 CreateEventDispatcher(), GetInstalledScriptsInfoPtr(),
-                base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
+                base::BindOnce(&ServiceWorkerUtils::NoOpStatusCallback));
   base::RunLoop().RunUntilIdle();
 
   // Worker should handle the failure of binding on the remote side as detach.
@@ -862,7 +862,7 @@
       CreateStartParams(version_id, pattern, url);
   worker->Start(std::move(params), CreateProviderInfoGetter(),
                 CreateEventDispatcher(), GetInstalledScriptsInfoPtr(),
-                base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
+                base::BindOnce(&ServiceWorkerUtils::NoOpStatusCallback));
   base::RunLoop().RunUntilIdle();
 
   // Worker should handle the sudden shutdown as detach.
@@ -919,7 +919,7 @@
       CreateStartParams(version_id, pattern, url);
   worker->Start(std::move(params), CreateProviderInfoGetter(),
                 CreateEventDispatcher(), GetInstalledScriptsInfoPtr(),
-                base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
+                base::BindOnce(&ServiceWorkerUtils::NoOpStatusCallback));
   worker->AddMessageToConsole(test_message.first, test_message.second);
   base::RunLoop().RunUntilIdle();
 
diff --git a/content/browser/service_worker/foreign_fetch_request_handler_unittest.cc b/content/browser/service_worker/foreign_fetch_request_handler_unittest.cc
index 7f55a3c..7d1f246 100644
--- a/content/browser/service_worker/foreign_fetch_request_handler_unittest.cc
+++ b/content/browser/service_worker/foreign_fetch_request_handler_unittest.cc
@@ -382,11 +382,11 @@
 
   // Make sure worker has a non-zero timeout.
   version->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
-                       base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
+                       base::BindOnce(&ServiceWorkerUtils::NoOpStatusCallback));
   base::RunLoop().RunUntilIdle();
   version->StartRequestWithCustomTimeout(
       ServiceWorkerMetrics::EventType::ACTIVATE,
-      base::Bind(&ServiceWorkerUtils::NoOpStatusCallback),
+      base::BindOnce(&ServiceWorkerUtils::NoOpStatusCallback),
       base::TimeDelta::FromSeconds(10), ServiceWorkerVersion::KILL_ON_TIMEOUT);
 
   // Advance clock by a couple seconds.
diff --git a/content/browser/service_worker/service_worker_cache_writer.cc b/content/browser/service_worker/service_worker_cache_writer.cc
index 288e43d..a45dfed 100644
--- a/content/browser/service_worker/service_worker_cache_writer.cc
+++ b/content/browser/service_worker/service_worker_cache_writer.cc
@@ -131,11 +131,11 @@
 
 net::Error ServiceWorkerCacheWriter::MaybeWriteHeaders(
     HttpResponseInfoIOBuffer* headers,
-    const OnWriteCompleteCallback& callback) {
+    OnWriteCompleteCallback callback) {
   DCHECK(!io_pending_);
 
   headers_to_write_ = headers;
-  pending_callback_ = callback;
+  pending_callback_ = std::move(callback);
   DCHECK_EQ(state_, STATE_START);
   int result = DoLoop(net::OK);
 
@@ -159,12 +159,12 @@
 net::Error ServiceWorkerCacheWriter::MaybeWriteData(
     net::IOBuffer* buf,
     size_t buf_size,
-    const OnWriteCompleteCallback& callback) {
+    OnWriteCompleteCallback callback) {
   DCHECK(!io_pending_);
 
   data_to_write_ = buf;
   len_to_write_ = buf_size;
-  pending_callback_ = callback;
+  pending_callback_ = std::move(callback);
 
   if (comparing_)
     state_ = STATE_READ_DATA_FOR_COMPARE;
@@ -493,11 +493,11 @@
   // If the result is ERR_IO_PENDING, the pending callback will be run by a
   // later invocation of AsyncDoLoop.
   if (result != net::ERR_IO_PENDING) {
-    OnWriteCompleteCallback callback = pending_callback_;
+    OnWriteCompleteCallback callback = std::move(pending_callback_);
     pending_callback_.Reset();
     net::Error error = result >= 0 ? net::OK : static_cast<net::Error>(result);
     io_pending_ = false;
-    callback.Run(error);
+    std::move(callback).Run(error);
   }
 }
 
diff --git a/content/browser/service_worker/service_worker_cache_writer.h b/content/browser/service_worker/service_worker_cache_writer.h
index 0e3bd70..2f06d2c 100644
--- a/content/browser/service_worker/service_worker_cache_writer.h
+++ b/content/browser/service_worker/service_worker_cache_writer.h
@@ -37,7 +37,7 @@
 // for comments about this.
 class CONTENT_EXPORT ServiceWorkerCacheWriter {
  public:
-  using OnWriteCompleteCallback = base::Callback<void(net::Error)>;
+  using OnWriteCompleteCallback = base::OnceCallback<void(net::Error)>;
 
   // The |compare_reader| may be null, in which case this instance will
   // unconditionally write back data supplied to |MaybeWriteHeaders| and
@@ -57,7 +57,7 @@
   // equivalent to the existing cached data. See the source of this function for
   // details about how this function drives the state machine.
   net::Error MaybeWriteHeaders(HttpResponseInfoIOBuffer* headers,
-                               const OnWriteCompleteCallback& callback);
+                               OnWriteCompleteCallback callback);
 
   // Writes the supplied body data |data| back to the cache. Returns
   // ERR_IO_PENDING if the write will complete asynchronously, in which case
@@ -68,7 +68,7 @@
   // function for details about how this function drives the state machine.
   net::Error MaybeWriteData(net::IOBuffer* buf,
                             size_t buf_size,
-                            const OnWriteCompleteCallback& callback);
+                            OnWriteCompleteCallback callback);
 
   // Returns a count of bytes written back to the cache.
   size_t bytes_written() const { return bytes_written_; }
diff --git a/content/browser/service_worker/service_worker_cache_writer_unittest.cc b/content/browser/service_worker/service_worker_cache_writer_unittest.cc
index b15e819..c0a62ea 100644
--- a/content/browser/service_worker/service_worker_cache_writer_unittest.cc
+++ b/content/browser/service_worker/service_worker_cache_writer_unittest.cc
@@ -375,8 +375,8 @@
   }
 
   ServiceWorkerCacheWriter::OnWriteCompleteCallback CreateWriteCallback() {
-    return base::Bind(&ServiceWorkerCacheWriterTest::OnWriteComplete,
-                      base::Unretained(this));
+    return base::BindOnce(&ServiceWorkerCacheWriterTest::OnWriteComplete,
+                          base::Unretained(this));
   }
 
   void OnWriteComplete(net::Error error) {
diff --git a/content/browser/service_worker/service_worker_context_wrapper.cc b/content/browser/service_worker/service_worker_context_wrapper.cc
index e338eb6..573911f 100644
--- a/content/browser/service_worker/service_worker_context_wrapper.cc
+++ b/content/browser/service_worker/service_worker_context_wrapper.cc
@@ -65,7 +65,7 @@
     // |registration| is 1, it will be deleted after WorkerStarted is called.
     registration->active_version()->StartWorker(
         ServiceWorkerMetrics::EventType::UNKNOWN,
-        base::Bind(WorkerStarted, callback));
+        base::BindOnce(WorkerStarted, callback));
     return;
   }
   BrowserThread::PostTask(
@@ -113,7 +113,7 @@
         ServiceWorkerMetrics::EventType::EXTERNAL_REQUEST,
         base::BindOnce(&DidStartWorker, active_version,
                        std::move(info_callback)),
-        base::Bind(&DidFailStartWorker, base::Passed(&failure_callback)));
+        base::BindOnce(&DidFailStartWorker, std::move(failure_callback)));
   } else {
     std::move(failure_callback).Run();
   }
@@ -1012,7 +1012,7 @@
 
   registration->active_version()->StartWorker(
       ServiceWorkerMetrics::EventType::NAVIGATION_HINT,
-      base::Bind(
+      base::BindOnce(
           &ServiceWorkerContextWrapper::DidStartServiceWorkerForNavigationHint,
           this, registration->pattern(), base::Passed(std::move(callback))));
 }
diff --git a/content/browser/service_worker/service_worker_dispatcher_host.cc b/content/browser/service_worker/service_worker_dispatcher_host.cc
index ac94460..261ac251 100644
--- a/content/browser/service_worker/service_worker_dispatcher_host.cc
+++ b/content/browser/service_worker/service_worker_dispatcher_host.cc
@@ -790,7 +790,7 @@
                      this, worker, message, source_origin, sent_message_ports,
                      ExtendableMessageEventSource(source_info), timeout,
                      callback),
-      base::Bind(
+      base::BindOnce(
           &ServiceWorkerDispatcherHost::DidFailToDispatchExtendableMessageEvent<
               SourceInfo>,
           this, sent_message_ports, source_info, callback));
diff --git a/content/browser/service_worker/service_worker_fetch_dispatcher.cc b/content/browser/service_worker/service_worker_fetch_dispatcher.cc
index 3046220b..764b213 100644
--- a/content/browser/service_worker/service_worker_fetch_dispatcher.cc
+++ b/content/browser/service_worker/service_worker_fetch_dispatcher.cc
@@ -484,8 +484,8 @@
       GetEventType(),
       base::BindOnce(&ServiceWorkerFetchDispatcher::DidStartWorker,
                      weak_factory_.GetWeakPtr()),
-      base::Bind(&ServiceWorkerFetchDispatcher::DidFailToStartWorker,
-                 weak_factory_.GetWeakPtr()));
+      base::BindOnce(&ServiceWorkerFetchDispatcher::DidFailToStartWorker,
+                     weak_factory_.GetWeakPtr()));
 }
 
 void ServiceWorkerFetchDispatcher::DidStartWorker() {
@@ -519,23 +519,23 @@
   if (timeout_) {
     fetch_event_id = version_->StartRequestWithCustomTimeout(
         GetEventType(),
-        base::Bind(&ServiceWorkerFetchDispatcher::DidFailToDispatch,
-                   weak_factory_.GetWeakPtr(),
-                   base::Passed(&response_callback)),
+        base::BindOnce(&ServiceWorkerFetchDispatcher::DidFailToDispatch,
+                       weak_factory_.GetWeakPtr(),
+                       std::move(response_callback)),
         *timeout_, ServiceWorkerVersion::CONTINUE_ON_TIMEOUT);
     event_finish_id = version_->StartRequestWithCustomTimeout(
         FetchTypeToWaitUntilEventType(request_->fetch_type),
-        base::Bind(&ServiceWorkerUtils::NoOpStatusCallback), *timeout_,
+        base::BindOnce(&ServiceWorkerUtils::NoOpStatusCallback), *timeout_,
         ServiceWorkerVersion::CONTINUE_ON_TIMEOUT);
   } else {
     fetch_event_id = version_->StartRequest(
         GetEventType(),
-        base::Bind(&ServiceWorkerFetchDispatcher::DidFailToDispatch,
-                   weak_factory_.GetWeakPtr(),
-                   base::Passed(&response_callback)));
+        base::BindOnce(&ServiceWorkerFetchDispatcher::DidFailToDispatch,
+                       weak_factory_.GetWeakPtr(),
+                       std::move(response_callback)));
     event_finish_id = version_->StartRequest(
         FetchTypeToWaitUntilEventType(request_->fetch_type),
-        base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
+        base::BindOnce(&ServiceWorkerUtils::NoOpStatusCallback));
   }
 
   response_callback_rawptr->set_fetch_event_id(fetch_event_id);
diff --git a/content/browser/service_worker/service_worker_internals_ui.cc b/content/browser/service_worker/service_worker_internals_ui.cc
index 9c03f37b..77da353 100644
--- a/content/browser/service_worker/service_worker_internals_ui.cc
+++ b/content/browser/service_worker/service_worker_internals_ui.cc
@@ -492,9 +492,9 @@
     return;
   }
 
-  base::Callback<void(ServiceWorkerStatusCode)> callback =
+  base::OnceCallback<void(ServiceWorkerStatusCode)> callback =
       base::Bind(OperationCompleteCallback, AsWeakPtr(), callback_id);
-  StopWorkerWithId(context, version_id, callback);
+  StopWorkerWithId(context, version_id, std::move(callback));
 }
 
 void ServiceWorkerInternalsUI::InspectWorker(const ListValue* args) {
@@ -566,47 +566,50 @@
 void ServiceWorkerInternalsUI::StopWorkerWithId(
     scoped_refptr<ServiceWorkerContextWrapper> context,
     int64_t version_id,
-    const StatusCallback& callback) {
+    StatusCallback callback) {
   if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
     BrowserThread::PostTask(
         BrowserThread::IO, FROM_HERE,
         base::BindOnce(&ServiceWorkerInternalsUI::StopWorkerWithId,
-                       base::Unretained(this), context, version_id, callback));
+                       base::Unretained(this), context, version_id,
+                       std::move(callback)));
     return;
   }
 
   scoped_refptr<ServiceWorkerVersion> version =
       context->GetLiveVersion(version_id);
   if (!version.get()) {
-    callback.Run(SERVICE_WORKER_ERROR_NOT_FOUND);
+    std::move(callback).Run(SERVICE_WORKER_ERROR_NOT_FOUND);
     return;
   }
 
   // ServiceWorkerVersion::StopWorker() takes a base::OnceClosure for argument,
   // so bind SERVICE_WORKER_OK to callback here.
-  version->StopWorker(base::BindOnce(callback, SERVICE_WORKER_OK));
+  version->StopWorker(base::BindOnce(std::move(callback), SERVICE_WORKER_OK));
 }
 
 void ServiceWorkerInternalsUI::UnregisterWithScope(
     scoped_refptr<ServiceWorkerContextWrapper> context,
     const GURL& scope,
-    const ServiceWorkerInternalsUI::StatusCallback& callback) const {
+    ServiceWorkerInternalsUI::StatusCallback callback) const {
   if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
     BrowserThread::PostTask(
         BrowserThread::IO, FROM_HERE,
         base::BindOnce(&ServiceWorkerInternalsUI::UnregisterWithScope,
-                       base::Unretained(this), context, scope, callback));
+                       base::Unretained(this), context, scope,
+                       std::move(callback)));
     return;
   }
 
   if (!context->context()) {
-    callback.Run(SERVICE_WORKER_ERROR_ABORT);
+    std::move(callback).Run(SERVICE_WORKER_ERROR_ABORT);
     return;
   }
 
   // ServiceWorkerContextWrapper::UnregisterServiceWorker doesn't work here
   // because that reduces a status code to boolean.
-  context->context()->UnregisterServiceWorker(scope, callback);
+  context->context()->UnregisterServiceWorker(
+      scope, base::AdaptCallbackForRepeating(std::move(callback)));
 }
 
 }  // namespace content
diff --git a/content/browser/service_worker/service_worker_internals_ui.h b/content/browser/service_worker/service_worker_internals_ui.h
index 5ecb7c1..b9237da 100644
--- a/content/browser/service_worker/service_worker_internals_ui.h
+++ b/content/browser/service_worker/service_worker_internals_ui.h
@@ -28,7 +28,7 @@
     : public WebUIController,
       public base::SupportsWeakPtr<ServiceWorkerInternalsUI> {
  public:
-  typedef base::Callback<void(ServiceWorkerStatusCode)> StatusCallback;
+  using StatusCallback = base::OnceCallback<void(ServiceWorkerStatusCode)>;
 
   explicit ServiceWorkerInternalsUI(WebUI* web_ui);
 
@@ -59,10 +59,10 @@
 
   void StopWorkerWithId(scoped_refptr<ServiceWorkerContextWrapper> context,
                         int64_t version_id,
-                        const StatusCallback& callback);
+                        StatusCallback callback);
   void UnregisterWithScope(scoped_refptr<ServiceWorkerContextWrapper> context,
                            const GURL& scope,
-                           const StatusCallback& callback) const;
+                           StatusCallback callback) const;
 
   std::unordered_map<uintptr_t, std::unique_ptr<PartitionObserver>> observers_;
   int next_partition_id_;
diff --git a/content/browser/service_worker/service_worker_register_job.cc b/content/browser/service_worker/service_worker_register_job.cc
index 2acd824..2ff5ac4c 100644
--- a/content/browser/service_worker/service_worker_register_job.cc
+++ b/content/browser/service_worker/service_worker_register_job.cc
@@ -445,8 +445,8 @@
       ServiceWorkerMetrics::EventType::INSTALL,
       base::BindOnce(&ServiceWorkerRegisterJob::DispatchInstallEvent,
                      weak_factory_.GetWeakPtr()),
-      base::Bind(&ServiceWorkerRegisterJob::OnInstallFailed,
-                 weak_factory_.GetWeakPtr()));
+      base::BindOnce(&ServiceWorkerRegisterJob::OnInstallFailed,
+                     weak_factory_.GetWeakPtr()));
 
   // A subsequent registration job may terminate our installing worker. It can
   // only do so after we've started the worker and dispatched the install
diff --git a/content/browser/service_worker/service_worker_registration.cc b/content/browser/service_worker/service_worker_registration.cc
index 1774f422..e7a8b36 100644
--- a/content/browser/service_worker/service_worker_registration.cc
+++ b/content/browser/service_worker/service_worker_registration.cc
@@ -397,8 +397,8 @@
       ServiceWorkerMetrics::EventType::ACTIVATE,
       base::BindOnce(&ServiceWorkerRegistration::DispatchActivateEvent, this,
                      activating_version),
-      base::Bind(&ServiceWorkerRegistration::OnActivateEventFinished, this,
-                 activating_version));
+      base::BindOnce(&ServiceWorkerRegistration::OnActivateEventFinished, this,
+                     activating_version));
 }
 
 void ServiceWorkerRegistration::DeleteVersion(
diff --git a/content/browser/service_worker/service_worker_script_url_loader.cc b/content/browser/service_worker/service_worker_script_url_loader.cc
index 1f79a03..5a2a4eb 100644
--- a/content/browser/service_worker/service_worker_script_url_loader.cc
+++ b/content/browser/service_worker/service_worker_script_url_loader.cc
@@ -5,6 +5,7 @@
 #include "content/browser/service_worker/service_worker_script_url_loader.h"
 
 #include <memory>
+#include "base/numerics/safe_conversions.h"
 #include "content/browser/appcache/appcache_response.h"
 #include "content/browser/service_worker/service_worker_cache_writer.h"
 #include "content/browser/service_worker/service_worker_context_core.h"
@@ -21,7 +22,7 @@
 
 // Buffer size for reading script data from network. We chose this size because
 // the AppCache uses this.
-const size_t kReadBufferSize = 32768;
+const uint32_t kReadBufferSize = 32768;
 
 }  // namespace
 
@@ -296,10 +297,13 @@
 void ServiceWorkerScriptURLLoader::OnNetworkDataAvailable(MojoResult) {
   DCHECK(network_consumer_.is_valid());
   scoped_refptr<network::MojoToNetPendingBuffer> pending_buffer;
-  uint32_t available = 0;
+  uint32_t bytes_available = 0;
   MojoResult result = network::MojoToNetPendingBuffer::BeginRead(
-      &network_consumer_, &pending_buffer, &available);
+      &network_consumer_, &pending_buffer, &bytes_available);
   switch (result) {
+    case MOJO_RESULT_OK:
+      WriteData(std::move(pending_buffer), bytes_available);
+      return;
     case MOJO_RESULT_FAILED_PRECONDITION:
       // Closed by peer. This indicates all the data from the network service
       // are read or there is an error. In the error case, the reason is
@@ -311,60 +315,58 @@
     case MOJO_RESULT_SHOULD_WAIT:
       network_watcher_.ArmOrNotify();
       return;
-    case MOJO_RESULT_OK:
-      break;
-    default:
-      // TODO(nhiroki): Currently we handle a few limited cases. Audit other
-      // cases.
-      NOTREACHED() << static_cast<int>(result);
-      return;
   }
-
-  // Read the received data to |buffer|.
-  size_t bytes_to_be_read = std::min<size_t>(kReadBufferSize, available);
-  auto buffer = base::MakeRefCounted<network::MojoToNetIOBuffer>(
-      pending_buffer.get(), bytes_to_be_read);
-
-  WriteData(std::move(buffer), bytes_to_be_read, std::move(pending_buffer));
+  NOTREACHED() << static_cast<int>(result);
 }
 
 void ServiceWorkerScriptURLLoader::WriteData(
-    scoped_refptr<net::IOBuffer> buffer,
-    size_t available_bytes,
-    scoped_refptr<network::MojoToNetPendingBuffer> pending_buffer) {
-  uint32_t bytes_written = available_bytes;
+    scoped_refptr<network::MojoToNetPendingBuffer> pending_buffer,
+    uint32_t bytes_available) {
+  // Cap the buffer size up to |kReadBufferSize|. The remaining will be written
+  // next time.
+  uint32_t bytes_written = std::min<uint32_t>(kReadBufferSize, bytes_available);
+
+  auto buffer = base::MakeRefCounted<network::MojoToNetIOBuffer>(
+      pending_buffer.get(), bytes_written);
   MojoResult result = client_producer_->WriteData(
-      buffer->data(), &bytes_written, MOJO_WRITE_DATA_FLAG_ALL_OR_NONE);
+      buffer->data(), &bytes_written, MOJO_WRITE_DATA_FLAG_NONE);
   switch (result) {
+    case MOJO_RESULT_OK:
+      break;
     case MOJO_RESULT_FAILED_PRECONDITION:
       CommitCompleted(ResourceRequestCompletionStatus(net::ERR_FAILED));
       return;
-    case MOJO_RESULT_OK:
-      break;
+    case MOJO_RESULT_SHOULD_WAIT:
+      // No data was written to |client_producer_| because the pipe was full.
+      // Retry when the pipe becomes ready again.
+      pending_buffer->CompleteRead(0);
+      network_consumer_ = pending_buffer->ReleaseHandle();
+      network_watcher_.ArmOrNotify();
+      return;
     default:
-      // TODO(nhiroki): Currently we handle a few limited cases. Audit other
-      // cases.
       NOTREACHED() << static_cast<int>(result);
       return;
   }
 
+  // Write the buffer in the service worker script storage up to the size we
+  // successfully wrote to the data pipe (i.e., |bytes_written|).
   net::Error error = cache_writer_->MaybeWriteData(
-      buffer.get(), bytes_written,
+      buffer.get(), base::strict_cast<size_t>(bytes_written),
       base::Bind(&ServiceWorkerScriptURLLoader::OnWriteDataComplete,
-                 weak_factory_.GetWeakPtr(), bytes_written,
-                 make_scoped_refptr(pending_buffer.get())));
+                 weak_factory_.GetWeakPtr(),
+                 make_scoped_refptr(pending_buffer.get()), bytes_written));
   if (error == net::ERR_IO_PENDING) {
     // OnWriteDataComplete() will be called asynchronously.
     return;
   }
   // MaybeWriteData() doesn't run the callback if it finishes synchronously, so
   // explicitly call it here.
-  OnWriteDataComplete(available_bytes, std::move(pending_buffer), error);
+  OnWriteDataComplete(std::move(pending_buffer), bytes_written, error);
 }
 
 void ServiceWorkerScriptURLLoader::OnWriteDataComplete(
-    size_t bytes_written,
     scoped_refptr<network::MojoToNetPendingBuffer> pending_buffer,
+    uint32_t bytes_written,
     net::Error error) {
   DCHECK_NE(net::ERR_IO_PENDING, error);
   if (error != net::OK) {
@@ -375,7 +377,6 @@
   pending_buffer->CompleteRead(bytes_written);
   // Get the consumer handle from a previous read operation if we have one.
   network_consumer_ = pending_buffer->ReleaseHandle();
-  pending_buffer = nullptr;
   network_watcher_.ArmOrNotify();
 }
 
diff --git a/content/browser/service_worker/service_worker_script_url_loader.h b/content/browser/service_worker/service_worker_script_url_loader.h
index 3892c11..5a9f9a9 100644
--- a/content/browser/service_worker/service_worker_script_url_loader.h
+++ b/content/browser/service_worker/service_worker_script_url_loader.h
@@ -105,12 +105,11 @@
   void OnNetworkDataAvailable(MojoResult);
 
   // Writes the given data into the service worker script storage.
-  void WriteData(scoped_refptr<net::IOBuffer> buffer,
-                 size_t available_bytes,
-                 scoped_refptr<network::MojoToNetPendingBuffer> pending_buffer);
+  void WriteData(scoped_refptr<network::MojoToNetPendingBuffer> pending_buffer,
+                 uint32_t bytes_available);
   void OnWriteDataComplete(
-      size_t bytes_written,
       scoped_refptr<network::MojoToNetPendingBuffer> pending_buffer,
+      uint32_t bytes_written,
       net::Error error);
 
   // This is the last method that is called on this class. Notifies the final
diff --git a/content/browser/service_worker/service_worker_url_loader_job_unittest.cc b/content/browser/service_worker/service_worker_url_loader_job_unittest.cc
index 8ecaed4..8ce80cc6 100644
--- a/content/browser/service_worker/service_worker_url_loader_job_unittest.cc
+++ b/content/browser/service_worker/service_worker_url_loader_job_unittest.cc
@@ -398,11 +398,6 @@
   head->url_list_via_service_worker = std::vector<GURL>();
   head->response_type_via_service_worker =
       network::mojom::FetchResponseType::kDefault;
-  // TODO(falken): start and ready time should be set, and we'll need
-  // a different way of comparing expectation to actual since we don't know
-  // the actual time.
-  head->service_worker_start_time = base::TimeTicks();
-  head->service_worker_ready_time = base::TimeTicks();
   head->is_in_cache_storage = false;
   head->cache_storage_cache_name = std::string();
   head->did_service_worker_navigation_preload = false;
diff --git a/content/browser/service_worker/service_worker_url_request_job_unittest.cc b/content/browser/service_worker/service_worker_url_request_job_unittest.cc
index f784fcf0..cbd0ca08 100644
--- a/content/browser/service_worker/service_worker_url_request_job_unittest.cc
+++ b/content/browser/service_worker/service_worker_url_request_job_unittest.cc
@@ -552,7 +552,7 @@
   ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE;
   base::HistogramTester histogram_tester;
   version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
-                        base::Bind(&SaveStatusCallback, &status));
+                        base::BindOnce(&SaveStatusCallback, &status));
   base::RunLoop().RunUntilIdle();
   helper->CompleteStartWorker();
   base::RunLoop().RunUntilIdle();
diff --git a/content/browser/service_worker/service_worker_version.cc b/content/browser/service_worker/service_worker_version.cc
index 254b883..7ed8796 100644
--- a/content/browser/service_worker/service_worker_version.cc
+++ b/content/browser/service_worker/service_worker_version.cc
@@ -92,25 +92,18 @@
                   const Arg& arg) {
   CallbackArray callbacks;
   callbacks.swap(*callbacks_ptr);
-  for (const auto& callback : callbacks)
-    callback.Run(arg);
-}
-
-void RunStartWorkerCallback(
-    const StatusCallback& callback,
-    scoped_refptr<ServiceWorkerRegistration> protect,
-    ServiceWorkerStatusCode status) {
-  callback.Run(status);
+  for (auto& callback : callbacks)
+    std::move(callback).Run(arg);
 }
 
 // A callback adapter to start a |task| after StartWorker.
 void RunTaskAfterStartWorker(base::WeakPtr<ServiceWorkerVersion> version,
-                             const StatusCallback& error_callback,
+                             StatusCallback error_callback,
                              base::OnceClosure task,
                              ServiceWorkerStatusCode status) {
   if (status != SERVICE_WORKER_OK) {
     if (!error_callback.is_null())
-      error_callback.Run(status);
+      std::move(error_callback).Run(status);
     return;
   }
   if (version->running_status() != EmbeddedWorkerStatus::RUNNING) {
@@ -118,7 +111,7 @@
     // it looks it's not running yet.
     NOTREACHED() << "The worker's not running after successful StartWorker";
     if (!error_callback.is_null())
-      error_callback.Run(SERVICE_WORKER_ERROR_START_WORKER_FAILED);
+      std::move(error_callback).Run(SERVICE_WORKER_ERROR_START_WORKER_FAILED);
     return;
   }
   std::move(task).Run();
@@ -312,9 +305,9 @@
   // user closed the tab before the SW could start up.
   if (!start_callbacks_.empty()) {
     // RecordStartWorkerResult must be the first element of start_callbacks_.
-    StatusCallback record_start_worker_result = start_callbacks_[0];
+    StatusCallback record_start_worker_result = std::move(start_callbacks_[0]);
     start_callbacks_.clear();
-    record_start_worker_result.Run(SERVICE_WORKER_ERROR_ABORT);
+    std::move(record_start_worker_result).Run(SERVICE_WORKER_ERROR_ABORT);
   }
 
   if (context_)
@@ -443,7 +436,7 @@
 }
 
 void ServiceWorkerVersion::StartWorker(ServiceWorkerMetrics::EventType purpose,
-                                       const StatusCallback& callback) {
+                                       StatusCallback callback) {
   TRACE_EVENT_INSTANT2(
       "ServiceWorker", "ServiceWorkerVersion::StartWorker (instant)",
       TRACE_EVENT_SCOPE_THREAD, "Script", script_url_.spec(), "Purpose",
@@ -456,14 +449,15 @@
     RecordStartWorkerResult(purpose, status_, kInvalidTraceId,
                             is_browser_startup_complete,
                             SERVICE_WORKER_ERROR_ABORT);
-    RunSoon(base::BindOnce(callback, SERVICE_WORKER_ERROR_ABORT));
+    RunSoon(base::BindOnce(std::move(callback), SERVICE_WORKER_ERROR_ABORT));
     return;
   }
   if (is_redundant()) {
     RecordStartWorkerResult(purpose, status_, kInvalidTraceId,
                             is_browser_startup_complete,
                             SERVICE_WORKER_ERROR_REDUNDANT);
-    RunSoon(base::BindOnce(callback, SERVICE_WORKER_ERROR_REDUNDANT));
+    RunSoon(
+        base::BindOnce(std::move(callback), SERVICE_WORKER_ERROR_REDUNDANT));
     return;
   }
 
@@ -478,7 +472,8 @@
     RecordStartWorkerResult(purpose, status_, kInvalidTraceId,
                             is_browser_startup_complete,
                             SERVICE_WORKER_ERROR_DISALLOWED);
-    RunSoon(base::BindOnce(callback, SERVICE_WORKER_ERROR_DISALLOWED));
+    RunSoon(
+        base::BindOnce(std::move(callback), SERVICE_WORKER_ERROR_DISALLOWED));
     return;
   }
 
@@ -489,7 +484,8 @@
       registration_id_, scope_.GetOrigin(),
       base::Bind(&ServiceWorkerVersion::DidEnsureLiveRegistrationForStartWorker,
                  weak_factory_.GetWeakPtr(), purpose, status_,
-                 is_browser_startup_complete, callback));
+                 is_browser_startup_complete,
+                 base::Passed(std::move(callback))));
 }
 
 void ServiceWorkerVersion::StopWorker(base::OnceClosure callback) {
@@ -553,14 +549,14 @@
 
 int ServiceWorkerVersion::StartRequest(
     ServiceWorkerMetrics::EventType event_type,
-    const StatusCallback& error_callback) {
-  return StartRequestWithCustomTimeout(event_type, error_callback,
+    StatusCallback error_callback) {
+  return StartRequestWithCustomTimeout(event_type, std::move(error_callback),
                                        kRequestTimeout, KILL_ON_TIMEOUT);
 }
 
 int ServiceWorkerVersion::StartRequestWithCustomTimeout(
     ServiceWorkerMetrics::EventType event_type,
-    const StatusCallback& error_callback,
+    StatusCallback error_callback,
     const base::TimeDelta& timeout,
     TimeoutBehavior timeout_behavior) {
   DCHECK_EQ(EmbeddedWorkerStatus::RUNNING, running_status())
@@ -572,8 +568,9 @@
       << "Event of type " << static_cast<int>(event_type)
       << " can only be dispatched to an active worker: " << status();
 
-  int request_id = pending_requests_.Add(base::MakeUnique<PendingRequest>(
-      error_callback, clock_->Now(), tick_clock_->NowTicks(), event_type));
+  int request_id = pending_requests_.Add(
+      base::MakeUnique<PendingRequest>(std::move(error_callback), clock_->Now(),
+                                       tick_clock_->NowTicks(), event_type));
   TRACE_EVENT_ASYNC_BEGIN2("ServiceWorker", "ServiceWorkerVersion::Request",
                            pending_requests_.Lookup(request_id), "Request id",
                            request_id, "Event type",
@@ -598,8 +595,8 @@
 
   int request_id =
       StartRequest(ServiceWorkerMetrics::EventType::EXTERNAL_REQUEST,
-                   base::Bind(&ServiceWorkerVersion::CleanUpExternalRequest,
-                              this, request_uuid));
+                   base::BindOnce(&ServiceWorkerVersion::CleanUpExternalRequest,
+                                  this, request_uuid));
   external_request_uuid_to_request_id_[request_uuid] = request_id;
   return true;
 }
@@ -663,15 +660,15 @@
 void ServiceWorkerVersion::RunAfterStartWorker(
     ServiceWorkerMetrics::EventType purpose,
     base::OnceClosure task,
-    const StatusCallback& error_callback) {
+    StatusCallback error_callback) {
   if (running_status() == EmbeddedWorkerStatus::RUNNING) {
     DCHECK(start_callbacks_.empty());
     std::move(task).Run();
     return;
   }
-  StartWorker(purpose,
-              base::Bind(&RunTaskAfterStartWorker, weak_factory_.GetWeakPtr(),
-                         error_callback, base::Passed(std::move(task))));
+  StartWorker(purpose, base::AdaptCallbackForRepeating(base::BindOnce(
+                           &RunTaskAfterStartWorker, weak_factory_.GetWeakPtr(),
+                           std::move(error_callback), std::move(task))));
 }
 
 void ServiceWorkerVersion::AddControllee(
@@ -860,11 +857,11 @@
 }
 
 ServiceWorkerVersion::PendingRequest::PendingRequest(
-    const StatusCallback& callback,
+    StatusCallback callback,
     base::Time time,
     const base::TimeTicks& time_ticks,
     ServiceWorkerMetrics::EventType event_type)
-    : error_callback(callback),
+    : error_callback(std::move(callback)),
       start_time(time),
       start_time_ticks(time_ticks),
       event_type(event_type) {}
@@ -1080,11 +1077,11 @@
   if (!request)
     return;
   // Copy error callback before calling FinishRequest.
-  StatusCallback callback = request->error_callback;
+  StatusCallback callback = std::move(request->error_callback);
 
   FinishRequest(request_id, status == SERVICE_WORKER_OK, dispatch_event_time);
 
-  callback.Run(status);
+  std::move(callback).Run(status);
 }
 
 void ServiceWorkerVersion::CountFeature(uint32_t feature) {
@@ -1433,7 +1430,7 @@
     ServiceWorkerMetrics::EventType purpose,
     Status prestart_status,
     bool is_browser_startup_complete,
-    const StatusCallback& callback,
+    StatusCallback callback,
     ServiceWorkerStatusCode status,
     scoped_refptr<ServiceWorkerRegistration> registration) {
   scoped_refptr<ServiceWorkerRegistration> protect = registration;
@@ -1451,14 +1448,16 @@
   if (status != SERVICE_WORKER_OK) {
     RecordStartWorkerResult(purpose, prestart_status, kInvalidTraceId,
                             is_browser_startup_complete, status);
-    RunSoon(base::BindOnce(callback, SERVICE_WORKER_ERROR_START_WORKER_FAILED));
+    RunSoon(base::BindOnce(std::move(callback),
+                           SERVICE_WORKER_ERROR_START_WORKER_FAILED));
     return;
   }
   if (is_redundant()) {
     RecordStartWorkerResult(purpose, prestart_status, kInvalidTraceId,
                             is_browser_startup_complete,
                             SERVICE_WORKER_ERROR_REDUNDANT);
-    RunSoon(base::BindOnce(callback, SERVICE_WORKER_ERROR_REDUNDANT));
+    RunSoon(
+        base::BindOnce(std::move(callback), SERVICE_WORKER_ERROR_REDUNDANT));
     return;
   }
 
@@ -1466,7 +1465,7 @@
 
   switch (running_status()) {
     case EmbeddedWorkerStatus::RUNNING:
-      RunSoon(base::BindOnce(callback, SERVICE_WORKER_OK));
+      RunSoon(base::BindOnce(std::move(callback), SERVICE_WORKER_OK));
       return;
     case EmbeddedWorkerStatus::STARTING:
       DCHECK(!start_callbacks_.empty());
@@ -1482,16 +1481,15 @@
         DCHECK(!start_worker_first_purpose_);
         start_worker_first_purpose_ = purpose;
         start_callbacks_.push_back(
-            base::Bind(&ServiceWorkerVersion::RecordStartWorkerResult,
-                       weak_factory_.GetWeakPtr(), purpose, prestart_status,
-                       trace_id, is_browser_startup_complete));
+            base::BindOnce(&ServiceWorkerVersion::RecordStartWorkerResult,
+                           weak_factory_.GetWeakPtr(), purpose, prestart_status,
+                           trace_id, is_browser_startup_complete));
       }
       break;
   }
 
   // Keep the live registration while starting the worker.
-  start_callbacks_.push_back(
-      base::Bind(&RunStartWorkerCallback, callback, protect));
+  start_callbacks_.push_back(std::move(callback));
 
   if (running_status() == EmbeddedWorkerStatus::STOPPED)
     StartWorkerInternal();
@@ -1546,10 +1544,10 @@
       // Unretained is used here because the callback will be owned by
       // |embedded_worker_| whose owner is |this|.
       base::BindOnce(&CompleteProviderHostPreparation, base::Unretained(this),
-                     base::Passed(&pending_provider_host), context()),
-      std::move(event_dispatcher_request), std::move(installed_scripts_info),
-      base::Bind(&ServiceWorkerVersion::OnStartSentAndScriptEvaluated,
-                 weak_factory_.GetWeakPtr()));
+                     std::move(pending_provider_host), context()),
+      mojo::MakeRequest(&event_dispatcher_), std::move(installed_scripts_info),
+      base::BindOnce(&ServiceWorkerVersion::OnStartSentAndScriptEvaluated,
+                     weak_factory_.GetWeakPtr()));
   event_dispatcher_.set_connection_error_handler(base::BindOnce(
       &OnEventDispatcherConnectionError, embedded_worker_->AsWeakPtr()));
 }
@@ -1783,7 +1781,7 @@
 
   TRACE_EVENT_ASYNC_END1("ServiceWorker", "ServiceWorkerVersion::Request",
                          request, "Error", "Timeout");
-  request->error_callback.Run(SERVICE_WORKER_ERROR_TIMEOUT);
+  std::move(request->error_callback).Run(SERVICE_WORKER_ERROR_TIMEOUT);
   pending_requests_.Remove(info.id);
   return true;
 }
@@ -1911,7 +1909,8 @@
   while (!iter.IsAtEnd()) {
     TRACE_EVENT_ASYNC_END1("ServiceWorker", "ServiceWorkerVersion::Request",
                            iter.GetCurrentValue(), "Error", "Worker Stopped");
-    iter.GetCurrentValue()->error_callback.Run(SERVICE_WORKER_ERROR_FAILED);
+    std::move(iter.GetCurrentValue()->error_callback)
+        .Run(SERVICE_WORKER_ERROR_FAILED);
     iter.Advance();
   }
   pending_requests_.Clear();
diff --git a/content/browser/service_worker/service_worker_version.h b/content/browser/service_worker/service_worker_version.h
index cc19f27..f64ea891 100644
--- a/content/browser/service_worker/service_worker_version.h
+++ b/content/browser/service_worker/service_worker_version.h
@@ -69,7 +69,10 @@
     : public base::RefCounted<ServiceWorkerVersion>,
       public EmbeddedWorkerInstance::Listener {
  public:
-  using StatusCallback = base::Callback<void(ServiceWorkerStatusCode)>;
+  // TODO(crbug.com/755477): LegacyStatusCallback which does not use
+  // OnceCallback is deprecated and should be removed soon.
+  using LegacyStatusCallback = base::Callback<void(ServiceWorkerStatusCode)>;
+  using StatusCallback = base::OnceCallback<void(ServiceWorkerStatusCode)>;
   using SimpleEventCallback =
       base::Callback<void(ServiceWorkerStatusCode, base::Time)>;
 
@@ -202,7 +205,7 @@
   // This returns OK (success) if the worker is already running.
   // |purpose| is recorded in UMA.
   void StartWorker(ServiceWorkerMetrics::EventType purpose,
-                   const StatusCallback& callback);
+                   StatusCallback callback);
 
   // Stops an embedded worker for this version.
   void StopWorker(base::OnceClosure callback);
@@ -227,7 +230,7 @@
   // |purpose| is used for UMA.
   void RunAfterStartWorker(ServiceWorkerMetrics::EventType purpose,
                            base::OnceClosure task,
-                           const StatusCallback& error_callback);
+                           StatusCallback error_callback);
 
   // Call this while the worker is running before dispatching an event to the
   // worker. This informs ServiceWorkerVersion about the event in progress. The
@@ -243,12 +246,12 @@
   // killed before the request finishes. In this case, the caller should not
   // call FinishRequest.
   int StartRequest(ServiceWorkerMetrics::EventType event_type,
-                   const StatusCallback& error_callback);
+                   StatusCallback error_callback);
 
   // Same as StartRequest, but allows the caller to specify a custom timeout for
   // the event, as well as the behavior for when the request times out.
   int StartRequestWithCustomTimeout(ServiceWorkerMetrics::EventType event_type,
-                                    const StatusCallback& error_callback,
+                                    StatusCallback error_callback,
                                     const base::TimeDelta& timeout,
                                     TimeoutBehavior timeout_behavior);
 
@@ -464,7 +467,7 @@
   };
 
   struct PendingRequest {
-    PendingRequest(const StatusCallback& error_callback,
+    PendingRequest(StatusCallback error_callback,
                    base::Time time,
                    const base::TimeTicks& time_ticks,
                    ServiceWorkerMetrics::EventType event_type);
@@ -609,7 +612,7 @@
       ServiceWorkerMetrics::EventType purpose,
       Status prestart_status,
       bool is_browser_startup_complete,
-      const StatusCallback& callback,
+      StatusCallback callback,
       ServiceWorkerStatusCode status,
       scoped_refptr<ServiceWorkerRegistration> registration);
   void StartWorkerInternal();
diff --git a/content/browser/service_worker/service_worker_version_unittest.cc b/content/browser/service_worker/service_worker_version_unittest.cc
index 8d5107ed..afce9ef 100644
--- a/content/browser/service_worker/service_worker_version_unittest.cc
+++ b/content/browser/service_worker/service_worker_version_unittest.cc
@@ -792,11 +792,11 @@
   version_->RunAfterStartWorker(
       ServiceWorkerMetrics::EventType::UNKNOWN,
       base::BindOnce(&base::DoNothing),
-      base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
+      base::BindOnce(&ServiceWorkerUtils::NoOpStatusCallback));
   version_->RunAfterStartWorker(
       ServiceWorkerMetrics::EventType::UNKNOWN,
       base::BindOnce(&base::DoNothing),
-      base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
+      base::BindOnce(&ServiceWorkerUtils::NoOpStatusCallback));
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(stale_time, version_->stale_time_);
 
@@ -831,8 +831,8 @@
   void OnStopWorker(int embedded_worker_id) override {
     EXPECT_FALSE(stop_worker_callback_);
     stop_worker_callback_ =
-        base::Bind(&MessageReceiverControlEvents::SimulateWorkerStopped,
-                   base::Unretained(this), embedded_worker_id);
+        base::BindOnce(&MessageReceiverControlEvents::SimulateWorkerStopped,
+                       base::Unretained(this), embedded_worker_id);
   }
 
   bool has_extendable_message_event_callback() {
@@ -844,12 +844,14 @@
     return std::move(extendable_message_event_callback_);
   }
 
-  const base::Closure& stop_worker_callback() { return stop_worker_callback_; }
+  base::OnceClosure stop_worker_callback() {
+    return std::move(stop_worker_callback_);
+  }
 
  private:
   mojom::ServiceWorkerEventDispatcher::DispatchExtendableMessageEventCallback
       extendable_message_event_callback_;
-  base::Closure stop_worker_callback_;
+  base::OnceClosure stop_worker_callback_;
 };
 
 class ServiceWorkerRequestTimeoutTest : public ServiceWorkerVersionTest {
@@ -871,7 +873,7 @@
         ->TakeExtendableMessageEventCallback();
   }
 
-  const base::Closure& stop_worker_callback() {
+  base::OnceClosure stop_worker_callback() {
     return static_cast<MessageReceiverControlEvents*>(helper_.get())
         ->stop_worker_callback();
   }
@@ -885,8 +887,9 @@
       SERVICE_WORKER_ERROR_NETWORK;  // dummy value
   version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
 
-  version_->StartWorker(ServiceWorkerMetrics::EventType::FETCH_MAIN_FRAME,
-                        base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
+  version_->StartWorker(
+      ServiceWorkerMetrics::EventType::FETCH_MAIN_FRAME,
+      base::BindOnce(&ServiceWorkerUtils::NoOpStatusCallback));
   base::RunLoop().RunUntilIdle();
 
   // Create a request.
@@ -915,8 +918,10 @@
   version_->timeout_timer_.user_task().Run();
   base::RunLoop().RunUntilIdle();
 
+  base::OnceClosure callback = stop_worker_callback();
+
   // The renderer should have received a StopWorker request.
-  EXPECT_TRUE(stop_worker_callback());
+  EXPECT_TRUE(callback);
   // The request should have timed out.
   EXPECT_EQ(SERVICE_WORKER_ERROR_TIMEOUT, error_status);
   // Calling FinishRequest should be no-op, since the request timed out.
@@ -930,7 +935,7 @@
   base::RunLoop().RunUntilIdle();
 
   // Simulate the renderer stopping the worker.
-  stop_worker_callback().Run();
+  std::move(callback).Run();
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, version_->running_status());
 }
@@ -939,8 +944,9 @@
   ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_NETWORK;  // dummy value
   version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
 
-  version_->StartWorker(ServiceWorkerMetrics::EventType::SYNC,
-                        base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
+  version_->StartWorker(
+      ServiceWorkerMetrics::EventType::SYNC,
+      base::BindOnce(&ServiceWorkerUtils::NoOpStatusCallback));
   base::RunLoop().RunUntilIdle();
 
   // Create a request that should expire Now().
@@ -966,8 +972,9 @@
   ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_NETWORK;  // dummy value
   version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
 
-  version_->StartWorker(ServiceWorkerMetrics::EventType::SYNC,
-                        base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
+  version_->StartWorker(
+      ServiceWorkerMetrics::EventType::SYNC,
+      base::BindOnce(&ServiceWorkerUtils::NoOpStatusCallback));
   base::RunLoop().RunUntilIdle();
 
   // Create a request that should expire Now().
@@ -996,8 +1003,9 @@
       SERVICE_WORKER_ERROR_MAX_VALUE;  // dummy value
   version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
 
-  version_->StartWorker(ServiceWorkerMetrics::EventType::SYNC,
-                        base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
+  version_->StartWorker(
+      ServiceWorkerMetrics::EventType::SYNC,
+      base::BindOnce(&ServiceWorkerUtils::NoOpStatusCallback));
   base::RunLoop().RunUntilIdle();
 
   base::SimpleTestTickClock* tick_clock = SetTickClockForTesting();
@@ -1058,8 +1066,9 @@
       SERVICE_WORKER_ERROR_NETWORK;  // dummy value
   version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
 
-  version_->StartWorker(ServiceWorkerMetrics::EventType::FETCH_MAIN_FRAME,
-                        base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
+  version_->StartWorker(
+      ServiceWorkerMetrics::EventType::FETCH_MAIN_FRAME,
+      base::BindOnce(&ServiceWorkerUtils::NoOpStatusCallback));
   base::RunLoop().RunUntilIdle();
 
   // Create a fetch request that should expire sometime later.
diff --git a/content/browser/service_worker/service_worker_write_to_cache_job.cc b/content/browser/service_worker/service_worker_write_to_cache_job.cc
index 3dc9ef9..277a0f72 100644
--- a/content/browser/service_worker/service_worker_write_to_cache_job.cc
+++ b/content/browser/service_worker/service_worker_write_to_cache_job.cc
@@ -5,7 +5,6 @@
 #include "content/browser/service_worker/service_worker_write_to_cache_job.h"
 
 #include "base/bind.h"
-#include "base/callback.h"
 #include "base/command_line.h"
 #include "base/memory/ptr_util.h"
 #include "base/strings/stringprintf.h"
@@ -28,6 +27,7 @@
 #include "net/url_request/url_request.h"
 #include "net/url_request/url_request_context.h"
 #include "net/url_request/url_request_status.h"
+#include "third_party/WebKit/common/mime_util/mime_util.h"
 #include "third_party/WebKit/public/web/WebConsoleMessage.h"
 
 namespace content {
@@ -338,9 +338,7 @@
   if (resource_type_ == RESOURCE_TYPE_SERVICE_WORKER) {
     std::string mime_type;
     request->GetMimeType(&mime_type);
-    if (mime_type != "application/x-javascript" &&
-        mime_type != "text/javascript" &&
-        mime_type != "application/javascript") {
+    if (!blink::IsSupportedJavascriptMimeType(mime_type)) {
       std::string error_message =
           mime_type.empty()
               ? kNoMIMEError
@@ -366,8 +364,8 @@
           new net::HttpResponseInfo(net_request_->response_info()));
   net::Error error = cache_writer_->MaybeWriteHeaders(
       info_buffer.get(),
-      base::Bind(&ServiceWorkerWriteToCacheJob::OnWriteHeadersComplete,
-                 weak_factory_.GetWeakPtr()));
+      base::BindOnce(&ServiceWorkerWriteToCacheJob::OnWriteHeadersComplete,
+                     weak_factory_.GetWeakPtr()));
   if (error == net::ERR_IO_PENDING)
     return;
   OnWriteHeadersComplete(error);
@@ -440,8 +438,8 @@
   io_buffer_bytes_ = bytes_read;
   net::Error error = cache_writer_->MaybeWriteData(
       io_buffer_.get(), bytes_read,
-      base::Bind(&ServiceWorkerWriteToCacheJob::OnWriteDataComplete,
-                 weak_factory_.GetWeakPtr()));
+      base::BindOnce(&ServiceWorkerWriteToCacheJob::OnWriteDataComplete,
+                     weak_factory_.GetWeakPtr()));
 
   // In case of ERR_IO_PENDING, this logic is done in OnWriteDataComplete.
   if (error != net::ERR_IO_PENDING && bytes_read == 0) {
diff --git a/content/common/cursors/webcursor.cc b/content/common/cursors/webcursor.cc
index a85d6a8..f56402b6 100644
--- a/content/common/cursors/webcursor.cc
+++ b/content/common/cursors/webcursor.cc
@@ -89,9 +89,8 @@
       // The * 4 is because the expected format is an array of RGBA pixel
       // values.
       if (size_x * size_y * 4 != data_len) {
-        LOG(WARNING) << "WebCursor's data length and image size mismatch: "
-                     << size_x << "x" << size_y << "x4 != "
-                     << data_len;
+        DLOG(WARNING) << "WebCursor's data length and image size mismatch: "
+                      << size_x << "x" << size_y << "x4 != " << data_len;
         return false;
       }
 
@@ -109,25 +108,21 @@
       }
     }
   }
-  return DeserializePlatformData(iter);
+  return true;
 }
 
-bool WebCursor::Serialize(base::Pickle* pickle) const {
-  if (!pickle->WriteInt(type_) ||
-      !pickle->WriteInt(hotspot_.x()) ||
-      !pickle->WriteInt(hotspot_.y()) ||
-      !pickle->WriteInt(custom_size_.width()) ||
-      !pickle->WriteInt(custom_size_.height()) ||
-      !pickle->WriteFloat(custom_scale_))
-    return false;
+void WebCursor::Serialize(base::Pickle* pickle) const {
+  pickle->WriteInt(type_);
+  pickle->WriteInt(hotspot_.x());
+  pickle->WriteInt(hotspot_.y());
+  pickle->WriteInt(custom_size_.width());
+  pickle->WriteInt(custom_size_.height());
+  pickle->WriteFloat(custom_scale_);
 
   const char* data = NULL;
   if (!custom_data_.empty())
     data = &custom_data_[0];
-  if (!pickle->WriteData(data, custom_data_.size()))
-    return false;
-
-  return SerializePlatformData(pickle);
+  pickle->WriteData(data, custom_data_.size());
 }
 
 bool WebCursor::IsCustom() const {
diff --git a/content/common/cursors/webcursor.h b/content/common/cursors/webcursor.h
index 4f7bd59..485eef5 100644
--- a/content/common/cursors/webcursor.h
+++ b/content/common/cursors/webcursor.h
@@ -57,7 +57,7 @@
 
   // Serialization / De-serialization
   bool Deserialize(base::PickleIterator* iter);
-  bool Serialize(base::Pickle* pickle) const;
+  void Serialize(base::Pickle* pickle) const;
 
   // Returns true if GetCustomCursor should be used to allocate a platform
   // specific cursor object.  Otherwise GetCursor should be used.
@@ -103,10 +103,6 @@
   // Platform specific initialization goes here.
   void InitPlatformData();
 
-  // Platform specific Serialization / De-serialization
-  bool SerializePlatformData(base::Pickle* pickle) const;
-  bool DeserializePlatformData(base::PickleIterator* iter);
-
   // Returns true if the platform data in the current cursor object
   // matches that of the cursor passed in.
   bool IsPlatformDataEqual(const WebCursor& other) const ;
diff --git a/content/common/cursors/webcursor_android.cc b/content/common/cursors/webcursor_android.cc
index d1d720e..fc1f67f0 100644
--- a/content/common/cursors/webcursor_android.cc
+++ b/content/common/cursors/webcursor_android.cc
@@ -24,14 +24,6 @@
 void WebCursor::InitPlatformData() {
 }
 
-bool WebCursor::SerializePlatformData(base::Pickle* pickle) const {
-  return true;
-}
-
-bool WebCursor::DeserializePlatformData(base::PickleIterator* iter) {
-  return true;
-}
-
 bool WebCursor::IsPlatformDataEqual(const WebCursor& other) const {
   return true;
 }
diff --git a/content/common/cursors/webcursor_aurawin.cc b/content/common/cursors/webcursor_aurawin.cc
index e379cfa4..5b32064 100644
--- a/content/common/cursors/webcursor_aurawin.cc
+++ b/content/common/cursors/webcursor_aurawin.cc
@@ -40,14 +40,6 @@
   device_scale_factor_ = 1.f;
 }
 
-bool WebCursor::SerializePlatformData(base::Pickle* pickle) const {
-  return true;
-}
-
-bool WebCursor::DeserializePlatformData(base::PickleIterator* iter) {
-  return true;
-}
-
 bool WebCursor::IsPlatformDataEqual(const WebCursor& other) const {
   return true;
 }
diff --git a/content/common/cursors/webcursor_aurax11.cc b/content/common/cursors/webcursor_aurax11.cc
index d4c9d1d..feeba909 100644
--- a/content/common/cursors/webcursor_aurax11.cc
+++ b/content/common/cursors/webcursor_aurax11.cc
@@ -34,14 +34,6 @@
   device_scale_factor_ = 1.f;
 }
 
-bool WebCursor::SerializePlatformData(base::Pickle* pickle) const {
-  return true;
-}
-
-bool WebCursor::DeserializePlatformData(base::PickleIterator* iter) {
-  return true;
-}
-
 bool WebCursor::IsPlatformDataEqual(const WebCursor& other) const {
   return true;
 }
diff --git a/content/common/cursors/webcursor_mac.mm b/content/common/cursors/webcursor_mac.mm
index 00d1748..a55335de 100644
--- a/content/common/cursors/webcursor_mac.mm
+++ b/content/common/cursors/webcursor_mac.mm
@@ -360,14 +360,6 @@
   return;
 }
 
-bool WebCursor::SerializePlatformData(base::Pickle* pickle) const {
-  return true;
-}
-
-bool WebCursor::DeserializePlatformData(base::PickleIterator* iter) {
-  return true;
-}
-
 bool WebCursor::IsPlatformDataEqual(const WebCursor& other) const {
   return true;
 }
diff --git a/content/common/cursors/webcursor_ozone.cc b/content/common/cursors/webcursor_ozone.cc
index b28ab00..101af76c 100644
--- a/content/common/cursors/webcursor_ozone.cc
+++ b/content/common/cursors/webcursor_ozone.cc
@@ -69,14 +69,6 @@
       gfx::Size(kDefaultMaxCursorWidth, kDefaultMaxCursorHeight);
 }
 
-bool WebCursor::SerializePlatformData(base::Pickle* pickle) const {
-  return true;
-}
-
-bool WebCursor::DeserializePlatformData(base::PickleIterator* iter) {
-  return true;
-}
-
 bool WebCursor::IsPlatformDataEqual(const WebCursor& other) const {
   return true;
 }
diff --git a/content/public/android/BUILD.gn b/content/public/android/BUILD.gn
index fa847e8..b6261a8 100644
--- a/content/public/android/BUILD.gn
+++ b/content/public/android/BUILD.gn
@@ -497,6 +497,7 @@
   java_files = [
     "junit/src/org/chromium/content/browser/BindingManagerImplTest.java",
     "junit/src/org/chromium/content/browser/MenuDescriptorTest.java",
+    "junit/src/org/chromium/content/browser/SelectionPopupControllerTest.java",
     "junit/src/org/chromium/content/browser/SpareChildConnectionTest.java",
     "junit/src/org/chromium/content/browser/androidoverlay/DialogOverlayCoreTest.java",
     "junit/src/org/chromium/content/browser/input/RangeTest.java",
@@ -513,6 +514,7 @@
     "//media/mojo/interfaces:interfaces_java",
     "//mojo/public/java:bindings_java",
     "//third_party/WebKit/public:android_mojo_bindings_java",
+    "//ui/android:ui_java",
     "//ui/gfx/geometry/mojo:mojo_java",
   ]
 }
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
index 0eb5d448..0ba566b6 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
@@ -480,6 +480,8 @@
 
         mSelectionPopupController = new SelectionPopupController(
                 mContext, windowAndroid, webContents, mContainerView, mRenderCoordinates);
+        mSelectionPopupController.setSelectionClient(SmartSelectionClient.create(
+                mSelectionPopupController.getResultCallback(), windowAndroid, webContents));
         mSelectionPopupController.setCallback(ActionModeCallbackHelper.EMPTY_CALLBACK);
         mSelectionPopupController.setContainerView(mContainerView);
 
@@ -2136,7 +2138,8 @@
      * Sets TextClassifier for Smart Text selection.
      */
     public void setTextClassifier(TextClassifier textClassifier) {
-        mSelectionPopupController.setTextClassifier(textClassifier);
+        SelectionClient client = mSelectionPopupController.getSelectionClient();
+        if (client != null) client.setTextClassifier(textClassifier);
     }
 
     /**
@@ -2145,14 +2148,16 @@
      * classifier.
      */
     public TextClassifier getTextClassifier() {
-        return mSelectionPopupController.getTextClassifier();
+        SelectionClient client = mSelectionPopupController.getSelectionClient();
+        return client == null ? null : client.getTextClassifier();
     }
 
     /**
      * Returns the TextClassifier which has been set with setTextClassifier(), or null.
      */
     public TextClassifier getCustomTextClassifier() {
-        return mSelectionPopupController.getCustomTextClassifier();
+        SelectionClient client = mSelectionPopupController.getSelectionClient();
+        return client == null ? null : client.getCustomTextClassifier();
     }
 
     private native long nativeInit(WebContents webContents, ViewAndroidDelegate viewAndroidDelegate,
diff --git a/content/public/android/java/src/org/chromium/content/browser/SelectionClient.java b/content/public/android/java/src/org/chromium/content/browser/SelectionClient.java
index 6194573..2554b3e7 100644
--- a/content/public/android/java/src/org/chromium/content/browser/SelectionClient.java
+++ b/content/public/android/java/src/org/chromium/content/browser/SelectionClient.java
@@ -4,6 +4,9 @@
 
 package org.chromium.content.browser;
 
+import android.content.Intent;
+import android.graphics.drawable.Drawable;
+import android.view.View.OnClickListener;
 import android.view.textclassifier.TextClassifier;
 
 /**
@@ -11,6 +14,61 @@
  */
 public interface SelectionClient {
     /**
+     * The result of the text analysis.
+     */
+    public static class Result {
+        /**
+         * The number of characters that the left boundary of the original
+         * selection should be moved. Negative number means moving left.
+         */
+        public int startAdjust;
+
+        /**
+         * The number of characters that the right boundary of the original
+         * selection should be moved. Negative number means moving left.
+         */
+        public int endAdjust;
+
+        /**
+         * Label for the suggested menu item.
+         */
+        public CharSequence label;
+
+        /**
+         * Icon for the suggested menu item.
+         */
+        public Drawable icon;
+
+        /**
+         * Intent for the suggested menu item.
+         */
+        public Intent intent;
+
+        /**
+         * OnClickListener for the suggested menu item.
+         */
+        public OnClickListener onClickListener;
+
+        /**
+         * A helper method that returns true if the result has both visual info
+         * and an action so that, for instance, one can make a new menu item.
+         */
+        public boolean hasNamedAction() {
+            return (label != null || icon != null) && (intent != null || onClickListener != null);
+        }
+    }
+
+    /**
+     * The interface that returns the result of the selected text analysis.
+     */
+    public interface ResultCallback {
+        /**
+         * The result is delivered with this method.
+         */
+        void onClassified(Result result);
+    }
+
+    /**
      * Notification that the web content selection has changed, regardless of the causal action.
      * @param selection The newly established selection.
      */
@@ -52,23 +110,27 @@
      * Cancel any outstanding requests the embedder had previously requested using
      * SelectionClient.requestSelectionPopupUpdates().
      */
-    public void cancelAllRequests();
+    void cancelAllRequests();
 
     /**
      * Sets TextClassifier for the Smart Text selection. Pass null argument to use the system
      * classifier
      */
-    public void setTextClassifier(TextClassifier textClassifier);
+    default void setTextClassifier(TextClassifier textClassifier) {}
 
     /**
      * Gets TextClassifier that is used for the Smart Text selection. If the custom classifier
      * has been set with setTextClassifier, returns that object, otherwise returns the system
      * classifier.
      */
-    public TextClassifier getTextClassifier();
+    default TextClassifier getTextClassifier() {
+        return null;
+    }
 
     /**
      * Returns the TextClassifier which has been set with setTextClassifier(), or null.
      */
-    public TextClassifier getCustomTextClassifier();
+    default TextClassifier getCustomTextClassifier() {
+        return null;
+    }
 }
diff --git a/content/public/android/java/src/org/chromium/content/browser/SelectionPopupController.java b/content/public/android/java/src/org/chromium/content/browser/SelectionPopupController.java
index 273f604..579a007 100644
--- a/content/public/android/java/src/org/chromium/content/browser/SelectionPopupController.java
+++ b/content/public/android/java/src/org/chromium/content/browser/SelectionPopupController.java
@@ -30,7 +30,6 @@
 import android.view.View;
 import android.view.ViewConfiguration;
 import android.view.WindowManager;
-import android.view.textclassifier.TextClassifier;
 
 import org.chromium.base.BuildInfo;
 import org.chromium.base.Log;
@@ -94,6 +93,8 @@
     private final RenderCoordinates mRenderCoordinates;
     private ActionMode.Callback mCallback;
 
+    private SelectionClient.ResultCallback mResultCallback;
+
     // Used to customize PastePopupMenu
     private ActionMode.Callback mNonSelectionCallback;
 
@@ -134,8 +135,8 @@
     private SelectionClient mSelectionClient;
 
     // The classificaton result of the selected text if the selection exists and
-    // SmartSelectionProvider was able to classify it, otherwise null.
-    private SmartSelectionProvider.Result mClassificationResult;
+    // SelectionClient was able to classify it, otherwise null.
+    private SelectionClient.Result mClassificationResult;
 
     // This variable is set to true when showActionMode() is postponed till classification result
     // arrives or till the selection is adjusted based on the classification result.
@@ -154,6 +155,26 @@
      */
     public SelectionPopupController(Context context, WindowAndroid window, WebContents webContents,
             View view, RenderCoordinates renderCoordinates) {
+        this(context, window, webContents, view, renderCoordinates, /* initialNative = */ true);
+    }
+
+    /**
+     * Create {@link SelectionPopupController} instance. Note that it will create an instance with
+     * no link to native side.
+     * @param context Context for action mode.
+     * @param window WindowAndroid instance.
+     * @param webContents WebContents instance.
+     * @param view Container view.
+     * @param renderCoordinates Coordinates info used to position elements.
+     */
+    public static SelectionPopupController createForTesting(Context context, WindowAndroid window,
+            WebContents webContents, View view, RenderCoordinates renderCoordinates) {
+        return new SelectionPopupController(
+                context, window, webContents, view, renderCoordinates, /* initialNative = */ false);
+    }
+
+    private SelectionPopupController(Context context, WindowAndroid window, WebContents webContents,
+            View view, RenderCoordinates renderCoordinates, boolean initializeNative) {
         mContext = context;
         mWindowAndroid = window;
         mWebContents = webContents;
@@ -173,12 +194,11 @@
             }
         };
 
-        mSelectionClient =
-                SmartSelectionClient.create(new SmartSelectionCallback(), window, webContents);
+        mResultCallback = new SmartSelectionCallback();
 
         mLastSelectedText = "";
 
-        nativeInit(webContents);
+        if (initializeNative) nativeInit(webContents);
     }
 
     /**
@@ -207,6 +227,14 @@
         mNonSelectionCallback = callback;
     }
 
+    public SelectionClient.ResultCallback getResultCallback() {
+        return mResultCallback;
+    }
+
+    public SelectionClient getSelectionClient() {
+        return mSelectionClient;
+    }
+
     @Override
     public boolean isActionModeValid() {
         return mActionMode != null;
@@ -1136,33 +1164,10 @@
                 PackageManager.MATCH_DEFAULT_ONLY).size() > 0;
     }
 
-    /**
-     * Sets TextClassifier for Smart Text selection.
-     */
-    public void setTextClassifier(TextClassifier textClassifier) {
-        if (mSelectionClient != null) mSelectionClient.setTextClassifier(textClassifier);
-    }
-
-    /**
-     * Returns TextClassifier that is used for Smart Text selection. If the custom classifier
-     * has been set with setTextClassifier, returns that object, otherwise returns the system
-     * classifier.
-     */
-    public TextClassifier getTextClassifier() {
-        return mSelectionClient == null ? null : mSelectionClient.getTextClassifier();
-    }
-
-    /**
-     * Returns the TextClassifier which has been set with setTextClassifier(), or null.
-     */
-    public TextClassifier getCustomTextClassifier() {
-        return mSelectionClient == null ? null : mSelectionClient.getCustomTextClassifier();
-    }
-
     // The callback class that delivers result from a SmartSelectionClient.
-    private class SmartSelectionCallback implements SmartSelectionProvider.ResultCallback {
+    private class SmartSelectionCallback implements SelectionClient.ResultCallback {
         @Override
-        public void onClassified(SmartSelectionProvider.Result result) {
+        public void onClassified(SelectionClient.Result result) {
             // If the selection does not exist any more, discard |result|.
             if (!hasSelection()) {
                 assert !mHidden;
diff --git a/content/public/android/java/src/org/chromium/content/browser/SmartSelectionClient.java b/content/public/android/java/src/org/chromium/content/browser/SmartSelectionClient.java
index 3a5e9937..d92643b 100644
--- a/content/public/android/java/src/org/chromium/content/browser/SmartSelectionClient.java
+++ b/content/public/android/java/src/org/chromium/content/browser/SmartSelectionClient.java
@@ -45,7 +45,7 @@
 
     private long mNativeSmartSelectionClient;
     private SmartSelectionProvider mProvider;
-    private SmartSelectionProvider.ResultCallback mCallback;
+    private ResultCallback mCallback;
 
     public static void setEnabled(boolean enabled) {
         sEnabled = enabled;
@@ -55,15 +55,15 @@
      * Creates the SmartSelectionClient. Returns null in case SmartSelectionProvider does not exist
      * in the system.
      */
-    public static SmartSelectionClient create(SmartSelectionProvider.ResultCallback callback,
-            WindowAndroid windowAndroid, WebContents webContents) {
+    public static SmartSelectionClient create(
+            ResultCallback callback, WindowAndroid windowAndroid, WebContents webContents) {
         if (!sEnabled) return null;
         SmartSelectionProvider provider = new SmartSelectionProvider(callback, windowAndroid);
         return new SmartSelectionClient(provider, callback, webContents);
     }
 
-    private SmartSelectionClient(SmartSelectionProvider provider,
-            SmartSelectionProvider.ResultCallback callback, WebContents webContents) {
+    private SmartSelectionClient(
+            SmartSelectionProvider provider, ResultCallback callback, WebContents webContents) {
         mProvider = provider;
         mCallback = callback;
         mNativeSmartSelectionClient = nativeInit(webContents);
@@ -132,7 +132,7 @@
     private void onSurroundingTextReceived(
             @RequestType int callbackData, String text, int start, int end) {
         if (!textHasValidSelection(text, start, end)) {
-            mCallback.onClassified(new SmartSelectionProvider.Result());
+            mCallback.onClassified(new Result());
             return;
         }
 
diff --git a/content/public/android/java/src/org/chromium/content/browser/SmartSelectionProvider.java b/content/public/android/java/src/org/chromium/content/browser/SmartSelectionProvider.java
index 14da940..a84023a 100644
--- a/content/public/android/java/src/org/chromium/content/browser/SmartSelectionProvider.java
+++ b/content/public/android/java/src/org/chromium/content/browser/SmartSelectionProvider.java
@@ -7,14 +7,11 @@
 import android.annotation.SuppressLint;
 import android.annotation.TargetApi;
 import android.content.Context;
-import android.content.Intent;
-import android.graphics.drawable.Drawable;
 import android.os.AsyncTask;
 import android.os.Build;
 import android.os.Handler;
 import android.os.LocaleList;
 import android.support.annotation.IntDef;
-import android.view.View.OnClickListener;
 import android.view.textclassifier.TextClassification;
 import android.view.textclassifier.TextClassificationManager;
 import android.view.textclassifier.TextClassifier;
@@ -30,61 +27,6 @@
  * Controls Smart Text selection. Talks to the Android TextClassificationManager API.
  */
 public class SmartSelectionProvider {
-    /**
-     * The result of the text analysis.
-     */
-    public static class Result {
-        /**
-         * The number of characters that the left boundary of the original
-         * selection should be moved. Negative number means moving left.
-         */
-        public int startAdjust;
-
-        /**
-         * The number of characters that the right boundary of the original
-         * selection should be moved. Negative number means moving left.
-         */
-        public int endAdjust;
-
-        /**
-         * Label for the suggested menu item.
-         */
-        public CharSequence label;
-
-        /**
-         * Icon for the suggested menu item.
-         */
-        public Drawable icon;
-
-        /**
-         * Intent for the suggested menu item.
-         */
-        public Intent intent;
-
-        /**
-         * OnClickListener for the suggested menu item.
-         */
-        public OnClickListener onClickListener;
-
-        /**
-         * A helper method that returns true if the result has both visual info
-         * and an action so that, for instance, one can make a new menu item.
-         */
-        public boolean hasNamedAction() {
-            return (label != null || icon != null) && (intent != null || onClickListener != null);
-        }
-    }
-
-    /**
-     * The interface that returns the result of the selected text analysis.
-     */
-    public interface ResultCallback {
-        /**
-         * The result is delivered with this method.
-         */
-        void onClassified(Result result);
-    }
-
     private static final String TAG = "SmartSelProvider";
 
     @IntDef({CLASSIFY, SUGGEST_AND_CLASSIFY})
@@ -94,7 +36,7 @@
     private static final int CLASSIFY = 0;
     private static final int SUGGEST_AND_CLASSIFY = 1;
 
-    private ResultCallback mResultCallback;
+    private SelectionClient.ResultCallback mResultCallback;
     private WindowAndroid mWindowAndroid;
     private ClassificationTask mClassificationTask;
     private TextClassifier mTextClassifier;
@@ -102,14 +44,15 @@
     private Handler mHandler;
     private Runnable mFailureResponseRunnable;
 
-    public SmartSelectionProvider(ResultCallback callback, WindowAndroid windowAndroid) {
+    public SmartSelectionProvider(
+            SelectionClient.ResultCallback callback, WindowAndroid windowAndroid) {
         mResultCallback = callback;
         mWindowAndroid = windowAndroid;
         mHandler = new Handler();
         mFailureResponseRunnable = new Runnable() {
             @Override
             public void run() {
-                mResultCallback.onClassified(new Result());
+                mResultCallback.onClassified(new SelectionClient.Result());
             }
         };
     }
@@ -155,7 +98,7 @@
     @TargetApi(Build.VERSION_CODES.O)
     private void sendSmartSelectionRequest(
             @RequestType int requestType, CharSequence text, int start, int end, Locale[] locales) {
-        TextClassifier classifier = (TextClassifier) getTextClassifier();
+        TextClassifier classifier = getTextClassifier();
         if (classifier == null || classifier == TextClassifier.NO_OP) {
             mHandler.post(mFailureResponseRunnable);
             return;
@@ -172,7 +115,7 @@
     }
 
     @TargetApi(Build.VERSION_CODES.O)
-    private class ClassificationTask extends AsyncTask<Void, Void, Result> {
+    private class ClassificationTask extends AsyncTask<Void, Void, SelectionClient.Result> {
         private final TextClassifier mTextClassifier;
         private final int mRequestType;
         private final CharSequence mText;
@@ -191,7 +134,7 @@
         }
 
         @Override
-        protected Result doInBackground(Void... params) {
+        protected SelectionClient.Result doInBackground(Void... params) {
             int start = mOriginalStart;
             int end = mOriginalEnd;
 
@@ -200,7 +143,7 @@
                         mText, start, end, makeLocaleList(mLocales));
                 start = Math.max(0, suggested.getSelectionStartIndex());
                 end = Math.min(mText.length(), suggested.getSelectionEndIndex());
-                if (isCancelled()) return new Result();
+                if (isCancelled()) return new SelectionClient.Result();
             }
 
             TextClassification tc =
@@ -214,8 +157,8 @@
             return new LocaleList(locales);
         }
 
-        private Result makeResult(int start, int end, TextClassification tc) {
-            Result result = new Result();
+        private SelectionClient.Result makeResult(int start, int end, TextClassification tc) {
+            SelectionClient.Result result = new SelectionClient.Result();
 
             result.startAdjust = start - mOriginalStart;
             result.endAdjust = end - mOriginalEnd;
@@ -228,7 +171,7 @@
         }
 
         @Override
-        protected void onPostExecute(Result result) {
+        protected void onPostExecute(SelectionClient.Result result) {
             mResultCallback.onClassified(result);
         }
     }
diff --git a/content/public/android/junit/src/org/chromium/content/browser/SelectionPopupControllerTest.java b/content/public/android/junit/src/org/chromium/content/browser/SelectionPopupControllerTest.java
new file mode 100644
index 0000000..10647ae
--- /dev/null
+++ b/content/public/android/junit/src/org/chromium/content/browser/SelectionPopupControllerTest.java
@@ -0,0 +1,79 @@
+// 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.
+
+package org.chromium.content.browser;
+
+import static org.junit.Assert.assertNotNull;
+
+import android.content.Context;
+import android.view.View;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+
+import org.chromium.base.test.util.Feature;
+import org.chromium.content_public.browser.WebContents;
+import org.chromium.testing.local.LocalRobolectricTestRunner;
+import org.chromium.ui.base.WindowAndroid;
+
+/**
+ * Unit tests for {@SelectionPopupController}.
+ */
+@RunWith(LocalRobolectricTestRunner.class)
+@Config(manifest = Config.NONE)
+public class SelectionPopupControllerTest {
+    SelectionPopupController mController;
+    Context mContext;
+    WindowAndroid mWindowAndroid;
+    WebContents mWebContents;
+    View mView;
+    RenderCoordinates mRenderCoordinates;
+
+    class MySelectionClient implements SelectionClient {
+        @Override
+        public void onSelectionChanged(String selection) {}
+
+        @Override
+        public void onSelectionEvent(int eventType, float posXPix, float poxYPix) {}
+
+        @Override
+        public void showUnhandledTapUIIfNeeded(int x, int y) {}
+
+        @Override
+        public void selectWordAroundCaretAck(boolean didSelect, int startAdjust, int endAdjust) {}
+
+        @Override
+        public boolean requestSelectionPopupUpdates(boolean shouldSuggest) {
+            return false;
+        }
+
+        @Override
+        public void cancelAllRequests() {}
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+
+        mContext = Mockito.mock(Context.class);
+        mWindowAndroid = Mockito.mock(WindowAndroid.class);
+        mWebContents = Mockito.mock(WebContents.class);
+        mView = Mockito.mock(View.class);
+        mRenderCoordinates = Mockito.mock(RenderCoordinates.class);
+
+        mController = SelectionPopupController.createForTesting(
+                mContext, mWindowAndroid, mWebContents, mView, mRenderCoordinates);
+    }
+
+    @Test
+    @Feature({"SmartSelection"})
+    public void testSmartSelectionAdjustSelectionRange() {
+        assertNotNull(mController);
+        MySelectionClient client = new MySelectionClient();
+    }
+}
diff --git a/content/public/browser/devtools_manager_delegate.cc b/content/public/browser/devtools_manager_delegate.cc
index b572162e..ebd1ad6 100644
--- a/content/public/browser/devtools_manager_delegate.cc
+++ b/content/public/browser/devtools_manager_delegate.cc
@@ -39,11 +39,10 @@
     content::DevToolsAgentHost* agent_host,
     int session_id) {}
 
-base::DictionaryValue* DevToolsManagerDelegate::HandleCommand(
-    DevToolsAgentHost* agent_host,
-    int session_id,
-    base::DictionaryValue* command) {
-  return nullptr;
+bool DevToolsManagerDelegate::HandleCommand(DevToolsAgentHost* agent_host,
+                                            int session_id,
+                                            base::DictionaryValue* command) {
+  return false;
 }
 
 bool DevToolsManagerDelegate::HandleAsyncCommand(
diff --git a/content/public/browser/devtools_manager_delegate.h b/content/public/browser/devtools_manager_delegate.h
index ef4b174d..1136340b 100644
--- a/content/public/browser/devtools_manager_delegate.h
+++ b/content/public/browser/devtools_manager_delegate.h
@@ -42,16 +42,17 @@
   // Creates new inspectable target given the |url|.
   virtual scoped_refptr<DevToolsAgentHost> CreateNewTarget(const GURL& url);
 
+  // Called when a new session is created/destroyed. Note that |session_id| is
+  // globally unique.
   virtual void SessionCreated(content::DevToolsAgentHost* agent_host,
                               int session_id);
-
   virtual void SessionDestroyed(content::DevToolsAgentHost* agent_host,
                                 int session_id);
 
-  // Result ownership is passed to the caller.
-  virtual base::DictionaryValue* HandleCommand(DevToolsAgentHost* agent_host,
-                                               int session_id,
-                                               base::DictionaryValue* command);
+  // Returns true if the command has been handled, false otherwise.
+  virtual bool HandleCommand(DevToolsAgentHost* agent_host,
+                             int session_id,
+                             base::DictionaryValue* command);
 
   using CommandCallback =
       base::Callback<void(std::unique_ptr<base::DictionaryValue> response)>;
diff --git a/content/public/browser/navigation_entry.h b/content/public/browser/navigation_entry.h
index 1d760c4d..aca9f8e 100644
--- a/content/public/browser/navigation_entry.h
+++ b/content/public/browser/navigation_entry.h
@@ -65,8 +65,8 @@
   // of GURLs for compatibility with legacy Android WebView apps.
   virtual void SetDataURLAsString(
       scoped_refptr<base::RefCountedString> data_url) = 0;
-  virtual const scoped_refptr<const base::RefCountedString> GetDataURLAsString()
-      const = 0;
+  virtual const scoped_refptr<const base::RefCountedString>&
+  GetDataURLAsString() const = 0;
 #endif
 
   // The referring URL. Can be empty.
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc
index 1a4987e..6ad7f33 100644
--- a/content/public/common/content_switches.cc
+++ b/content/public/common/content_switches.cc
@@ -362,6 +362,10 @@
 const char kDisableBrowserSideNavigation[] = "disable-browser-side-navigation";
 const char kEnableBrowserSideNavigation[]   = "enable-browser-side-navigation";
 
+// Enable animating of images in the compositor instead of blink.
+const char kEnableCompositorImageAnimations[] =
+    "enable-compositor-image-animations";
+
 // Enables display list based 2d canvas implementation. Options:
 //  1. Enable: allow browser to use display list for 2d canvas (browser makes
 //     decision).
@@ -637,6 +641,11 @@
 // INFO = 0, WARNING = 1, LOG_ERROR = 2, LOG_FATAL = 3.
 const char kLoggingLevel[]                  = "log-level";
 
+// Overrides the default file name to use for general-purpose logging (does not
+// affect which events are logged). Currently supported only in app_shell.
+// TODO(crbug.com/760431): Make this work in chrome and content_shell too.
+const char kLogFile[] = "log-file";
+
 // Enables saving net log events to a file and sets the file name to use.
 const char kLogNetLog[]                     = "log-net-log";
 
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h
index 71b0100..d11eab1 100644
--- a/content/public/common/content_switches.h
+++ b/content/public/common/content_switches.h
@@ -115,6 +115,7 @@
 CONTENT_EXPORT extern const char kEnableBlinkFeatures[];
 CONTENT_EXPORT extern const char kEnableBackgroundFetchPersistence[];
 CONTENT_EXPORT extern const char kEnableBrowserSideNavigation[];
+CONTENT_EXPORT extern const char kEnableCompositorImageAnimations[];
 CONTENT_EXPORT extern const char kEnableDisplayList2dCanvas[];
 CONTENT_EXPORT extern const char kEnableDistanceFieldText[];
 CONTENT_EXPORT extern const char kEnableExperimentalCanvasFeatures[];
@@ -189,6 +190,7 @@
 CONTENT_EXPORT extern const char kJavaScriptHarmony[];
 CONTENT_EXPORT extern const char kLogGpuControlListDecisions[];
 CONTENT_EXPORT extern const char kLoggingLevel[];
+CONTENT_EXPORT extern const char kLogFile[];
 CONTENT_EXPORT extern const char kLogNetLog[];
 CONTENT_EXPORT extern const char kMainFrameResizesAreOrientationChanges[];
 extern const char kMaxUntiledLayerHeight[];
diff --git a/content/renderer/gpu/render_widget_compositor.cc b/content/renderer/gpu/render_widget_compositor.cc
index aeb94bc..fbd0f388 100644
--- a/content/renderer/gpu/render_widget_compositor.cc
+++ b/content/renderer/gpu/render_widget_compositor.cc
@@ -595,6 +595,9 @@
   settings.wait_for_all_pipeline_stages_before_draw =
       cmd.HasSwitch(cc::switches::kRunAllCompositorStagesBeforeDraw);
 
+  settings.enable_image_animations =
+      cmd.HasSwitch(switches::kEnableCompositorImageAnimations);
+
   return settings;
 }
 
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc
index 4c342e71..5dc03fa 100644
--- a/content/renderer/render_thread_impl.cc
+++ b/content/renderer/render_thread_impl.cc
@@ -857,6 +857,9 @@
     is_distance_field_text_enabled_ = false;
   }
 
+  WebRuntimeFeatures::EnableCompositorImageAnimations(
+      command_line.HasSwitch(switches::kEnableCompositorImageAnimations));
+
   // Note that under Linux, the media library will normally already have
   // been initialized by the Zygote before this instance became a Renderer.
   media::InitializeMediaLibrary();
diff --git a/content/test/gpu/gpu_tests/pixel_expectations.py b/content/test/gpu/gpu_tests/pixel_expectations.py
index 2b2e2a33..02d2e8b 100644
--- a/content/test/gpu/gpu_tests/pixel_expectations.py
+++ b/content/test/gpu/gpu_tests/pixel_expectations.py
@@ -52,29 +52,10 @@
     self.Flaky('Pixel_OffscreenCanvas2DResizeOnWorker',
         ['win10', ('intel', 0x1912)], bug=690663)
 
-    # TODO(kbr): re-enable after new baselines gathered. crbug.com/730303
-    # self.Flaky('Pixel_OffscreenCanvasTransferBeforeStyleResize',
-    #           ['mac', 'linux', 'win', 'android'], bug=735228)
-    # self.Flaky('Pixel_OffscreenCanvasTransferAfterStyleResize',
-    #           ['mac', 'linux', 'win', 'android'], bug=735171)
-    # self.Flaky('Pixel_OffscreenCanvasWebGLSoftwareCompositingWorker',
-    #     ['mac', ('nvidia', 0xfe9), 'debug'], bug=751328)
+    self.Flaky('Pixel_OffscreenCanvasTransferBeforeStyleResize',
+              ['mac', 'linux', 'win', 'android'], bug=735228)
+    self.Flaky('Pixel_OffscreenCanvasTransferAfterStyleResize',
+              ['mac', 'linux', 'win', 'android'], bug=735171)
 
-    # TODO(kbr): re-enable after new baselines generated.
-    self.Fail('Pixel_2DCanvasWebGL', bug=730303)
-    self.Fail('Pixel_IOSurface2DCanvasWebGL', ['mac'], bug=730303)
-    self.Fail('Pixel_OffscreenCanvasTransferAfterStyleResize', bug=730303)
-    self.Fail('Pixel_OffscreenCanvasTransferBeforeStyleResize', bug=730303)
-    self.Fail('Pixel_OffscreenCanvasWebGLDefault', bug=730303)
-    self.Fail('Pixel_OffscreenCanvasWebGLDefaultWorker', bug=730303)
-    self.Fail('Pixel_OffscreenCanvasWebglResizeOnWorker', bug=730303)
-    self.Fail('Pixel_OffscreenCanvasWebGLSoftwareCompositing',
-              ['mac', 'linux', 'win'], bug=730303)
-    self.Fail('Pixel_OffscreenCanvasWebGLSoftwareCompositingWorker',
-              ['mac', 'linux', 'win'], bug=730303)
-    self.Fail('Pixel_WebGLGreenTriangle_AA_Alpha', bug=730303)
-    self.Fail('Pixel_WebGLGreenTriangle_AA_NoAlpha', bug=730303)
-    self.Fail('Pixel_WebGLGreenTriangle_NonChromiumImage_AA_Alpha',
-              ['mac'], bug=730303)
-    self.Fail('Pixel_WebGLGreenTriangle_NonChromiumImage_AA_NoAlpha',
-              ['mac'], bug=730303)
+    self.Flaky('Pixel_OffscreenCanvasWebGLSoftwareCompositingWorker',
+        ['mac', ('nvidia', 0xfe9), 'debug'], bug=751328)
diff --git a/content/test/test_background_sync_manager.cc b/content/test/test_background_sync_manager.cc
index 70af708..92fb542 100644
--- a/content/test/test_background_sync_manager.cc
+++ b/content/test/test_background_sync_manager.cc
@@ -77,7 +77,7 @@
     const std::string& tag,
     scoped_refptr<ServiceWorkerVersion> active_version,
     blink::mojom::BackgroundSyncEventLastChance last_chance,
-    const ServiceWorkerVersion::StatusCallback& callback) {
+    const ServiceWorkerVersion::LegacyStatusCallback& callback) {
   ASSERT_FALSE(dispatch_sync_callback_.is_null());
   last_chance_ = last_chance;
   dispatch_sync_callback_.Run(active_version, callback);
diff --git a/content/test/test_background_sync_manager.h b/content/test/test_background_sync_manager.h
index 5965bae..c100e16 100644
--- a/content/test/test_background_sync_manager.h
+++ b/content/test/test_background_sync_manager.h
@@ -37,7 +37,7 @@
  public:
   using DispatchSyncCallback = base::RepeatingCallback<void(
       const scoped_refptr<ServiceWorkerVersion>&,
-      const ServiceWorkerVersion::StatusCallback&)>;
+      const ServiceWorkerVersion::LegacyStatusCallback&)>;
 
   explicit TestBackgroundSyncManager(
       scoped_refptr<ServiceWorkerContextWrapper> service_worker_context);
@@ -108,7 +108,7 @@
       const std::string& tag,
       scoped_refptr<ServiceWorkerVersion> active_version,
       blink::mojom::BackgroundSyncEventLastChance last_chance,
-      const ServiceWorkerVersion::StatusCallback& callback) override;
+      const ServiceWorkerVersion::LegacyStatusCallback& callback) override;
 
   // Override to just store delayed task, and allow tests to control the clock
   // and when delayed tasks are executed.
diff --git a/extensions/shell/app/shell_main_delegate.cc b/extensions/shell/app/shell_main_delegate.cc
index 6c9a6ab9..fceead0 100644
--- a/extensions/shell/app/shell_main_delegate.cc
+++ b/extensions/shell/app/shell_main_delegate.cc
@@ -79,8 +79,13 @@
 }
 
 void InitLogging() {
-  const base::FilePath log_path =
-      GetDataPath().Append(FILE_PATH_LITERAL("app_shell.log"));
+  base::FilePath log_path;
+  if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kLogFile)) {
+    log_path = base::CommandLine::ForCurrentProcess()->GetSwitchValuePath(
+        switches::kLogFile);
+  } else {
+    log_path = GetDataPath().Append(FILE_PATH_LITERAL("app_shell.log"));
+  }
 
   // Set up log initialization settings.
   logging::LoggingSettings settings;
diff --git a/headless/lib/browser/headless_devtools_manager_delegate.cc b/headless/lib/browser/headless_devtools_manager_delegate.cc
index 74e0f81..3e39b54c 100644
--- a/headless/lib/browser/headless_devtools_manager_delegate.cc
+++ b/headless/lib/browser/headless_devtools_manager_delegate.cc
@@ -7,6 +7,7 @@
 #include <string>
 #include <utility>
 
+#include "base/json/json_writer.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/devtools_agent_host.h"
 #include "content/public/browser/devtools_frontend_host.h"
@@ -100,6 +101,12 @@
 }
 #endif
 
+std::string ToString(std::unique_ptr<base::DictionaryValue> value) {
+  std::string json;
+  base::JSONWriter::Write(*value, &json);
+  return json;
+}
+
 }  // namespace
 
 #if BUILDFLAG(ENABLE_BASIC_PRINTING)
@@ -199,33 +206,37 @@
 
 HeadlessDevToolsManagerDelegate::~HeadlessDevToolsManagerDelegate() {}
 
-base::DictionaryValue* HeadlessDevToolsManagerDelegate::HandleCommand(
+bool HeadlessDevToolsManagerDelegate::HandleCommand(
     content::DevToolsAgentHost* agent_host,
     int session_id,
     base::DictionaryValue* command) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
   if (!browser_)
-    return nullptr;
+    return false;
 
   int id;
   std::string method;
   if (!command->GetInteger("id", &id) || !command->GetString("method", &method))
-    return nullptr;
+    return false;
 
   auto find_it = command_map_.find(method);
   if (find_it == command_map_.end())
-    return nullptr;
+    return false;
 
   // Handle Browser domain commands only from Browser DevToolsAgentHost.
   if (method.find("Browser.") == 0 &&
       agent_host->GetType() != content::DevToolsAgentHost::kTypeBrowser)
-    return nullptr;
+    return false;
 
   const base::DictionaryValue* params = nullptr;
   command->GetDictionary("params", &params);
   auto cmd_result = find_it->second.Run(id, params);
-  return cmd_result.release();
+  if (!cmd_result)
+    return false;
+  agent_host->SendProtocolMessageToClient(session_id,
+                                          ToString(std::move(cmd_result)));
+  return true;
 }
 
 bool HeadlessDevToolsManagerDelegate::HandleAsyncCommand(
diff --git a/headless/lib/browser/headless_devtools_manager_delegate.h b/headless/lib/browser/headless_devtools_manager_delegate.h
index 72177e2b..43de7da5 100644
--- a/headless/lib/browser/headless_devtools_manager_delegate.h
+++ b/headless/lib/browser/headless_devtools_manager_delegate.h
@@ -39,9 +39,9 @@
   ~HeadlessDevToolsManagerDelegate() override;
 
   // DevToolsManagerDelegate implementation:
-  base::DictionaryValue* HandleCommand(content::DevToolsAgentHost* agent_host,
-                                       int session_id,
-                                       base::DictionaryValue* command) override;
+  bool HandleCommand(content::DevToolsAgentHost* agent_host,
+                     int session_id,
+                     base::DictionaryValue* command) override;
   bool HandleAsyncCommand(content::DevToolsAgentHost* agent_host,
                           int session_id,
                           base::DictionaryValue* command,
diff --git a/ipc/ipc_fuzzing_tests.cc b/ipc/ipc_fuzzing_tests.cc
index 75c13b1..ca8827b 100644
--- a/ipc/ipc_fuzzing_tests.cc
+++ b/ipc/ipc_fuzzing_tests.cc
@@ -46,8 +46,8 @@
   uint32_t v1 = std::numeric_limits<uint32_t>::max() - 1;
   int v2 = 666;
   IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL);
-  EXPECT_TRUE(m.WriteInt(v1));
-  EXPECT_TRUE(m.WriteInt(v2));
+  m.WriteInt(v1);
+  m.WriteInt(v2);
 
   base::PickleIterator iter(m);
   std::string vs;
@@ -59,8 +59,8 @@
   uint32_t v1 = std::numeric_limits<uint32_t>::max() - 1;
   int v2 = 777;
   IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL);
-  EXPECT_TRUE(m.WriteInt(v1));
-  EXPECT_TRUE(m.WriteInt(v2));
+  m.WriteInt(v1);
+  m.WriteInt(v2);
 
   base::PickleIterator iter(m);
   base::string16 vs;
@@ -70,8 +70,8 @@
 TEST(IPCMessageIntegrity, ReadBytesBadIterator) {
   // This was BUG 1035467.
   IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL);
-  EXPECT_TRUE(m.WriteInt(1));
-  EXPECT_TRUE(m.WriteInt(2));
+  m.WriteInt(1);
+  m.WriteInt(2);
 
   base::PickleIterator iter(m);
   const char* data = NULL;
@@ -83,10 +83,10 @@
   // has a specialized template which is not vulnerable to this bug. So here
   // try to hit the non-specialized case vector<P>.
   IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL);
-  EXPECT_TRUE(m.WriteInt(-1));   // This is the count of elements.
-  EXPECT_TRUE(m.WriteInt(1));
-  EXPECT_TRUE(m.WriteInt(2));
-  EXPECT_TRUE(m.WriteInt(3));
+  m.WriteInt(-1);  // This is the count of elements.
+  m.WriteInt(1);
+  m.WriteInt(2);
+  m.WriteInt(3);
 
   std::vector<double> vec;
   base::PickleIterator iter(m);
@@ -102,9 +102,9 @@
   // This was BUG 1006367. This is the large but positive length case. Again
   // we try to hit the non-specialized case vector<P>.
   IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL);
-  EXPECT_TRUE(m.WriteInt(0x21000003));   // This is the count of elements.
-  EXPECT_TRUE(m.WriteInt64(1));
-  EXPECT_TRUE(m.WriteInt64(2));
+  m.WriteInt(0x21000003);  // This is the count of elements.
+  m.WriteInt64(1);
+  m.WriteInt64(2);
 
   std::vector<int64_t> vec;
   base::PickleIterator iter(m);
@@ -116,9 +116,9 @@
   // integer overflow when computing the actual byte size. Again we try to hit
   // the non-specialized case vector<P>.
   IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL);
-  EXPECT_TRUE(m.WriteInt(0x71000000));   // This is the count of elements.
-  EXPECT_TRUE(m.WriteInt64(1));
-  EXPECT_TRUE(m.WriteInt64(2));
+  m.WriteInt(0x71000000);  // This is the count of elements.
+  m.WriteInt64(1);
+  m.WriteInt64(2);
 
   std::vector<int64_t> vec;
   base::PickleIterator iter(m);
diff --git a/ipc/ipc_message_unittest.cc b/ipc/ipc_message_unittest.cc
index 36b5d28..5d9da31 100644
--- a/ipc/ipc_message_unittest.cc
+++ b/ipc/ipc_message_unittest.cc
@@ -40,9 +40,9 @@
   base::string16 v3(base::ASCIIToUTF16("hello world"));
 
   IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL);
-  EXPECT_TRUE(m.WriteInt(v1));
-  EXPECT_TRUE(m.WriteString(v2));
-  EXPECT_TRUE(m.WriteString16(v3));
+  m.WriteInt(v1);
+  m.WriteString(v2);
+  m.WriteString16(v3);
 
   base::PickleIterator iter(m);
 
@@ -124,8 +124,8 @@
 
 TEST(IPCMessageTest, FindNext) {
   IPC::Message message;
-  EXPECT_TRUE(message.WriteString("Goooooooogle"));
-  EXPECT_TRUE(message.WriteInt(111));
+  message.WriteString("Goooooooogle");
+  message.WriteInt(111);
 
   std::vector<char> message_data(message.size() + 7);
   memcpy(message_data.data(), message.data(), message.size());
@@ -173,8 +173,8 @@
 
 TEST(IPCMessageTest, FindNextOverflow) {
   IPC::Message message;
-  EXPECT_TRUE(message.WriteString("Data"));
-  EXPECT_TRUE(message.WriteInt(777));
+  message.WriteString("Data");
+  message.WriteInt(777);
 
   const char* data_start = reinterpret_cast<const char*>(message.data());
   const char* data_end = data_start + message.size();
diff --git a/ipc/ipc_message_utils.cc b/ipc/ipc_message_utils.cc
index 285e4842..655a2a6 100644
--- a/ipc/ipc_message_utils.cc
+++ b/ipc/ipc_message_utils.cc
@@ -1020,7 +1020,8 @@
     return false;
 
   r->SetHeaderValues(static_cast<int32_t>(routing_id), type, flags);
-  return r->WriteBytes(payload, payload_size);
+  r->WriteBytes(payload, payload_size);
+  return true;
 }
 
 void ParamTraits<Message>::Log(const Message& p, std::string* l) {
diff --git a/ipc/ipc_sync_message.cc b/ipc/ipc_sync_message.cc
index 34cb875..98a1ad8 100644
--- a/ipc/ipc_sync_message.cc
+++ b/ipc/ipc_sync_message.cc
@@ -103,11 +103,7 @@
 bool SyncMessage::WriteSyncHeader(Message* msg, const SyncHeader& header) {
   DCHECK(msg->is_sync() || msg->is_reply());
   DCHECK(msg->payload_size() == 0);
-  bool result = msg->WriteInt(header.message_id);
-  if (!result) {
-    NOTREACHED();
-    return false;
-  }
+  msg->WriteInt(header.message_id);
 
   // Note: if you add anything here, you need to update kSyncMessageHeaderSize.
   DCHECK(kSyncMessageHeaderSize == msg->payload_size());
diff --git a/net/cert/signed_certificate_timestamp.cc b/net/cert/signed_certificate_timestamp.cc
index 9096fde..a2ec06e 100644
--- a/net/cert/signed_certificate_timestamp.cc
+++ b/net/cert/signed_certificate_timestamp.cc
@@ -34,15 +34,15 @@
 SignedCertificateTimestamp::~SignedCertificateTimestamp() {}
 
 void SignedCertificateTimestamp::Persist(base::Pickle* pickle) {
-  CHECK(pickle->WriteInt(version));
-  CHECK(pickle->WriteString(log_id));
-  CHECK(pickle->WriteInt64(timestamp.ToInternalValue()));
-  CHECK(pickle->WriteString(extensions));
-  CHECK(pickle->WriteInt(signature.hash_algorithm));
-  CHECK(pickle->WriteInt(signature.signature_algorithm));
-  CHECK(pickle->WriteString(signature.signature_data));
-  CHECK(pickle->WriteInt(origin));
-  CHECK(pickle->WriteString(log_description));
+  pickle->WriteInt(version);
+  pickle->WriteString(log_id);
+  pickle->WriteInt64(timestamp.ToInternalValue());
+  pickle->WriteString(extensions);
+  pickle->WriteInt(signature.hash_algorithm);
+  pickle->WriteInt(signature.signature_algorithm);
+  pickle->WriteString(signature.signature_data);
+  pickle->WriteInt(origin);
+  pickle->WriteString(log_description);
 }
 
 // static
diff --git a/net/cert/x509_certificate.cc b/net/cert/x509_certificate.cc
index 14aaa5b4..2fe306cb 100644
--- a/net/cert/x509_certificate.cc
+++ b/net/cert/x509_certificate.cc
@@ -295,18 +295,10 @@
     NOTREACHED();
     return;
   }
-  if (!pickle->WriteInt(
-          static_cast<int>(intermediate_ca_certs_.size() + 1)) ||
-      !WriteOSCertHandleToPickle(cert_handle_, pickle)) {
-    NOTREACHED();
-    return;
-  }
-  for (size_t i = 0; i < intermediate_ca_certs_.size(); ++i) {
-    if (!WriteOSCertHandleToPickle(intermediate_ca_certs_[i], pickle)) {
-      NOTREACHED();
-      return;
-    }
-  }
+  pickle->WriteInt(static_cast<int>(intermediate_ca_certs_.size() + 1));
+  WriteOSCertHandleToPickle(cert_handle_, pickle);
+  for (size_t i = 0; i < intermediate_ca_certs_.size(); ++i)
+    WriteOSCertHandleToPickle(intermediate_ca_certs_[i], pickle);
 }
 
 void X509Certificate::GetDNSNames(std::vector<std::string>* dns_names) const {
diff --git a/net/cert/x509_certificate.h b/net/cert/x509_certificate.h
index aba3c2e..a34217d 100644
--- a/net/cert/x509_certificate.h
+++ b/net/cert/x509_certificate.h
@@ -346,7 +346,7 @@
 
   // Writes a single certificate to |pickle| in DER form. Returns false on
   // failure.
-  static bool WriteOSCertHandleToPickle(OSCertHandle handle,
+  static void WriteOSCertHandleToPickle(OSCertHandle handle,
                                         base::Pickle* pickle);
 
   // The subject of the certificate.
diff --git a/net/cert/x509_certificate_bytes.cc b/net/cert/x509_certificate_bytes.cc
index 2a0d11f..3fdbc267 100644
--- a/net/cert/x509_certificate_bytes.cc
+++ b/net/cert/x509_certificate_bytes.cc
@@ -454,9 +454,9 @@
 }
 
 // static
-bool X509Certificate::WriteOSCertHandleToPickle(OSCertHandle cert_handle,
+void X509Certificate::WriteOSCertHandleToPickle(OSCertHandle cert_handle,
                                                 base::Pickle* pickle) {
-  return pickle->WriteData(
+  pickle->WriteData(
       reinterpret_cast<const char*>(CRYPTO_BUFFER_data(cert_handle)),
       CRYPTO_BUFFER_len(cert_handle));
 }
diff --git a/net/cert/x509_certificate_nss.cc b/net/cert/x509_certificate_nss.cc
index 3ab486fc5..ce1fd169 100644
--- a/net/cert/x509_certificate_nss.cc
+++ b/net/cert/x509_certificate_nss.cc
@@ -391,11 +391,10 @@
 }
 
 // static
-bool X509Certificate::WriteOSCertHandleToPickle(OSCertHandle cert_handle,
+void X509Certificate::WriteOSCertHandleToPickle(OSCertHandle cert_handle,
                                                 base::Pickle* pickle) {
-  return pickle->WriteData(
-      reinterpret_cast<const char*>(cert_handle->derCert.data),
-      cert_handle->derCert.len);
+  pickle->WriteData(reinterpret_cast<const char*>(cert_handle->derCert.data),
+                    cert_handle->derCert.len);
 }
 
 // static
diff --git a/net/disk_cache/simple/simple_index_file.cc b/net/disk_cache/simple/simple_index_file.cc
index edc3b02d..69e8093f 100644
--- a/net/disk_cache/simple/simple_index_file.cc
+++ b/net/disk_cache/simple/simple_index_file.cc
@@ -255,13 +255,11 @@
 }
 
 // static
-bool SimpleIndexFile::SerializeFinalData(base::Time cache_modified,
+void SimpleIndexFile::SerializeFinalData(base::Time cache_modified,
                                          base::Pickle* pickle) {
-  if (!pickle->WriteInt64(cache_modified.ToInternalValue()))
-    return false;
+  pickle->WriteInt64(cache_modified.ToInternalValue());
   SimpleIndexFile::PickleHeader* header_p = pickle->headerT<PickleHeader>();
   header_p->crc = CalculatePickleCRC(*pickle);
-  return true;
 }
 
 bool SimpleIndexFile::IndexMetadata::Deserialize(base::PickleIterator* it) {
diff --git a/net/disk_cache/simple/simple_index_file.h b/net/disk_cache/simple/simple_index_file.h
index 3946e2e2..c74feef 100644
--- a/net/disk_cache/simple/simple_index_file.h
+++ b/net/disk_cache/simple/simple_index_file.h
@@ -143,7 +143,7 @@
   // performed on a thread accessing the disk. It is not combined with the main
   // serialization path to avoid extra thread hops or copying the pickle to the
   // worker thread.
-  static bool SerializeFinalData(base::Time cache_modified,
+  static void SerializeFinalData(base::Time cache_modified,
                                  base::Pickle* pickle);
 
   // Given the contents of an index file |data| of length |data_len|, returns
diff --git a/net/disk_cache/simple/simple_index_file_unittest.cc b/net/disk_cache/simple/simple_index_file_unittest.cc
index d39d40a..16e420e3 100644
--- a/net/disk_cache/simple/simple_index_file_unittest.cc
+++ b/net/disk_cache/simple/simple_index_file_unittest.cc
@@ -202,7 +202,7 @@
       WrappedSimpleIndexFile::Serialize(index_metadata, entries);
   EXPECT_TRUE(pickle.get() != NULL);
   base::Time now = base::Time::Now();
-  EXPECT_TRUE(WrappedSimpleIndexFile::SerializeFinalData(now, pickle.get()));
+  WrappedSimpleIndexFile::SerializeFinalData(now, pickle.get());
   base::Time when_index_last_saw_cache;
   SimpleIndexLoadResult deserialize_result;
   WrappedSimpleIndexFile::Deserialize(static_cast<const char*>(pickle->data()),
@@ -244,7 +244,7 @@
       WrappedSimpleIndexFile::Serialize(v7_metadata, entries);
   ASSERT_TRUE(pickle.get() != NULL);
   base::Time now = base::Time::Now();
-  ASSERT_TRUE(WrappedSimpleIndexFile::SerializeFinalData(now, pickle.get()));
+  WrappedSimpleIndexFile::SerializeFinalData(now, pickle.get());
 
   // Now read it back. We should get the sizes rounded, and 0 for mem entries.
   base::Time when_index_last_saw_cache;
diff --git a/net/quic/chromium/quic_server_info.cc b/net/quic/chromium/quic_server_info.cc
index 3e53fa5..021cdee4 100644
--- a/net/quic/chromium/quic_server_info.cc
+++ b/net/quic/chromium/quic_server_info.cc
@@ -125,23 +125,20 @@
 }
 
 string QuicServerInfo::SerializeInner() const {
-  base::Pickle p(sizeof(base::Pickle::Header));
+  if (state_.certs.size() > std::numeric_limits<uint32_t>::max())
+    return std::string();
 
-  if (!p.WriteInt(kQuicCryptoConfigVersion) ||
-      !p.WriteString(state_.server_config) ||
-      !p.WriteString(state_.source_address_token) ||
-      !p.WriteString(state_.cert_sct) || !p.WriteString(state_.chlo_hash) ||
-      !p.WriteString(state_.server_config_sig) ||
-      state_.certs.size() > std::numeric_limits<uint32_t>::max() ||
-      !p.WriteUInt32(state_.certs.size())) {
-    return string();
-  }
+  base::Pickle p;
+  p.WriteInt(kQuicCryptoConfigVersion);
+  p.WriteString(state_.server_config);
+  p.WriteString(state_.source_address_token);
+  p.WriteString(state_.cert_sct);
+  p.WriteString(state_.chlo_hash);
+  p.WriteString(state_.server_config_sig);
+  p.WriteUInt32(state_.certs.size());
 
-  for (size_t i = 0; i < state_.certs.size(); i++) {
-    if (!p.WriteString(state_.certs[i])) {
-      return string();
-    }
-  }
+  for (size_t i = 0; i < state_.certs.size(); i++)
+    p.WriteString(state_.certs[i]);
 
   return string(reinterpret_cast<const char*>(p.data()), p.size());
 }
diff --git a/ppapi/proxy/serialized_handle.cc b/ppapi/proxy/serialized_handle.cc
index 88796cd..85595b3 100644
--- a/ppapi/proxy/serialized_handle.cc
+++ b/ppapi/proxy/serialized_handle.cc
@@ -86,18 +86,14 @@
 }
 
 // static
-bool SerializedHandle::WriteHeader(const Header& hdr, base::Pickle* pickle) {
-  if (!pickle->WriteInt(hdr.type))
-    return false;
+void SerializedHandle::WriteHeader(const Header& hdr, base::Pickle* pickle) {
+  pickle->WriteInt(hdr.type);
   if (hdr.type == SHARED_MEMORY) {
-    if (!pickle->WriteUInt32(hdr.size))
-      return false;
+    pickle->WriteUInt32(hdr.size);
+  } else if (hdr.type == FILE) {
+    pickle->WriteInt(hdr.open_flags);
+    pickle->WriteInt(hdr.file_io);
   }
-  if (hdr.type == FILE) {
-    if (!pickle->WriteInt(hdr.open_flags) || !pickle->WriteInt(hdr.file_io))
-      return false;
-  }
-  return true;
 }
 
 // static
diff --git a/ppapi/proxy/serialized_handle.h b/ppapi/proxy/serialized_handle.h
index 3eb5993..0df012d 100644
--- a/ppapi/proxy/serialized_handle.h
+++ b/ppapi/proxy/serialized_handle.h
@@ -127,7 +127,7 @@
   // Write/Read a Header, which contains all the data except the handle. This
   // allows us to write the handle in a platform-specific way, as is necessary
   // in NaClIPCAdapter to share handles with NaCl from Windows.
-  static bool WriteHeader(const Header& hdr, base::Pickle* pickle);
+  static void WriteHeader(const Header& hdr, base::Pickle* pickle);
   static bool ReadHeader(base::PickleIterator* iter, Header* hdr);
 
  private:
diff --git a/skia/ext/skia_utils_base.cc b/skia/ext/skia_utils_base.cc
index 041c4c7..3569a80 100644
--- a/skia/ext/skia_utils_base.cc
+++ b/skia/ext/skia_utils_base.cc
@@ -60,21 +60,21 @@
   return true;
 }
 
-bool WriteSkString(base::Pickle* pickle, const SkString& str) {
-  return pickle->WriteData(str.c_str(), str.size());
+void WriteSkString(base::Pickle* pickle, const SkString& str) {
+  pickle->WriteData(str.c_str(), str.size());
 }
 
-bool WriteSkFontIdentity(base::Pickle* pickle,
+void WriteSkFontIdentity(base::Pickle* pickle,
                          const SkFontConfigInterface::FontIdentity& identity) {
-  return pickle->WriteUInt32(identity.fID) &&
-         pickle->WriteUInt32(identity.fTTCIndex) &&
-         WriteSkString(pickle, identity.fString);
+  pickle->WriteUInt32(identity.fID);
+  pickle->WriteUInt32(identity.fTTCIndex);
+  WriteSkString(pickle, identity.fString);
 }
 
-bool WriteSkFontStyle(base::Pickle* pickle, SkFontStyle style) {
-  return pickle->WriteUInt16(style.weight()) &&
-         pickle->WriteUInt16(style.width()) &&
-         pickle->WriteUInt16(style.slant());
+void WriteSkFontStyle(base::Pickle* pickle, SkFontStyle style) {
+  pickle->WriteUInt16(style.weight());
+  pickle->WriteUInt16(style.width());
+  pickle->WriteUInt16(style.slant());
 }
 
 }  // namespace skia
diff --git a/skia/ext/skia_utils_base.h b/skia/ext/skia_utils_base.h
index 82da02b2..6a3675b 100644
--- a/skia/ext/skia_utils_base.h
+++ b/skia/ext/skia_utils_base.h
@@ -27,16 +27,16 @@
 // style is not null, copy it into style.
 SK_API bool ReadSkFontStyle(base::PickleIterator* iter, SkFontStyle* style);
 
-// Return true if str can be written into the request pickle.
-SK_API bool WriteSkString(base::Pickle* pickle, const SkString& str);
+// Writes str into the request pickle.
+SK_API void WriteSkString(base::Pickle* pickle, const SkString& str);
 
-// Return true if identity can be written into the request pickle.
-SK_API bool WriteSkFontIdentity(
+// Writes identity into the request pickle.
+SK_API void WriteSkFontIdentity(
     base::Pickle* pickle,
     const SkFontConfigInterface::FontIdentity& identity);
 
-// Return true if str can be written into the request pickle.
-SK_API bool WriteSkFontStyle(base::Pickle* pickle, SkFontStyle style);
+// Writes style into the request pickle.
+SK_API void WriteSkFontStyle(base::Pickle* pickle, SkFontStyle style);
 
 }  // namespace skia
 
diff --git a/storage/browser/fileapi/sandbox_directory_database.cc b/storage/browser/fileapi/sandbox_directory_database.cc
index 7b73e14..589dcb89 100644
--- a/storage/browser/fileapi/sandbox_directory_database.cc
+++ b/storage/browser/fileapi/sandbox_directory_database.cc
@@ -29,7 +29,7 @@
 
 namespace {
 
-bool PickleFromFileInfo(const storage::SandboxDirectoryDatabase::FileInfo& info,
+void PickleFromFileInfo(const storage::SandboxDirectoryDatabase::FileInfo& info,
                         base::Pickle* pickle) {
   DCHECK(pickle);
   std::string data_path;
@@ -41,14 +41,10 @@
   data_path = storage::FilePathToString(info.data_path);
   name = storage::FilePathToString(base::FilePath(info.name));
 
-  if (pickle->WriteInt64(info.parent_id) &&
-      pickle->WriteString(data_path) &&
-      pickle->WriteString(name) &&
-      pickle->WriteInt64(time.ToInternalValue()))
-    return true;
-
-  NOTREACHED();
-  return false;
+  pickle->WriteInt64(info.parent_id);
+  pickle->WriteString(data_path);
+  pickle->WriteString(name);
+  pickle->WriteInt64(time.ToInternalValue());
 }
 
 bool FileInfoFromPickle(const base::Pickle& pickle,
@@ -637,8 +633,7 @@
     return false;
   info.modification_time = modification_time;
   base::Pickle pickle;
-  if (!PickleFromFileInfo(info, &pickle))
-    return false;
+  PickleFromFileInfo(info, &pickle);
   leveldb::Status status = db_->Put(
       leveldb::WriteOptions(),
       GetFileLookupKey(file_id),
@@ -669,8 +664,7 @@
   if (!RemoveFileInfoHelper(src_file_id, &batch))
     return false;
   base::Pickle pickle;
-  if (!PickleFromFileInfo(dest_file_info, &pickle))
-    return false;
+  PickleFromFileInfo(dest_file_info, &pickle);
   batch.Put(
       GetFileLookupKey(dest_file_id),
       leveldb::Slice(reinterpret_cast<const char *>(pickle.data()),
@@ -917,8 +911,7 @@
     batch->Put(child_key, id_string);
   }
   base::Pickle pickle;
-  if (!PickleFromFileInfo(info, &pickle))
-    return false;
+  PickleFromFileInfo(info, &pickle);
   batch->Put(
       id_string,
       leveldb::Slice(reinterpret_cast<const char *>(pickle.data()),
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService b/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService
index 99e43250f..2a06f6e 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService
@@ -382,7 +382,6 @@
 Bug(none) http/tests/payments/payment-app-interfaces.html [ Crash Failure Timeout ]
 Bug(none) http/tests/payments/payment-instruments.html [ Crash Failure Timeout ]
 Bug(none) http/tests/payments/payment-request-event.html [ Crash Failure Pass Timeout ]
-crbug.com/766241 http/tests/permissions/test-api-surface.html [ Crash Pass ]
 Bug(none) http/tests/permissions/test-query.html [ Crash Failure ]
 Bug(none) http/tests/push_messaging/application-server-key-format-test.html [ Crash Failure Timeout ]
 Bug(none) http/tests/push_messaging/application-server-key-standard-endpoint.html [ Crash Failure Timeout ]
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/link-element-register-mime-types.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/link-element-register-mime-types.https-expected.txt
index 28bf3a7..f45b6685 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/link-element-register-mime-types.https-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/link-element-register-mime-types.https-expected.txt
@@ -3,37 +3,37 @@
 FAIL Registering script with bad MIME type Test bug: need to pass exception to assert_throws()
 FAIL Registering script that imports script with no MIME type assert_unreached: Should have rejected: Registration of no MIME type imported script should fail. Reached unreachable code
 FAIL Registering script that imports script with bad MIME type assert_unreached: Should have rejected: Registration of plain text imported script should fail. Reached unreachable code
-FAIL Registering script with good MIME type application/ecmascript promise_test: Unhandled rejection with value: object "[object Event]"
+PASS Registering script with good MIME type application/ecmascript
 PASS Registering script that imports script with good MIME type application/ecmascript
 PASS Registering script with good MIME type application/javascript
 PASS Registering script that imports script with good MIME type application/javascript
-FAIL Registering script with good MIME type application/x-ecmascript promise_test: Unhandled rejection with value: object "[object Event]"
+PASS Registering script with good MIME type application/x-ecmascript
 PASS Registering script that imports script with good MIME type application/x-ecmascript
 PASS Registering script with good MIME type application/x-javascript
 PASS Registering script that imports script with good MIME type application/x-javascript
-FAIL Registering script with good MIME type text/ecmascript promise_test: Unhandled rejection with value: object "[object Event]"
+PASS Registering script with good MIME type text/ecmascript
 PASS Registering script that imports script with good MIME type text/ecmascript
 PASS Registering script with good MIME type text/javascript
 PASS Registering script that imports script with good MIME type text/javascript
-FAIL Registering script with good MIME type text/javascript1.0 promise_test: Unhandled rejection with value: object "[object Event]"
+PASS Registering script with good MIME type text/javascript1.0
 PASS Registering script that imports script with good MIME type text/javascript1.0
-FAIL Registering script with good MIME type text/javascript1.1 promise_test: Unhandled rejection with value: object "[object Event]"
+PASS Registering script with good MIME type text/javascript1.1
 PASS Registering script that imports script with good MIME type text/javascript1.1
-FAIL Registering script with good MIME type text/javascript1.2 promise_test: Unhandled rejection with value: object "[object Event]"
+PASS Registering script with good MIME type text/javascript1.2
 PASS Registering script that imports script with good MIME type text/javascript1.2
-FAIL Registering script with good MIME type text/javascript1.3 promise_test: Unhandled rejection with value: object "[object Event]"
+PASS Registering script with good MIME type text/javascript1.3
 PASS Registering script that imports script with good MIME type text/javascript1.3
-FAIL Registering script with good MIME type text/javascript1.4 promise_test: Unhandled rejection with value: object "[object Event]"
+PASS Registering script with good MIME type text/javascript1.4
 PASS Registering script that imports script with good MIME type text/javascript1.4
-FAIL Registering script with good MIME type text/javascript1.5 promise_test: Unhandled rejection with value: object "[object Event]"
+PASS Registering script with good MIME type text/javascript1.5
 PASS Registering script that imports script with good MIME type text/javascript1.5
-FAIL Registering script with good MIME type text/jscript promise_test: Unhandled rejection with value: object "[object Event]"
+PASS Registering script with good MIME type text/jscript
 PASS Registering script that imports script with good MIME type text/jscript
-FAIL Registering script with good MIME type text/livescript promise_test: Unhandled rejection with value: object "[object Event]"
+PASS Registering script with good MIME type text/livescript
 PASS Registering script that imports script with good MIME type text/livescript
-FAIL Registering script with good MIME type text/x-ecmascript promise_test: Unhandled rejection with value: object "[object Event]"
+PASS Registering script with good MIME type text/x-ecmascript
 PASS Registering script that imports script with good MIME type text/x-ecmascript
-FAIL Registering script with good MIME type text/x-javascript promise_test: Unhandled rejection with value: object "[object Event]"
+PASS Registering script with good MIME type text/x-javascript
 PASS Registering script that imports script with good MIME type text/x-javascript
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/registration-mime-types.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/registration-mime-types.https-expected.txt
index e4d2ccd0..c6c3cbc 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/registration-mime-types.https-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/registration-mime-types.https-expected.txt
@@ -3,37 +3,37 @@
 PASS Registering script with bad MIME type
 FAIL Registering script that imports script with no MIME type assert_unreached: Should have rejected: Registration of no MIME type imported script should fail. Reached unreachable code
 FAIL Registering script that imports script with bad MIME type assert_unreached: Should have rejected: Registration of plain text imported script should fail. Reached unreachable code
-FAIL Registering script with good MIME type application/ecmascript promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('application/ecmascript')."
+PASS Registering script with good MIME type application/ecmascript
 PASS Registering script that imports script with good MIME type application/ecmascript
 PASS Registering script with good MIME type application/javascript
 PASS Registering script that imports script with good MIME type application/javascript
-FAIL Registering script with good MIME type application/x-ecmascript promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('application/x-ecmascript')."
+PASS Registering script with good MIME type application/x-ecmascript
 PASS Registering script that imports script with good MIME type application/x-ecmascript
 PASS Registering script with good MIME type application/x-javascript
 PASS Registering script that imports script with good MIME type application/x-javascript
-FAIL Registering script with good MIME type text/ecmascript promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/ecmascript')."
+PASS Registering script with good MIME type text/ecmascript
 PASS Registering script that imports script with good MIME type text/ecmascript
 PASS Registering script with good MIME type text/javascript
 PASS Registering script that imports script with good MIME type text/javascript
-FAIL Registering script with good MIME type text/javascript1.0 promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/javascript1.0')."
+PASS Registering script with good MIME type text/javascript1.0
 PASS Registering script that imports script with good MIME type text/javascript1.0
-FAIL Registering script with good MIME type text/javascript1.1 promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/javascript1.1')."
+PASS Registering script with good MIME type text/javascript1.1
 PASS Registering script that imports script with good MIME type text/javascript1.1
-FAIL Registering script with good MIME type text/javascript1.2 promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/javascript1.2')."
+PASS Registering script with good MIME type text/javascript1.2
 PASS Registering script that imports script with good MIME type text/javascript1.2
-FAIL Registering script with good MIME type text/javascript1.3 promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/javascript1.3')."
+PASS Registering script with good MIME type text/javascript1.3
 PASS Registering script that imports script with good MIME type text/javascript1.3
-FAIL Registering script with good MIME type text/javascript1.4 promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/javascript1.4')."
+PASS Registering script with good MIME type text/javascript1.4
 PASS Registering script that imports script with good MIME type text/javascript1.4
-FAIL Registering script with good MIME type text/javascript1.5 promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/javascript1.5')."
+PASS Registering script with good MIME type text/javascript1.5
 PASS Registering script that imports script with good MIME type text/javascript1.5
-FAIL Registering script with good MIME type text/jscript promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/jscript')."
+PASS Registering script with good MIME type text/jscript
 PASS Registering script that imports script with good MIME type text/jscript
-FAIL Registering script with good MIME type text/livescript promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/livescript')."
+PASS Registering script with good MIME type text/livescript
 PASS Registering script that imports script with good MIME type text/livescript
-FAIL Registering script with good MIME type text/x-ecmascript promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/x-ecmascript')."
+PASS Registering script with good MIME type text/x-ecmascript
 PASS Registering script that imports script with good MIME type text/x-ecmascript
-FAIL Registering script with good MIME type text/x-javascript promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/x-javascript')."
+PASS Registering script with good MIME type text/x-javascript
 PASS Registering script that imports script with good MIME type text/x-javascript
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/serviceworker/cache-add.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/serviceworker/cache-add.https-expected.txt
deleted file mode 100644
index a1555dcb8..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/serviceworker/cache-add.https-expected.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-This is a testharness.js-based test.
-PASS Cache.add and Cache.addAll
-PASS Cache.add called with no arguments
-PASS Cache.add called with relative URL specified as a string
-PASS Cache.add called with non-HTTP/HTTPS URL
-PASS Cache.add called with Request object
-PASS Cache.add called with POST request
-PASS Cache.add called twice with the same Request object
-PASS Cache.add with request with null body (not consumed)
-PASS Cache.add with 206 response
-PASS Cache.addAll with 206 response
-PASS Cache.add with request that results in a status of 404
-PASS Cache.add with request that results in a status of 500
-PASS Cache.addAll with no arguments
-PASS Cache.addAll with a mix of valid and undefined arguments
-PASS Cache.addAll with an empty array
-PASS Cache.addAll with string URL arguments
-PASS Cache.addAll with Request arguments
-PASS Cache.addAll with a mix of succeeding and failing requests
-FAIL Cache.addAll called with the same Request object specified twice assert_unreached: Should have rejected: Cache.addAll should throw InvalidStateError if the same request is added twice. Reached unreachable code
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/serviceworker/cache-matchAll.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/serviceworker/cache-matchAll.https-expected.txt
deleted file mode 100644
index 83bb89f..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/serviceworker/cache-matchAll.https-expected.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-This is a testharness.js-based test.
-PASS Cache.matchAll
-PASS Cache.matchAll with no matching entries
-PASS Cache.matchAll with URL
-PASS Cache.matchAll with Request
-PASS Cache.matchAll with new Request
-PASS Cache.matchAll with HEAD
-PASS Cache.matchAll with ignoreSearch option (request with no search parameters)
-PASS Cache.matchAll with ignoreSearch option (request with search parameters)
-PASS Cache.matchAll supports ignoreMethod
-PASS Cache.matchAll supports ignoreVary
-PASS Cache.matchAll with URL containing fragment
-PASS Cache.matchAll with string fragment "http" as query
-PASS Cache.matchAll without parameters
-FAIL Cache.matchAll with responses containing "Vary" header assert_equals: Cache.matchAll should match the entire header if a vary header is present in both the query and cached requests. expected 1 but got 0
-FAIL Cache.matchAll with multiple vary pairs assert_equals: Cache.matchAll should support multiple vary request/response pairs. expected 3 but got 1
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/serviceworker/cache-storage.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/serviceworker/cache-storage.https-expected.txt
deleted file mode 100644
index 22932f4..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/serviceworker/cache-storage.https-expected.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-This is a testharness.js-based test.
-PASS CacheStorage
-PASS CacheStorage.open
-PASS CacheStorage.delete dooms, but does not delete immediately
-PASS CacheStorage.open with an empty name
-PASS CacheStorage.open with no arguments
-PASS CacheStorage.has with existing cache
-PASS CacheStorage.has with nonexistent cache
-PASS CacheStorage.open with existing cache
-PASS CacheStorage.delete with existing cache
-PASS CacheStorage.delete with nonexistent cache
-FAIL CacheStorage names are DOMStrings not USVStrings assert_true: keys should include cache with bad name expected true got false
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/window/cache-add.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/window/cache-add.https-expected.txt
deleted file mode 100644
index 3f3f278..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/window/cache-add.https-expected.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-This is a testharness.js-based test.
-PASS Cache.add called with no arguments
-PASS Cache.add called with relative URL specified as a string
-PASS Cache.add called with non-HTTP/HTTPS URL
-PASS Cache.add called with Request object
-PASS Cache.add called with POST request
-PASS Cache.add called twice with the same Request object
-PASS Cache.add with request with null body (not consumed)
-PASS Cache.add with 206 response
-PASS Cache.addAll with 206 response
-PASS Cache.add with request that results in a status of 404
-PASS Cache.add with request that results in a status of 500
-PASS Cache.addAll with no arguments
-PASS Cache.addAll with a mix of valid and undefined arguments
-PASS Cache.addAll with an empty array
-PASS Cache.addAll with string URL arguments
-PASS Cache.addAll with Request arguments
-PASS Cache.addAll with a mix of succeeding and failing requests
-FAIL Cache.addAll called with the same Request object specified twice assert_unreached: Should have rejected: Cache.addAll should throw InvalidStateError if the same request is added twice. Reached unreachable code
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/window/cache-matchAll.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/window/cache-matchAll.https-expected.txt
deleted file mode 100644
index 69fcf49eb..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/window/cache-matchAll.https-expected.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-This is a testharness.js-based test.
-PASS Cache.matchAll with no matching entries
-PASS Cache.matchAll with URL
-PASS Cache.matchAll with Request
-PASS Cache.matchAll with new Request
-PASS Cache.matchAll with HEAD
-PASS Cache.matchAll with ignoreSearch option (request with no search parameters)
-PASS Cache.matchAll with ignoreSearch option (request with search parameters)
-PASS Cache.matchAll supports ignoreMethod
-PASS Cache.matchAll supports ignoreVary
-PASS Cache.matchAll with URL containing fragment
-PASS Cache.matchAll with string fragment "http" as query
-PASS Cache.matchAll without parameters
-FAIL Cache.matchAll with responses containing "Vary" header assert_equals: Cache.matchAll should match the entire header if a vary header is present in both the query and cached requests. expected 1 but got 0
-FAIL Cache.matchAll with multiple vary pairs assert_equals: Cache.matchAll should support multiple vary request/response pairs. expected 3 but got 1
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/window/cache-storage.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/window/cache-storage.https-expected.txt
deleted file mode 100644
index d1c62496..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/window/cache-storage.https-expected.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-This is a testharness.js-based test.
-PASS CacheStorage.open
-PASS CacheStorage.delete dooms, but does not delete immediately
-PASS CacheStorage.open with an empty name
-PASS CacheStorage.open with no arguments
-PASS CacheStorage.has with existing cache
-PASS CacheStorage.has with nonexistent cache
-PASS CacheStorage.open with existing cache
-PASS CacheStorage.delete with existing cache
-PASS CacheStorage.delete with nonexistent cache
-FAIL CacheStorage names are DOMStrings not USVStrings assert_true: keys should include cache with bad name expected true got false
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/window/sandboxed-iframes.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/window/sandboxed-iframes.https-expected.txt
deleted file mode 100644
index dc39b96..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/window/sandboxed-iframes.https-expected.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-
-This is a testharness.js-based test.
-PASS Sandboxed iframe with allow-same-origin is allowed access
-FAIL Sandboxed iframe without allow-same-origin is denied access assert_equals: Access should be denied if sandbox lacks allow-same-origin expected "denied" but got "unexpecteddenied"
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/worker/cache-add.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/worker/cache-add.https-expected.txt
deleted file mode 100644
index 3f3f278..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/worker/cache-add.https-expected.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-This is a testharness.js-based test.
-PASS Cache.add called with no arguments
-PASS Cache.add called with relative URL specified as a string
-PASS Cache.add called with non-HTTP/HTTPS URL
-PASS Cache.add called with Request object
-PASS Cache.add called with POST request
-PASS Cache.add called twice with the same Request object
-PASS Cache.add with request with null body (not consumed)
-PASS Cache.add with 206 response
-PASS Cache.addAll with 206 response
-PASS Cache.add with request that results in a status of 404
-PASS Cache.add with request that results in a status of 500
-PASS Cache.addAll with no arguments
-PASS Cache.addAll with a mix of valid and undefined arguments
-PASS Cache.addAll with an empty array
-PASS Cache.addAll with string URL arguments
-PASS Cache.addAll with Request arguments
-PASS Cache.addAll with a mix of succeeding and failing requests
-FAIL Cache.addAll called with the same Request object specified twice assert_unreached: Should have rejected: Cache.addAll should throw InvalidStateError if the same request is added twice. Reached unreachable code
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/worker/cache-matchAll.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/worker/cache-matchAll.https-expected.txt
deleted file mode 100644
index 69fcf49eb..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/worker/cache-matchAll.https-expected.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-This is a testharness.js-based test.
-PASS Cache.matchAll with no matching entries
-PASS Cache.matchAll with URL
-PASS Cache.matchAll with Request
-PASS Cache.matchAll with new Request
-PASS Cache.matchAll with HEAD
-PASS Cache.matchAll with ignoreSearch option (request with no search parameters)
-PASS Cache.matchAll with ignoreSearch option (request with search parameters)
-PASS Cache.matchAll supports ignoreMethod
-PASS Cache.matchAll supports ignoreVary
-PASS Cache.matchAll with URL containing fragment
-PASS Cache.matchAll with string fragment "http" as query
-PASS Cache.matchAll without parameters
-FAIL Cache.matchAll with responses containing "Vary" header assert_equals: Cache.matchAll should match the entire header if a vary header is present in both the query and cached requests. expected 1 but got 0
-FAIL Cache.matchAll with multiple vary pairs assert_equals: Cache.matchAll should support multiple vary request/response pairs. expected 3 but got 1
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/worker/cache-storage.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/worker/cache-storage.https-expected.txt
deleted file mode 100644
index d1c62496..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/worker/cache-storage.https-expected.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-This is a testharness.js-based test.
-PASS CacheStorage.open
-PASS CacheStorage.delete dooms, but does not delete immediately
-PASS CacheStorage.open with an empty name
-PASS CacheStorage.open with no arguments
-PASS CacheStorage.has with existing cache
-PASS CacheStorage.has with nonexistent cache
-PASS CacheStorage.open with existing cache
-PASS CacheStorage.delete with existing cache
-PASS CacheStorage.delete with nonexistent cache
-FAIL CacheStorage names are DOMStrings not USVStrings assert_true: keys should include cache with bad name expected true got false
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/clients-get-client-types.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/clients-get-client-types.https-expected.txt
deleted file mode 100644
index 58bae30..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/clients-get-client-types.https-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Test Clients.get() with window and worker clients assert_not_equals: Worker(Started by main frame) client should not be undefined got disallowed value undefined
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/clients-matchall-client-types.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/clients-matchall-client-types.https-expected.txt
deleted file mode 100644
index 1f2011a..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/clients-matchall-client-types.https-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-FAIL Verify matchAll() with window client type assert_unreached: unexpected rejection: assert_array_equals: property 2, expected "https://web-platform.test:8444/service-workers/service-worker/resources/clients-matchall-client-types-iframe.html" but got "https://web-platform.test:8444/service-workers/service-worker/resources/url-modified-via-pushstate.html" Reached unreachable code
-FAIL Verify matchAll() with {window, sharedworker, worker} client types promise_test: Unhandled rejection with value: object "Error: wait_for_state must be passed a ServiceWorker"
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/clients-matchall-order.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/clients-matchall-order.https-expected.txt
deleted file mode 100644
index 78737fe..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/clients-matchall-order.https-expected.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-This is a testharness.js-based test.
-PASS Clients.matchAll() returns non-focused controlled windows in creation order.
-PASS Clients.matchAll() returns controlled windows in focus order.  Case 1.
-PASS Clients.matchAll() returns controlled windows in focus order.  Case 2.
-FAIL Clients.matchAll() returns non-focused uncontrolled windows in creation order. assert_equals: expected 6 but got 5
-FAIL Clients.matchAll() returns uncontrolled windows in focus order.  Case 1. assert_equals: expected 6 but got 5
-FAIL Clients.matchAll() returns uncontrolled windows in focus order.  Case 2. assert_equals: expected 6 but got 5
-FAIL Clients.matchAll() returns controlled windows and frames in focus order. assert_equals: expected URL index 1 expected "https://web-platform.test:8444/service-workers/service-worker/resources/empty.html?name=focus-controlled-nested-windows&q=1" but got "https://web-platform.test:8444/service-workers/service-worker/resources/empty.html?name=focus-controlled-nested-windows&q=1&nested=true"
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/fetch-event-redirect.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/fetch-event-redirect.https-expected.txt
deleted file mode 100644
index f91bc57e..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/fetch-event-redirect.https-expected.txt
+++ /dev/null
@@ -1,57 +0,0 @@
-This is a testharness.js-based test.
-PASS Non-navigation, manual redirect, cors mode Request redirected to same-origin without credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, cors mode Request redirected to no-cors without credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, cors mode Request redirected to cors without credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, same-origin mode Request redirected to same-origin without credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, same-origin mode Request redirected to no-cors without credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, same-origin mode Request redirected to cors without credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, no-cors mode Request redirected to same-origin without credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, no-cors mode Request redirected to no-cors without credentials should succeed interception and response should not be redirected
-PASS Non-navigation, manual redirect, no-cors mode Request redirected to cors without credentials should succeed interception and response should not be redirected
-PASS Non-navigation, manual redirect, cors mode Request redirected to same-origin with credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, cors mode Request redirected to no-cors with credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, cors mode Request redirected to cors with credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, same-origin mode Request redirected to same-origin with credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, same-origin mode Request redirected to no-cors with credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, same-origin mode Request redirected to cors with credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, no-cors mode Request redirected to same-origin with credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, no-cors mode Request redirected to no-cors with credentials should succeed interception and response should not be redirected
-PASS Non-navigation, manual redirect, no-cors mode Request redirected to cors with credentials should succeed interception and response should not be redirected
-PASS Non-navigation, follow redirect, cors mode Request redirected to same-origin without credentials should succeed interception and response should be redirected
-PASS Non-navigation, follow redirect, cors mode Request redirected to no-cors without credentials should fail interception and response should not be redirected
-PASS Non-navigation, follow redirect, cors mode Request redirected to cors without credentials should succeed interception and response should be redirected
-PASS Non-navigation, follow redirect, same-origin mode Request redirected to same-origin without credentials should succeed interception and response should be redirected
-PASS Non-navigation, follow redirect, same-origin mode Request redirected to no-cors without credentials should fail interception and response should not be redirected
-PASS Non-navigation, follow redirect, same-origin mode Request redirected to cors without credentials should fail interception and response should not be redirected
-PASS Non-navigation, follow redirect, no-cors mode Request redirected to same-origin without credentials should succeed interception and response should be redirected
-PASS Non-navigation, follow redirect, no-cors mode Request redirected to no-cors without credentials should succeed interception and response should not be redirected
-PASS Non-navigation, follow redirect, no-cors mode Request redirected to cors without credentials should succeed interception and response should not be redirected
-FAIL Non-navigation, follow redirect, cors mode Request redirected to same-origin with credentials should succeed interception and response should be redirected assert_unreached: unexpected rejection: TypeError: Failed to fetch Reached unreachable code
-PASS Non-navigation, follow redirect, cors mode Request redirected to no-cors with credentials should fail interception and response should not be redirected
-PASS Non-navigation, follow redirect, cors mode Request redirected to cors with credentials should fail interception and response should be redirected
-FAIL Non-navigation, follow redirect, same-origin mode Request redirected to same-origin with credentials should succeed interception and response should be redirected assert_unreached: unexpected rejection: TypeError: Failed to fetch Reached unreachable code
-PASS Non-navigation, follow redirect, same-origin mode Request redirected to no-cors with credentials should fail interception and response should not be redirected
-PASS Non-navigation, follow redirect, same-origin mode Request redirected to cors with credentials should fail interception and response should not be redirected
-FAIL Non-navigation, follow redirect, no-cors mode Request redirected to same-origin with credentials should succeed interception and response should be redirected assert_unreached: unexpected rejection: TypeError: Failed to fetch Reached unreachable code
-FAIL Non-navigation, follow redirect, no-cors mode Request redirected to no-cors with credentials should succeed interception and response should not be redirected assert_unreached: unexpected rejection: TypeError: Failed to fetch Reached unreachable code
-FAIL Non-navigation, follow redirect, no-cors mode Request redirected to cors with credentials should succeed interception and response should not be redirected assert_unreached: unexpected rejection: TypeError: Failed to fetch Reached unreachable code
-PASS Non-navigation, error redirect, cors mode Request redirected to same-origin without credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, cors mode Request redirected to no-cors without credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, cors mode Request redirected to cors without credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, same-origin mode Request redirected to same-origin without credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, same-origin mode Request redirected to no-cors without credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, same-origin mode Request redirected to cors without credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, no-cors mode Request redirected to same-origin without credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, no-cors mode Request redirected to no-cors without credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, no-cors mode Request redirected to cors without credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, cors mode Request redirected to same-origin with credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, cors mode Request redirected to no-cors with credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, cors mode Request redirected to cors with credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, same-origin mode Request redirected to same-origin with credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, same-origin mode Request redirected to no-cors with credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, same-origin mode Request redirected to cors with credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, no-cors mode Request redirected to same-origin with credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, no-cors mode Request redirected to no-cors with credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, no-cors mode Request redirected to cors with credentials should fail interception and response should not be redirected
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/fetch-event-referrer-policy.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/fetch-event-referrer-policy.https-expected.txt
deleted file mode 100644
index 4ed287e..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/fetch-event-referrer-policy.https-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Service Worker responds to fetch event with the referrer policy assert_unreached: unexpected rejection: assert_equals: Service Worker should respond to fetch with the referrer URL when a member of RequestInit is present expected "Referrer: https://web-platform.test:8444/service-workers/service-worker/fake-referrer\nReferrerPolicy: no-referrer-when-downgrade" but got "Referrer: https://web-platform.test:8444/service-workers/service-worker/resources/fake-referrer\nReferrerPolicy: no-referrer-when-downgrade" Reached unreachable code
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/fetch-event-within-sw-manual.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/fetch-event-within-sw-manual.https-expected.txt
deleted file mode 100644
index e774a74..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/fetch-event-within-sw-manual.https-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Notification requests intercepted both from window and SW promise_test: Unhandled rejection with value: object "Error: You must allow notifications for this origin before running this test."
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/fetch-event.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/fetch-event.https-expected.txt
deleted file mode 100644
index 2eb875c..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/fetch-event.https-expected.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-This is a testharness.js-based test.
-PASS Service Worker headers in the request of a fetch event
-PASS Service Worker responds to fetch event with string
-PASS Service Worker responds to fetch event with blob body
-PASS Service Worker responds to fetch event with the referrer URL
-PASS Service Worker responds to fetch event with an existing client id
-PASS Service Worker does not respond to fetch event
-PASS Service Worker responds to fetch event with null response body
-PASS Service Worker fetches other file in fetch event
-PASS Service Worker responds to fetch event with POST form
-PASS Multiple calls of respondWith must throw InvalidStateErrors
-PASS Service Worker event.respondWith must set the used flag
-PASS Service Worker should expose FetchEvent URL fragments.
-FAIL Service Worker responds to fetch event with the correct cache types assert_unreached: unexpected rejection: assert_equals: Service Worker should respond to fetch with the correct type expected "no-store" but got "default" Reached unreachable code
-FAIL Service Worker should intercept EventSource assert_unreached: unexpected rejection: assert_equals: EventSource should bypass the http cache. expected "no-store" but got "default" Reached unreachable code
-FAIL Service Worker responds to fetch event with the correct integrity_metadata assert_unreached: unexpected rejection: assert_equals: integrity expected "gs0nqru8KbsrIt5YToQqS9fYao4GQJXtcId610g7cCU=" but got "" Reached unreachable code
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/fetch-request-xhr-sync.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/fetch-request-xhr-sync.https-expected.txt
deleted file mode 100644
index 724b7d8..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/fetch-request-xhr-sync.https-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Verify SyncXHR is intercepted assert_equals: HTTP response status code for intercepted request expected 200 but got 404
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/fetch-request-xhr.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/fetch-request-xhr.https-expected.txt
deleted file mode 100644
index b52f7871..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/fetch-request-xhr.https-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Verify the body of FetchEvent using XMLHttpRequest assert_array_equals: event.request has the expected headers for same-origin GET. lengths differ, expected 1 got 2
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/import-scripts-redirect.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/import-scripts-redirect.https-expected.txt
deleted file mode 100644
index 54836e4..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/import-scripts-redirect.https-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-FAIL importScripts() supports redirects promise_test: Unhandled rejection with value: object "TypeError: Failed to register a ServiceWorker: ServiceWorker script evaluation failed"
-FAIL importScripts() supports redirects and can be updated promise_test: Unhandled rejection with value: object "TypeError: Failed to register a ServiceWorker: ServiceWorker script evaluation failed"
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/import-scripts-updated-flag.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/import-scripts-updated-flag.https-expected.txt
deleted file mode 100644
index 0e50082..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/import-scripts-updated-flag.https-expected.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-This is a testharness.js-based test.
-PASS initialize global state
-PASS import script previously imported at worker evaluation time
-PASS import script previously imported at worker install time
-FAIL import script not previously imported assert_equals: expected (string) "TypeError" but got (object) null
-PASS Tests for importScripts: import scripts updated flag
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/interfaces-sw.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/interfaces-sw.https-expected.txt
deleted file mode 100644
index 3c98081d..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/interfaces-sw.https-expected.txt
+++ /dev/null
@@ -1,187 +0,0 @@
-This is a testharness.js-based test.
-PASS Interfaces and attributes in ServiceWorkerGlobalScope
-PASS test setup (cache creation)
-PASS Event constructors
-PASS ServiceWorkerGlobalScope interface: existence and properties of interface object
-PASS ServiceWorkerGlobalScope interface object length
-PASS ServiceWorkerGlobalScope interface object name
-PASS ServiceWorkerGlobalScope interface: existence and properties of interface prototype object
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to a new value via Object.setPrototypeOf should throw a TypeError
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to a new value via __proto__ should throw a TypeError
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to a new value via Reflect.setPrototypeOf should return false
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to its original value via Object.setPrototypeOf should not throw
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to its original value via __proto__ should not throw
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to its original value via Reflect.setPrototypeOf should return true
-PASS ServiceWorkerGlobalScope interface: existence and properties of interface prototype object's "constructor" property
-PASS ServiceWorkerGlobalScope interface: attribute clients
-PASS ServiceWorkerGlobalScope interface: attribute registration
-PASS ServiceWorkerGlobalScope interface: operation skipWaiting()
-PASS ServiceWorkerGlobalScope interface: attribute oninstall
-PASS ServiceWorkerGlobalScope interface: attribute onactivate
-PASS ServiceWorkerGlobalScope interface: attribute onfetch
-PASS ServiceWorkerGlobalScope interface: attribute onforeignfetch
-PASS ServiceWorkerGlobalScope interface: attribute onmessage
-FAIL ServiceWorkerGlobalScope interface: attribute onmessageerror assert_own_property: The global object must have a property "onmessageerror" expected property "onmessageerror" missing
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to a new value via Object.setPrototypeOf should throw a TypeError
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to a new value via __proto__ should throw a TypeError
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to a new value via Reflect.setPrototypeOf should return false
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to its original value via Object.setPrototypeOf should not throw
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to its original value via __proto__ should not throw
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to its original value via Reflect.setPrototypeOf should return true
-PASS ServiceWorkerGlobalScope must be primary interface of self
-PASS Stringification of self
-PASS ServiceWorkerGlobalScope interface: self must inherit property "clients" with the proper type
-PASS ServiceWorkerGlobalScope interface: self must inherit property "registration" with the proper type
-PASS ServiceWorkerGlobalScope interface: self must inherit property "skipWaiting()" with the proper type
-PASS ServiceWorkerGlobalScope interface: self must inherit property "oninstall" with the proper type
-PASS ServiceWorkerGlobalScope interface: self must inherit property "onactivate" with the proper type
-PASS ServiceWorkerGlobalScope interface: self must inherit property "onfetch" with the proper type
-PASS ServiceWorkerGlobalScope interface: self must inherit property "onforeignfetch" with the proper type
-PASS ServiceWorkerGlobalScope interface: self must inherit property "onmessage" with the proper type
-FAIL ServiceWorkerGlobalScope interface: self must inherit property "onmessageerror" with the proper type assert_own_property: expected property "onmessageerror" missing
-PASS Client interface: existence and properties of interface object
-PASS Client interface object length
-PASS Client interface object name
-PASS Client interface: existence and properties of interface prototype object
-PASS Client interface: existence and properties of interface prototype object's "constructor" property
-PASS Client interface: attribute url
-PASS Client interface: attribute id
-PASS Client interface: attribute type
-FAIL Client interface: attribute reserved assert_true: The prototype object must have a property "reserved" expected true got false
-PASS Client interface: operation postMessage(any, [object Object])
-PASS WindowClient interface: existence and properties of interface object
-PASS WindowClient interface object length
-PASS WindowClient interface object name
-PASS WindowClient interface: existence and properties of interface prototype object
-PASS WindowClient interface: existence and properties of interface prototype object's "constructor" property
-PASS WindowClient interface: attribute visibilityState
-PASS WindowClient interface: attribute focused
-FAIL WindowClient interface: attribute ancestorOrigins assert_true: The prototype object must have a property "ancestorOrigins" expected true got false
-PASS WindowClient interface: operation focus()
-PASS WindowClient interface: operation navigate(USVString)
-PASS Clients interface: existence and properties of interface object
-PASS Clients interface object length
-PASS Clients interface object name
-PASS Clients interface: existence and properties of interface prototype object
-PASS Clients interface: existence and properties of interface prototype object's "constructor" property
-PASS Clients interface: operation get(DOMString)
-PASS Clients interface: operation matchAll(ClientQueryOptions)
-PASS Clients interface: operation openWindow(USVString)
-PASS Clients interface: operation claim()
-PASS Clients must be primary interface of self.clients
-PASS Stringification of self.clients
-PASS Clients interface: self.clients must inherit property "get(DOMString)" with the proper type
-PASS Clients interface: calling get(DOMString) on self.clients with too few arguments must throw TypeError
-PASS Clients interface: self.clients must inherit property "matchAll(ClientQueryOptions)" with the proper type
-PASS Clients interface: calling matchAll(ClientQueryOptions) on self.clients with too few arguments must throw TypeError
-PASS Clients interface: self.clients must inherit property "openWindow(USVString)" with the proper type
-PASS Clients interface: calling openWindow(USVString) on self.clients with too few arguments must throw TypeError
-PASS Clients interface: self.clients must inherit property "claim()" with the proper type
-FAIL ServiceWorker interface: existence and properties of interface object assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface object length assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface object name assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface: existence and properties of interface prototype object assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface: attribute scriptURL assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface: attribute state assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface: operation postMessage(any, [object Object]) assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface: attribute onstatechange assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-PASS ServiceWorkerRegistration interface: existence and properties of interface object
-PASS ServiceWorkerRegistration interface object length
-PASS ServiceWorkerRegistration interface object name
-PASS ServiceWorkerRegistration interface: existence and properties of interface prototype object
-PASS ServiceWorkerRegistration interface: existence and properties of interface prototype object's "constructor" property
-PASS ServiceWorkerRegistration interface: attribute installing
-PASS ServiceWorkerRegistration interface: attribute waiting
-PASS ServiceWorkerRegistration interface: attribute active
-PASS ServiceWorkerRegistration interface: attribute navigationPreload
-PASS ServiceWorkerRegistration interface: attribute scope
-FAIL ServiceWorkerRegistration interface: attribute updateViaCache assert_true: The prototype object must have a property "updateViaCache" expected true got false
-PASS ServiceWorkerRegistration interface: operation update()
-PASS ServiceWorkerRegistration interface: operation unregister()
-PASS ServiceWorkerRegistration interface: attribute onupdatefound
-PASS ServiceWorkerRegistration must be primary interface of self.registration
-PASS Stringification of self.registration
-PASS ServiceWorkerRegistration interface: self.registration must inherit property "installing" with the proper type
-PASS ServiceWorkerRegistration interface: self.registration must inherit property "waiting" with the proper type
-PASS ServiceWorkerRegistration interface: self.registration must inherit property "active" with the proper type
-PASS ServiceWorkerRegistration interface: self.registration must inherit property "navigationPreload" with the proper type
-PASS ServiceWorkerRegistration interface: self.registration must inherit property "scope" with the proper type
-FAIL ServiceWorkerRegistration interface: self.registration must inherit property "updateViaCache" with the proper type assert_inherits: property "updateViaCache" not found in prototype chain
-PASS ServiceWorkerRegistration interface: self.registration must inherit property "update()" with the proper type
-PASS ServiceWorkerRegistration interface: self.registration must inherit property "unregister()" with the proper type
-PASS ServiceWorkerRegistration interface: self.registration must inherit property "onupdatefound" with the proper type
-PASS EventTarget interface: self.registration must inherit property "addEventListener(DOMString, EventListener, [object Object],[object Object])" with the proper type
-PASS EventTarget interface: calling addEventListener(DOMString, EventListener, [object Object],[object Object]) on self.registration with too few arguments must throw TypeError
-PASS EventTarget interface: self.registration must inherit property "removeEventListener(DOMString, EventListener, [object Object],[object Object])" with the proper type
-PASS EventTarget interface: calling removeEventListener(DOMString, EventListener, [object Object],[object Object]) on self.registration with too few arguments must throw TypeError
-PASS EventTarget interface: self.registration must inherit property "dispatchEvent(Event)" with the proper type
-PASS EventTarget interface: calling dispatchEvent(Event) on self.registration with too few arguments must throw TypeError
-PASS EventTarget interface: existence and properties of interface object
-PASS EventTarget interface object length
-PASS EventTarget interface object name
-PASS EventTarget interface: existence and properties of interface prototype object
-PASS EventTarget interface: existence and properties of interface prototype object's "constructor" property
-PASS EventTarget interface: operation addEventListener(DOMString, EventListener, [object Object],[object Object])
-PASS EventTarget interface: operation removeEventListener(DOMString, EventListener, [object Object],[object Object])
-PASS EventTarget interface: operation dispatchEvent(Event)
-PASS NavigationPreloadManager interface: existence and properties of interface object
-PASS NavigationPreloadManager interface object length
-PASS NavigationPreloadManager interface object name
-PASS NavigationPreloadManager interface: existence and properties of interface prototype object
-PASS NavigationPreloadManager interface: existence and properties of interface prototype object's "constructor" property
-PASS NavigationPreloadManager interface: operation enable()
-PASS NavigationPreloadManager interface: operation disable()
-PASS NavigationPreloadManager interface: operation setHeaderValue(ByteString)
-PASS NavigationPreloadManager interface: operation getState()
-PASS Cache interface: existence and properties of interface object
-PASS Cache interface object length
-PASS Cache interface object name
-PASS Cache interface: existence and properties of interface prototype object
-PASS Cache interface: existence and properties of interface prototype object's "constructor" property
-PASS Cache interface: operation match(RequestInfo, CacheQueryOptions)
-PASS Cache interface: operation matchAll(RequestInfo, CacheQueryOptions)
-PASS Cache interface: operation add(RequestInfo)
-PASS Cache interface: operation addAll([object Object])
-PASS Cache interface: operation put(RequestInfo, Response)
-PASS Cache interface: operation delete(RequestInfo, CacheQueryOptions)
-PASS Cache interface: operation keys(RequestInfo, CacheQueryOptions)
-PASS Cache must be primary interface of self.cacheInstance
-PASS Stringification of self.cacheInstance
-PASS Cache interface: self.cacheInstance must inherit property "match(RequestInfo, CacheQueryOptions)" with the proper type
-PASS Cache interface: calling match(RequestInfo, CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "matchAll(RequestInfo, CacheQueryOptions)" with the proper type
-PASS Cache interface: calling matchAll(RequestInfo, CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "add(RequestInfo)" with the proper type
-PASS Cache interface: calling add(RequestInfo) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "addAll([object Object])" with the proper type
-PASS Cache interface: calling addAll([object Object]) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "put(RequestInfo, Response)" with the proper type
-PASS Cache interface: calling put(RequestInfo, Response) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "delete(RequestInfo, CacheQueryOptions)" with the proper type
-PASS Cache interface: calling delete(RequestInfo, CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "keys(RequestInfo, CacheQueryOptions)" with the proper type
-PASS Cache interface: calling keys(RequestInfo, CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError
-PASS CacheStorage interface: existence and properties of interface object
-PASS CacheStorage interface object length
-PASS CacheStorage interface object name
-PASS CacheStorage interface: existence and properties of interface prototype object
-PASS CacheStorage interface: existence and properties of interface prototype object's "constructor" property
-PASS CacheStorage interface: operation match(RequestInfo, CacheQueryOptions)
-PASS CacheStorage interface: operation has(DOMString)
-PASS CacheStorage interface: operation open(DOMString)
-PASS CacheStorage interface: operation delete(DOMString)
-PASS CacheStorage interface: operation keys()
-PASS CacheStorage must be primary interface of self.caches
-PASS Stringification of self.caches
-PASS CacheStorage interface: self.caches must inherit property "match(RequestInfo, CacheQueryOptions)" with the proper type
-PASS CacheStorage interface: calling match(RequestInfo, CacheQueryOptions) on self.caches with too few arguments must throw TypeError
-PASS CacheStorage interface: self.caches must inherit property "has(DOMString)" with the proper type
-PASS CacheStorage interface: calling has(DOMString) on self.caches with too few arguments must throw TypeError
-PASS CacheStorage interface: self.caches must inherit property "open(DOMString)" with the proper type
-PASS CacheStorage interface: calling open(DOMString) on self.caches with too few arguments must throw TypeError
-PASS CacheStorage interface: self.caches must inherit property "delete(DOMString)" with the proper type
-PASS CacheStorage interface: calling delete(DOMString) on self.caches with too few arguments must throw TypeError
-PASS CacheStorage interface: self.caches must inherit property "keys()" with the proper type
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/interfaces-window.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/interfaces-window.https-expected.txt
deleted file mode 100644
index 178972d..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/interfaces-window.https-expected.txt
+++ /dev/null
@@ -1,101 +0,0 @@
-This is a testharness.js-based test.
-PASS test setup (worker registration)
-PASS WorkerGlobalScope interface: existence and properties of interface object
-PASS ServiceWorkerGlobalScope interface: existence and properties of interface object
-PASS Client interface: existence and properties of interface object
-PASS WindowClient interface: existence and properties of interface object
-PASS Clients interface: existence and properties of interface object
-PASS ServiceWorker interface: existence and properties of interface object
-PASS ServiceWorker interface object length
-PASS ServiceWorker interface object name
-PASS ServiceWorker interface: existence and properties of interface prototype object
-PASS ServiceWorker interface: existence and properties of interface prototype object's "constructor" property
-PASS ServiceWorker interface: attribute scriptURL
-PASS ServiceWorker interface: attribute state
-PASS ServiceWorker interface: operation postMessage(any, [object Object])
-PASS ServiceWorker interface: attribute onstatechange
-PASS ServiceWorker must be primary interface of window.registrationInstance.installing
-PASS Stringification of window.registrationInstance.installing
-PASS ServiceWorker interface: window.registrationInstance.installing must inherit property "scriptURL" with the proper type
-PASS ServiceWorker interface: window.registrationInstance.installing must inherit property "state" with the proper type
-PASS ServiceWorker interface: window.registrationInstance.installing must inherit property "postMessage(any, [object Object])" with the proper type
-PASS ServiceWorker interface: calling postMessage(any, [object Object]) on window.registrationInstance.installing with too few arguments must throw TypeError
-PASS ServiceWorker interface: window.registrationInstance.installing must inherit property "onstatechange" with the proper type
-PASS EventTarget interface: window.registrationInstance.installing must inherit property "addEventListener(DOMString, EventListener, [object Object],[object Object])" with the proper type
-PASS EventTarget interface: calling addEventListener(DOMString, EventListener, [object Object],[object Object]) on window.registrationInstance.installing with too few arguments must throw TypeError
-PASS EventTarget interface: window.registrationInstance.installing must inherit property "removeEventListener(DOMString, EventListener, [object Object],[object Object])" with the proper type
-PASS EventTarget interface: calling removeEventListener(DOMString, EventListener, [object Object],[object Object]) on window.registrationInstance.installing with too few arguments must throw TypeError
-PASS EventTarget interface: window.registrationInstance.installing must inherit property "dispatchEvent(Event)" with the proper type
-PASS EventTarget interface: calling dispatchEvent(Event) on window.registrationInstance.installing with too few arguments must throw TypeError
-PASS ServiceWorkerRegistration interface: existence and properties of interface object
-PASS ServiceWorkerRegistration interface object length
-PASS ServiceWorkerRegistration interface object name
-PASS ServiceWorkerRegistration interface: existence and properties of interface prototype object
-PASS ServiceWorkerRegistration interface: existence and properties of interface prototype object's "constructor" property
-PASS ServiceWorkerRegistration interface: attribute installing
-PASS ServiceWorkerRegistration interface: attribute waiting
-PASS ServiceWorkerRegistration interface: attribute active
-PASS ServiceWorkerRegistration interface: attribute navigationPreload
-PASS ServiceWorkerRegistration interface: attribute scope
-FAIL ServiceWorkerRegistration interface: attribute updateViaCache assert_true: The prototype object must have a property "updateViaCache" expected true got false
-PASS ServiceWorkerRegistration interface: operation update()
-PASS ServiceWorkerRegistration interface: operation unregister()
-PASS ServiceWorkerRegistration interface: attribute onupdatefound
-PASS ServiceWorkerRegistration must be primary interface of window.registrationInstance
-PASS Stringification of window.registrationInstance
-PASS ServiceWorkerRegistration interface: window.registrationInstance must inherit property "installing" with the proper type
-PASS ServiceWorkerRegistration interface: window.registrationInstance must inherit property "waiting" with the proper type
-PASS ServiceWorkerRegistration interface: window.registrationInstance must inherit property "active" with the proper type
-PASS ServiceWorkerRegistration interface: window.registrationInstance must inherit property "navigationPreload" with the proper type
-PASS ServiceWorkerRegistration interface: window.registrationInstance must inherit property "scope" with the proper type
-FAIL ServiceWorkerRegistration interface: window.registrationInstance must inherit property "updateViaCache" with the proper type assert_inherits: property "updateViaCache" not found in prototype chain
-PASS ServiceWorkerRegistration interface: window.registrationInstance must inherit property "update()" with the proper type
-PASS ServiceWorkerRegistration interface: window.registrationInstance must inherit property "unregister()" with the proper type
-PASS ServiceWorkerRegistration interface: window.registrationInstance must inherit property "onupdatefound" with the proper type
-PASS EventTarget interface: window.registrationInstance must inherit property "addEventListener(DOMString, EventListener, [object Object],[object Object])" with the proper type
-PASS EventTarget interface: calling addEventListener(DOMString, EventListener, [object Object],[object Object]) on window.registrationInstance with too few arguments must throw TypeError
-PASS EventTarget interface: window.registrationInstance must inherit property "removeEventListener(DOMString, EventListener, [object Object],[object Object])" with the proper type
-PASS EventTarget interface: calling removeEventListener(DOMString, EventListener, [object Object],[object Object]) on window.registrationInstance with too few arguments must throw TypeError
-PASS EventTarget interface: window.registrationInstance must inherit property "dispatchEvent(Event)" with the proper type
-PASS EventTarget interface: calling dispatchEvent(Event) on window.registrationInstance with too few arguments must throw TypeError
-PASS EventTarget interface: existence and properties of interface object
-PASS EventTarget interface object length
-PASS EventTarget interface object name
-PASS EventTarget interface: existence and properties of interface prototype object
-PASS EventTarget interface: existence and properties of interface prototype object's "constructor" property
-PASS EventTarget interface: operation addEventListener(DOMString, EventListener, [object Object],[object Object])
-PASS EventTarget interface: operation removeEventListener(DOMString, EventListener, [object Object],[object Object])
-PASS EventTarget interface: operation dispatchEvent(Event)
-PASS NavigationPreloadManager interface: existence and properties of interface object
-PASS NavigationPreloadManager interface object length
-PASS NavigationPreloadManager interface object name
-PASS NavigationPreloadManager interface: existence and properties of interface prototype object
-PASS NavigationPreloadManager interface: existence and properties of interface prototype object's "constructor" property
-PASS NavigationPreloadManager interface: operation enable()
-PASS NavigationPreloadManager interface: operation disable()
-PASS NavigationPreloadManager interface: operation setHeaderValue(ByteString)
-PASS NavigationPreloadManager interface: operation getState()
-PASS Cache interface: existence and properties of interface object
-PASS Cache interface object length
-PASS Cache interface object name
-PASS Cache interface: existence and properties of interface prototype object
-PASS Cache interface: existence and properties of interface prototype object's "constructor" property
-PASS Cache interface: operation match(RequestInfo, CacheQueryOptions)
-PASS Cache interface: operation matchAll(RequestInfo, CacheQueryOptions)
-PASS Cache interface: operation add(RequestInfo)
-PASS Cache interface: operation addAll([object Object])
-PASS Cache interface: operation put(RequestInfo, Response)
-PASS Cache interface: operation delete(RequestInfo, CacheQueryOptions)
-PASS Cache interface: operation keys(RequestInfo, CacheQueryOptions)
-PASS CacheStorage interface: existence and properties of interface object
-PASS CacheStorage interface object length
-PASS CacheStorage interface object name
-PASS CacheStorage interface: existence and properties of interface prototype object
-PASS CacheStorage interface: existence and properties of interface prototype object's "constructor" property
-PASS CacheStorage interface: operation match(RequestInfo, CacheQueryOptions)
-PASS CacheStorage interface: operation has(DOMString)
-PASS CacheStorage interface: operation open(DOMString)
-PASS CacheStorage interface: operation delete(DOMString)
-PASS CacheStorage interface: operation keys()
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/link-element-register-mime-types.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/link-element-register-mime-types.https-expected.txt
deleted file mode 100644
index 28bf3a7..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/link-element-register-mime-types.https-expected.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-This is a testharness.js-based test.
-FAIL Registering script with no MIME type Test bug: need to pass exception to assert_throws()
-FAIL Registering script with bad MIME type Test bug: need to pass exception to assert_throws()
-FAIL Registering script that imports script with no MIME type assert_unreached: Should have rejected: Registration of no MIME type imported script should fail. Reached unreachable code
-FAIL Registering script that imports script with bad MIME type assert_unreached: Should have rejected: Registration of plain text imported script should fail. Reached unreachable code
-FAIL Registering script with good MIME type application/ecmascript promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type application/ecmascript
-PASS Registering script with good MIME type application/javascript
-PASS Registering script that imports script with good MIME type application/javascript
-FAIL Registering script with good MIME type application/x-ecmascript promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type application/x-ecmascript
-PASS Registering script with good MIME type application/x-javascript
-PASS Registering script that imports script with good MIME type application/x-javascript
-FAIL Registering script with good MIME type text/ecmascript promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type text/ecmascript
-PASS Registering script with good MIME type text/javascript
-PASS Registering script that imports script with good MIME type text/javascript
-FAIL Registering script with good MIME type text/javascript1.0 promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type text/javascript1.0
-FAIL Registering script with good MIME type text/javascript1.1 promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type text/javascript1.1
-FAIL Registering script with good MIME type text/javascript1.2 promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type text/javascript1.2
-FAIL Registering script with good MIME type text/javascript1.3 promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type text/javascript1.3
-FAIL Registering script with good MIME type text/javascript1.4 promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type text/javascript1.4
-FAIL Registering script with good MIME type text/javascript1.5 promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type text/javascript1.5
-FAIL Registering script with good MIME type text/jscript promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type text/jscript
-FAIL Registering script with good MIME type text/livescript promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type text/livescript
-FAIL Registering script with good MIME type text/x-ecmascript promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type text/x-ecmascript
-FAIL Registering script with good MIME type text/x-javascript promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type text/x-javascript
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/link-element-register-scope.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/link-element-register-scope.https-expected.txt
deleted file mode 100644
index c2ebe84..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/link-element-register-scope.https-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-This is a testharness.js-based test.
-FAIL Scope including URL-encoded slash Test bug: need to pass exception to assert_throws()
-FAIL Scope including URL-encoded backslash Test bug: need to pass exception to assert_throws()
-PASS Scope including URL-encoded multibyte characters
-PASS Scope including non-escaped multibyte characters
-PASS Scope including self-reference
-PASS Scope including parent-reference
-PASS Scope including consecutive slashes
-FAIL Scope URL is same-origin filesystem: URL Test bug: need to pass exception to assert_throws()
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/link-element-register-script-url.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/link-element-register-script-url.https-expected.txt
deleted file mode 100644
index ce29087..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/link-element-register-script-url.https-expected.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-This is a testharness.js-based test.
-FAIL Script URL including URL-encoded slash Test bug: need to pass exception to assert_throws()
-FAIL Script URL including uppercase URL-encoded slash Test bug: need to pass exception to assert_throws()
-FAIL Script URL including URL-encoded backslash Test bug: need to pass exception to assert_throws()
-FAIL Script URL including uppercase URL-encoded backslash Test bug: need to pass exception to assert_throws()
-PASS Script URL including self-reference
-PASS Script URL including parent-reference
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/link-element-register-script.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/link-element-register-script.https-expected.txt
deleted file mode 100644
index 1dbf650..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/link-element-register-script.https-expected.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-This is a testharness.js-based test.
-FAIL Registering invalid chunked encoding script Test bug: need to pass exception to assert_throws()
-FAIL Registering invalid chunked encoding script with flush Test bug: need to pass exception to assert_throws()
-FAIL Registering script including parse error Test bug: need to pass exception to assert_throws()
-FAIL Registering script including undefined error Test bug: need to pass exception to assert_throws()
-FAIL Registering script including uncaught exception Test bug: need to pass exception to assert_throws()
-FAIL Registering script importing malformed script Test bug: need to pass exception to assert_throws()
-FAIL Registering non-existent script Test bug: need to pass exception to assert_throws()
-FAIL Registering script importing non-existent script Test bug: need to pass exception to assert_throws()
-PASS Registering script including caught exception
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/link-element-register-security-error.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/link-element-register-security-error.https-expected.txt
deleted file mode 100644
index 78c5360..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/link-element-register-security-error.https-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-This is a testharness.js-based test.
-FAIL Registering same scope as the script directory without the last slash Test bug: need to pass exception to assert_throws()
-FAIL Registration scope outside the script directory Test bug: need to pass exception to assert_throws()
-FAIL Registering scope outside domain Test bug: need to pass exception to assert_throws()
-FAIL Registering script outside domain Test bug: need to pass exception to assert_throws()
-FAIL Registering redirected script Test bug: need to pass exception to assert_throws()
-FAIL Scope including parent-reference and not under the script directory Test bug: need to pass exception to assert_throws()
-FAIL Script URL including consecutive slashes Test bug: need to pass exception to assert_throws()
-FAIL Script URL is same-origin filesystem: URL Test bug: need to pass exception to assert_throws()
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/navigate-window.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/navigate-window.https-expected.txt
deleted file mode 100644
index 59459ec..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/navigate-window.https-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-FAIL Clients.matchAll() should not show an old window as controlled after it navigates. assert_unreached: unexpected rejection: assert_equals: client should have expected frame type expected "top-level" but got "auxiliary" Reached unreachable code
-FAIL Clients.matchAll() should not show an old window after it navigates. assert_unreached: unexpected rejection: assert_equals: client should have expected frame type expected "top-level" but got "auxiliary" Reached unreachable code
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/registration-mime-types.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/registration-mime-types.https-expected.txt
deleted file mode 100644
index e4d2ccd0..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/registration-mime-types.https-expected.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-This is a testharness.js-based test.
-PASS Registering script with no MIME type
-PASS Registering script with bad MIME type
-FAIL Registering script that imports script with no MIME type assert_unreached: Should have rejected: Registration of no MIME type imported script should fail. Reached unreachable code
-FAIL Registering script that imports script with bad MIME type assert_unreached: Should have rejected: Registration of plain text imported script should fail. Reached unreachable code
-FAIL Registering script with good MIME type application/ecmascript promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('application/ecmascript')."
-PASS Registering script that imports script with good MIME type application/ecmascript
-PASS Registering script with good MIME type application/javascript
-PASS Registering script that imports script with good MIME type application/javascript
-FAIL Registering script with good MIME type application/x-ecmascript promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('application/x-ecmascript')."
-PASS Registering script that imports script with good MIME type application/x-ecmascript
-PASS Registering script with good MIME type application/x-javascript
-PASS Registering script that imports script with good MIME type application/x-javascript
-FAIL Registering script with good MIME type text/ecmascript promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/ecmascript')."
-PASS Registering script that imports script with good MIME type text/ecmascript
-PASS Registering script with good MIME type text/javascript
-PASS Registering script that imports script with good MIME type text/javascript
-FAIL Registering script with good MIME type text/javascript1.0 promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/javascript1.0')."
-PASS Registering script that imports script with good MIME type text/javascript1.0
-FAIL Registering script with good MIME type text/javascript1.1 promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/javascript1.1')."
-PASS Registering script that imports script with good MIME type text/javascript1.1
-FAIL Registering script with good MIME type text/javascript1.2 promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/javascript1.2')."
-PASS Registering script that imports script with good MIME type text/javascript1.2
-FAIL Registering script with good MIME type text/javascript1.3 promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/javascript1.3')."
-PASS Registering script that imports script with good MIME type text/javascript1.3
-FAIL Registering script with good MIME type text/javascript1.4 promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/javascript1.4')."
-PASS Registering script that imports script with good MIME type text/javascript1.4
-FAIL Registering script with good MIME type text/javascript1.5 promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/javascript1.5')."
-PASS Registering script that imports script with good MIME type text/javascript1.5
-FAIL Registering script with good MIME type text/jscript promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/jscript')."
-PASS Registering script that imports script with good MIME type text/jscript
-FAIL Registering script with good MIME type text/livescript promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/livescript')."
-PASS Registering script that imports script with good MIME type text/livescript
-FAIL Registering script with good MIME type text/x-ecmascript promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/x-ecmascript')."
-PASS Registering script that imports script with good MIME type text/x-ecmascript
-FAIL Registering script with good MIME type text/x-javascript promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/x-javascript')."
-PASS Registering script that imports script with good MIME type text/x-javascript
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/registration-updateviacache.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/registration-updateviacache.https-expected.txt
deleted file mode 100644
index 6cc7619..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/registration-updateviacache.https-expected.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-This is a testharness.js-based test.
-FAIL register-via-api-updateViaCache-undefined assert_equals: reg.updateViaCache expected (string) "imports" but got (undefined) undefined
-FAIL register-via-api-updateViaCache-imports assert_equals: reg.updateViaCache expected (string) "imports" but got (undefined) undefined
-FAIL register-via-api-updateViaCache-all assert_equals: reg.updateViaCache expected (string) "all" but got (undefined) undefined
-FAIL register-via-api-updateViaCache-none assert_equals: reg.updateViaCache expected (string) "none" but got (undefined) undefined
-FAIL register-via-link-element-updateViaCache-undefined assert_equals: reg.updateViaCache expected (string) "imports" but got (undefined) undefined
-FAIL register-via-link-element-updateViaCache-imports assert_equals: reg.updateViaCache expected (string) "imports" but got (undefined) undefined
-FAIL register-via-link-element-updateViaCache-all assert_equals: reg.updateViaCache expected (string) "all" but got (undefined) undefined
-FAIL register-via-link-element-updateViaCache-none assert_equals: reg.updateViaCache expected (string) "none" but got (undefined) undefined
-FAIL register-via-link-header-updateViaCache-undefined assert_equals: reg.updateViaCache expected (string) "imports" but got (undefined) undefined
-FAIL register-via-link-header-updateViaCache-imports assert_equals: reg.updateViaCache expected (string) "imports" but got (undefined) undefined
-FAIL register-via-link-header-updateViaCache-all assert_equals: reg.updateViaCache expected (string) "all" but got (undefined) undefined
-FAIL register-via-link-header-updateViaCache-none assert_equals: reg.updateViaCache expected (string) "none" but got (undefined) undefined
-FAIL register-with-updateViaCache-undefined-then-undefined assert_equals: reg.updateViaCache updated expected (string) "imports" but got (undefined) undefined
-FAIL register-with-updateViaCache-undefined-then-imports assert_equals: reg.updateViaCache updated expected (string) "imports" but got (undefined) undefined
-FAIL register-with-updateViaCache-undefined-then-all assert_equals: reg.updateViaCache updated expected (string) "all" but got (undefined) undefined
-FAIL register-with-updateViaCache-undefined-then-none assert_equals: reg.updateViaCache updated expected (string) "none" but got (undefined) undefined
-FAIL register-with-updateViaCache-imports-then-undefined assert_equals: reg.updateViaCache updated expected (string) "imports" but got (undefined) undefined
-FAIL register-with-updateViaCache-imports-then-imports assert_equals: reg.updateViaCache updated expected (string) "imports" but got (undefined) undefined
-FAIL register-with-updateViaCache-imports-then-all assert_equals: reg.updateViaCache updated expected (string) "all" but got (undefined) undefined
-FAIL register-with-updateViaCache-imports-then-none assert_equals: reg.updateViaCache updated expected (string) "none" but got (undefined) undefined
-FAIL register-with-updateViaCache-all-then-undefined assert_equals: reg.updateViaCache updated expected (string) "imports" but got (undefined) undefined
-FAIL register-with-updateViaCache-all-then-imports assert_equals: reg.updateViaCache updated expected (string) "imports" but got (undefined) undefined
-FAIL register-with-updateViaCache-all-then-all assert_equals: reg.updateViaCache updated expected (string) "all" but got (undefined) undefined
-FAIL register-with-updateViaCache-all-then-none assert_equals: reg.updateViaCache updated expected (string) "none" but got (undefined) undefined
-FAIL register-with-updateViaCache-none-then-undefined assert_equals: reg.updateViaCache updated expected (string) "imports" but got (undefined) undefined
-FAIL register-with-updateViaCache-none-then-imports assert_equals: reg.updateViaCache updated expected (string) "imports" but got (undefined) undefined
-FAIL register-with-updateViaCache-none-then-all assert_equals: reg.updateViaCache updated expected (string) "all" but got (undefined) undefined
-FAIL register-with-updateViaCache-none-then-none assert_equals: reg.updateViaCache updated expected (string) "none" but got (undefined) undefined
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/update-recovery.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/update-recovery.https-expected.txt
deleted file mode 100644
index f62fe77..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/update-recovery.https-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Recover from a bad service worker by updating after a failed navigation. assert_unreached: unexpected rejection: expected bad iframe should not fire a load event! Reached unreachable code
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/worker-interception.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/worker-interception.https-expected.txt
deleted file mode 100644
index f6d95f7..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-blobs/external/wpt/service-workers/service-worker/worker-interception.https-expected.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-This is a testharness.js-based test.
-FAIL Verify worker script from uncontrolled document is intercepted by Service Worker promise_test: Unhandled rejection with value: undefined
-FAIL Verify worker script intercepted by same-origin response succeeds promise_test: Unhandled rejection with value: undefined
-FAIL Verify worker script intercepted by cors response succeeds promise_test: Unhandled rejection with value: undefined
-PASS Verify worker script intercepted by no-cors cross-origin response fails
-PASS Verify worker loads from controlled document are intercepted by Service Worker
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/outofblink-cors/external/wpt/service-workers/service-worker/import-scripts-redirect.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/outofblink-cors/external/wpt/service-workers/service-worker/import-scripts-redirect.https-expected.txt
deleted file mode 100644
index 54836e4..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/outofblink-cors/external/wpt/service-workers/service-worker/import-scripts-redirect.https-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-FAIL importScripts() supports redirects promise_test: Unhandled rejection with value: object "TypeError: Failed to register a ServiceWorker: ServiceWorker script evaluation failed"
-FAIL importScripts() supports redirects and can be updated promise_test: Unhandled rejection with value: object "TypeError: Failed to register a ServiceWorker: ServiceWorker script evaluation failed"
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/outofblink-cors/external/wpt/service-workers/service-worker/link-element-register-security-error.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/outofblink-cors/external/wpt/service-workers/service-worker/link-element-register-security-error.https-expected.txt
deleted file mode 100644
index 78c5360..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/outofblink-cors/external/wpt/service-workers/service-worker/link-element-register-security-error.https-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-This is a testharness.js-based test.
-FAIL Registering same scope as the script directory without the last slash Test bug: need to pass exception to assert_throws()
-FAIL Registration scope outside the script directory Test bug: need to pass exception to assert_throws()
-FAIL Registering scope outside domain Test bug: need to pass exception to assert_throws()
-FAIL Registering script outside domain Test bug: need to pass exception to assert_throws()
-FAIL Registering redirected script Test bug: need to pass exception to assert_throws()
-FAIL Scope including parent-reference and not under the script directory Test bug: need to pass exception to assert_throws()
-FAIL Script URL including consecutive slashes Test bug: need to pass exception to assert_throws()
-FAIL Script URL is same-origin filesystem: URL Test bug: need to pass exception to assert_throws()
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/serviceworker/cache-add.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/serviceworker/cache-add.https-expected.txt
deleted file mode 100644
index a1555dcb8..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/serviceworker/cache-add.https-expected.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-This is a testharness.js-based test.
-PASS Cache.add and Cache.addAll
-PASS Cache.add called with no arguments
-PASS Cache.add called with relative URL specified as a string
-PASS Cache.add called with non-HTTP/HTTPS URL
-PASS Cache.add called with Request object
-PASS Cache.add called with POST request
-PASS Cache.add called twice with the same Request object
-PASS Cache.add with request with null body (not consumed)
-PASS Cache.add with 206 response
-PASS Cache.addAll with 206 response
-PASS Cache.add with request that results in a status of 404
-PASS Cache.add with request that results in a status of 500
-PASS Cache.addAll with no arguments
-PASS Cache.addAll with a mix of valid and undefined arguments
-PASS Cache.addAll with an empty array
-PASS Cache.addAll with string URL arguments
-PASS Cache.addAll with Request arguments
-PASS Cache.addAll with a mix of succeeding and failing requests
-FAIL Cache.addAll called with the same Request object specified twice assert_unreached: Should have rejected: Cache.addAll should throw InvalidStateError if the same request is added twice. Reached unreachable code
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/serviceworker/cache-matchAll.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/serviceworker/cache-matchAll.https-expected.txt
deleted file mode 100644
index 83bb89f..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/serviceworker/cache-matchAll.https-expected.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-This is a testharness.js-based test.
-PASS Cache.matchAll
-PASS Cache.matchAll with no matching entries
-PASS Cache.matchAll with URL
-PASS Cache.matchAll with Request
-PASS Cache.matchAll with new Request
-PASS Cache.matchAll with HEAD
-PASS Cache.matchAll with ignoreSearch option (request with no search parameters)
-PASS Cache.matchAll with ignoreSearch option (request with search parameters)
-PASS Cache.matchAll supports ignoreMethod
-PASS Cache.matchAll supports ignoreVary
-PASS Cache.matchAll with URL containing fragment
-PASS Cache.matchAll with string fragment "http" as query
-PASS Cache.matchAll without parameters
-FAIL Cache.matchAll with responses containing "Vary" header assert_equals: Cache.matchAll should match the entire header if a vary header is present in both the query and cached requests. expected 1 but got 0
-FAIL Cache.matchAll with multiple vary pairs assert_equals: Cache.matchAll should support multiple vary request/response pairs. expected 3 but got 1
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/serviceworker/cache-storage.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/serviceworker/cache-storage.https-expected.txt
deleted file mode 100644
index 22932f4..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/serviceworker/cache-storage.https-expected.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-This is a testharness.js-based test.
-PASS CacheStorage
-PASS CacheStorage.open
-PASS CacheStorage.delete dooms, but does not delete immediately
-PASS CacheStorage.open with an empty name
-PASS CacheStorage.open with no arguments
-PASS CacheStorage.has with existing cache
-PASS CacheStorage.has with nonexistent cache
-PASS CacheStorage.open with existing cache
-PASS CacheStorage.delete with existing cache
-PASS CacheStorage.delete with nonexistent cache
-FAIL CacheStorage names are DOMStrings not USVStrings assert_true: keys should include cache with bad name expected true got false
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/window/cache-add.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/window/cache-add.https-expected.txt
deleted file mode 100644
index 3f3f278..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/window/cache-add.https-expected.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-This is a testharness.js-based test.
-PASS Cache.add called with no arguments
-PASS Cache.add called with relative URL specified as a string
-PASS Cache.add called with non-HTTP/HTTPS URL
-PASS Cache.add called with Request object
-PASS Cache.add called with POST request
-PASS Cache.add called twice with the same Request object
-PASS Cache.add with request with null body (not consumed)
-PASS Cache.add with 206 response
-PASS Cache.addAll with 206 response
-PASS Cache.add with request that results in a status of 404
-PASS Cache.add with request that results in a status of 500
-PASS Cache.addAll with no arguments
-PASS Cache.addAll with a mix of valid and undefined arguments
-PASS Cache.addAll with an empty array
-PASS Cache.addAll with string URL arguments
-PASS Cache.addAll with Request arguments
-PASS Cache.addAll with a mix of succeeding and failing requests
-FAIL Cache.addAll called with the same Request object specified twice assert_unreached: Should have rejected: Cache.addAll should throw InvalidStateError if the same request is added twice. Reached unreachable code
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/window/cache-matchAll.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/window/cache-matchAll.https-expected.txt
deleted file mode 100644
index 69fcf49eb..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/window/cache-matchAll.https-expected.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-This is a testharness.js-based test.
-PASS Cache.matchAll with no matching entries
-PASS Cache.matchAll with URL
-PASS Cache.matchAll with Request
-PASS Cache.matchAll with new Request
-PASS Cache.matchAll with HEAD
-PASS Cache.matchAll with ignoreSearch option (request with no search parameters)
-PASS Cache.matchAll with ignoreSearch option (request with search parameters)
-PASS Cache.matchAll supports ignoreMethod
-PASS Cache.matchAll supports ignoreVary
-PASS Cache.matchAll with URL containing fragment
-PASS Cache.matchAll with string fragment "http" as query
-PASS Cache.matchAll without parameters
-FAIL Cache.matchAll with responses containing "Vary" header assert_equals: Cache.matchAll should match the entire header if a vary header is present in both the query and cached requests. expected 1 but got 0
-FAIL Cache.matchAll with multiple vary pairs assert_equals: Cache.matchAll should support multiple vary request/response pairs. expected 3 but got 1
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/window/cache-storage.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/window/cache-storage.https-expected.txt
deleted file mode 100644
index d1c62496..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/window/cache-storage.https-expected.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-This is a testharness.js-based test.
-PASS CacheStorage.open
-PASS CacheStorage.delete dooms, but does not delete immediately
-PASS CacheStorage.open with an empty name
-PASS CacheStorage.open with no arguments
-PASS CacheStorage.has with existing cache
-PASS CacheStorage.has with nonexistent cache
-PASS CacheStorage.open with existing cache
-PASS CacheStorage.delete with existing cache
-PASS CacheStorage.delete with nonexistent cache
-FAIL CacheStorage names are DOMStrings not USVStrings assert_true: keys should include cache with bad name expected true got false
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/window/sandboxed-iframes.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/window/sandboxed-iframes.https-expected.txt
deleted file mode 100644
index dc39b96..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/window/sandboxed-iframes.https-expected.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-
-This is a testharness.js-based test.
-PASS Sandboxed iframe with allow-same-origin is allowed access
-FAIL Sandboxed iframe without allow-same-origin is denied access assert_equals: Access should be denied if sandbox lacks allow-same-origin expected "denied" but got "unexpecteddenied"
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/worker/cache-add.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/worker/cache-add.https-expected.txt
deleted file mode 100644
index 3f3f278..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/worker/cache-add.https-expected.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-This is a testharness.js-based test.
-PASS Cache.add called with no arguments
-PASS Cache.add called with relative URL specified as a string
-PASS Cache.add called with non-HTTP/HTTPS URL
-PASS Cache.add called with Request object
-PASS Cache.add called with POST request
-PASS Cache.add called twice with the same Request object
-PASS Cache.add with request with null body (not consumed)
-PASS Cache.add with 206 response
-PASS Cache.addAll with 206 response
-PASS Cache.add with request that results in a status of 404
-PASS Cache.add with request that results in a status of 500
-PASS Cache.addAll with no arguments
-PASS Cache.addAll with a mix of valid and undefined arguments
-PASS Cache.addAll with an empty array
-PASS Cache.addAll with string URL arguments
-PASS Cache.addAll with Request arguments
-PASS Cache.addAll with a mix of succeeding and failing requests
-FAIL Cache.addAll called with the same Request object specified twice assert_unreached: Should have rejected: Cache.addAll should throw InvalidStateError if the same request is added twice. Reached unreachable code
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/worker/cache-matchAll.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/worker/cache-matchAll.https-expected.txt
deleted file mode 100644
index 69fcf49eb..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/worker/cache-matchAll.https-expected.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-This is a testharness.js-based test.
-PASS Cache.matchAll with no matching entries
-PASS Cache.matchAll with URL
-PASS Cache.matchAll with Request
-PASS Cache.matchAll with new Request
-PASS Cache.matchAll with HEAD
-PASS Cache.matchAll with ignoreSearch option (request with no search parameters)
-PASS Cache.matchAll with ignoreSearch option (request with search parameters)
-PASS Cache.matchAll supports ignoreMethod
-PASS Cache.matchAll supports ignoreVary
-PASS Cache.matchAll with URL containing fragment
-PASS Cache.matchAll with string fragment "http" as query
-PASS Cache.matchAll without parameters
-FAIL Cache.matchAll with responses containing "Vary" header assert_equals: Cache.matchAll should match the entire header if a vary header is present in both the query and cached requests. expected 1 but got 0
-FAIL Cache.matchAll with multiple vary pairs assert_equals: Cache.matchAll should support multiple vary request/response pairs. expected 3 but got 1
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/worker/cache-storage.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/worker/cache-storage.https-expected.txt
deleted file mode 100644
index d1c62496..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/worker/cache-storage.https-expected.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-This is a testharness.js-based test.
-PASS CacheStorage.open
-PASS CacheStorage.delete dooms, but does not delete immediately
-PASS CacheStorage.open with an empty name
-PASS CacheStorage.open with no arguments
-PASS CacheStorage.has with existing cache
-PASS CacheStorage.has with nonexistent cache
-PASS CacheStorage.open with existing cache
-PASS CacheStorage.delete with existing cache
-PASS CacheStorage.delete with nonexistent cache
-FAIL CacheStorage names are DOMStrings not USVStrings assert_true: keys should include cache with bad name expected true got false
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/clients-get-client-types.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/clients-get-client-types.https-expected.txt
deleted file mode 100644
index 58bae30..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/clients-get-client-types.https-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Test Clients.get() with window and worker clients assert_not_equals: Worker(Started by main frame) client should not be undefined got disallowed value undefined
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/clients-matchall-client-types.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/clients-matchall-client-types.https-expected.txt
deleted file mode 100644
index 1f2011a..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/clients-matchall-client-types.https-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-FAIL Verify matchAll() with window client type assert_unreached: unexpected rejection: assert_array_equals: property 2, expected "https://web-platform.test:8444/service-workers/service-worker/resources/clients-matchall-client-types-iframe.html" but got "https://web-platform.test:8444/service-workers/service-worker/resources/url-modified-via-pushstate.html" Reached unreachable code
-FAIL Verify matchAll() with {window, sharedworker, worker} client types promise_test: Unhandled rejection with value: object "Error: wait_for_state must be passed a ServiceWorker"
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/clients-matchall-order.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/clients-matchall-order.https-expected.txt
deleted file mode 100644
index 78737fe..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/clients-matchall-order.https-expected.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-This is a testharness.js-based test.
-PASS Clients.matchAll() returns non-focused controlled windows in creation order.
-PASS Clients.matchAll() returns controlled windows in focus order.  Case 1.
-PASS Clients.matchAll() returns controlled windows in focus order.  Case 2.
-FAIL Clients.matchAll() returns non-focused uncontrolled windows in creation order. assert_equals: expected 6 but got 5
-FAIL Clients.matchAll() returns uncontrolled windows in focus order.  Case 1. assert_equals: expected 6 but got 5
-FAIL Clients.matchAll() returns uncontrolled windows in focus order.  Case 2. assert_equals: expected 6 but got 5
-FAIL Clients.matchAll() returns controlled windows and frames in focus order. assert_equals: expected URL index 1 expected "https://web-platform.test:8444/service-workers/service-worker/resources/empty.html?name=focus-controlled-nested-windows&q=1" but got "https://web-platform.test:8444/service-workers/service-worker/resources/empty.html?name=focus-controlled-nested-windows&q=1&nested=true"
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/fetch-event-redirect.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/fetch-event-redirect.https-expected.txt
deleted file mode 100644
index f91bc57e..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/fetch-event-redirect.https-expected.txt
+++ /dev/null
@@ -1,57 +0,0 @@
-This is a testharness.js-based test.
-PASS Non-navigation, manual redirect, cors mode Request redirected to same-origin without credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, cors mode Request redirected to no-cors without credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, cors mode Request redirected to cors without credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, same-origin mode Request redirected to same-origin without credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, same-origin mode Request redirected to no-cors without credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, same-origin mode Request redirected to cors without credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, no-cors mode Request redirected to same-origin without credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, no-cors mode Request redirected to no-cors without credentials should succeed interception and response should not be redirected
-PASS Non-navigation, manual redirect, no-cors mode Request redirected to cors without credentials should succeed interception and response should not be redirected
-PASS Non-navigation, manual redirect, cors mode Request redirected to same-origin with credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, cors mode Request redirected to no-cors with credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, cors mode Request redirected to cors with credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, same-origin mode Request redirected to same-origin with credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, same-origin mode Request redirected to no-cors with credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, same-origin mode Request redirected to cors with credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, no-cors mode Request redirected to same-origin with credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, no-cors mode Request redirected to no-cors with credentials should succeed interception and response should not be redirected
-PASS Non-navigation, manual redirect, no-cors mode Request redirected to cors with credentials should succeed interception and response should not be redirected
-PASS Non-navigation, follow redirect, cors mode Request redirected to same-origin without credentials should succeed interception and response should be redirected
-PASS Non-navigation, follow redirect, cors mode Request redirected to no-cors without credentials should fail interception and response should not be redirected
-PASS Non-navigation, follow redirect, cors mode Request redirected to cors without credentials should succeed interception and response should be redirected
-PASS Non-navigation, follow redirect, same-origin mode Request redirected to same-origin without credentials should succeed interception and response should be redirected
-PASS Non-navigation, follow redirect, same-origin mode Request redirected to no-cors without credentials should fail interception and response should not be redirected
-PASS Non-navigation, follow redirect, same-origin mode Request redirected to cors without credentials should fail interception and response should not be redirected
-PASS Non-navigation, follow redirect, no-cors mode Request redirected to same-origin without credentials should succeed interception and response should be redirected
-PASS Non-navigation, follow redirect, no-cors mode Request redirected to no-cors without credentials should succeed interception and response should not be redirected
-PASS Non-navigation, follow redirect, no-cors mode Request redirected to cors without credentials should succeed interception and response should not be redirected
-FAIL Non-navigation, follow redirect, cors mode Request redirected to same-origin with credentials should succeed interception and response should be redirected assert_unreached: unexpected rejection: TypeError: Failed to fetch Reached unreachable code
-PASS Non-navigation, follow redirect, cors mode Request redirected to no-cors with credentials should fail interception and response should not be redirected
-PASS Non-navigation, follow redirect, cors mode Request redirected to cors with credentials should fail interception and response should be redirected
-FAIL Non-navigation, follow redirect, same-origin mode Request redirected to same-origin with credentials should succeed interception and response should be redirected assert_unreached: unexpected rejection: TypeError: Failed to fetch Reached unreachable code
-PASS Non-navigation, follow redirect, same-origin mode Request redirected to no-cors with credentials should fail interception and response should not be redirected
-PASS Non-navigation, follow redirect, same-origin mode Request redirected to cors with credentials should fail interception and response should not be redirected
-FAIL Non-navigation, follow redirect, no-cors mode Request redirected to same-origin with credentials should succeed interception and response should be redirected assert_unreached: unexpected rejection: TypeError: Failed to fetch Reached unreachable code
-FAIL Non-navigation, follow redirect, no-cors mode Request redirected to no-cors with credentials should succeed interception and response should not be redirected assert_unreached: unexpected rejection: TypeError: Failed to fetch Reached unreachable code
-FAIL Non-navigation, follow redirect, no-cors mode Request redirected to cors with credentials should succeed interception and response should not be redirected assert_unreached: unexpected rejection: TypeError: Failed to fetch Reached unreachable code
-PASS Non-navigation, error redirect, cors mode Request redirected to same-origin without credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, cors mode Request redirected to no-cors without credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, cors mode Request redirected to cors without credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, same-origin mode Request redirected to same-origin without credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, same-origin mode Request redirected to no-cors without credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, same-origin mode Request redirected to cors without credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, no-cors mode Request redirected to same-origin without credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, no-cors mode Request redirected to no-cors without credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, no-cors mode Request redirected to cors without credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, cors mode Request redirected to same-origin with credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, cors mode Request redirected to no-cors with credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, cors mode Request redirected to cors with credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, same-origin mode Request redirected to same-origin with credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, same-origin mode Request redirected to no-cors with credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, same-origin mode Request redirected to cors with credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, no-cors mode Request redirected to same-origin with credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, no-cors mode Request redirected to no-cors with credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, no-cors mode Request redirected to cors with credentials should fail interception and response should not be redirected
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/fetch-event-referrer-policy.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/fetch-event-referrer-policy.https-expected.txt
deleted file mode 100644
index 4ed287e..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/fetch-event-referrer-policy.https-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Service Worker responds to fetch event with the referrer policy assert_unreached: unexpected rejection: assert_equals: Service Worker should respond to fetch with the referrer URL when a member of RequestInit is present expected "Referrer: https://web-platform.test:8444/service-workers/service-worker/fake-referrer\nReferrerPolicy: no-referrer-when-downgrade" but got "Referrer: https://web-platform.test:8444/service-workers/service-worker/resources/fake-referrer\nReferrerPolicy: no-referrer-when-downgrade" Reached unreachable code
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/fetch-event-within-sw-manual.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/fetch-event-within-sw-manual.https-expected.txt
deleted file mode 100644
index e774a74..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/fetch-event-within-sw-manual.https-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Notification requests intercepted both from window and SW promise_test: Unhandled rejection with value: object "Error: You must allow notifications for this origin before running this test."
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/fetch-event.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/fetch-event.https-expected.txt
deleted file mode 100644
index 2eb875c..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/fetch-event.https-expected.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-This is a testharness.js-based test.
-PASS Service Worker headers in the request of a fetch event
-PASS Service Worker responds to fetch event with string
-PASS Service Worker responds to fetch event with blob body
-PASS Service Worker responds to fetch event with the referrer URL
-PASS Service Worker responds to fetch event with an existing client id
-PASS Service Worker does not respond to fetch event
-PASS Service Worker responds to fetch event with null response body
-PASS Service Worker fetches other file in fetch event
-PASS Service Worker responds to fetch event with POST form
-PASS Multiple calls of respondWith must throw InvalidStateErrors
-PASS Service Worker event.respondWith must set the used flag
-PASS Service Worker should expose FetchEvent URL fragments.
-FAIL Service Worker responds to fetch event with the correct cache types assert_unreached: unexpected rejection: assert_equals: Service Worker should respond to fetch with the correct type expected "no-store" but got "default" Reached unreachable code
-FAIL Service Worker should intercept EventSource assert_unreached: unexpected rejection: assert_equals: EventSource should bypass the http cache. expected "no-store" but got "default" Reached unreachable code
-FAIL Service Worker responds to fetch event with the correct integrity_metadata assert_unreached: unexpected rejection: assert_equals: integrity expected "gs0nqru8KbsrIt5YToQqS9fYao4GQJXtcId610g7cCU=" but got "" Reached unreachable code
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/fetch-request-xhr-sync.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/fetch-request-xhr-sync.https-expected.txt
deleted file mode 100644
index 724b7d8..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/fetch-request-xhr-sync.https-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Verify SyncXHR is intercepted assert_equals: HTTP response status code for intercepted request expected 200 but got 404
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/fetch-request-xhr.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/fetch-request-xhr.https-expected.txt
deleted file mode 100644
index b52f7871..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/fetch-request-xhr.https-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Verify the body of FetchEvent using XMLHttpRequest assert_array_equals: event.request has the expected headers for same-origin GET. lengths differ, expected 1 got 2
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/import-scripts-redirect.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/import-scripts-redirect.https-expected.txt
deleted file mode 100644
index 54836e4..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/import-scripts-redirect.https-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-FAIL importScripts() supports redirects promise_test: Unhandled rejection with value: object "TypeError: Failed to register a ServiceWorker: ServiceWorker script evaluation failed"
-FAIL importScripts() supports redirects and can be updated promise_test: Unhandled rejection with value: object "TypeError: Failed to register a ServiceWorker: ServiceWorker script evaluation failed"
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/import-scripts-updated-flag.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/import-scripts-updated-flag.https-expected.txt
deleted file mode 100644
index 0e50082..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/import-scripts-updated-flag.https-expected.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-This is a testharness.js-based test.
-PASS initialize global state
-PASS import script previously imported at worker evaluation time
-PASS import script previously imported at worker install time
-FAIL import script not previously imported assert_equals: expected (string) "TypeError" but got (object) null
-PASS Tests for importScripts: import scripts updated flag
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/interfaces-sw.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/interfaces-sw.https-expected.txt
deleted file mode 100644
index 3c98081d..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/interfaces-sw.https-expected.txt
+++ /dev/null
@@ -1,187 +0,0 @@
-This is a testharness.js-based test.
-PASS Interfaces and attributes in ServiceWorkerGlobalScope
-PASS test setup (cache creation)
-PASS Event constructors
-PASS ServiceWorkerGlobalScope interface: existence and properties of interface object
-PASS ServiceWorkerGlobalScope interface object length
-PASS ServiceWorkerGlobalScope interface object name
-PASS ServiceWorkerGlobalScope interface: existence and properties of interface prototype object
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to a new value via Object.setPrototypeOf should throw a TypeError
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to a new value via __proto__ should throw a TypeError
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to a new value via Reflect.setPrototypeOf should return false
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to its original value via Object.setPrototypeOf should not throw
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to its original value via __proto__ should not throw
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to its original value via Reflect.setPrototypeOf should return true
-PASS ServiceWorkerGlobalScope interface: existence and properties of interface prototype object's "constructor" property
-PASS ServiceWorkerGlobalScope interface: attribute clients
-PASS ServiceWorkerGlobalScope interface: attribute registration
-PASS ServiceWorkerGlobalScope interface: operation skipWaiting()
-PASS ServiceWorkerGlobalScope interface: attribute oninstall
-PASS ServiceWorkerGlobalScope interface: attribute onactivate
-PASS ServiceWorkerGlobalScope interface: attribute onfetch
-PASS ServiceWorkerGlobalScope interface: attribute onforeignfetch
-PASS ServiceWorkerGlobalScope interface: attribute onmessage
-FAIL ServiceWorkerGlobalScope interface: attribute onmessageerror assert_own_property: The global object must have a property "onmessageerror" expected property "onmessageerror" missing
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to a new value via Object.setPrototypeOf should throw a TypeError
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to a new value via __proto__ should throw a TypeError
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to a new value via Reflect.setPrototypeOf should return false
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to its original value via Object.setPrototypeOf should not throw
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to its original value via __proto__ should not throw
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to its original value via Reflect.setPrototypeOf should return true
-PASS ServiceWorkerGlobalScope must be primary interface of self
-PASS Stringification of self
-PASS ServiceWorkerGlobalScope interface: self must inherit property "clients" with the proper type
-PASS ServiceWorkerGlobalScope interface: self must inherit property "registration" with the proper type
-PASS ServiceWorkerGlobalScope interface: self must inherit property "skipWaiting()" with the proper type
-PASS ServiceWorkerGlobalScope interface: self must inherit property "oninstall" with the proper type
-PASS ServiceWorkerGlobalScope interface: self must inherit property "onactivate" with the proper type
-PASS ServiceWorkerGlobalScope interface: self must inherit property "onfetch" with the proper type
-PASS ServiceWorkerGlobalScope interface: self must inherit property "onforeignfetch" with the proper type
-PASS ServiceWorkerGlobalScope interface: self must inherit property "onmessage" with the proper type
-FAIL ServiceWorkerGlobalScope interface: self must inherit property "onmessageerror" with the proper type assert_own_property: expected property "onmessageerror" missing
-PASS Client interface: existence and properties of interface object
-PASS Client interface object length
-PASS Client interface object name
-PASS Client interface: existence and properties of interface prototype object
-PASS Client interface: existence and properties of interface prototype object's "constructor" property
-PASS Client interface: attribute url
-PASS Client interface: attribute id
-PASS Client interface: attribute type
-FAIL Client interface: attribute reserved assert_true: The prototype object must have a property "reserved" expected true got false
-PASS Client interface: operation postMessage(any, [object Object])
-PASS WindowClient interface: existence and properties of interface object
-PASS WindowClient interface object length
-PASS WindowClient interface object name
-PASS WindowClient interface: existence and properties of interface prototype object
-PASS WindowClient interface: existence and properties of interface prototype object's "constructor" property
-PASS WindowClient interface: attribute visibilityState
-PASS WindowClient interface: attribute focused
-FAIL WindowClient interface: attribute ancestorOrigins assert_true: The prototype object must have a property "ancestorOrigins" expected true got false
-PASS WindowClient interface: operation focus()
-PASS WindowClient interface: operation navigate(USVString)
-PASS Clients interface: existence and properties of interface object
-PASS Clients interface object length
-PASS Clients interface object name
-PASS Clients interface: existence and properties of interface prototype object
-PASS Clients interface: existence and properties of interface prototype object's "constructor" property
-PASS Clients interface: operation get(DOMString)
-PASS Clients interface: operation matchAll(ClientQueryOptions)
-PASS Clients interface: operation openWindow(USVString)
-PASS Clients interface: operation claim()
-PASS Clients must be primary interface of self.clients
-PASS Stringification of self.clients
-PASS Clients interface: self.clients must inherit property "get(DOMString)" with the proper type
-PASS Clients interface: calling get(DOMString) on self.clients with too few arguments must throw TypeError
-PASS Clients interface: self.clients must inherit property "matchAll(ClientQueryOptions)" with the proper type
-PASS Clients interface: calling matchAll(ClientQueryOptions) on self.clients with too few arguments must throw TypeError
-PASS Clients interface: self.clients must inherit property "openWindow(USVString)" with the proper type
-PASS Clients interface: calling openWindow(USVString) on self.clients with too few arguments must throw TypeError
-PASS Clients interface: self.clients must inherit property "claim()" with the proper type
-FAIL ServiceWorker interface: existence and properties of interface object assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface object length assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface object name assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface: existence and properties of interface prototype object assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface: attribute scriptURL assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface: attribute state assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface: operation postMessage(any, [object Object]) assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface: attribute onstatechange assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-PASS ServiceWorkerRegistration interface: existence and properties of interface object
-PASS ServiceWorkerRegistration interface object length
-PASS ServiceWorkerRegistration interface object name
-PASS ServiceWorkerRegistration interface: existence and properties of interface prototype object
-PASS ServiceWorkerRegistration interface: existence and properties of interface prototype object's "constructor" property
-PASS ServiceWorkerRegistration interface: attribute installing
-PASS ServiceWorkerRegistration interface: attribute waiting
-PASS ServiceWorkerRegistration interface: attribute active
-PASS ServiceWorkerRegistration interface: attribute navigationPreload
-PASS ServiceWorkerRegistration interface: attribute scope
-FAIL ServiceWorkerRegistration interface: attribute updateViaCache assert_true: The prototype object must have a property "updateViaCache" expected true got false
-PASS ServiceWorkerRegistration interface: operation update()
-PASS ServiceWorkerRegistration interface: operation unregister()
-PASS ServiceWorkerRegistration interface: attribute onupdatefound
-PASS ServiceWorkerRegistration must be primary interface of self.registration
-PASS Stringification of self.registration
-PASS ServiceWorkerRegistration interface: self.registration must inherit property "installing" with the proper type
-PASS ServiceWorkerRegistration interface: self.registration must inherit property "waiting" with the proper type
-PASS ServiceWorkerRegistration interface: self.registration must inherit property "active" with the proper type
-PASS ServiceWorkerRegistration interface: self.registration must inherit property "navigationPreload" with the proper type
-PASS ServiceWorkerRegistration interface: self.registration must inherit property "scope" with the proper type
-FAIL ServiceWorkerRegistration interface: self.registration must inherit property "updateViaCache" with the proper type assert_inherits: property "updateViaCache" not found in prototype chain
-PASS ServiceWorkerRegistration interface: self.registration must inherit property "update()" with the proper type
-PASS ServiceWorkerRegistration interface: self.registration must inherit property "unregister()" with the proper type
-PASS ServiceWorkerRegistration interface: self.registration must inherit property "onupdatefound" with the proper type
-PASS EventTarget interface: self.registration must inherit property "addEventListener(DOMString, EventListener, [object Object],[object Object])" with the proper type
-PASS EventTarget interface: calling addEventListener(DOMString, EventListener, [object Object],[object Object]) on self.registration with too few arguments must throw TypeError
-PASS EventTarget interface: self.registration must inherit property "removeEventListener(DOMString, EventListener, [object Object],[object Object])" with the proper type
-PASS EventTarget interface: calling removeEventListener(DOMString, EventListener, [object Object],[object Object]) on self.registration with too few arguments must throw TypeError
-PASS EventTarget interface: self.registration must inherit property "dispatchEvent(Event)" with the proper type
-PASS EventTarget interface: calling dispatchEvent(Event) on self.registration with too few arguments must throw TypeError
-PASS EventTarget interface: existence and properties of interface object
-PASS EventTarget interface object length
-PASS EventTarget interface object name
-PASS EventTarget interface: existence and properties of interface prototype object
-PASS EventTarget interface: existence and properties of interface prototype object's "constructor" property
-PASS EventTarget interface: operation addEventListener(DOMString, EventListener, [object Object],[object Object])
-PASS EventTarget interface: operation removeEventListener(DOMString, EventListener, [object Object],[object Object])
-PASS EventTarget interface: operation dispatchEvent(Event)
-PASS NavigationPreloadManager interface: existence and properties of interface object
-PASS NavigationPreloadManager interface object length
-PASS NavigationPreloadManager interface object name
-PASS NavigationPreloadManager interface: existence and properties of interface prototype object
-PASS NavigationPreloadManager interface: existence and properties of interface prototype object's "constructor" property
-PASS NavigationPreloadManager interface: operation enable()
-PASS NavigationPreloadManager interface: operation disable()
-PASS NavigationPreloadManager interface: operation setHeaderValue(ByteString)
-PASS NavigationPreloadManager interface: operation getState()
-PASS Cache interface: existence and properties of interface object
-PASS Cache interface object length
-PASS Cache interface object name
-PASS Cache interface: existence and properties of interface prototype object
-PASS Cache interface: existence and properties of interface prototype object's "constructor" property
-PASS Cache interface: operation match(RequestInfo, CacheQueryOptions)
-PASS Cache interface: operation matchAll(RequestInfo, CacheQueryOptions)
-PASS Cache interface: operation add(RequestInfo)
-PASS Cache interface: operation addAll([object Object])
-PASS Cache interface: operation put(RequestInfo, Response)
-PASS Cache interface: operation delete(RequestInfo, CacheQueryOptions)
-PASS Cache interface: operation keys(RequestInfo, CacheQueryOptions)
-PASS Cache must be primary interface of self.cacheInstance
-PASS Stringification of self.cacheInstance
-PASS Cache interface: self.cacheInstance must inherit property "match(RequestInfo, CacheQueryOptions)" with the proper type
-PASS Cache interface: calling match(RequestInfo, CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "matchAll(RequestInfo, CacheQueryOptions)" with the proper type
-PASS Cache interface: calling matchAll(RequestInfo, CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "add(RequestInfo)" with the proper type
-PASS Cache interface: calling add(RequestInfo) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "addAll([object Object])" with the proper type
-PASS Cache interface: calling addAll([object Object]) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "put(RequestInfo, Response)" with the proper type
-PASS Cache interface: calling put(RequestInfo, Response) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "delete(RequestInfo, CacheQueryOptions)" with the proper type
-PASS Cache interface: calling delete(RequestInfo, CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "keys(RequestInfo, CacheQueryOptions)" with the proper type
-PASS Cache interface: calling keys(RequestInfo, CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError
-PASS CacheStorage interface: existence and properties of interface object
-PASS CacheStorage interface object length
-PASS CacheStorage interface object name
-PASS CacheStorage interface: existence and properties of interface prototype object
-PASS CacheStorage interface: existence and properties of interface prototype object's "constructor" property
-PASS CacheStorage interface: operation match(RequestInfo, CacheQueryOptions)
-PASS CacheStorage interface: operation has(DOMString)
-PASS CacheStorage interface: operation open(DOMString)
-PASS CacheStorage interface: operation delete(DOMString)
-PASS CacheStorage interface: operation keys()
-PASS CacheStorage must be primary interface of self.caches
-PASS Stringification of self.caches
-PASS CacheStorage interface: self.caches must inherit property "match(RequestInfo, CacheQueryOptions)" with the proper type
-PASS CacheStorage interface: calling match(RequestInfo, CacheQueryOptions) on self.caches with too few arguments must throw TypeError
-PASS CacheStorage interface: self.caches must inherit property "has(DOMString)" with the proper type
-PASS CacheStorage interface: calling has(DOMString) on self.caches with too few arguments must throw TypeError
-PASS CacheStorage interface: self.caches must inherit property "open(DOMString)" with the proper type
-PASS CacheStorage interface: calling open(DOMString) on self.caches with too few arguments must throw TypeError
-PASS CacheStorage interface: self.caches must inherit property "delete(DOMString)" with the proper type
-PASS CacheStorage interface: calling delete(DOMString) on self.caches with too few arguments must throw TypeError
-PASS CacheStorage interface: self.caches must inherit property "keys()" with the proper type
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/interfaces-window.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/interfaces-window.https-expected.txt
deleted file mode 100644
index 178972d..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/interfaces-window.https-expected.txt
+++ /dev/null
@@ -1,101 +0,0 @@
-This is a testharness.js-based test.
-PASS test setup (worker registration)
-PASS WorkerGlobalScope interface: existence and properties of interface object
-PASS ServiceWorkerGlobalScope interface: existence and properties of interface object
-PASS Client interface: existence and properties of interface object
-PASS WindowClient interface: existence and properties of interface object
-PASS Clients interface: existence and properties of interface object
-PASS ServiceWorker interface: existence and properties of interface object
-PASS ServiceWorker interface object length
-PASS ServiceWorker interface object name
-PASS ServiceWorker interface: existence and properties of interface prototype object
-PASS ServiceWorker interface: existence and properties of interface prototype object's "constructor" property
-PASS ServiceWorker interface: attribute scriptURL
-PASS ServiceWorker interface: attribute state
-PASS ServiceWorker interface: operation postMessage(any, [object Object])
-PASS ServiceWorker interface: attribute onstatechange
-PASS ServiceWorker must be primary interface of window.registrationInstance.installing
-PASS Stringification of window.registrationInstance.installing
-PASS ServiceWorker interface: window.registrationInstance.installing must inherit property "scriptURL" with the proper type
-PASS ServiceWorker interface: window.registrationInstance.installing must inherit property "state" with the proper type
-PASS ServiceWorker interface: window.registrationInstance.installing must inherit property "postMessage(any, [object Object])" with the proper type
-PASS ServiceWorker interface: calling postMessage(any, [object Object]) on window.registrationInstance.installing with too few arguments must throw TypeError
-PASS ServiceWorker interface: window.registrationInstance.installing must inherit property "onstatechange" with the proper type
-PASS EventTarget interface: window.registrationInstance.installing must inherit property "addEventListener(DOMString, EventListener, [object Object],[object Object])" with the proper type
-PASS EventTarget interface: calling addEventListener(DOMString, EventListener, [object Object],[object Object]) on window.registrationInstance.installing with too few arguments must throw TypeError
-PASS EventTarget interface: window.registrationInstance.installing must inherit property "removeEventListener(DOMString, EventListener, [object Object],[object Object])" with the proper type
-PASS EventTarget interface: calling removeEventListener(DOMString, EventListener, [object Object],[object Object]) on window.registrationInstance.installing with too few arguments must throw TypeError
-PASS EventTarget interface: window.registrationInstance.installing must inherit property "dispatchEvent(Event)" with the proper type
-PASS EventTarget interface: calling dispatchEvent(Event) on window.registrationInstance.installing with too few arguments must throw TypeError
-PASS ServiceWorkerRegistration interface: existence and properties of interface object
-PASS ServiceWorkerRegistration interface object length
-PASS ServiceWorkerRegistration interface object name
-PASS ServiceWorkerRegistration interface: existence and properties of interface prototype object
-PASS ServiceWorkerRegistration interface: existence and properties of interface prototype object's "constructor" property
-PASS ServiceWorkerRegistration interface: attribute installing
-PASS ServiceWorkerRegistration interface: attribute waiting
-PASS ServiceWorkerRegistration interface: attribute active
-PASS ServiceWorkerRegistration interface: attribute navigationPreload
-PASS ServiceWorkerRegistration interface: attribute scope
-FAIL ServiceWorkerRegistration interface: attribute updateViaCache assert_true: The prototype object must have a property "updateViaCache" expected true got false
-PASS ServiceWorkerRegistration interface: operation update()
-PASS ServiceWorkerRegistration interface: operation unregister()
-PASS ServiceWorkerRegistration interface: attribute onupdatefound
-PASS ServiceWorkerRegistration must be primary interface of window.registrationInstance
-PASS Stringification of window.registrationInstance
-PASS ServiceWorkerRegistration interface: window.registrationInstance must inherit property "installing" with the proper type
-PASS ServiceWorkerRegistration interface: window.registrationInstance must inherit property "waiting" with the proper type
-PASS ServiceWorkerRegistration interface: window.registrationInstance must inherit property "active" with the proper type
-PASS ServiceWorkerRegistration interface: window.registrationInstance must inherit property "navigationPreload" with the proper type
-PASS ServiceWorkerRegistration interface: window.registrationInstance must inherit property "scope" with the proper type
-FAIL ServiceWorkerRegistration interface: window.registrationInstance must inherit property "updateViaCache" with the proper type assert_inherits: property "updateViaCache" not found in prototype chain
-PASS ServiceWorkerRegistration interface: window.registrationInstance must inherit property "update()" with the proper type
-PASS ServiceWorkerRegistration interface: window.registrationInstance must inherit property "unregister()" with the proper type
-PASS ServiceWorkerRegistration interface: window.registrationInstance must inherit property "onupdatefound" with the proper type
-PASS EventTarget interface: window.registrationInstance must inherit property "addEventListener(DOMString, EventListener, [object Object],[object Object])" with the proper type
-PASS EventTarget interface: calling addEventListener(DOMString, EventListener, [object Object],[object Object]) on window.registrationInstance with too few arguments must throw TypeError
-PASS EventTarget interface: window.registrationInstance must inherit property "removeEventListener(DOMString, EventListener, [object Object],[object Object])" with the proper type
-PASS EventTarget interface: calling removeEventListener(DOMString, EventListener, [object Object],[object Object]) on window.registrationInstance with too few arguments must throw TypeError
-PASS EventTarget interface: window.registrationInstance must inherit property "dispatchEvent(Event)" with the proper type
-PASS EventTarget interface: calling dispatchEvent(Event) on window.registrationInstance with too few arguments must throw TypeError
-PASS EventTarget interface: existence and properties of interface object
-PASS EventTarget interface object length
-PASS EventTarget interface object name
-PASS EventTarget interface: existence and properties of interface prototype object
-PASS EventTarget interface: existence and properties of interface prototype object's "constructor" property
-PASS EventTarget interface: operation addEventListener(DOMString, EventListener, [object Object],[object Object])
-PASS EventTarget interface: operation removeEventListener(DOMString, EventListener, [object Object],[object Object])
-PASS EventTarget interface: operation dispatchEvent(Event)
-PASS NavigationPreloadManager interface: existence and properties of interface object
-PASS NavigationPreloadManager interface object length
-PASS NavigationPreloadManager interface object name
-PASS NavigationPreloadManager interface: existence and properties of interface prototype object
-PASS NavigationPreloadManager interface: existence and properties of interface prototype object's "constructor" property
-PASS NavigationPreloadManager interface: operation enable()
-PASS NavigationPreloadManager interface: operation disable()
-PASS NavigationPreloadManager interface: operation setHeaderValue(ByteString)
-PASS NavigationPreloadManager interface: operation getState()
-PASS Cache interface: existence and properties of interface object
-PASS Cache interface object length
-PASS Cache interface object name
-PASS Cache interface: existence and properties of interface prototype object
-PASS Cache interface: existence and properties of interface prototype object's "constructor" property
-PASS Cache interface: operation match(RequestInfo, CacheQueryOptions)
-PASS Cache interface: operation matchAll(RequestInfo, CacheQueryOptions)
-PASS Cache interface: operation add(RequestInfo)
-PASS Cache interface: operation addAll([object Object])
-PASS Cache interface: operation put(RequestInfo, Response)
-PASS Cache interface: operation delete(RequestInfo, CacheQueryOptions)
-PASS Cache interface: operation keys(RequestInfo, CacheQueryOptions)
-PASS CacheStorage interface: existence and properties of interface object
-PASS CacheStorage interface object length
-PASS CacheStorage interface object name
-PASS CacheStorage interface: existence and properties of interface prototype object
-PASS CacheStorage interface: existence and properties of interface prototype object's "constructor" property
-PASS CacheStorage interface: operation match(RequestInfo, CacheQueryOptions)
-PASS CacheStorage interface: operation has(DOMString)
-PASS CacheStorage interface: operation open(DOMString)
-PASS CacheStorage interface: operation delete(DOMString)
-PASS CacheStorage interface: operation keys()
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/link-element-register-mime-types.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/link-element-register-mime-types.https-expected.txt
deleted file mode 100644
index 28bf3a7..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/link-element-register-mime-types.https-expected.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-This is a testharness.js-based test.
-FAIL Registering script with no MIME type Test bug: need to pass exception to assert_throws()
-FAIL Registering script with bad MIME type Test bug: need to pass exception to assert_throws()
-FAIL Registering script that imports script with no MIME type assert_unreached: Should have rejected: Registration of no MIME type imported script should fail. Reached unreachable code
-FAIL Registering script that imports script with bad MIME type assert_unreached: Should have rejected: Registration of plain text imported script should fail. Reached unreachable code
-FAIL Registering script with good MIME type application/ecmascript promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type application/ecmascript
-PASS Registering script with good MIME type application/javascript
-PASS Registering script that imports script with good MIME type application/javascript
-FAIL Registering script with good MIME type application/x-ecmascript promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type application/x-ecmascript
-PASS Registering script with good MIME type application/x-javascript
-PASS Registering script that imports script with good MIME type application/x-javascript
-FAIL Registering script with good MIME type text/ecmascript promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type text/ecmascript
-PASS Registering script with good MIME type text/javascript
-PASS Registering script that imports script with good MIME type text/javascript
-FAIL Registering script with good MIME type text/javascript1.0 promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type text/javascript1.0
-FAIL Registering script with good MIME type text/javascript1.1 promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type text/javascript1.1
-FAIL Registering script with good MIME type text/javascript1.2 promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type text/javascript1.2
-FAIL Registering script with good MIME type text/javascript1.3 promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type text/javascript1.3
-FAIL Registering script with good MIME type text/javascript1.4 promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type text/javascript1.4
-FAIL Registering script with good MIME type text/javascript1.5 promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type text/javascript1.5
-FAIL Registering script with good MIME type text/jscript promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type text/jscript
-FAIL Registering script with good MIME type text/livescript promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type text/livescript
-FAIL Registering script with good MIME type text/x-ecmascript promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type text/x-ecmascript
-FAIL Registering script with good MIME type text/x-javascript promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type text/x-javascript
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/link-element-register-scope.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/link-element-register-scope.https-expected.txt
deleted file mode 100644
index c2ebe84..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/link-element-register-scope.https-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-This is a testharness.js-based test.
-FAIL Scope including URL-encoded slash Test bug: need to pass exception to assert_throws()
-FAIL Scope including URL-encoded backslash Test bug: need to pass exception to assert_throws()
-PASS Scope including URL-encoded multibyte characters
-PASS Scope including non-escaped multibyte characters
-PASS Scope including self-reference
-PASS Scope including parent-reference
-PASS Scope including consecutive slashes
-FAIL Scope URL is same-origin filesystem: URL Test bug: need to pass exception to assert_throws()
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/link-element-register-script-url.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/link-element-register-script-url.https-expected.txt
deleted file mode 100644
index ce29087..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/link-element-register-script-url.https-expected.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-This is a testharness.js-based test.
-FAIL Script URL including URL-encoded slash Test bug: need to pass exception to assert_throws()
-FAIL Script URL including uppercase URL-encoded slash Test bug: need to pass exception to assert_throws()
-FAIL Script URL including URL-encoded backslash Test bug: need to pass exception to assert_throws()
-FAIL Script URL including uppercase URL-encoded backslash Test bug: need to pass exception to assert_throws()
-PASS Script URL including self-reference
-PASS Script URL including parent-reference
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/link-element-register-script.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/link-element-register-script.https-expected.txt
deleted file mode 100644
index 1dbf650..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/link-element-register-script.https-expected.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-This is a testharness.js-based test.
-FAIL Registering invalid chunked encoding script Test bug: need to pass exception to assert_throws()
-FAIL Registering invalid chunked encoding script with flush Test bug: need to pass exception to assert_throws()
-FAIL Registering script including parse error Test bug: need to pass exception to assert_throws()
-FAIL Registering script including undefined error Test bug: need to pass exception to assert_throws()
-FAIL Registering script including uncaught exception Test bug: need to pass exception to assert_throws()
-FAIL Registering script importing malformed script Test bug: need to pass exception to assert_throws()
-FAIL Registering non-existent script Test bug: need to pass exception to assert_throws()
-FAIL Registering script importing non-existent script Test bug: need to pass exception to assert_throws()
-PASS Registering script including caught exception
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/link-element-register-security-error.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/link-element-register-security-error.https-expected.txt
deleted file mode 100644
index 78c5360..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/link-element-register-security-error.https-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-This is a testharness.js-based test.
-FAIL Registering same scope as the script directory without the last slash Test bug: need to pass exception to assert_throws()
-FAIL Registration scope outside the script directory Test bug: need to pass exception to assert_throws()
-FAIL Registering scope outside domain Test bug: need to pass exception to assert_throws()
-FAIL Registering script outside domain Test bug: need to pass exception to assert_throws()
-FAIL Registering redirected script Test bug: need to pass exception to assert_throws()
-FAIL Scope including parent-reference and not under the script directory Test bug: need to pass exception to assert_throws()
-FAIL Script URL including consecutive slashes Test bug: need to pass exception to assert_throws()
-FAIL Script URL is same-origin filesystem: URL Test bug: need to pass exception to assert_throws()
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/navigate-window.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/navigate-window.https-expected.txt
deleted file mode 100644
index 59459ec..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/navigate-window.https-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-FAIL Clients.matchAll() should not show an old window as controlled after it navigates. assert_unreached: unexpected rejection: assert_equals: client should have expected frame type expected "top-level" but got "auxiliary" Reached unreachable code
-FAIL Clients.matchAll() should not show an old window after it navigates. assert_unreached: unexpected rejection: assert_equals: client should have expected frame type expected "top-level" but got "auxiliary" Reached unreachable code
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/registration-mime-types.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/registration-mime-types.https-expected.txt
deleted file mode 100644
index e4d2ccd0..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/registration-mime-types.https-expected.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-This is a testharness.js-based test.
-PASS Registering script with no MIME type
-PASS Registering script with bad MIME type
-FAIL Registering script that imports script with no MIME type assert_unreached: Should have rejected: Registration of no MIME type imported script should fail. Reached unreachable code
-FAIL Registering script that imports script with bad MIME type assert_unreached: Should have rejected: Registration of plain text imported script should fail. Reached unreachable code
-FAIL Registering script with good MIME type application/ecmascript promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('application/ecmascript')."
-PASS Registering script that imports script with good MIME type application/ecmascript
-PASS Registering script with good MIME type application/javascript
-PASS Registering script that imports script with good MIME type application/javascript
-FAIL Registering script with good MIME type application/x-ecmascript promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('application/x-ecmascript')."
-PASS Registering script that imports script with good MIME type application/x-ecmascript
-PASS Registering script with good MIME type application/x-javascript
-PASS Registering script that imports script with good MIME type application/x-javascript
-FAIL Registering script with good MIME type text/ecmascript promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/ecmascript')."
-PASS Registering script that imports script with good MIME type text/ecmascript
-PASS Registering script with good MIME type text/javascript
-PASS Registering script that imports script with good MIME type text/javascript
-FAIL Registering script with good MIME type text/javascript1.0 promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/javascript1.0')."
-PASS Registering script that imports script with good MIME type text/javascript1.0
-FAIL Registering script with good MIME type text/javascript1.1 promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/javascript1.1')."
-PASS Registering script that imports script with good MIME type text/javascript1.1
-FAIL Registering script with good MIME type text/javascript1.2 promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/javascript1.2')."
-PASS Registering script that imports script with good MIME type text/javascript1.2
-FAIL Registering script with good MIME type text/javascript1.3 promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/javascript1.3')."
-PASS Registering script that imports script with good MIME type text/javascript1.3
-FAIL Registering script with good MIME type text/javascript1.4 promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/javascript1.4')."
-PASS Registering script that imports script with good MIME type text/javascript1.4
-FAIL Registering script with good MIME type text/javascript1.5 promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/javascript1.5')."
-PASS Registering script that imports script with good MIME type text/javascript1.5
-FAIL Registering script with good MIME type text/jscript promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/jscript')."
-PASS Registering script that imports script with good MIME type text/jscript
-FAIL Registering script with good MIME type text/livescript promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/livescript')."
-PASS Registering script that imports script with good MIME type text/livescript
-FAIL Registering script with good MIME type text/x-ecmascript promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/x-ecmascript')."
-PASS Registering script that imports script with good MIME type text/x-ecmascript
-FAIL Registering script with good MIME type text/x-javascript promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/x-javascript')."
-PASS Registering script that imports script with good MIME type text/x-javascript
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/registration-updateviacache.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/registration-updateviacache.https-expected.txt
deleted file mode 100644
index 6cc7619..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/registration-updateviacache.https-expected.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-This is a testharness.js-based test.
-FAIL register-via-api-updateViaCache-undefined assert_equals: reg.updateViaCache expected (string) "imports" but got (undefined) undefined
-FAIL register-via-api-updateViaCache-imports assert_equals: reg.updateViaCache expected (string) "imports" but got (undefined) undefined
-FAIL register-via-api-updateViaCache-all assert_equals: reg.updateViaCache expected (string) "all" but got (undefined) undefined
-FAIL register-via-api-updateViaCache-none assert_equals: reg.updateViaCache expected (string) "none" but got (undefined) undefined
-FAIL register-via-link-element-updateViaCache-undefined assert_equals: reg.updateViaCache expected (string) "imports" but got (undefined) undefined
-FAIL register-via-link-element-updateViaCache-imports assert_equals: reg.updateViaCache expected (string) "imports" but got (undefined) undefined
-FAIL register-via-link-element-updateViaCache-all assert_equals: reg.updateViaCache expected (string) "all" but got (undefined) undefined
-FAIL register-via-link-element-updateViaCache-none assert_equals: reg.updateViaCache expected (string) "none" but got (undefined) undefined
-FAIL register-via-link-header-updateViaCache-undefined assert_equals: reg.updateViaCache expected (string) "imports" but got (undefined) undefined
-FAIL register-via-link-header-updateViaCache-imports assert_equals: reg.updateViaCache expected (string) "imports" but got (undefined) undefined
-FAIL register-via-link-header-updateViaCache-all assert_equals: reg.updateViaCache expected (string) "all" but got (undefined) undefined
-FAIL register-via-link-header-updateViaCache-none assert_equals: reg.updateViaCache expected (string) "none" but got (undefined) undefined
-FAIL register-with-updateViaCache-undefined-then-undefined assert_equals: reg.updateViaCache updated expected (string) "imports" but got (undefined) undefined
-FAIL register-with-updateViaCache-undefined-then-imports assert_equals: reg.updateViaCache updated expected (string) "imports" but got (undefined) undefined
-FAIL register-with-updateViaCache-undefined-then-all assert_equals: reg.updateViaCache updated expected (string) "all" but got (undefined) undefined
-FAIL register-with-updateViaCache-undefined-then-none assert_equals: reg.updateViaCache updated expected (string) "none" but got (undefined) undefined
-FAIL register-with-updateViaCache-imports-then-undefined assert_equals: reg.updateViaCache updated expected (string) "imports" but got (undefined) undefined
-FAIL register-with-updateViaCache-imports-then-imports assert_equals: reg.updateViaCache updated expected (string) "imports" but got (undefined) undefined
-FAIL register-with-updateViaCache-imports-then-all assert_equals: reg.updateViaCache updated expected (string) "all" but got (undefined) undefined
-FAIL register-with-updateViaCache-imports-then-none assert_equals: reg.updateViaCache updated expected (string) "none" but got (undefined) undefined
-FAIL register-with-updateViaCache-all-then-undefined assert_equals: reg.updateViaCache updated expected (string) "imports" but got (undefined) undefined
-FAIL register-with-updateViaCache-all-then-imports assert_equals: reg.updateViaCache updated expected (string) "imports" but got (undefined) undefined
-FAIL register-with-updateViaCache-all-then-all assert_equals: reg.updateViaCache updated expected (string) "all" but got (undefined) undefined
-FAIL register-with-updateViaCache-all-then-none assert_equals: reg.updateViaCache updated expected (string) "none" but got (undefined) undefined
-FAIL register-with-updateViaCache-none-then-undefined assert_equals: reg.updateViaCache updated expected (string) "imports" but got (undefined) undefined
-FAIL register-with-updateViaCache-none-then-imports assert_equals: reg.updateViaCache updated expected (string) "imports" but got (undefined) undefined
-FAIL register-with-updateViaCache-none-then-all assert_equals: reg.updateViaCache updated expected (string) "all" but got (undefined) undefined
-FAIL register-with-updateViaCache-none-then-none assert_equals: reg.updateViaCache updated expected (string) "none" but got (undefined) undefined
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/update-recovery.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/update-recovery.https-expected.txt
deleted file mode 100644
index f62fe77..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/update-recovery.https-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Recover from a bad service worker by updating after a failed navigation. assert_unreached: unexpected rejection: expected bad iframe should not fire a load event! Reached unreachable code
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/worker-interception.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/worker-interception.https-expected.txt
deleted file mode 100644
index f6d95f7..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/worker-interception.https-expected.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-This is a testharness.js-based test.
-FAIL Verify worker script from uncontrolled document is intercepted by Service Worker promise_test: Unhandled rejection with value: undefined
-FAIL Verify worker script intercepted by same-origin response succeeds promise_test: Unhandled rejection with value: undefined
-FAIL Verify worker script intercepted by cors response succeeds promise_test: Unhandled rejection with value: undefined
-PASS Verify worker script intercepted by no-cors cross-origin response fails
-PASS Verify worker loads from controlled document are intercepted by Service Worker
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/serviceworker/cache-add.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/serviceworker/cache-add.https-expected.txt
deleted file mode 100644
index a1555dcb8..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/serviceworker/cache-add.https-expected.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-This is a testharness.js-based test.
-PASS Cache.add and Cache.addAll
-PASS Cache.add called with no arguments
-PASS Cache.add called with relative URL specified as a string
-PASS Cache.add called with non-HTTP/HTTPS URL
-PASS Cache.add called with Request object
-PASS Cache.add called with POST request
-PASS Cache.add called twice with the same Request object
-PASS Cache.add with request with null body (not consumed)
-PASS Cache.add with 206 response
-PASS Cache.addAll with 206 response
-PASS Cache.add with request that results in a status of 404
-PASS Cache.add with request that results in a status of 500
-PASS Cache.addAll with no arguments
-PASS Cache.addAll with a mix of valid and undefined arguments
-PASS Cache.addAll with an empty array
-PASS Cache.addAll with string URL arguments
-PASS Cache.addAll with Request arguments
-PASS Cache.addAll with a mix of succeeding and failing requests
-FAIL Cache.addAll called with the same Request object specified twice assert_unreached: Should have rejected: Cache.addAll should throw InvalidStateError if the same request is added twice. Reached unreachable code
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/serviceworker/cache-matchAll.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/serviceworker/cache-matchAll.https-expected.txt
deleted file mode 100644
index 83bb89f..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/serviceworker/cache-matchAll.https-expected.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-This is a testharness.js-based test.
-PASS Cache.matchAll
-PASS Cache.matchAll with no matching entries
-PASS Cache.matchAll with URL
-PASS Cache.matchAll with Request
-PASS Cache.matchAll with new Request
-PASS Cache.matchAll with HEAD
-PASS Cache.matchAll with ignoreSearch option (request with no search parameters)
-PASS Cache.matchAll with ignoreSearch option (request with search parameters)
-PASS Cache.matchAll supports ignoreMethod
-PASS Cache.matchAll supports ignoreVary
-PASS Cache.matchAll with URL containing fragment
-PASS Cache.matchAll with string fragment "http" as query
-PASS Cache.matchAll without parameters
-FAIL Cache.matchAll with responses containing "Vary" header assert_equals: Cache.matchAll should match the entire header if a vary header is present in both the query and cached requests. expected 1 but got 0
-FAIL Cache.matchAll with multiple vary pairs assert_equals: Cache.matchAll should support multiple vary request/response pairs. expected 3 but got 1
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/serviceworker/cache-storage.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/serviceworker/cache-storage.https-expected.txt
deleted file mode 100644
index 22932f4..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/serviceworker/cache-storage.https-expected.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-This is a testharness.js-based test.
-PASS CacheStorage
-PASS CacheStorage.open
-PASS CacheStorage.delete dooms, but does not delete immediately
-PASS CacheStorage.open with an empty name
-PASS CacheStorage.open with no arguments
-PASS CacheStorage.has with existing cache
-PASS CacheStorage.has with nonexistent cache
-PASS CacheStorage.open with existing cache
-PASS CacheStorage.delete with existing cache
-PASS CacheStorage.delete with nonexistent cache
-FAIL CacheStorage names are DOMStrings not USVStrings assert_true: keys should include cache with bad name expected true got false
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/window/cache-add.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/window/cache-add.https-expected.txt
deleted file mode 100644
index 3f3f278..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/window/cache-add.https-expected.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-This is a testharness.js-based test.
-PASS Cache.add called with no arguments
-PASS Cache.add called with relative URL specified as a string
-PASS Cache.add called with non-HTTP/HTTPS URL
-PASS Cache.add called with Request object
-PASS Cache.add called with POST request
-PASS Cache.add called twice with the same Request object
-PASS Cache.add with request with null body (not consumed)
-PASS Cache.add with 206 response
-PASS Cache.addAll with 206 response
-PASS Cache.add with request that results in a status of 404
-PASS Cache.add with request that results in a status of 500
-PASS Cache.addAll with no arguments
-PASS Cache.addAll with a mix of valid and undefined arguments
-PASS Cache.addAll with an empty array
-PASS Cache.addAll with string URL arguments
-PASS Cache.addAll with Request arguments
-PASS Cache.addAll with a mix of succeeding and failing requests
-FAIL Cache.addAll called with the same Request object specified twice assert_unreached: Should have rejected: Cache.addAll should throw InvalidStateError if the same request is added twice. Reached unreachable code
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/window/cache-matchAll.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/window/cache-matchAll.https-expected.txt
deleted file mode 100644
index 69fcf49eb..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/window/cache-matchAll.https-expected.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-This is a testharness.js-based test.
-PASS Cache.matchAll with no matching entries
-PASS Cache.matchAll with URL
-PASS Cache.matchAll with Request
-PASS Cache.matchAll with new Request
-PASS Cache.matchAll with HEAD
-PASS Cache.matchAll with ignoreSearch option (request with no search parameters)
-PASS Cache.matchAll with ignoreSearch option (request with search parameters)
-PASS Cache.matchAll supports ignoreMethod
-PASS Cache.matchAll supports ignoreVary
-PASS Cache.matchAll with URL containing fragment
-PASS Cache.matchAll with string fragment "http" as query
-PASS Cache.matchAll without parameters
-FAIL Cache.matchAll with responses containing "Vary" header assert_equals: Cache.matchAll should match the entire header if a vary header is present in both the query and cached requests. expected 1 but got 0
-FAIL Cache.matchAll with multiple vary pairs assert_equals: Cache.matchAll should support multiple vary request/response pairs. expected 3 but got 1
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/window/cache-storage.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/window/cache-storage.https-expected.txt
deleted file mode 100644
index d1c62496..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/window/cache-storage.https-expected.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-This is a testharness.js-based test.
-PASS CacheStorage.open
-PASS CacheStorage.delete dooms, but does not delete immediately
-PASS CacheStorage.open with an empty name
-PASS CacheStorage.open with no arguments
-PASS CacheStorage.has with existing cache
-PASS CacheStorage.has with nonexistent cache
-PASS CacheStorage.open with existing cache
-PASS CacheStorage.delete with existing cache
-PASS CacheStorage.delete with nonexistent cache
-FAIL CacheStorage names are DOMStrings not USVStrings assert_true: keys should include cache with bad name expected true got false
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/window/sandboxed-iframes.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/window/sandboxed-iframes.https-expected.txt
deleted file mode 100644
index dc39b96..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/window/sandboxed-iframes.https-expected.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-
-This is a testharness.js-based test.
-PASS Sandboxed iframe with allow-same-origin is allowed access
-FAIL Sandboxed iframe without allow-same-origin is denied access assert_equals: Access should be denied if sandbox lacks allow-same-origin expected "denied" but got "unexpecteddenied"
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/worker/cache-add.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/worker/cache-add.https-expected.txt
deleted file mode 100644
index 3f3f278..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/worker/cache-add.https-expected.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-This is a testharness.js-based test.
-PASS Cache.add called with no arguments
-PASS Cache.add called with relative URL specified as a string
-PASS Cache.add called with non-HTTP/HTTPS URL
-PASS Cache.add called with Request object
-PASS Cache.add called with POST request
-PASS Cache.add called twice with the same Request object
-PASS Cache.add with request with null body (not consumed)
-PASS Cache.add with 206 response
-PASS Cache.addAll with 206 response
-PASS Cache.add with request that results in a status of 404
-PASS Cache.add with request that results in a status of 500
-PASS Cache.addAll with no arguments
-PASS Cache.addAll with a mix of valid and undefined arguments
-PASS Cache.addAll with an empty array
-PASS Cache.addAll with string URL arguments
-PASS Cache.addAll with Request arguments
-PASS Cache.addAll with a mix of succeeding and failing requests
-FAIL Cache.addAll called with the same Request object specified twice assert_unreached: Should have rejected: Cache.addAll should throw InvalidStateError if the same request is added twice. Reached unreachable code
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/worker/cache-matchAll.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/worker/cache-matchAll.https-expected.txt
deleted file mode 100644
index 69fcf49eb..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/worker/cache-matchAll.https-expected.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-This is a testharness.js-based test.
-PASS Cache.matchAll with no matching entries
-PASS Cache.matchAll with URL
-PASS Cache.matchAll with Request
-PASS Cache.matchAll with new Request
-PASS Cache.matchAll with HEAD
-PASS Cache.matchAll with ignoreSearch option (request with no search parameters)
-PASS Cache.matchAll with ignoreSearch option (request with search parameters)
-PASS Cache.matchAll supports ignoreMethod
-PASS Cache.matchAll supports ignoreVary
-PASS Cache.matchAll with URL containing fragment
-PASS Cache.matchAll with string fragment "http" as query
-PASS Cache.matchAll without parameters
-FAIL Cache.matchAll with responses containing "Vary" header assert_equals: Cache.matchAll should match the entire header if a vary header is present in both the query and cached requests. expected 1 but got 0
-FAIL Cache.matchAll with multiple vary pairs assert_equals: Cache.matchAll should support multiple vary request/response pairs. expected 3 but got 1
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/worker/cache-storage.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/worker/cache-storage.https-expected.txt
deleted file mode 100644
index d1c62496..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/cache-storage/worker/cache-storage.https-expected.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-This is a testharness.js-based test.
-PASS CacheStorage.open
-PASS CacheStorage.delete dooms, but does not delete immediately
-PASS CacheStorage.open with an empty name
-PASS CacheStorage.open with no arguments
-PASS CacheStorage.has with existing cache
-PASS CacheStorage.has with nonexistent cache
-PASS CacheStorage.open with existing cache
-PASS CacheStorage.delete with existing cache
-PASS CacheStorage.delete with nonexistent cache
-FAIL CacheStorage names are DOMStrings not USVStrings assert_true: keys should include cache with bad name expected true got false
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/clients-get-client-types.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/clients-get-client-types.https-expected.txt
deleted file mode 100644
index 58bae30..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/clients-get-client-types.https-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Test Clients.get() with window and worker clients assert_not_equals: Worker(Started by main frame) client should not be undefined got disallowed value undefined
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/clients-matchall-client-types.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/clients-matchall-client-types.https-expected.txt
deleted file mode 100644
index 1f2011a..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/clients-matchall-client-types.https-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-FAIL Verify matchAll() with window client type assert_unreached: unexpected rejection: assert_array_equals: property 2, expected "https://web-platform.test:8444/service-workers/service-worker/resources/clients-matchall-client-types-iframe.html" but got "https://web-platform.test:8444/service-workers/service-worker/resources/url-modified-via-pushstate.html" Reached unreachable code
-FAIL Verify matchAll() with {window, sharedworker, worker} client types promise_test: Unhandled rejection with value: object "Error: wait_for_state must be passed a ServiceWorker"
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/clients-matchall-order.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/clients-matchall-order.https-expected.txt
deleted file mode 100644
index 78737fe..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/clients-matchall-order.https-expected.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-This is a testharness.js-based test.
-PASS Clients.matchAll() returns non-focused controlled windows in creation order.
-PASS Clients.matchAll() returns controlled windows in focus order.  Case 1.
-PASS Clients.matchAll() returns controlled windows in focus order.  Case 2.
-FAIL Clients.matchAll() returns non-focused uncontrolled windows in creation order. assert_equals: expected 6 but got 5
-FAIL Clients.matchAll() returns uncontrolled windows in focus order.  Case 1. assert_equals: expected 6 but got 5
-FAIL Clients.matchAll() returns uncontrolled windows in focus order.  Case 2. assert_equals: expected 6 but got 5
-FAIL Clients.matchAll() returns controlled windows and frames in focus order. assert_equals: expected URL index 1 expected "https://web-platform.test:8444/service-workers/service-worker/resources/empty.html?name=focus-controlled-nested-windows&q=1" but got "https://web-platform.test:8444/service-workers/service-worker/resources/empty.html?name=focus-controlled-nested-windows&q=1&nested=true"
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/fetch-event-redirect.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/fetch-event-redirect.https-expected.txt
deleted file mode 100644
index f91bc57e..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/fetch-event-redirect.https-expected.txt
+++ /dev/null
@@ -1,57 +0,0 @@
-This is a testharness.js-based test.
-PASS Non-navigation, manual redirect, cors mode Request redirected to same-origin without credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, cors mode Request redirected to no-cors without credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, cors mode Request redirected to cors without credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, same-origin mode Request redirected to same-origin without credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, same-origin mode Request redirected to no-cors without credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, same-origin mode Request redirected to cors without credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, no-cors mode Request redirected to same-origin without credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, no-cors mode Request redirected to no-cors without credentials should succeed interception and response should not be redirected
-PASS Non-navigation, manual redirect, no-cors mode Request redirected to cors without credentials should succeed interception and response should not be redirected
-PASS Non-navigation, manual redirect, cors mode Request redirected to same-origin with credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, cors mode Request redirected to no-cors with credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, cors mode Request redirected to cors with credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, same-origin mode Request redirected to same-origin with credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, same-origin mode Request redirected to no-cors with credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, same-origin mode Request redirected to cors with credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, no-cors mode Request redirected to same-origin with credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, no-cors mode Request redirected to no-cors with credentials should succeed interception and response should not be redirected
-PASS Non-navigation, manual redirect, no-cors mode Request redirected to cors with credentials should succeed interception and response should not be redirected
-PASS Non-navigation, follow redirect, cors mode Request redirected to same-origin without credentials should succeed interception and response should be redirected
-PASS Non-navigation, follow redirect, cors mode Request redirected to no-cors without credentials should fail interception and response should not be redirected
-PASS Non-navigation, follow redirect, cors mode Request redirected to cors without credentials should succeed interception and response should be redirected
-PASS Non-navigation, follow redirect, same-origin mode Request redirected to same-origin without credentials should succeed interception and response should be redirected
-PASS Non-navigation, follow redirect, same-origin mode Request redirected to no-cors without credentials should fail interception and response should not be redirected
-PASS Non-navigation, follow redirect, same-origin mode Request redirected to cors without credentials should fail interception and response should not be redirected
-PASS Non-navigation, follow redirect, no-cors mode Request redirected to same-origin without credentials should succeed interception and response should be redirected
-PASS Non-navigation, follow redirect, no-cors mode Request redirected to no-cors without credentials should succeed interception and response should not be redirected
-PASS Non-navigation, follow redirect, no-cors mode Request redirected to cors without credentials should succeed interception and response should not be redirected
-FAIL Non-navigation, follow redirect, cors mode Request redirected to same-origin with credentials should succeed interception and response should be redirected assert_unreached: unexpected rejection: TypeError: Failed to fetch Reached unreachable code
-PASS Non-navigation, follow redirect, cors mode Request redirected to no-cors with credentials should fail interception and response should not be redirected
-PASS Non-navigation, follow redirect, cors mode Request redirected to cors with credentials should fail interception and response should be redirected
-FAIL Non-navigation, follow redirect, same-origin mode Request redirected to same-origin with credentials should succeed interception and response should be redirected assert_unreached: unexpected rejection: TypeError: Failed to fetch Reached unreachable code
-PASS Non-navigation, follow redirect, same-origin mode Request redirected to no-cors with credentials should fail interception and response should not be redirected
-PASS Non-navigation, follow redirect, same-origin mode Request redirected to cors with credentials should fail interception and response should not be redirected
-FAIL Non-navigation, follow redirect, no-cors mode Request redirected to same-origin with credentials should succeed interception and response should be redirected assert_unreached: unexpected rejection: TypeError: Failed to fetch Reached unreachable code
-FAIL Non-navigation, follow redirect, no-cors mode Request redirected to no-cors with credentials should succeed interception and response should not be redirected assert_unreached: unexpected rejection: TypeError: Failed to fetch Reached unreachable code
-FAIL Non-navigation, follow redirect, no-cors mode Request redirected to cors with credentials should succeed interception and response should not be redirected assert_unreached: unexpected rejection: TypeError: Failed to fetch Reached unreachable code
-PASS Non-navigation, error redirect, cors mode Request redirected to same-origin without credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, cors mode Request redirected to no-cors without credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, cors mode Request redirected to cors without credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, same-origin mode Request redirected to same-origin without credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, same-origin mode Request redirected to no-cors without credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, same-origin mode Request redirected to cors without credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, no-cors mode Request redirected to same-origin without credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, no-cors mode Request redirected to no-cors without credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, no-cors mode Request redirected to cors without credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, cors mode Request redirected to same-origin with credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, cors mode Request redirected to no-cors with credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, cors mode Request redirected to cors with credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, same-origin mode Request redirected to same-origin with credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, same-origin mode Request redirected to no-cors with credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, same-origin mode Request redirected to cors with credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, no-cors mode Request redirected to same-origin with credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, no-cors mode Request redirected to no-cors with credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, no-cors mode Request redirected to cors with credentials should fail interception and response should not be redirected
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/fetch-event-referrer-policy.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/fetch-event-referrer-policy.https-expected.txt
deleted file mode 100644
index 4ed287e..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/fetch-event-referrer-policy.https-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Service Worker responds to fetch event with the referrer policy assert_unreached: unexpected rejection: assert_equals: Service Worker should respond to fetch with the referrer URL when a member of RequestInit is present expected "Referrer: https://web-platform.test:8444/service-workers/service-worker/fake-referrer\nReferrerPolicy: no-referrer-when-downgrade" but got "Referrer: https://web-platform.test:8444/service-workers/service-worker/resources/fake-referrer\nReferrerPolicy: no-referrer-when-downgrade" Reached unreachable code
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/fetch-event-within-sw-manual.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/fetch-event-within-sw-manual.https-expected.txt
deleted file mode 100644
index e774a74..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/fetch-event-within-sw-manual.https-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Notification requests intercepted both from window and SW promise_test: Unhandled rejection with value: object "Error: You must allow notifications for this origin before running this test."
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/fetch-event.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/fetch-event.https-expected.txt
deleted file mode 100644
index 2eb875c..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/fetch-event.https-expected.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-This is a testharness.js-based test.
-PASS Service Worker headers in the request of a fetch event
-PASS Service Worker responds to fetch event with string
-PASS Service Worker responds to fetch event with blob body
-PASS Service Worker responds to fetch event with the referrer URL
-PASS Service Worker responds to fetch event with an existing client id
-PASS Service Worker does not respond to fetch event
-PASS Service Worker responds to fetch event with null response body
-PASS Service Worker fetches other file in fetch event
-PASS Service Worker responds to fetch event with POST form
-PASS Multiple calls of respondWith must throw InvalidStateErrors
-PASS Service Worker event.respondWith must set the used flag
-PASS Service Worker should expose FetchEvent URL fragments.
-FAIL Service Worker responds to fetch event with the correct cache types assert_unreached: unexpected rejection: assert_equals: Service Worker should respond to fetch with the correct type expected "no-store" but got "default" Reached unreachable code
-FAIL Service Worker should intercept EventSource assert_unreached: unexpected rejection: assert_equals: EventSource should bypass the http cache. expected "no-store" but got "default" Reached unreachable code
-FAIL Service Worker responds to fetch event with the correct integrity_metadata assert_unreached: unexpected rejection: assert_equals: integrity expected "gs0nqru8KbsrIt5YToQqS9fYao4GQJXtcId610g7cCU=" but got "" Reached unreachable code
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/fetch-request-xhr-sync.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/fetch-request-xhr-sync.https-expected.txt
deleted file mode 100644
index 724b7d8..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/fetch-request-xhr-sync.https-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Verify SyncXHR is intercepted assert_equals: HTTP response status code for intercepted request expected 200 but got 404
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/fetch-request-xhr.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/fetch-request-xhr.https-expected.txt
deleted file mode 100644
index b52f7871..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/fetch-request-xhr.https-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Verify the body of FetchEvent using XMLHttpRequest assert_array_equals: event.request has the expected headers for same-origin GET. lengths differ, expected 1 got 2
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/import-scripts-redirect.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/import-scripts-redirect.https-expected.txt
deleted file mode 100644
index 54836e4..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/import-scripts-redirect.https-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-FAIL importScripts() supports redirects promise_test: Unhandled rejection with value: object "TypeError: Failed to register a ServiceWorker: ServiceWorker script evaluation failed"
-FAIL importScripts() supports redirects and can be updated promise_test: Unhandled rejection with value: object "TypeError: Failed to register a ServiceWorker: ServiceWorker script evaluation failed"
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/import-scripts-updated-flag.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/import-scripts-updated-flag.https-expected.txt
deleted file mode 100644
index 0e50082..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/import-scripts-updated-flag.https-expected.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-This is a testharness.js-based test.
-PASS initialize global state
-PASS import script previously imported at worker evaluation time
-PASS import script previously imported at worker install time
-FAIL import script not previously imported assert_equals: expected (string) "TypeError" but got (object) null
-PASS Tests for importScripts: import scripts updated flag
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/interfaces-sw.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/interfaces-sw.https-expected.txt
deleted file mode 100644
index 3c98081d..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/interfaces-sw.https-expected.txt
+++ /dev/null
@@ -1,187 +0,0 @@
-This is a testharness.js-based test.
-PASS Interfaces and attributes in ServiceWorkerGlobalScope
-PASS test setup (cache creation)
-PASS Event constructors
-PASS ServiceWorkerGlobalScope interface: existence and properties of interface object
-PASS ServiceWorkerGlobalScope interface object length
-PASS ServiceWorkerGlobalScope interface object name
-PASS ServiceWorkerGlobalScope interface: existence and properties of interface prototype object
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to a new value via Object.setPrototypeOf should throw a TypeError
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to a new value via __proto__ should throw a TypeError
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to a new value via Reflect.setPrototypeOf should return false
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to its original value via Object.setPrototypeOf should not throw
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to its original value via __proto__ should not throw
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to its original value via Reflect.setPrototypeOf should return true
-PASS ServiceWorkerGlobalScope interface: existence and properties of interface prototype object's "constructor" property
-PASS ServiceWorkerGlobalScope interface: attribute clients
-PASS ServiceWorkerGlobalScope interface: attribute registration
-PASS ServiceWorkerGlobalScope interface: operation skipWaiting()
-PASS ServiceWorkerGlobalScope interface: attribute oninstall
-PASS ServiceWorkerGlobalScope interface: attribute onactivate
-PASS ServiceWorkerGlobalScope interface: attribute onfetch
-PASS ServiceWorkerGlobalScope interface: attribute onforeignfetch
-PASS ServiceWorkerGlobalScope interface: attribute onmessage
-FAIL ServiceWorkerGlobalScope interface: attribute onmessageerror assert_own_property: The global object must have a property "onmessageerror" expected property "onmessageerror" missing
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to a new value via Object.setPrototypeOf should throw a TypeError
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to a new value via __proto__ should throw a TypeError
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to a new value via Reflect.setPrototypeOf should return false
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to its original value via Object.setPrototypeOf should not throw
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to its original value via __proto__ should not throw
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to its original value via Reflect.setPrototypeOf should return true
-PASS ServiceWorkerGlobalScope must be primary interface of self
-PASS Stringification of self
-PASS ServiceWorkerGlobalScope interface: self must inherit property "clients" with the proper type
-PASS ServiceWorkerGlobalScope interface: self must inherit property "registration" with the proper type
-PASS ServiceWorkerGlobalScope interface: self must inherit property "skipWaiting()" with the proper type
-PASS ServiceWorkerGlobalScope interface: self must inherit property "oninstall" with the proper type
-PASS ServiceWorkerGlobalScope interface: self must inherit property "onactivate" with the proper type
-PASS ServiceWorkerGlobalScope interface: self must inherit property "onfetch" with the proper type
-PASS ServiceWorkerGlobalScope interface: self must inherit property "onforeignfetch" with the proper type
-PASS ServiceWorkerGlobalScope interface: self must inherit property "onmessage" with the proper type
-FAIL ServiceWorkerGlobalScope interface: self must inherit property "onmessageerror" with the proper type assert_own_property: expected property "onmessageerror" missing
-PASS Client interface: existence and properties of interface object
-PASS Client interface object length
-PASS Client interface object name
-PASS Client interface: existence and properties of interface prototype object
-PASS Client interface: existence and properties of interface prototype object's "constructor" property
-PASS Client interface: attribute url
-PASS Client interface: attribute id
-PASS Client interface: attribute type
-FAIL Client interface: attribute reserved assert_true: The prototype object must have a property "reserved" expected true got false
-PASS Client interface: operation postMessage(any, [object Object])
-PASS WindowClient interface: existence and properties of interface object
-PASS WindowClient interface object length
-PASS WindowClient interface object name
-PASS WindowClient interface: existence and properties of interface prototype object
-PASS WindowClient interface: existence and properties of interface prototype object's "constructor" property
-PASS WindowClient interface: attribute visibilityState
-PASS WindowClient interface: attribute focused
-FAIL WindowClient interface: attribute ancestorOrigins assert_true: The prototype object must have a property "ancestorOrigins" expected true got false
-PASS WindowClient interface: operation focus()
-PASS WindowClient interface: operation navigate(USVString)
-PASS Clients interface: existence and properties of interface object
-PASS Clients interface object length
-PASS Clients interface object name
-PASS Clients interface: existence and properties of interface prototype object
-PASS Clients interface: existence and properties of interface prototype object's "constructor" property
-PASS Clients interface: operation get(DOMString)
-PASS Clients interface: operation matchAll(ClientQueryOptions)
-PASS Clients interface: operation openWindow(USVString)
-PASS Clients interface: operation claim()
-PASS Clients must be primary interface of self.clients
-PASS Stringification of self.clients
-PASS Clients interface: self.clients must inherit property "get(DOMString)" with the proper type
-PASS Clients interface: calling get(DOMString) on self.clients with too few arguments must throw TypeError
-PASS Clients interface: self.clients must inherit property "matchAll(ClientQueryOptions)" with the proper type
-PASS Clients interface: calling matchAll(ClientQueryOptions) on self.clients with too few arguments must throw TypeError
-PASS Clients interface: self.clients must inherit property "openWindow(USVString)" with the proper type
-PASS Clients interface: calling openWindow(USVString) on self.clients with too few arguments must throw TypeError
-PASS Clients interface: self.clients must inherit property "claim()" with the proper type
-FAIL ServiceWorker interface: existence and properties of interface object assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface object length assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface object name assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface: existence and properties of interface prototype object assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface: attribute scriptURL assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface: attribute state assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface: operation postMessage(any, [object Object]) assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface: attribute onstatechange assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-PASS ServiceWorkerRegistration interface: existence and properties of interface object
-PASS ServiceWorkerRegistration interface object length
-PASS ServiceWorkerRegistration interface object name
-PASS ServiceWorkerRegistration interface: existence and properties of interface prototype object
-PASS ServiceWorkerRegistration interface: existence and properties of interface prototype object's "constructor" property
-PASS ServiceWorkerRegistration interface: attribute installing
-PASS ServiceWorkerRegistration interface: attribute waiting
-PASS ServiceWorkerRegistration interface: attribute active
-PASS ServiceWorkerRegistration interface: attribute navigationPreload
-PASS ServiceWorkerRegistration interface: attribute scope
-FAIL ServiceWorkerRegistration interface: attribute updateViaCache assert_true: The prototype object must have a property "updateViaCache" expected true got false
-PASS ServiceWorkerRegistration interface: operation update()
-PASS ServiceWorkerRegistration interface: operation unregister()
-PASS ServiceWorkerRegistration interface: attribute onupdatefound
-PASS ServiceWorkerRegistration must be primary interface of self.registration
-PASS Stringification of self.registration
-PASS ServiceWorkerRegistration interface: self.registration must inherit property "installing" with the proper type
-PASS ServiceWorkerRegistration interface: self.registration must inherit property "waiting" with the proper type
-PASS ServiceWorkerRegistration interface: self.registration must inherit property "active" with the proper type
-PASS ServiceWorkerRegistration interface: self.registration must inherit property "navigationPreload" with the proper type
-PASS ServiceWorkerRegistration interface: self.registration must inherit property "scope" with the proper type
-FAIL ServiceWorkerRegistration interface: self.registration must inherit property "updateViaCache" with the proper type assert_inherits: property "updateViaCache" not found in prototype chain
-PASS ServiceWorkerRegistration interface: self.registration must inherit property "update()" with the proper type
-PASS ServiceWorkerRegistration interface: self.registration must inherit property "unregister()" with the proper type
-PASS ServiceWorkerRegistration interface: self.registration must inherit property "onupdatefound" with the proper type
-PASS EventTarget interface: self.registration must inherit property "addEventListener(DOMString, EventListener, [object Object],[object Object])" with the proper type
-PASS EventTarget interface: calling addEventListener(DOMString, EventListener, [object Object],[object Object]) on self.registration with too few arguments must throw TypeError
-PASS EventTarget interface: self.registration must inherit property "removeEventListener(DOMString, EventListener, [object Object],[object Object])" with the proper type
-PASS EventTarget interface: calling removeEventListener(DOMString, EventListener, [object Object],[object Object]) on self.registration with too few arguments must throw TypeError
-PASS EventTarget interface: self.registration must inherit property "dispatchEvent(Event)" with the proper type
-PASS EventTarget interface: calling dispatchEvent(Event) on self.registration with too few arguments must throw TypeError
-PASS EventTarget interface: existence and properties of interface object
-PASS EventTarget interface object length
-PASS EventTarget interface object name
-PASS EventTarget interface: existence and properties of interface prototype object
-PASS EventTarget interface: existence and properties of interface prototype object's "constructor" property
-PASS EventTarget interface: operation addEventListener(DOMString, EventListener, [object Object],[object Object])
-PASS EventTarget interface: operation removeEventListener(DOMString, EventListener, [object Object],[object Object])
-PASS EventTarget interface: operation dispatchEvent(Event)
-PASS NavigationPreloadManager interface: existence and properties of interface object
-PASS NavigationPreloadManager interface object length
-PASS NavigationPreloadManager interface object name
-PASS NavigationPreloadManager interface: existence and properties of interface prototype object
-PASS NavigationPreloadManager interface: existence and properties of interface prototype object's "constructor" property
-PASS NavigationPreloadManager interface: operation enable()
-PASS NavigationPreloadManager interface: operation disable()
-PASS NavigationPreloadManager interface: operation setHeaderValue(ByteString)
-PASS NavigationPreloadManager interface: operation getState()
-PASS Cache interface: existence and properties of interface object
-PASS Cache interface object length
-PASS Cache interface object name
-PASS Cache interface: existence and properties of interface prototype object
-PASS Cache interface: existence and properties of interface prototype object's "constructor" property
-PASS Cache interface: operation match(RequestInfo, CacheQueryOptions)
-PASS Cache interface: operation matchAll(RequestInfo, CacheQueryOptions)
-PASS Cache interface: operation add(RequestInfo)
-PASS Cache interface: operation addAll([object Object])
-PASS Cache interface: operation put(RequestInfo, Response)
-PASS Cache interface: operation delete(RequestInfo, CacheQueryOptions)
-PASS Cache interface: operation keys(RequestInfo, CacheQueryOptions)
-PASS Cache must be primary interface of self.cacheInstance
-PASS Stringification of self.cacheInstance
-PASS Cache interface: self.cacheInstance must inherit property "match(RequestInfo, CacheQueryOptions)" with the proper type
-PASS Cache interface: calling match(RequestInfo, CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "matchAll(RequestInfo, CacheQueryOptions)" with the proper type
-PASS Cache interface: calling matchAll(RequestInfo, CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "add(RequestInfo)" with the proper type
-PASS Cache interface: calling add(RequestInfo) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "addAll([object Object])" with the proper type
-PASS Cache interface: calling addAll([object Object]) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "put(RequestInfo, Response)" with the proper type
-PASS Cache interface: calling put(RequestInfo, Response) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "delete(RequestInfo, CacheQueryOptions)" with the proper type
-PASS Cache interface: calling delete(RequestInfo, CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "keys(RequestInfo, CacheQueryOptions)" with the proper type
-PASS Cache interface: calling keys(RequestInfo, CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError
-PASS CacheStorage interface: existence and properties of interface object
-PASS CacheStorage interface object length
-PASS CacheStorage interface object name
-PASS CacheStorage interface: existence and properties of interface prototype object
-PASS CacheStorage interface: existence and properties of interface prototype object's "constructor" property
-PASS CacheStorage interface: operation match(RequestInfo, CacheQueryOptions)
-PASS CacheStorage interface: operation has(DOMString)
-PASS CacheStorage interface: operation open(DOMString)
-PASS CacheStorage interface: operation delete(DOMString)
-PASS CacheStorage interface: operation keys()
-PASS CacheStorage must be primary interface of self.caches
-PASS Stringification of self.caches
-PASS CacheStorage interface: self.caches must inherit property "match(RequestInfo, CacheQueryOptions)" with the proper type
-PASS CacheStorage interface: calling match(RequestInfo, CacheQueryOptions) on self.caches with too few arguments must throw TypeError
-PASS CacheStorage interface: self.caches must inherit property "has(DOMString)" with the proper type
-PASS CacheStorage interface: calling has(DOMString) on self.caches with too few arguments must throw TypeError
-PASS CacheStorage interface: self.caches must inherit property "open(DOMString)" with the proper type
-PASS CacheStorage interface: calling open(DOMString) on self.caches with too few arguments must throw TypeError
-PASS CacheStorage interface: self.caches must inherit property "delete(DOMString)" with the proper type
-PASS CacheStorage interface: calling delete(DOMString) on self.caches with too few arguments must throw TypeError
-PASS CacheStorage interface: self.caches must inherit property "keys()" with the proper type
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/interfaces-window.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/interfaces-window.https-expected.txt
deleted file mode 100644
index 178972d..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/interfaces-window.https-expected.txt
+++ /dev/null
@@ -1,101 +0,0 @@
-This is a testharness.js-based test.
-PASS test setup (worker registration)
-PASS WorkerGlobalScope interface: existence and properties of interface object
-PASS ServiceWorkerGlobalScope interface: existence and properties of interface object
-PASS Client interface: existence and properties of interface object
-PASS WindowClient interface: existence and properties of interface object
-PASS Clients interface: existence and properties of interface object
-PASS ServiceWorker interface: existence and properties of interface object
-PASS ServiceWorker interface object length
-PASS ServiceWorker interface object name
-PASS ServiceWorker interface: existence and properties of interface prototype object
-PASS ServiceWorker interface: existence and properties of interface prototype object's "constructor" property
-PASS ServiceWorker interface: attribute scriptURL
-PASS ServiceWorker interface: attribute state
-PASS ServiceWorker interface: operation postMessage(any, [object Object])
-PASS ServiceWorker interface: attribute onstatechange
-PASS ServiceWorker must be primary interface of window.registrationInstance.installing
-PASS Stringification of window.registrationInstance.installing
-PASS ServiceWorker interface: window.registrationInstance.installing must inherit property "scriptURL" with the proper type
-PASS ServiceWorker interface: window.registrationInstance.installing must inherit property "state" with the proper type
-PASS ServiceWorker interface: window.registrationInstance.installing must inherit property "postMessage(any, [object Object])" with the proper type
-PASS ServiceWorker interface: calling postMessage(any, [object Object]) on window.registrationInstance.installing with too few arguments must throw TypeError
-PASS ServiceWorker interface: window.registrationInstance.installing must inherit property "onstatechange" with the proper type
-PASS EventTarget interface: window.registrationInstance.installing must inherit property "addEventListener(DOMString, EventListener, [object Object],[object Object])" with the proper type
-PASS EventTarget interface: calling addEventListener(DOMString, EventListener, [object Object],[object Object]) on window.registrationInstance.installing with too few arguments must throw TypeError
-PASS EventTarget interface: window.registrationInstance.installing must inherit property "removeEventListener(DOMString, EventListener, [object Object],[object Object])" with the proper type
-PASS EventTarget interface: calling removeEventListener(DOMString, EventListener, [object Object],[object Object]) on window.registrationInstance.installing with too few arguments must throw TypeError
-PASS EventTarget interface: window.registrationInstance.installing must inherit property "dispatchEvent(Event)" with the proper type
-PASS EventTarget interface: calling dispatchEvent(Event) on window.registrationInstance.installing with too few arguments must throw TypeError
-PASS ServiceWorkerRegistration interface: existence and properties of interface object
-PASS ServiceWorkerRegistration interface object length
-PASS ServiceWorkerRegistration interface object name
-PASS ServiceWorkerRegistration interface: existence and properties of interface prototype object
-PASS ServiceWorkerRegistration interface: existence and properties of interface prototype object's "constructor" property
-PASS ServiceWorkerRegistration interface: attribute installing
-PASS ServiceWorkerRegistration interface: attribute waiting
-PASS ServiceWorkerRegistration interface: attribute active
-PASS ServiceWorkerRegistration interface: attribute navigationPreload
-PASS ServiceWorkerRegistration interface: attribute scope
-FAIL ServiceWorkerRegistration interface: attribute updateViaCache assert_true: The prototype object must have a property "updateViaCache" expected true got false
-PASS ServiceWorkerRegistration interface: operation update()
-PASS ServiceWorkerRegistration interface: operation unregister()
-PASS ServiceWorkerRegistration interface: attribute onupdatefound
-PASS ServiceWorkerRegistration must be primary interface of window.registrationInstance
-PASS Stringification of window.registrationInstance
-PASS ServiceWorkerRegistration interface: window.registrationInstance must inherit property "installing" with the proper type
-PASS ServiceWorkerRegistration interface: window.registrationInstance must inherit property "waiting" with the proper type
-PASS ServiceWorkerRegistration interface: window.registrationInstance must inherit property "active" with the proper type
-PASS ServiceWorkerRegistration interface: window.registrationInstance must inherit property "navigationPreload" with the proper type
-PASS ServiceWorkerRegistration interface: window.registrationInstance must inherit property "scope" with the proper type
-FAIL ServiceWorkerRegistration interface: window.registrationInstance must inherit property "updateViaCache" with the proper type assert_inherits: property "updateViaCache" not found in prototype chain
-PASS ServiceWorkerRegistration interface: window.registrationInstance must inherit property "update()" with the proper type
-PASS ServiceWorkerRegistration interface: window.registrationInstance must inherit property "unregister()" with the proper type
-PASS ServiceWorkerRegistration interface: window.registrationInstance must inherit property "onupdatefound" with the proper type
-PASS EventTarget interface: window.registrationInstance must inherit property "addEventListener(DOMString, EventListener, [object Object],[object Object])" with the proper type
-PASS EventTarget interface: calling addEventListener(DOMString, EventListener, [object Object],[object Object]) on window.registrationInstance with too few arguments must throw TypeError
-PASS EventTarget interface: window.registrationInstance must inherit property "removeEventListener(DOMString, EventListener, [object Object],[object Object])" with the proper type
-PASS EventTarget interface: calling removeEventListener(DOMString, EventListener, [object Object],[object Object]) on window.registrationInstance with too few arguments must throw TypeError
-PASS EventTarget interface: window.registrationInstance must inherit property "dispatchEvent(Event)" with the proper type
-PASS EventTarget interface: calling dispatchEvent(Event) on window.registrationInstance with too few arguments must throw TypeError
-PASS EventTarget interface: existence and properties of interface object
-PASS EventTarget interface object length
-PASS EventTarget interface object name
-PASS EventTarget interface: existence and properties of interface prototype object
-PASS EventTarget interface: existence and properties of interface prototype object's "constructor" property
-PASS EventTarget interface: operation addEventListener(DOMString, EventListener, [object Object],[object Object])
-PASS EventTarget interface: operation removeEventListener(DOMString, EventListener, [object Object],[object Object])
-PASS EventTarget interface: operation dispatchEvent(Event)
-PASS NavigationPreloadManager interface: existence and properties of interface object
-PASS NavigationPreloadManager interface object length
-PASS NavigationPreloadManager interface object name
-PASS NavigationPreloadManager interface: existence and properties of interface prototype object
-PASS NavigationPreloadManager interface: existence and properties of interface prototype object's "constructor" property
-PASS NavigationPreloadManager interface: operation enable()
-PASS NavigationPreloadManager interface: operation disable()
-PASS NavigationPreloadManager interface: operation setHeaderValue(ByteString)
-PASS NavigationPreloadManager interface: operation getState()
-PASS Cache interface: existence and properties of interface object
-PASS Cache interface object length
-PASS Cache interface object name
-PASS Cache interface: existence and properties of interface prototype object
-PASS Cache interface: existence and properties of interface prototype object's "constructor" property
-PASS Cache interface: operation match(RequestInfo, CacheQueryOptions)
-PASS Cache interface: operation matchAll(RequestInfo, CacheQueryOptions)
-PASS Cache interface: operation add(RequestInfo)
-PASS Cache interface: operation addAll([object Object])
-PASS Cache interface: operation put(RequestInfo, Response)
-PASS Cache interface: operation delete(RequestInfo, CacheQueryOptions)
-PASS Cache interface: operation keys(RequestInfo, CacheQueryOptions)
-PASS CacheStorage interface: existence and properties of interface object
-PASS CacheStorage interface object length
-PASS CacheStorage interface object name
-PASS CacheStorage interface: existence and properties of interface prototype object
-PASS CacheStorage interface: existence and properties of interface prototype object's "constructor" property
-PASS CacheStorage interface: operation match(RequestInfo, CacheQueryOptions)
-PASS CacheStorage interface: operation has(DOMString)
-PASS CacheStorage interface: operation open(DOMString)
-PASS CacheStorage interface: operation delete(DOMString)
-PASS CacheStorage interface: operation keys()
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/link-element-register-mime-types.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/link-element-register-mime-types.https-expected.txt
deleted file mode 100644
index 28bf3a7..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/link-element-register-mime-types.https-expected.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-This is a testharness.js-based test.
-FAIL Registering script with no MIME type Test bug: need to pass exception to assert_throws()
-FAIL Registering script with bad MIME type Test bug: need to pass exception to assert_throws()
-FAIL Registering script that imports script with no MIME type assert_unreached: Should have rejected: Registration of no MIME type imported script should fail. Reached unreachable code
-FAIL Registering script that imports script with bad MIME type assert_unreached: Should have rejected: Registration of plain text imported script should fail. Reached unreachable code
-FAIL Registering script with good MIME type application/ecmascript promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type application/ecmascript
-PASS Registering script with good MIME type application/javascript
-PASS Registering script that imports script with good MIME type application/javascript
-FAIL Registering script with good MIME type application/x-ecmascript promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type application/x-ecmascript
-PASS Registering script with good MIME type application/x-javascript
-PASS Registering script that imports script with good MIME type application/x-javascript
-FAIL Registering script with good MIME type text/ecmascript promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type text/ecmascript
-PASS Registering script with good MIME type text/javascript
-PASS Registering script that imports script with good MIME type text/javascript
-FAIL Registering script with good MIME type text/javascript1.0 promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type text/javascript1.0
-FAIL Registering script with good MIME type text/javascript1.1 promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type text/javascript1.1
-FAIL Registering script with good MIME type text/javascript1.2 promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type text/javascript1.2
-FAIL Registering script with good MIME type text/javascript1.3 promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type text/javascript1.3
-FAIL Registering script with good MIME type text/javascript1.4 promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type text/javascript1.4
-FAIL Registering script with good MIME type text/javascript1.5 promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type text/javascript1.5
-FAIL Registering script with good MIME type text/jscript promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type text/jscript
-FAIL Registering script with good MIME type text/livescript promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type text/livescript
-FAIL Registering script with good MIME type text/x-ecmascript promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type text/x-ecmascript
-FAIL Registering script with good MIME type text/x-javascript promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type text/x-javascript
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/link-element-register-scope.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/link-element-register-scope.https-expected.txt
deleted file mode 100644
index c2ebe84..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/link-element-register-scope.https-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-This is a testharness.js-based test.
-FAIL Scope including URL-encoded slash Test bug: need to pass exception to assert_throws()
-FAIL Scope including URL-encoded backslash Test bug: need to pass exception to assert_throws()
-PASS Scope including URL-encoded multibyte characters
-PASS Scope including non-escaped multibyte characters
-PASS Scope including self-reference
-PASS Scope including parent-reference
-PASS Scope including consecutive slashes
-FAIL Scope URL is same-origin filesystem: URL Test bug: need to pass exception to assert_throws()
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/link-element-register-script-url.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/link-element-register-script-url.https-expected.txt
deleted file mode 100644
index ce29087..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/link-element-register-script-url.https-expected.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-This is a testharness.js-based test.
-FAIL Script URL including URL-encoded slash Test bug: need to pass exception to assert_throws()
-FAIL Script URL including uppercase URL-encoded slash Test bug: need to pass exception to assert_throws()
-FAIL Script URL including URL-encoded backslash Test bug: need to pass exception to assert_throws()
-FAIL Script URL including uppercase URL-encoded backslash Test bug: need to pass exception to assert_throws()
-PASS Script URL including self-reference
-PASS Script URL including parent-reference
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/link-element-register-script.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/link-element-register-script.https-expected.txt
deleted file mode 100644
index 1dbf650..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/link-element-register-script.https-expected.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-This is a testharness.js-based test.
-FAIL Registering invalid chunked encoding script Test bug: need to pass exception to assert_throws()
-FAIL Registering invalid chunked encoding script with flush Test bug: need to pass exception to assert_throws()
-FAIL Registering script including parse error Test bug: need to pass exception to assert_throws()
-FAIL Registering script including undefined error Test bug: need to pass exception to assert_throws()
-FAIL Registering script including uncaught exception Test bug: need to pass exception to assert_throws()
-FAIL Registering script importing malformed script Test bug: need to pass exception to assert_throws()
-FAIL Registering non-existent script Test bug: need to pass exception to assert_throws()
-FAIL Registering script importing non-existent script Test bug: need to pass exception to assert_throws()
-PASS Registering script including caught exception
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/link-element-register-security-error.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/link-element-register-security-error.https-expected.txt
deleted file mode 100644
index 78c5360..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/link-element-register-security-error.https-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-This is a testharness.js-based test.
-FAIL Registering same scope as the script directory without the last slash Test bug: need to pass exception to assert_throws()
-FAIL Registration scope outside the script directory Test bug: need to pass exception to assert_throws()
-FAIL Registering scope outside domain Test bug: need to pass exception to assert_throws()
-FAIL Registering script outside domain Test bug: need to pass exception to assert_throws()
-FAIL Registering redirected script Test bug: need to pass exception to assert_throws()
-FAIL Scope including parent-reference and not under the script directory Test bug: need to pass exception to assert_throws()
-FAIL Script URL including consecutive slashes Test bug: need to pass exception to assert_throws()
-FAIL Script URL is same-origin filesystem: URL Test bug: need to pass exception to assert_throws()
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/navigate-window.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/navigate-window.https-expected.txt
deleted file mode 100644
index 59459ec..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/navigate-window.https-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-FAIL Clients.matchAll() should not show an old window as controlled after it navigates. assert_unreached: unexpected rejection: assert_equals: client should have expected frame type expected "top-level" but got "auxiliary" Reached unreachable code
-FAIL Clients.matchAll() should not show an old window after it navigates. assert_unreached: unexpected rejection: assert_equals: client should have expected frame type expected "top-level" but got "auxiliary" Reached unreachable code
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/registration-mime-types.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/registration-mime-types.https-expected.txt
deleted file mode 100644
index e4d2ccd0..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/registration-mime-types.https-expected.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-This is a testharness.js-based test.
-PASS Registering script with no MIME type
-PASS Registering script with bad MIME type
-FAIL Registering script that imports script with no MIME type assert_unreached: Should have rejected: Registration of no MIME type imported script should fail. Reached unreachable code
-FAIL Registering script that imports script with bad MIME type assert_unreached: Should have rejected: Registration of plain text imported script should fail. Reached unreachable code
-FAIL Registering script with good MIME type application/ecmascript promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('application/ecmascript')."
-PASS Registering script that imports script with good MIME type application/ecmascript
-PASS Registering script with good MIME type application/javascript
-PASS Registering script that imports script with good MIME type application/javascript
-FAIL Registering script with good MIME type application/x-ecmascript promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('application/x-ecmascript')."
-PASS Registering script that imports script with good MIME type application/x-ecmascript
-PASS Registering script with good MIME type application/x-javascript
-PASS Registering script that imports script with good MIME type application/x-javascript
-FAIL Registering script with good MIME type text/ecmascript promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/ecmascript')."
-PASS Registering script that imports script with good MIME type text/ecmascript
-PASS Registering script with good MIME type text/javascript
-PASS Registering script that imports script with good MIME type text/javascript
-FAIL Registering script with good MIME type text/javascript1.0 promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/javascript1.0')."
-PASS Registering script that imports script with good MIME type text/javascript1.0
-FAIL Registering script with good MIME type text/javascript1.1 promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/javascript1.1')."
-PASS Registering script that imports script with good MIME type text/javascript1.1
-FAIL Registering script with good MIME type text/javascript1.2 promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/javascript1.2')."
-PASS Registering script that imports script with good MIME type text/javascript1.2
-FAIL Registering script with good MIME type text/javascript1.3 promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/javascript1.3')."
-PASS Registering script that imports script with good MIME type text/javascript1.3
-FAIL Registering script with good MIME type text/javascript1.4 promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/javascript1.4')."
-PASS Registering script that imports script with good MIME type text/javascript1.4
-FAIL Registering script with good MIME type text/javascript1.5 promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/javascript1.5')."
-PASS Registering script that imports script with good MIME type text/javascript1.5
-FAIL Registering script with good MIME type text/jscript promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/jscript')."
-PASS Registering script that imports script with good MIME type text/jscript
-FAIL Registering script with good MIME type text/livescript promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/livescript')."
-PASS Registering script that imports script with good MIME type text/livescript
-FAIL Registering script with good MIME type text/x-ecmascript promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/x-ecmascript')."
-PASS Registering script that imports script with good MIME type text/x-ecmascript
-FAIL Registering script with good MIME type text/x-javascript promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/x-javascript')."
-PASS Registering script that imports script with good MIME type text/x-javascript
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/registration-updateviacache.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/registration-updateviacache.https-expected.txt
deleted file mode 100644
index 6cc7619..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/registration-updateviacache.https-expected.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-This is a testharness.js-based test.
-FAIL register-via-api-updateViaCache-undefined assert_equals: reg.updateViaCache expected (string) "imports" but got (undefined) undefined
-FAIL register-via-api-updateViaCache-imports assert_equals: reg.updateViaCache expected (string) "imports" but got (undefined) undefined
-FAIL register-via-api-updateViaCache-all assert_equals: reg.updateViaCache expected (string) "all" but got (undefined) undefined
-FAIL register-via-api-updateViaCache-none assert_equals: reg.updateViaCache expected (string) "none" but got (undefined) undefined
-FAIL register-via-link-element-updateViaCache-undefined assert_equals: reg.updateViaCache expected (string) "imports" but got (undefined) undefined
-FAIL register-via-link-element-updateViaCache-imports assert_equals: reg.updateViaCache expected (string) "imports" but got (undefined) undefined
-FAIL register-via-link-element-updateViaCache-all assert_equals: reg.updateViaCache expected (string) "all" but got (undefined) undefined
-FAIL register-via-link-element-updateViaCache-none assert_equals: reg.updateViaCache expected (string) "none" but got (undefined) undefined
-FAIL register-via-link-header-updateViaCache-undefined assert_equals: reg.updateViaCache expected (string) "imports" but got (undefined) undefined
-FAIL register-via-link-header-updateViaCache-imports assert_equals: reg.updateViaCache expected (string) "imports" but got (undefined) undefined
-FAIL register-via-link-header-updateViaCache-all assert_equals: reg.updateViaCache expected (string) "all" but got (undefined) undefined
-FAIL register-via-link-header-updateViaCache-none assert_equals: reg.updateViaCache expected (string) "none" but got (undefined) undefined
-FAIL register-with-updateViaCache-undefined-then-undefined assert_equals: reg.updateViaCache updated expected (string) "imports" but got (undefined) undefined
-FAIL register-with-updateViaCache-undefined-then-imports assert_equals: reg.updateViaCache updated expected (string) "imports" but got (undefined) undefined
-FAIL register-with-updateViaCache-undefined-then-all assert_equals: reg.updateViaCache updated expected (string) "all" but got (undefined) undefined
-FAIL register-with-updateViaCache-undefined-then-none assert_equals: reg.updateViaCache updated expected (string) "none" but got (undefined) undefined
-FAIL register-with-updateViaCache-imports-then-undefined assert_equals: reg.updateViaCache updated expected (string) "imports" but got (undefined) undefined
-FAIL register-with-updateViaCache-imports-then-imports assert_equals: reg.updateViaCache updated expected (string) "imports" but got (undefined) undefined
-FAIL register-with-updateViaCache-imports-then-all assert_equals: reg.updateViaCache updated expected (string) "all" but got (undefined) undefined
-FAIL register-with-updateViaCache-imports-then-none assert_equals: reg.updateViaCache updated expected (string) "none" but got (undefined) undefined
-FAIL register-with-updateViaCache-all-then-undefined assert_equals: reg.updateViaCache updated expected (string) "imports" but got (undefined) undefined
-FAIL register-with-updateViaCache-all-then-imports assert_equals: reg.updateViaCache updated expected (string) "imports" but got (undefined) undefined
-FAIL register-with-updateViaCache-all-then-all assert_equals: reg.updateViaCache updated expected (string) "all" but got (undefined) undefined
-FAIL register-with-updateViaCache-all-then-none assert_equals: reg.updateViaCache updated expected (string) "none" but got (undefined) undefined
-FAIL register-with-updateViaCache-none-then-undefined assert_equals: reg.updateViaCache updated expected (string) "imports" but got (undefined) undefined
-FAIL register-with-updateViaCache-none-then-imports assert_equals: reg.updateViaCache updated expected (string) "imports" but got (undefined) undefined
-FAIL register-with-updateViaCache-none-then-all assert_equals: reg.updateViaCache updated expected (string) "all" but got (undefined) undefined
-FAIL register-with-updateViaCache-none-then-none assert_equals: reg.updateViaCache updated expected (string) "none" but got (undefined) undefined
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/update-recovery.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/update-recovery.https-expected.txt
deleted file mode 100644
index f62fe77..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/update-recovery.https-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Recover from a bad service worker by updating after a failed navigation. assert_unreached: unexpected rejection: expected bad iframe should not fire a load event! Reached unreachable code
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/worker-interception.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/worker-interception.https-expected.txt
deleted file mode 100644
index f6d95f7..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-blobs/external/wpt/service-workers/service-worker/worker-interception.https-expected.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-This is a testharness.js-based test.
-FAIL Verify worker script from uncontrolled document is intercepted by Service Worker promise_test: Unhandled rejection with value: undefined
-FAIL Verify worker script intercepted by same-origin response succeeds promise_test: Unhandled rejection with value: undefined
-FAIL Verify worker script intercepted by cors response succeeds promise_test: Unhandled rejection with value: undefined
-PASS Verify worker script intercepted by no-cors cross-origin response fails
-PASS Verify worker loads from controlled document are intercepted by Service Worker
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/outofblink-cors/external/wpt/service-workers/service-worker/import-scripts-redirect.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/outofblink-cors/external/wpt/service-workers/service-worker/import-scripts-redirect.https-expected.txt
deleted file mode 100644
index 54836e4..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/outofblink-cors/external/wpt/service-workers/service-worker/import-scripts-redirect.https-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-FAIL importScripts() supports redirects promise_test: Unhandled rejection with value: object "TypeError: Failed to register a ServiceWorker: ServiceWorker script evaluation failed"
-FAIL importScripts() supports redirects and can be updated promise_test: Unhandled rejection with value: object "TypeError: Failed to register a ServiceWorker: ServiceWorker script evaluation failed"
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/outofblink-cors/external/wpt/service-workers/service-worker/link-element-register-security-error.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/outofblink-cors/external/wpt/service-workers/service-worker/link-element-register-security-error.https-expected.txt
deleted file mode 100644
index 78c5360..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/outofblink-cors/external/wpt/service-workers/service-worker/link-element-register-security-error.https-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-This is a testharness.js-based test.
-FAIL Registering same scope as the script directory without the last slash Test bug: need to pass exception to assert_throws()
-FAIL Registration scope outside the script directory Test bug: need to pass exception to assert_throws()
-FAIL Registering scope outside domain Test bug: need to pass exception to assert_throws()
-FAIL Registering script outside domain Test bug: need to pass exception to assert_throws()
-FAIL Registering redirected script Test bug: need to pass exception to assert_throws()
-FAIL Scope including parent-reference and not under the script directory Test bug: need to pass exception to assert_throws()
-FAIL Script URL including consecutive slashes Test bug: need to pass exception to assert_throws()
-FAIL Script URL is same-origin filesystem: URL Test bug: need to pass exception to assert_throws()
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/serviceworker/cache-add.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/serviceworker/cache-add.https-expected.txt
deleted file mode 100644
index a1555dcb8..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/serviceworker/cache-add.https-expected.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-This is a testharness.js-based test.
-PASS Cache.add and Cache.addAll
-PASS Cache.add called with no arguments
-PASS Cache.add called with relative URL specified as a string
-PASS Cache.add called with non-HTTP/HTTPS URL
-PASS Cache.add called with Request object
-PASS Cache.add called with POST request
-PASS Cache.add called twice with the same Request object
-PASS Cache.add with request with null body (not consumed)
-PASS Cache.add with 206 response
-PASS Cache.addAll with 206 response
-PASS Cache.add with request that results in a status of 404
-PASS Cache.add with request that results in a status of 500
-PASS Cache.addAll with no arguments
-PASS Cache.addAll with a mix of valid and undefined arguments
-PASS Cache.addAll with an empty array
-PASS Cache.addAll with string URL arguments
-PASS Cache.addAll with Request arguments
-PASS Cache.addAll with a mix of succeeding and failing requests
-FAIL Cache.addAll called with the same Request object specified twice assert_unreached: Should have rejected: Cache.addAll should throw InvalidStateError if the same request is added twice. Reached unreachable code
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/serviceworker/cache-matchAll.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/serviceworker/cache-matchAll.https-expected.txt
deleted file mode 100644
index 83bb89f..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/serviceworker/cache-matchAll.https-expected.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-This is a testharness.js-based test.
-PASS Cache.matchAll
-PASS Cache.matchAll with no matching entries
-PASS Cache.matchAll with URL
-PASS Cache.matchAll with Request
-PASS Cache.matchAll with new Request
-PASS Cache.matchAll with HEAD
-PASS Cache.matchAll with ignoreSearch option (request with no search parameters)
-PASS Cache.matchAll with ignoreSearch option (request with search parameters)
-PASS Cache.matchAll supports ignoreMethod
-PASS Cache.matchAll supports ignoreVary
-PASS Cache.matchAll with URL containing fragment
-PASS Cache.matchAll with string fragment "http" as query
-PASS Cache.matchAll without parameters
-FAIL Cache.matchAll with responses containing "Vary" header assert_equals: Cache.matchAll should match the entire header if a vary header is present in both the query and cached requests. expected 1 but got 0
-FAIL Cache.matchAll with multiple vary pairs assert_equals: Cache.matchAll should support multiple vary request/response pairs. expected 3 but got 1
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/serviceworker/cache-storage.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/serviceworker/cache-storage.https-expected.txt
deleted file mode 100644
index 22932f4..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/serviceworker/cache-storage.https-expected.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-This is a testharness.js-based test.
-PASS CacheStorage
-PASS CacheStorage.open
-PASS CacheStorage.delete dooms, but does not delete immediately
-PASS CacheStorage.open with an empty name
-PASS CacheStorage.open with no arguments
-PASS CacheStorage.has with existing cache
-PASS CacheStorage.has with nonexistent cache
-PASS CacheStorage.open with existing cache
-PASS CacheStorage.delete with existing cache
-PASS CacheStorage.delete with nonexistent cache
-FAIL CacheStorage names are DOMStrings not USVStrings assert_true: keys should include cache with bad name expected true got false
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/window/cache-add.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/window/cache-add.https-expected.txt
deleted file mode 100644
index 3f3f278..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/window/cache-add.https-expected.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-This is a testharness.js-based test.
-PASS Cache.add called with no arguments
-PASS Cache.add called with relative URL specified as a string
-PASS Cache.add called with non-HTTP/HTTPS URL
-PASS Cache.add called with Request object
-PASS Cache.add called with POST request
-PASS Cache.add called twice with the same Request object
-PASS Cache.add with request with null body (not consumed)
-PASS Cache.add with 206 response
-PASS Cache.addAll with 206 response
-PASS Cache.add with request that results in a status of 404
-PASS Cache.add with request that results in a status of 500
-PASS Cache.addAll with no arguments
-PASS Cache.addAll with a mix of valid and undefined arguments
-PASS Cache.addAll with an empty array
-PASS Cache.addAll with string URL arguments
-PASS Cache.addAll with Request arguments
-PASS Cache.addAll with a mix of succeeding and failing requests
-FAIL Cache.addAll called with the same Request object specified twice assert_unreached: Should have rejected: Cache.addAll should throw InvalidStateError if the same request is added twice. Reached unreachable code
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/window/cache-matchAll.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/window/cache-matchAll.https-expected.txt
deleted file mode 100644
index 69fcf49eb..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/window/cache-matchAll.https-expected.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-This is a testharness.js-based test.
-PASS Cache.matchAll with no matching entries
-PASS Cache.matchAll with URL
-PASS Cache.matchAll with Request
-PASS Cache.matchAll with new Request
-PASS Cache.matchAll with HEAD
-PASS Cache.matchAll with ignoreSearch option (request with no search parameters)
-PASS Cache.matchAll with ignoreSearch option (request with search parameters)
-PASS Cache.matchAll supports ignoreMethod
-PASS Cache.matchAll supports ignoreVary
-PASS Cache.matchAll with URL containing fragment
-PASS Cache.matchAll with string fragment "http" as query
-PASS Cache.matchAll without parameters
-FAIL Cache.matchAll with responses containing "Vary" header assert_equals: Cache.matchAll should match the entire header if a vary header is present in both the query and cached requests. expected 1 but got 0
-FAIL Cache.matchAll with multiple vary pairs assert_equals: Cache.matchAll should support multiple vary request/response pairs. expected 3 but got 1
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/window/cache-storage.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/window/cache-storage.https-expected.txt
deleted file mode 100644
index d1c62496..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/window/cache-storage.https-expected.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-This is a testharness.js-based test.
-PASS CacheStorage.open
-PASS CacheStorage.delete dooms, but does not delete immediately
-PASS CacheStorage.open with an empty name
-PASS CacheStorage.open with no arguments
-PASS CacheStorage.has with existing cache
-PASS CacheStorage.has with nonexistent cache
-PASS CacheStorage.open with existing cache
-PASS CacheStorage.delete with existing cache
-PASS CacheStorage.delete with nonexistent cache
-FAIL CacheStorage names are DOMStrings not USVStrings assert_true: keys should include cache with bad name expected true got false
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/window/sandboxed-iframes.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/window/sandboxed-iframes.https-expected.txt
deleted file mode 100644
index dc39b96..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/window/sandboxed-iframes.https-expected.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-
-This is a testharness.js-based test.
-PASS Sandboxed iframe with allow-same-origin is allowed access
-FAIL Sandboxed iframe without allow-same-origin is denied access assert_equals: Access should be denied if sandbox lacks allow-same-origin expected "denied" but got "unexpecteddenied"
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/worker/cache-add.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/worker/cache-add.https-expected.txt
deleted file mode 100644
index 3f3f278..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/worker/cache-add.https-expected.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-This is a testharness.js-based test.
-PASS Cache.add called with no arguments
-PASS Cache.add called with relative URL specified as a string
-PASS Cache.add called with non-HTTP/HTTPS URL
-PASS Cache.add called with Request object
-PASS Cache.add called with POST request
-PASS Cache.add called twice with the same Request object
-PASS Cache.add with request with null body (not consumed)
-PASS Cache.add with 206 response
-PASS Cache.addAll with 206 response
-PASS Cache.add with request that results in a status of 404
-PASS Cache.add with request that results in a status of 500
-PASS Cache.addAll with no arguments
-PASS Cache.addAll with a mix of valid and undefined arguments
-PASS Cache.addAll with an empty array
-PASS Cache.addAll with string URL arguments
-PASS Cache.addAll with Request arguments
-PASS Cache.addAll with a mix of succeeding and failing requests
-FAIL Cache.addAll called with the same Request object specified twice assert_unreached: Should have rejected: Cache.addAll should throw InvalidStateError if the same request is added twice. Reached unreachable code
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/worker/cache-matchAll.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/worker/cache-matchAll.https-expected.txt
deleted file mode 100644
index 69fcf49eb..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/worker/cache-matchAll.https-expected.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-This is a testharness.js-based test.
-PASS Cache.matchAll with no matching entries
-PASS Cache.matchAll with URL
-PASS Cache.matchAll with Request
-PASS Cache.matchAll with new Request
-PASS Cache.matchAll with HEAD
-PASS Cache.matchAll with ignoreSearch option (request with no search parameters)
-PASS Cache.matchAll with ignoreSearch option (request with search parameters)
-PASS Cache.matchAll supports ignoreMethod
-PASS Cache.matchAll supports ignoreVary
-PASS Cache.matchAll with URL containing fragment
-PASS Cache.matchAll with string fragment "http" as query
-PASS Cache.matchAll without parameters
-FAIL Cache.matchAll with responses containing "Vary" header assert_equals: Cache.matchAll should match the entire header if a vary header is present in both the query and cached requests. expected 1 but got 0
-FAIL Cache.matchAll with multiple vary pairs assert_equals: Cache.matchAll should support multiple vary request/response pairs. expected 3 but got 1
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/worker/cache-storage.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/worker/cache-storage.https-expected.txt
deleted file mode 100644
index d1c62496..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/cache-storage/worker/cache-storage.https-expected.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-This is a testharness.js-based test.
-PASS CacheStorage.open
-PASS CacheStorage.delete dooms, but does not delete immediately
-PASS CacheStorage.open with an empty name
-PASS CacheStorage.open with no arguments
-PASS CacheStorage.has with existing cache
-PASS CacheStorage.has with nonexistent cache
-PASS CacheStorage.open with existing cache
-PASS CacheStorage.delete with existing cache
-PASS CacheStorage.delete with nonexistent cache
-FAIL CacheStorage names are DOMStrings not USVStrings assert_true: keys should include cache with bad name expected true got false
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/clients-get-client-types.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/clients-get-client-types.https-expected.txt
deleted file mode 100644
index 58bae30..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/clients-get-client-types.https-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Test Clients.get() with window and worker clients assert_not_equals: Worker(Started by main frame) client should not be undefined got disallowed value undefined
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/clients-matchall-client-types.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/clients-matchall-client-types.https-expected.txt
deleted file mode 100644
index 1f2011a..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/clients-matchall-client-types.https-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-FAIL Verify matchAll() with window client type assert_unreached: unexpected rejection: assert_array_equals: property 2, expected "https://web-platform.test:8444/service-workers/service-worker/resources/clients-matchall-client-types-iframe.html" but got "https://web-platform.test:8444/service-workers/service-worker/resources/url-modified-via-pushstate.html" Reached unreachable code
-FAIL Verify matchAll() with {window, sharedworker, worker} client types promise_test: Unhandled rejection with value: object "Error: wait_for_state must be passed a ServiceWorker"
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/clients-matchall-order.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/clients-matchall-order.https-expected.txt
deleted file mode 100644
index 78737fe..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/clients-matchall-order.https-expected.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-This is a testharness.js-based test.
-PASS Clients.matchAll() returns non-focused controlled windows in creation order.
-PASS Clients.matchAll() returns controlled windows in focus order.  Case 1.
-PASS Clients.matchAll() returns controlled windows in focus order.  Case 2.
-FAIL Clients.matchAll() returns non-focused uncontrolled windows in creation order. assert_equals: expected 6 but got 5
-FAIL Clients.matchAll() returns uncontrolled windows in focus order.  Case 1. assert_equals: expected 6 but got 5
-FAIL Clients.matchAll() returns uncontrolled windows in focus order.  Case 2. assert_equals: expected 6 but got 5
-FAIL Clients.matchAll() returns controlled windows and frames in focus order. assert_equals: expected URL index 1 expected "https://web-platform.test:8444/service-workers/service-worker/resources/empty.html?name=focus-controlled-nested-windows&q=1" but got "https://web-platform.test:8444/service-workers/service-worker/resources/empty.html?name=focus-controlled-nested-windows&q=1&nested=true"
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/fetch-event-redirect.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/fetch-event-redirect.https-expected.txt
deleted file mode 100644
index f91bc57e..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/fetch-event-redirect.https-expected.txt
+++ /dev/null
@@ -1,57 +0,0 @@
-This is a testharness.js-based test.
-PASS Non-navigation, manual redirect, cors mode Request redirected to same-origin without credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, cors mode Request redirected to no-cors without credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, cors mode Request redirected to cors without credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, same-origin mode Request redirected to same-origin without credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, same-origin mode Request redirected to no-cors without credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, same-origin mode Request redirected to cors without credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, no-cors mode Request redirected to same-origin without credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, no-cors mode Request redirected to no-cors without credentials should succeed interception and response should not be redirected
-PASS Non-navigation, manual redirect, no-cors mode Request redirected to cors without credentials should succeed interception and response should not be redirected
-PASS Non-navigation, manual redirect, cors mode Request redirected to same-origin with credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, cors mode Request redirected to no-cors with credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, cors mode Request redirected to cors with credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, same-origin mode Request redirected to same-origin with credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, same-origin mode Request redirected to no-cors with credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, same-origin mode Request redirected to cors with credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, no-cors mode Request redirected to same-origin with credentials should fail opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, no-cors mode Request redirected to no-cors with credentials should succeed interception and response should not be redirected
-PASS Non-navigation, manual redirect, no-cors mode Request redirected to cors with credentials should succeed interception and response should not be redirected
-PASS Non-navigation, follow redirect, cors mode Request redirected to same-origin without credentials should succeed interception and response should be redirected
-PASS Non-navigation, follow redirect, cors mode Request redirected to no-cors without credentials should fail interception and response should not be redirected
-PASS Non-navigation, follow redirect, cors mode Request redirected to cors without credentials should succeed interception and response should be redirected
-PASS Non-navigation, follow redirect, same-origin mode Request redirected to same-origin without credentials should succeed interception and response should be redirected
-PASS Non-navigation, follow redirect, same-origin mode Request redirected to no-cors without credentials should fail interception and response should not be redirected
-PASS Non-navigation, follow redirect, same-origin mode Request redirected to cors without credentials should fail interception and response should not be redirected
-PASS Non-navigation, follow redirect, no-cors mode Request redirected to same-origin without credentials should succeed interception and response should be redirected
-PASS Non-navigation, follow redirect, no-cors mode Request redirected to no-cors without credentials should succeed interception and response should not be redirected
-PASS Non-navigation, follow redirect, no-cors mode Request redirected to cors without credentials should succeed interception and response should not be redirected
-FAIL Non-navigation, follow redirect, cors mode Request redirected to same-origin with credentials should succeed interception and response should be redirected assert_unreached: unexpected rejection: TypeError: Failed to fetch Reached unreachable code
-PASS Non-navigation, follow redirect, cors mode Request redirected to no-cors with credentials should fail interception and response should not be redirected
-PASS Non-navigation, follow redirect, cors mode Request redirected to cors with credentials should fail interception and response should be redirected
-FAIL Non-navigation, follow redirect, same-origin mode Request redirected to same-origin with credentials should succeed interception and response should be redirected assert_unreached: unexpected rejection: TypeError: Failed to fetch Reached unreachable code
-PASS Non-navigation, follow redirect, same-origin mode Request redirected to no-cors with credentials should fail interception and response should not be redirected
-PASS Non-navigation, follow redirect, same-origin mode Request redirected to cors with credentials should fail interception and response should not be redirected
-FAIL Non-navigation, follow redirect, no-cors mode Request redirected to same-origin with credentials should succeed interception and response should be redirected assert_unreached: unexpected rejection: TypeError: Failed to fetch Reached unreachable code
-FAIL Non-navigation, follow redirect, no-cors mode Request redirected to no-cors with credentials should succeed interception and response should not be redirected assert_unreached: unexpected rejection: TypeError: Failed to fetch Reached unreachable code
-FAIL Non-navigation, follow redirect, no-cors mode Request redirected to cors with credentials should succeed interception and response should not be redirected assert_unreached: unexpected rejection: TypeError: Failed to fetch Reached unreachable code
-PASS Non-navigation, error redirect, cors mode Request redirected to same-origin without credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, cors mode Request redirected to no-cors without credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, cors mode Request redirected to cors without credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, same-origin mode Request redirected to same-origin without credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, same-origin mode Request redirected to no-cors without credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, same-origin mode Request redirected to cors without credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, no-cors mode Request redirected to same-origin without credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, no-cors mode Request redirected to no-cors without credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, no-cors mode Request redirected to cors without credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, cors mode Request redirected to same-origin with credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, cors mode Request redirected to no-cors with credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, cors mode Request redirected to cors with credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, same-origin mode Request redirected to same-origin with credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, same-origin mode Request redirected to no-cors with credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, same-origin mode Request redirected to cors with credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, no-cors mode Request redirected to same-origin with credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, no-cors mode Request redirected to no-cors with credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, no-cors mode Request redirected to cors with credentials should fail interception and response should not be redirected
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/fetch-event-referrer-policy.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/fetch-event-referrer-policy.https-expected.txt
deleted file mode 100644
index 4ed287e..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/fetch-event-referrer-policy.https-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Service Worker responds to fetch event with the referrer policy assert_unreached: unexpected rejection: assert_equals: Service Worker should respond to fetch with the referrer URL when a member of RequestInit is present expected "Referrer: https://web-platform.test:8444/service-workers/service-worker/fake-referrer\nReferrerPolicy: no-referrer-when-downgrade" but got "Referrer: https://web-platform.test:8444/service-workers/service-worker/resources/fake-referrer\nReferrerPolicy: no-referrer-when-downgrade" Reached unreachable code
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/fetch-event-within-sw-manual.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/fetch-event-within-sw-manual.https-expected.txt
deleted file mode 100644
index e774a74..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/fetch-event-within-sw-manual.https-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Notification requests intercepted both from window and SW promise_test: Unhandled rejection with value: object "Error: You must allow notifications for this origin before running this test."
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/fetch-event.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/fetch-event.https-expected.txt
deleted file mode 100644
index 2eb875c..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/fetch-event.https-expected.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-This is a testharness.js-based test.
-PASS Service Worker headers in the request of a fetch event
-PASS Service Worker responds to fetch event with string
-PASS Service Worker responds to fetch event with blob body
-PASS Service Worker responds to fetch event with the referrer URL
-PASS Service Worker responds to fetch event with an existing client id
-PASS Service Worker does not respond to fetch event
-PASS Service Worker responds to fetch event with null response body
-PASS Service Worker fetches other file in fetch event
-PASS Service Worker responds to fetch event with POST form
-PASS Multiple calls of respondWith must throw InvalidStateErrors
-PASS Service Worker event.respondWith must set the used flag
-PASS Service Worker should expose FetchEvent URL fragments.
-FAIL Service Worker responds to fetch event with the correct cache types assert_unreached: unexpected rejection: assert_equals: Service Worker should respond to fetch with the correct type expected "no-store" but got "default" Reached unreachable code
-FAIL Service Worker should intercept EventSource assert_unreached: unexpected rejection: assert_equals: EventSource should bypass the http cache. expected "no-store" but got "default" Reached unreachable code
-FAIL Service Worker responds to fetch event with the correct integrity_metadata assert_unreached: unexpected rejection: assert_equals: integrity expected "gs0nqru8KbsrIt5YToQqS9fYao4GQJXtcId610g7cCU=" but got "" Reached unreachable code
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/fetch-request-xhr-sync.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/fetch-request-xhr-sync.https-expected.txt
deleted file mode 100644
index 724b7d8..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/fetch-request-xhr-sync.https-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Verify SyncXHR is intercepted assert_equals: HTTP response status code for intercepted request expected 200 but got 404
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/fetch-request-xhr.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/fetch-request-xhr.https-expected.txt
deleted file mode 100644
index b52f7871..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/fetch-request-xhr.https-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Verify the body of FetchEvent using XMLHttpRequest assert_array_equals: event.request has the expected headers for same-origin GET. lengths differ, expected 1 got 2
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/import-scripts-redirect.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/import-scripts-redirect.https-expected.txt
deleted file mode 100644
index 54836e4..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/import-scripts-redirect.https-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-FAIL importScripts() supports redirects promise_test: Unhandled rejection with value: object "TypeError: Failed to register a ServiceWorker: ServiceWorker script evaluation failed"
-FAIL importScripts() supports redirects and can be updated promise_test: Unhandled rejection with value: object "TypeError: Failed to register a ServiceWorker: ServiceWorker script evaluation failed"
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/import-scripts-updated-flag.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/import-scripts-updated-flag.https-expected.txt
deleted file mode 100644
index 0e50082..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/import-scripts-updated-flag.https-expected.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-This is a testharness.js-based test.
-PASS initialize global state
-PASS import script previously imported at worker evaluation time
-PASS import script previously imported at worker install time
-FAIL import script not previously imported assert_equals: expected (string) "TypeError" but got (object) null
-PASS Tests for importScripts: import scripts updated flag
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/interfaces-sw.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/interfaces-sw.https-expected.txt
deleted file mode 100644
index 3c98081d..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/interfaces-sw.https-expected.txt
+++ /dev/null
@@ -1,187 +0,0 @@
-This is a testharness.js-based test.
-PASS Interfaces and attributes in ServiceWorkerGlobalScope
-PASS test setup (cache creation)
-PASS Event constructors
-PASS ServiceWorkerGlobalScope interface: existence and properties of interface object
-PASS ServiceWorkerGlobalScope interface object length
-PASS ServiceWorkerGlobalScope interface object name
-PASS ServiceWorkerGlobalScope interface: existence and properties of interface prototype object
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to a new value via Object.setPrototypeOf should throw a TypeError
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to a new value via __proto__ should throw a TypeError
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to a new value via Reflect.setPrototypeOf should return false
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to its original value via Object.setPrototypeOf should not throw
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to its original value via __proto__ should not throw
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to its original value via Reflect.setPrototypeOf should return true
-PASS ServiceWorkerGlobalScope interface: existence and properties of interface prototype object's "constructor" property
-PASS ServiceWorkerGlobalScope interface: attribute clients
-PASS ServiceWorkerGlobalScope interface: attribute registration
-PASS ServiceWorkerGlobalScope interface: operation skipWaiting()
-PASS ServiceWorkerGlobalScope interface: attribute oninstall
-PASS ServiceWorkerGlobalScope interface: attribute onactivate
-PASS ServiceWorkerGlobalScope interface: attribute onfetch
-PASS ServiceWorkerGlobalScope interface: attribute onforeignfetch
-PASS ServiceWorkerGlobalScope interface: attribute onmessage
-FAIL ServiceWorkerGlobalScope interface: attribute onmessageerror assert_own_property: The global object must have a property "onmessageerror" expected property "onmessageerror" missing
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to a new value via Object.setPrototypeOf should throw a TypeError
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to a new value via __proto__ should throw a TypeError
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to a new value via Reflect.setPrototypeOf should return false
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to its original value via Object.setPrototypeOf should not throw
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to its original value via __proto__ should not throw
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to its original value via Reflect.setPrototypeOf should return true
-PASS ServiceWorkerGlobalScope must be primary interface of self
-PASS Stringification of self
-PASS ServiceWorkerGlobalScope interface: self must inherit property "clients" with the proper type
-PASS ServiceWorkerGlobalScope interface: self must inherit property "registration" with the proper type
-PASS ServiceWorkerGlobalScope interface: self must inherit property "skipWaiting()" with the proper type
-PASS ServiceWorkerGlobalScope interface: self must inherit property "oninstall" with the proper type
-PASS ServiceWorkerGlobalScope interface: self must inherit property "onactivate" with the proper type
-PASS ServiceWorkerGlobalScope interface: self must inherit property "onfetch" with the proper type
-PASS ServiceWorkerGlobalScope interface: self must inherit property "onforeignfetch" with the proper type
-PASS ServiceWorkerGlobalScope interface: self must inherit property "onmessage" with the proper type
-FAIL ServiceWorkerGlobalScope interface: self must inherit property "onmessageerror" with the proper type assert_own_property: expected property "onmessageerror" missing
-PASS Client interface: existence and properties of interface object
-PASS Client interface object length
-PASS Client interface object name
-PASS Client interface: existence and properties of interface prototype object
-PASS Client interface: existence and properties of interface prototype object's "constructor" property
-PASS Client interface: attribute url
-PASS Client interface: attribute id
-PASS Client interface: attribute type
-FAIL Client interface: attribute reserved assert_true: The prototype object must have a property "reserved" expected true got false
-PASS Client interface: operation postMessage(any, [object Object])
-PASS WindowClient interface: existence and properties of interface object
-PASS WindowClient interface object length
-PASS WindowClient interface object name
-PASS WindowClient interface: existence and properties of interface prototype object
-PASS WindowClient interface: existence and properties of interface prototype object's "constructor" property
-PASS WindowClient interface: attribute visibilityState
-PASS WindowClient interface: attribute focused
-FAIL WindowClient interface: attribute ancestorOrigins assert_true: The prototype object must have a property "ancestorOrigins" expected true got false
-PASS WindowClient interface: operation focus()
-PASS WindowClient interface: operation navigate(USVString)
-PASS Clients interface: existence and properties of interface object
-PASS Clients interface object length
-PASS Clients interface object name
-PASS Clients interface: existence and properties of interface prototype object
-PASS Clients interface: existence and properties of interface prototype object's "constructor" property
-PASS Clients interface: operation get(DOMString)
-PASS Clients interface: operation matchAll(ClientQueryOptions)
-PASS Clients interface: operation openWindow(USVString)
-PASS Clients interface: operation claim()
-PASS Clients must be primary interface of self.clients
-PASS Stringification of self.clients
-PASS Clients interface: self.clients must inherit property "get(DOMString)" with the proper type
-PASS Clients interface: calling get(DOMString) on self.clients with too few arguments must throw TypeError
-PASS Clients interface: self.clients must inherit property "matchAll(ClientQueryOptions)" with the proper type
-PASS Clients interface: calling matchAll(ClientQueryOptions) on self.clients with too few arguments must throw TypeError
-PASS Clients interface: self.clients must inherit property "openWindow(USVString)" with the proper type
-PASS Clients interface: calling openWindow(USVString) on self.clients with too few arguments must throw TypeError
-PASS Clients interface: self.clients must inherit property "claim()" with the proper type
-FAIL ServiceWorker interface: existence and properties of interface object assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface object length assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface object name assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface: existence and properties of interface prototype object assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface: attribute scriptURL assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface: attribute state assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface: operation postMessage(any, [object Object]) assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface: attribute onstatechange assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-PASS ServiceWorkerRegistration interface: existence and properties of interface object
-PASS ServiceWorkerRegistration interface object length
-PASS ServiceWorkerRegistration interface object name
-PASS ServiceWorkerRegistration interface: existence and properties of interface prototype object
-PASS ServiceWorkerRegistration interface: existence and properties of interface prototype object's "constructor" property
-PASS ServiceWorkerRegistration interface: attribute installing
-PASS ServiceWorkerRegistration interface: attribute waiting
-PASS ServiceWorkerRegistration interface: attribute active
-PASS ServiceWorkerRegistration interface: attribute navigationPreload
-PASS ServiceWorkerRegistration interface: attribute scope
-FAIL ServiceWorkerRegistration interface: attribute updateViaCache assert_true: The prototype object must have a property "updateViaCache" expected true got false
-PASS ServiceWorkerRegistration interface: operation update()
-PASS ServiceWorkerRegistration interface: operation unregister()
-PASS ServiceWorkerRegistration interface: attribute onupdatefound
-PASS ServiceWorkerRegistration must be primary interface of self.registration
-PASS Stringification of self.registration
-PASS ServiceWorkerRegistration interface: self.registration must inherit property "installing" with the proper type
-PASS ServiceWorkerRegistration interface: self.registration must inherit property "waiting" with the proper type
-PASS ServiceWorkerRegistration interface: self.registration must inherit property "active" with the proper type
-PASS ServiceWorkerRegistration interface: self.registration must inherit property "navigationPreload" with the proper type
-PASS ServiceWorkerRegistration interface: self.registration must inherit property "scope" with the proper type
-FAIL ServiceWorkerRegistration interface: self.registration must inherit property "updateViaCache" with the proper type assert_inherits: property "updateViaCache" not found in prototype chain
-PASS ServiceWorkerRegistration interface: self.registration must inherit property "update()" with the proper type
-PASS ServiceWorkerRegistration interface: self.registration must inherit property "unregister()" with the proper type
-PASS ServiceWorkerRegistration interface: self.registration must inherit property "onupdatefound" with the proper type
-PASS EventTarget interface: self.registration must inherit property "addEventListener(DOMString, EventListener, [object Object],[object Object])" with the proper type
-PASS EventTarget interface: calling addEventListener(DOMString, EventListener, [object Object],[object Object]) on self.registration with too few arguments must throw TypeError
-PASS EventTarget interface: self.registration must inherit property "removeEventListener(DOMString, EventListener, [object Object],[object Object])" with the proper type
-PASS EventTarget interface: calling removeEventListener(DOMString, EventListener, [object Object],[object Object]) on self.registration with too few arguments must throw TypeError
-PASS EventTarget interface: self.registration must inherit property "dispatchEvent(Event)" with the proper type
-PASS EventTarget interface: calling dispatchEvent(Event) on self.registration with too few arguments must throw TypeError
-PASS EventTarget interface: existence and properties of interface object
-PASS EventTarget interface object length
-PASS EventTarget interface object name
-PASS EventTarget interface: existence and properties of interface prototype object
-PASS EventTarget interface: existence and properties of interface prototype object's "constructor" property
-PASS EventTarget interface: operation addEventListener(DOMString, EventListener, [object Object],[object Object])
-PASS EventTarget interface: operation removeEventListener(DOMString, EventListener, [object Object],[object Object])
-PASS EventTarget interface: operation dispatchEvent(Event)
-PASS NavigationPreloadManager interface: existence and properties of interface object
-PASS NavigationPreloadManager interface object length
-PASS NavigationPreloadManager interface object name
-PASS NavigationPreloadManager interface: existence and properties of interface prototype object
-PASS NavigationPreloadManager interface: existence and properties of interface prototype object's "constructor" property
-PASS NavigationPreloadManager interface: operation enable()
-PASS NavigationPreloadManager interface: operation disable()
-PASS NavigationPreloadManager interface: operation setHeaderValue(ByteString)
-PASS NavigationPreloadManager interface: operation getState()
-PASS Cache interface: existence and properties of interface object
-PASS Cache interface object length
-PASS Cache interface object name
-PASS Cache interface: existence and properties of interface prototype object
-PASS Cache interface: existence and properties of interface prototype object's "constructor" property
-PASS Cache interface: operation match(RequestInfo, CacheQueryOptions)
-PASS Cache interface: operation matchAll(RequestInfo, CacheQueryOptions)
-PASS Cache interface: operation add(RequestInfo)
-PASS Cache interface: operation addAll([object Object])
-PASS Cache interface: operation put(RequestInfo, Response)
-PASS Cache interface: operation delete(RequestInfo, CacheQueryOptions)
-PASS Cache interface: operation keys(RequestInfo, CacheQueryOptions)
-PASS Cache must be primary interface of self.cacheInstance
-PASS Stringification of self.cacheInstance
-PASS Cache interface: self.cacheInstance must inherit property "match(RequestInfo, CacheQueryOptions)" with the proper type
-PASS Cache interface: calling match(RequestInfo, CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "matchAll(RequestInfo, CacheQueryOptions)" with the proper type
-PASS Cache interface: calling matchAll(RequestInfo, CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "add(RequestInfo)" with the proper type
-PASS Cache interface: calling add(RequestInfo) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "addAll([object Object])" with the proper type
-PASS Cache interface: calling addAll([object Object]) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "put(RequestInfo, Response)" with the proper type
-PASS Cache interface: calling put(RequestInfo, Response) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "delete(RequestInfo, CacheQueryOptions)" with the proper type
-PASS Cache interface: calling delete(RequestInfo, CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "keys(RequestInfo, CacheQueryOptions)" with the proper type
-PASS Cache interface: calling keys(RequestInfo, CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError
-PASS CacheStorage interface: existence and properties of interface object
-PASS CacheStorage interface object length
-PASS CacheStorage interface object name
-PASS CacheStorage interface: existence and properties of interface prototype object
-PASS CacheStorage interface: existence and properties of interface prototype object's "constructor" property
-PASS CacheStorage interface: operation match(RequestInfo, CacheQueryOptions)
-PASS CacheStorage interface: operation has(DOMString)
-PASS CacheStorage interface: operation open(DOMString)
-PASS CacheStorage interface: operation delete(DOMString)
-PASS CacheStorage interface: operation keys()
-PASS CacheStorage must be primary interface of self.caches
-PASS Stringification of self.caches
-PASS CacheStorage interface: self.caches must inherit property "match(RequestInfo, CacheQueryOptions)" with the proper type
-PASS CacheStorage interface: calling match(RequestInfo, CacheQueryOptions) on self.caches with too few arguments must throw TypeError
-PASS CacheStorage interface: self.caches must inherit property "has(DOMString)" with the proper type
-PASS CacheStorage interface: calling has(DOMString) on self.caches with too few arguments must throw TypeError
-PASS CacheStorage interface: self.caches must inherit property "open(DOMString)" with the proper type
-PASS CacheStorage interface: calling open(DOMString) on self.caches with too few arguments must throw TypeError
-PASS CacheStorage interface: self.caches must inherit property "delete(DOMString)" with the proper type
-PASS CacheStorage interface: calling delete(DOMString) on self.caches with too few arguments must throw TypeError
-PASS CacheStorage interface: self.caches must inherit property "keys()" with the proper type
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/interfaces-window.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/interfaces-window.https-expected.txt
deleted file mode 100644
index 178972d..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/interfaces-window.https-expected.txt
+++ /dev/null
@@ -1,101 +0,0 @@
-This is a testharness.js-based test.
-PASS test setup (worker registration)
-PASS WorkerGlobalScope interface: existence and properties of interface object
-PASS ServiceWorkerGlobalScope interface: existence and properties of interface object
-PASS Client interface: existence and properties of interface object
-PASS WindowClient interface: existence and properties of interface object
-PASS Clients interface: existence and properties of interface object
-PASS ServiceWorker interface: existence and properties of interface object
-PASS ServiceWorker interface object length
-PASS ServiceWorker interface object name
-PASS ServiceWorker interface: existence and properties of interface prototype object
-PASS ServiceWorker interface: existence and properties of interface prototype object's "constructor" property
-PASS ServiceWorker interface: attribute scriptURL
-PASS ServiceWorker interface: attribute state
-PASS ServiceWorker interface: operation postMessage(any, [object Object])
-PASS ServiceWorker interface: attribute onstatechange
-PASS ServiceWorker must be primary interface of window.registrationInstance.installing
-PASS Stringification of window.registrationInstance.installing
-PASS ServiceWorker interface: window.registrationInstance.installing must inherit property "scriptURL" with the proper type
-PASS ServiceWorker interface: window.registrationInstance.installing must inherit property "state" with the proper type
-PASS ServiceWorker interface: window.registrationInstance.installing must inherit property "postMessage(any, [object Object])" with the proper type
-PASS ServiceWorker interface: calling postMessage(any, [object Object]) on window.registrationInstance.installing with too few arguments must throw TypeError
-PASS ServiceWorker interface: window.registrationInstance.installing must inherit property "onstatechange" with the proper type
-PASS EventTarget interface: window.registrationInstance.installing must inherit property "addEventListener(DOMString, EventListener, [object Object],[object Object])" with the proper type
-PASS EventTarget interface: calling addEventListener(DOMString, EventListener, [object Object],[object Object]) on window.registrationInstance.installing with too few arguments must throw TypeError
-PASS EventTarget interface: window.registrationInstance.installing must inherit property "removeEventListener(DOMString, EventListener, [object Object],[object Object])" with the proper type
-PASS EventTarget interface: calling removeEventListener(DOMString, EventListener, [object Object],[object Object]) on window.registrationInstance.installing with too few arguments must throw TypeError
-PASS EventTarget interface: window.registrationInstance.installing must inherit property "dispatchEvent(Event)" with the proper type
-PASS EventTarget interface: calling dispatchEvent(Event) on window.registrationInstance.installing with too few arguments must throw TypeError
-PASS ServiceWorkerRegistration interface: existence and properties of interface object
-PASS ServiceWorkerRegistration interface object length
-PASS ServiceWorkerRegistration interface object name
-PASS ServiceWorkerRegistration interface: existence and properties of interface prototype object
-PASS ServiceWorkerRegistration interface: existence and properties of interface prototype object's "constructor" property
-PASS ServiceWorkerRegistration interface: attribute installing
-PASS ServiceWorkerRegistration interface: attribute waiting
-PASS ServiceWorkerRegistration interface: attribute active
-PASS ServiceWorkerRegistration interface: attribute navigationPreload
-PASS ServiceWorkerRegistration interface: attribute scope
-FAIL ServiceWorkerRegistration interface: attribute updateViaCache assert_true: The prototype object must have a property "updateViaCache" expected true got false
-PASS ServiceWorkerRegistration interface: operation update()
-PASS ServiceWorkerRegistration interface: operation unregister()
-PASS ServiceWorkerRegistration interface: attribute onupdatefound
-PASS ServiceWorkerRegistration must be primary interface of window.registrationInstance
-PASS Stringification of window.registrationInstance
-PASS ServiceWorkerRegistration interface: window.registrationInstance must inherit property "installing" with the proper type
-PASS ServiceWorkerRegistration interface: window.registrationInstance must inherit property "waiting" with the proper type
-PASS ServiceWorkerRegistration interface: window.registrationInstance must inherit property "active" with the proper type
-PASS ServiceWorkerRegistration interface: window.registrationInstance must inherit property "navigationPreload" with the proper type
-PASS ServiceWorkerRegistration interface: window.registrationInstance must inherit property "scope" with the proper type
-FAIL ServiceWorkerRegistration interface: window.registrationInstance must inherit property "updateViaCache" with the proper type assert_inherits: property "updateViaCache" not found in prototype chain
-PASS ServiceWorkerRegistration interface: window.registrationInstance must inherit property "update()" with the proper type
-PASS ServiceWorkerRegistration interface: window.registrationInstance must inherit property "unregister()" with the proper type
-PASS ServiceWorkerRegistration interface: window.registrationInstance must inherit property "onupdatefound" with the proper type
-PASS EventTarget interface: window.registrationInstance must inherit property "addEventListener(DOMString, EventListener, [object Object],[object Object])" with the proper type
-PASS EventTarget interface: calling addEventListener(DOMString, EventListener, [object Object],[object Object]) on window.registrationInstance with too few arguments must throw TypeError
-PASS EventTarget interface: window.registrationInstance must inherit property "removeEventListener(DOMString, EventListener, [object Object],[object Object])" with the proper type
-PASS EventTarget interface: calling removeEventListener(DOMString, EventListener, [object Object],[object Object]) on window.registrationInstance with too few arguments must throw TypeError
-PASS EventTarget interface: window.registrationInstance must inherit property "dispatchEvent(Event)" with the proper type
-PASS EventTarget interface: calling dispatchEvent(Event) on window.registrationInstance with too few arguments must throw TypeError
-PASS EventTarget interface: existence and properties of interface object
-PASS EventTarget interface object length
-PASS EventTarget interface object name
-PASS EventTarget interface: existence and properties of interface prototype object
-PASS EventTarget interface: existence and properties of interface prototype object's "constructor" property
-PASS EventTarget interface: operation addEventListener(DOMString, EventListener, [object Object],[object Object])
-PASS EventTarget interface: operation removeEventListener(DOMString, EventListener, [object Object],[object Object])
-PASS EventTarget interface: operation dispatchEvent(Event)
-PASS NavigationPreloadManager interface: existence and properties of interface object
-PASS NavigationPreloadManager interface object length
-PASS NavigationPreloadManager interface object name
-PASS NavigationPreloadManager interface: existence and properties of interface prototype object
-PASS NavigationPreloadManager interface: existence and properties of interface prototype object's "constructor" property
-PASS NavigationPreloadManager interface: operation enable()
-PASS NavigationPreloadManager interface: operation disable()
-PASS NavigationPreloadManager interface: operation setHeaderValue(ByteString)
-PASS NavigationPreloadManager interface: operation getState()
-PASS Cache interface: existence and properties of interface object
-PASS Cache interface object length
-PASS Cache interface object name
-PASS Cache interface: existence and properties of interface prototype object
-PASS Cache interface: existence and properties of interface prototype object's "constructor" property
-PASS Cache interface: operation match(RequestInfo, CacheQueryOptions)
-PASS Cache interface: operation matchAll(RequestInfo, CacheQueryOptions)
-PASS Cache interface: operation add(RequestInfo)
-PASS Cache interface: operation addAll([object Object])
-PASS Cache interface: operation put(RequestInfo, Response)
-PASS Cache interface: operation delete(RequestInfo, CacheQueryOptions)
-PASS Cache interface: operation keys(RequestInfo, CacheQueryOptions)
-PASS CacheStorage interface: existence and properties of interface object
-PASS CacheStorage interface object length
-PASS CacheStorage interface object name
-PASS CacheStorage interface: existence and properties of interface prototype object
-PASS CacheStorage interface: existence and properties of interface prototype object's "constructor" property
-PASS CacheStorage interface: operation match(RequestInfo, CacheQueryOptions)
-PASS CacheStorage interface: operation has(DOMString)
-PASS CacheStorage interface: operation open(DOMString)
-PASS CacheStorage interface: operation delete(DOMString)
-PASS CacheStorage interface: operation keys()
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/link-element-register-mime-types.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/link-element-register-mime-types.https-expected.txt
deleted file mode 100644
index 28bf3a7..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/link-element-register-mime-types.https-expected.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-This is a testharness.js-based test.
-FAIL Registering script with no MIME type Test bug: need to pass exception to assert_throws()
-FAIL Registering script with bad MIME type Test bug: need to pass exception to assert_throws()
-FAIL Registering script that imports script with no MIME type assert_unreached: Should have rejected: Registration of no MIME type imported script should fail. Reached unreachable code
-FAIL Registering script that imports script with bad MIME type assert_unreached: Should have rejected: Registration of plain text imported script should fail. Reached unreachable code
-FAIL Registering script with good MIME type application/ecmascript promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type application/ecmascript
-PASS Registering script with good MIME type application/javascript
-PASS Registering script that imports script with good MIME type application/javascript
-FAIL Registering script with good MIME type application/x-ecmascript promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type application/x-ecmascript
-PASS Registering script with good MIME type application/x-javascript
-PASS Registering script that imports script with good MIME type application/x-javascript
-FAIL Registering script with good MIME type text/ecmascript promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type text/ecmascript
-PASS Registering script with good MIME type text/javascript
-PASS Registering script that imports script with good MIME type text/javascript
-FAIL Registering script with good MIME type text/javascript1.0 promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type text/javascript1.0
-FAIL Registering script with good MIME type text/javascript1.1 promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type text/javascript1.1
-FAIL Registering script with good MIME type text/javascript1.2 promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type text/javascript1.2
-FAIL Registering script with good MIME type text/javascript1.3 promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type text/javascript1.3
-FAIL Registering script with good MIME type text/javascript1.4 promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type text/javascript1.4
-FAIL Registering script with good MIME type text/javascript1.5 promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type text/javascript1.5
-FAIL Registering script with good MIME type text/jscript promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type text/jscript
-FAIL Registering script with good MIME type text/livescript promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type text/livescript
-FAIL Registering script with good MIME type text/x-ecmascript promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type text/x-ecmascript
-FAIL Registering script with good MIME type text/x-javascript promise_test: Unhandled rejection with value: object "[object Event]"
-PASS Registering script that imports script with good MIME type text/x-javascript
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/link-element-register-scope.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/link-element-register-scope.https-expected.txt
deleted file mode 100644
index c2ebe84..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/link-element-register-scope.https-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-This is a testharness.js-based test.
-FAIL Scope including URL-encoded slash Test bug: need to pass exception to assert_throws()
-FAIL Scope including URL-encoded backslash Test bug: need to pass exception to assert_throws()
-PASS Scope including URL-encoded multibyte characters
-PASS Scope including non-escaped multibyte characters
-PASS Scope including self-reference
-PASS Scope including parent-reference
-PASS Scope including consecutive slashes
-FAIL Scope URL is same-origin filesystem: URL Test bug: need to pass exception to assert_throws()
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/link-element-register-script-url.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/link-element-register-script-url.https-expected.txt
deleted file mode 100644
index ce29087..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/link-element-register-script-url.https-expected.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-This is a testharness.js-based test.
-FAIL Script URL including URL-encoded slash Test bug: need to pass exception to assert_throws()
-FAIL Script URL including uppercase URL-encoded slash Test bug: need to pass exception to assert_throws()
-FAIL Script URL including URL-encoded backslash Test bug: need to pass exception to assert_throws()
-FAIL Script URL including uppercase URL-encoded backslash Test bug: need to pass exception to assert_throws()
-PASS Script URL including self-reference
-PASS Script URL including parent-reference
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/link-element-register-script.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/link-element-register-script.https-expected.txt
deleted file mode 100644
index 1dbf650..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/link-element-register-script.https-expected.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-This is a testharness.js-based test.
-FAIL Registering invalid chunked encoding script Test bug: need to pass exception to assert_throws()
-FAIL Registering invalid chunked encoding script with flush Test bug: need to pass exception to assert_throws()
-FAIL Registering script including parse error Test bug: need to pass exception to assert_throws()
-FAIL Registering script including undefined error Test bug: need to pass exception to assert_throws()
-FAIL Registering script including uncaught exception Test bug: need to pass exception to assert_throws()
-FAIL Registering script importing malformed script Test bug: need to pass exception to assert_throws()
-FAIL Registering non-existent script Test bug: need to pass exception to assert_throws()
-FAIL Registering script importing non-existent script Test bug: need to pass exception to assert_throws()
-PASS Registering script including caught exception
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/link-element-register-security-error.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/link-element-register-security-error.https-expected.txt
deleted file mode 100644
index 78c5360..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/link-element-register-security-error.https-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-This is a testharness.js-based test.
-FAIL Registering same scope as the script directory without the last slash Test bug: need to pass exception to assert_throws()
-FAIL Registration scope outside the script directory Test bug: need to pass exception to assert_throws()
-FAIL Registering scope outside domain Test bug: need to pass exception to assert_throws()
-FAIL Registering script outside domain Test bug: need to pass exception to assert_throws()
-FAIL Registering redirected script Test bug: need to pass exception to assert_throws()
-FAIL Scope including parent-reference and not under the script directory Test bug: need to pass exception to assert_throws()
-FAIL Script URL including consecutive slashes Test bug: need to pass exception to assert_throws()
-FAIL Script URL is same-origin filesystem: URL Test bug: need to pass exception to assert_throws()
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/navigate-window.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/navigate-window.https-expected.txt
deleted file mode 100644
index 59459ec..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/navigate-window.https-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-FAIL Clients.matchAll() should not show an old window as controlled after it navigates. assert_unreached: unexpected rejection: assert_equals: client should have expected frame type expected "top-level" but got "auxiliary" Reached unreachable code
-FAIL Clients.matchAll() should not show an old window after it navigates. assert_unreached: unexpected rejection: assert_equals: client should have expected frame type expected "top-level" but got "auxiliary" Reached unreachable code
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/registration-mime-types.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/registration-mime-types.https-expected.txt
deleted file mode 100644
index e4d2ccd0..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/registration-mime-types.https-expected.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-This is a testharness.js-based test.
-PASS Registering script with no MIME type
-PASS Registering script with bad MIME type
-FAIL Registering script that imports script with no MIME type assert_unreached: Should have rejected: Registration of no MIME type imported script should fail. Reached unreachable code
-FAIL Registering script that imports script with bad MIME type assert_unreached: Should have rejected: Registration of plain text imported script should fail. Reached unreachable code
-FAIL Registering script with good MIME type application/ecmascript promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('application/ecmascript')."
-PASS Registering script that imports script with good MIME type application/ecmascript
-PASS Registering script with good MIME type application/javascript
-PASS Registering script that imports script with good MIME type application/javascript
-FAIL Registering script with good MIME type application/x-ecmascript promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('application/x-ecmascript')."
-PASS Registering script that imports script with good MIME type application/x-ecmascript
-PASS Registering script with good MIME type application/x-javascript
-PASS Registering script that imports script with good MIME type application/x-javascript
-FAIL Registering script with good MIME type text/ecmascript promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/ecmascript')."
-PASS Registering script that imports script with good MIME type text/ecmascript
-PASS Registering script with good MIME type text/javascript
-PASS Registering script that imports script with good MIME type text/javascript
-FAIL Registering script with good MIME type text/javascript1.0 promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/javascript1.0')."
-PASS Registering script that imports script with good MIME type text/javascript1.0
-FAIL Registering script with good MIME type text/javascript1.1 promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/javascript1.1')."
-PASS Registering script that imports script with good MIME type text/javascript1.1
-FAIL Registering script with good MIME type text/javascript1.2 promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/javascript1.2')."
-PASS Registering script that imports script with good MIME type text/javascript1.2
-FAIL Registering script with good MIME type text/javascript1.3 promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/javascript1.3')."
-PASS Registering script that imports script with good MIME type text/javascript1.3
-FAIL Registering script with good MIME type text/javascript1.4 promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/javascript1.4')."
-PASS Registering script that imports script with good MIME type text/javascript1.4
-FAIL Registering script with good MIME type text/javascript1.5 promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/javascript1.5')."
-PASS Registering script that imports script with good MIME type text/javascript1.5
-FAIL Registering script with good MIME type text/jscript promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/jscript')."
-PASS Registering script that imports script with good MIME type text/jscript
-FAIL Registering script with good MIME type text/livescript promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/livescript')."
-PASS Registering script that imports script with good MIME type text/livescript
-FAIL Registering script with good MIME type text/x-ecmascript promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/x-ecmascript')."
-PASS Registering script that imports script with good MIME type text/x-ecmascript
-FAIL Registering script with good MIME type text/x-javascript promise_test: Unhandled rejection with value: object "SecurityError: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/x-javascript')."
-PASS Registering script that imports script with good MIME type text/x-javascript
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/registration-updateviacache.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/registration-updateviacache.https-expected.txt
deleted file mode 100644
index 6cc7619..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/registration-updateviacache.https-expected.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-This is a testharness.js-based test.
-FAIL register-via-api-updateViaCache-undefined assert_equals: reg.updateViaCache expected (string) "imports" but got (undefined) undefined
-FAIL register-via-api-updateViaCache-imports assert_equals: reg.updateViaCache expected (string) "imports" but got (undefined) undefined
-FAIL register-via-api-updateViaCache-all assert_equals: reg.updateViaCache expected (string) "all" but got (undefined) undefined
-FAIL register-via-api-updateViaCache-none assert_equals: reg.updateViaCache expected (string) "none" but got (undefined) undefined
-FAIL register-via-link-element-updateViaCache-undefined assert_equals: reg.updateViaCache expected (string) "imports" but got (undefined) undefined
-FAIL register-via-link-element-updateViaCache-imports assert_equals: reg.updateViaCache expected (string) "imports" but got (undefined) undefined
-FAIL register-via-link-element-updateViaCache-all assert_equals: reg.updateViaCache expected (string) "all" but got (undefined) undefined
-FAIL register-via-link-element-updateViaCache-none assert_equals: reg.updateViaCache expected (string) "none" but got (undefined) undefined
-FAIL register-via-link-header-updateViaCache-undefined assert_equals: reg.updateViaCache expected (string) "imports" but got (undefined) undefined
-FAIL register-via-link-header-updateViaCache-imports assert_equals: reg.updateViaCache expected (string) "imports" but got (undefined) undefined
-FAIL register-via-link-header-updateViaCache-all assert_equals: reg.updateViaCache expected (string) "all" but got (undefined) undefined
-FAIL register-via-link-header-updateViaCache-none assert_equals: reg.updateViaCache expected (string) "none" but got (undefined) undefined
-FAIL register-with-updateViaCache-undefined-then-undefined assert_equals: reg.updateViaCache updated expected (string) "imports" but got (undefined) undefined
-FAIL register-with-updateViaCache-undefined-then-imports assert_equals: reg.updateViaCache updated expected (string) "imports" but got (undefined) undefined
-FAIL register-with-updateViaCache-undefined-then-all assert_equals: reg.updateViaCache updated expected (string) "all" but got (undefined) undefined
-FAIL register-with-updateViaCache-undefined-then-none assert_equals: reg.updateViaCache updated expected (string) "none" but got (undefined) undefined
-FAIL register-with-updateViaCache-imports-then-undefined assert_equals: reg.updateViaCache updated expected (string) "imports" but got (undefined) undefined
-FAIL register-with-updateViaCache-imports-then-imports assert_equals: reg.updateViaCache updated expected (string) "imports" but got (undefined) undefined
-FAIL register-with-updateViaCache-imports-then-all assert_equals: reg.updateViaCache updated expected (string) "all" but got (undefined) undefined
-FAIL register-with-updateViaCache-imports-then-none assert_equals: reg.updateViaCache updated expected (string) "none" but got (undefined) undefined
-FAIL register-with-updateViaCache-all-then-undefined assert_equals: reg.updateViaCache updated expected (string) "imports" but got (undefined) undefined
-FAIL register-with-updateViaCache-all-then-imports assert_equals: reg.updateViaCache updated expected (string) "imports" but got (undefined) undefined
-FAIL register-with-updateViaCache-all-then-all assert_equals: reg.updateViaCache updated expected (string) "all" but got (undefined) undefined
-FAIL register-with-updateViaCache-all-then-none assert_equals: reg.updateViaCache updated expected (string) "none" but got (undefined) undefined
-FAIL register-with-updateViaCache-none-then-undefined assert_equals: reg.updateViaCache updated expected (string) "imports" but got (undefined) undefined
-FAIL register-with-updateViaCache-none-then-imports assert_equals: reg.updateViaCache updated expected (string) "imports" but got (undefined) undefined
-FAIL register-with-updateViaCache-none-then-all assert_equals: reg.updateViaCache updated expected (string) "all" but got (undefined) undefined
-FAIL register-with-updateViaCache-none-then-none assert_equals: reg.updateViaCache updated expected (string) "none" but got (undefined) undefined
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/update-recovery.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/update-recovery.https-expected.txt
deleted file mode 100644
index f62fe77..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/update-recovery.https-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Recover from a bad service worker by updating after a failed navigation. assert_unreached: unexpected rejection: expected bad iframe should not fire a load event! Reached unreachable code
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/worker-interception.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/worker-interception.https-expected.txt
deleted file mode 100644
index f6d95f7..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/worker-interception.https-expected.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-This is a testharness.js-based test.
-FAIL Verify worker script from uncontrolled document is intercepted by Service Worker promise_test: Unhandled rejection with value: undefined
-FAIL Verify worker script intercepted by same-origin response succeeds promise_test: Unhandled rejection with value: undefined
-FAIL Verify worker script intercepted by cors response succeeds promise_test: Unhandled rejection with value: undefined
-PASS Verify worker script intercepted by no-cors cross-origin response fails
-PASS Verify worker loads from controlled document are intercepted by Service Worker
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/Source/core/css/parser/CSSParserContext.cpp b/third_party/WebKit/Source/core/css/parser/CSSParserContext.cpp
index 2b1a7a8..282ed6fc 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSParserContext.cpp
+++ b/third_party/WebKit/Source/core/css/parser/CSSParserContext.cpp
@@ -6,6 +6,7 @@
 
 #include "core/css/CSSStyleSheet.h"
 #include "core/css/StyleSheetContents.h"
+#include "core/dom/ExecutionContext.h"
 #include "core/frame/Deprecation.h"
 #include "core/frame/Settings.h"
 #include "core/frame/csp/ContentSecurityPolicy.h"
@@ -15,6 +16,23 @@
 namespace blink {
 
 // static
+CSSParserContext* CSSParserContext::Create(const ExecutionContext& context) {
+  const Referrer referrer(context.Url().StrippedForUseAsReferrer(),
+                          context.GetReferrerPolicy());
+
+  ContentSecurityPolicyDisposition policy_disposition;
+  if (ContentSecurityPolicy::ShouldBypassMainWorld(&context))
+    policy_disposition = kDoNotCheckContentSecurityPolicy;
+  else
+    policy_disposition = kCheckContentSecurityPolicy;
+
+  return new CSSParserContext(
+      context.Url(), WTF::TextEncoding(), kHTMLStandardMode, kHTMLStandardMode,
+      kDynamicProfile, referrer, true, false, policy_disposition,
+      context.IsDocument() ? &ToDocument(context) : nullptr);
+}
+
+// static
 CSSParserContext* CSSParserContext::CreateWithStyleSheet(
     const CSSParserContext* other,
     const CSSStyleSheet* style_sheet) {
diff --git a/third_party/WebKit/Source/core/css/parser/CSSParserContext.h b/third_party/WebKit/Source/core/css/parser/CSSParserContext.h
index fe1c245..f1201f4 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSParserContext.h
+++ b/third_party/WebKit/Source/core/css/parser/CSSParserContext.h
@@ -55,6 +55,8 @@
       ReferrerPolicy referrer_policy_override,
       const WTF::TextEncoding& charset = WTF::TextEncoding(),
       SelectorProfile = kDynamicProfile);
+  // This is used for workers, where we don't have a document.
+  static CSSParserContext* Create(const ExecutionContext&);
 
   bool operator==(const CSSParserContext&) const;
   bool operator!=(const CSSParserContext& other) const {
diff --git a/third_party/WebKit/Source/core/dom/Element.cpp b/third_party/WebKit/Source/core/dom/Element.cpp
index 88c25b0..85b8a921 100644
--- a/third_party/WebKit/Source/core/dom/Element.cpp
+++ b/third_party/WebKit/Source/core/dom/Element.cpp
@@ -2373,6 +2373,22 @@
   return CreateShadowRootInternal(ShadowRootType::V0, exception_state);
 }
 
+bool Element::CanAttachShadowRoot() const {
+  const AtomicString& tag_name = localName();
+  return IsV0CustomElement() ||
+         GetCustomElementState() != CustomElementState::kUncustomized ||
+         tag_name == HTMLNames::articleTag || tag_name == HTMLNames::asideTag ||
+         tag_name == HTMLNames::blockquoteTag ||
+         tag_name == HTMLNames::bodyTag || tag_name == HTMLNames::divTag ||
+         tag_name == HTMLNames::footerTag || tag_name == HTMLNames::h1Tag ||
+         tag_name == HTMLNames::h2Tag || tag_name == HTMLNames::h3Tag ||
+         tag_name == HTMLNames::h4Tag || tag_name == HTMLNames::h5Tag ||
+         tag_name == HTMLNames::h6Tag || tag_name == HTMLNames::headerTag ||
+         tag_name == HTMLNames::navTag || tag_name == HTMLNames::mainTag ||
+         tag_name == HTMLNames::pTag || tag_name == HTMLNames::sectionTag ||
+         tag_name == HTMLNames::spanTag;
+}
+
 ShadowRoot* Element::attachShadow(const ScriptState* script_state,
                                   const ShadowRootInit& shadow_root_init_dict,
                                   ExceptionState& exception_state) {
@@ -2380,20 +2396,7 @@
       script_state, GetDocument(),
       HostsUsingFeatures::Feature::kElementAttachShadow);
 
-  const AtomicString& tag_name = localName();
-  bool tag_name_is_supported =
-      IsV0CustomElement() ||
-      GetCustomElementState() != CustomElementState::kUncustomized ||
-      tag_name == HTMLNames::articleTag || tag_name == HTMLNames::asideTag ||
-      tag_name == HTMLNames::blockquoteTag || tag_name == HTMLNames::bodyTag ||
-      tag_name == HTMLNames::divTag || tag_name == HTMLNames::footerTag ||
-      tag_name == HTMLNames::h1Tag || tag_name == HTMLNames::h2Tag ||
-      tag_name == HTMLNames::h3Tag || tag_name == HTMLNames::h4Tag ||
-      tag_name == HTMLNames::h5Tag || tag_name == HTMLNames::h6Tag ||
-      tag_name == HTMLNames::headerTag || tag_name == HTMLNames::navTag ||
-      tag_name == HTMLNames::mainTag || tag_name == HTMLNames::pTag ||
-      tag_name == HTMLNames::sectionTag || tag_name == HTMLNames::spanTag;
-  if (!tag_name_is_supported) {
+  if (!CanAttachShadowRoot()) {
     exception_state.ThrowDOMException(
         kNotSupportedError, "This element does not support attachShadow");
     return nullptr;
@@ -2406,8 +2409,6 @@
     return nullptr;
   }
 
-  GetDocument().SetShadowCascadeOrder(ShadowCascadeOrder::kShadowCascadeV1);
-
   ShadowRootType type = ShadowRootType::V0;
   if (shadow_root_init_dict.hasMode())
     type = shadow_root_init_dict.mode() == "open" ? ShadowRootType::kOpen
@@ -2418,23 +2419,23 @@
   else if (type == ShadowRootType::kOpen)
     UseCounter::Count(GetDocument(), WebFeature::kElementAttachShadowOpen);
 
-  ShadowRoot* shadow_root = CreateShadowRootInternal(type, exception_state);
-
-  if (shadow_root_init_dict.hasDelegatesFocus()) {
-    shadow_root->SetDelegatesFocus(shadow_root_init_dict.delegatesFocus());
-    UseCounter::Count(GetDocument(), WebFeature::kShadowRootDelegatesFocus);
+  if (!AreAuthorShadowsAllowed()) {
+    exception_state.ThrowDOMException(
+        kHierarchyRequestError,
+        "Author-created shadow roots are disabled for this element.");
+    return nullptr;
   }
 
-  return shadow_root;
+  DCHECK(!shadow_root_init_dict.hasMode() || !GetShadowRoot());
+  bool delegateFocus = shadow_root_init_dict.hasDelegatesFocus() &&
+                       shadow_root_init_dict.delegatesFocus();
+  return &AttachShadowRootInternal(type, delegateFocus);
 }
 
 ShadowRoot* Element::CreateShadowRootInternal(ShadowRootType type,
                                               ExceptionState& exception_state) {
   DCHECK(!ClosedShadowRoot());
 
-  if (AlwaysCreateUserAgentShadowRoot())
-    EnsureUserAgentShadowRoot();
-
   // Some elements make assumptions about what kind of layoutObjects they allow
   // as children so we can't allow author shadows on them for now.
   if (!AreAuthorShadowsAllowed()) {
@@ -2444,9 +2445,29 @@
     return nullptr;
   }
 
+  if (AlwaysCreateUserAgentShadowRoot())
+    EnsureUserAgentShadowRoot();
+
   return &EnsureShadow().AddShadowRoot(*this, type);
 }
 
+ShadowRoot& Element::AttachShadowRootInternal(ShadowRootType type,
+                                              const bool delegate_focus) {
+  DCHECK(CanAttachShadowRoot());
+  DCHECK(AreAuthorShadowsAllowed());
+  DCHECK(type == ShadowRootType::kOpen || type == ShadowRootType::kClosed)
+      << type;
+  DCHECK(!AlwaysCreateUserAgentShadowRoot());
+
+  GetDocument().SetShadowCascadeOrder(ShadowCascadeOrder::kShadowCascadeV1);
+
+  ShadowRoot& shadow_root = EnsureShadow().AddShadowRoot(*this, type);
+
+  shadow_root.SetDelegatesFocus(delegate_focus);
+
+  return shadow_root;
+}
+
 ShadowRoot* Element::GetShadowRoot() const {
   ElementShadow* element_shadow = Shadow();
   if (!element_shadow)
diff --git a/third_party/WebKit/Source/core/dom/Element.h b/third_party/WebKit/Source/core/dom/Element.h
index 79ec240..0f68771b 100644
--- a/third_party/WebKit/Source/core/dom/Element.h
+++ b/third_party/WebKit/Source/core/dom/Element.h
@@ -480,6 +480,8 @@
                            const ShadowRootInit&,
                            ExceptionState&);
   ShadowRoot* CreateShadowRootInternal(ShadowRootType, ExceptionState&);
+  ShadowRoot& AttachShadowRootInternal(ShadowRootType,
+                                       bool delegate_focus = false);
 
   ShadowRoot* OpenShadowRoot() const;
   ShadowRoot* ClosedShadowRoot() const;
@@ -888,6 +890,8 @@
   bool IsDocumentNode() const =
       delete;  // This will catch anyone doing an unnecessary check.
 
+  bool CanAttachShadowRoot() const;
+
   void StyleAttributeChanged(const AtomicString& new_style_string,
                              AttributeModificationReason);
 
diff --git a/third_party/WebKit/Source/core/editing/VisibleUnitsWordTest.cpp b/third_party/WebKit/Source/core/editing/VisibleUnitsWordTest.cpp
index c78e9ce..becbcc61 100644
--- a/third_party/WebKit/Source/core/editing/VisibleUnitsWordTest.cpp
+++ b/third_party/WebKit/Source/core/editing/VisibleUnitsWordTest.cpp
@@ -48,9 +48,9 @@
   InsertStyleElement("p::first-letter {font-size:200%;}");
   // TODO(editing-dev): We should make expected texts as same as
   // "StartOfWordBasic".
-  EXPECT_EQ("<p> (1|) abc def</p>", DoStartOfWord("<p>| (1) abc def</p>"));
-  EXPECT_EQ("<p> (1|) abc def</p>", DoStartOfWord("<p> |(1) abc def</p>"));
-  EXPECT_EQ("<p> (1|) abc def</p>", DoStartOfWord("<p> (|1) abc def</p>"));
+  EXPECT_EQ("<p> |(1) abc def</p>", DoStartOfWord("<p>| (1) abc def</p>"));
+  EXPECT_EQ("<p> |(1) abc def</p>", DoStartOfWord("<p> |(1) abc def</p>"));
+  EXPECT_EQ("<p> (|1) abc def</p>", DoStartOfWord("<p> (|1) abc def</p>"));
   EXPECT_EQ("<p> (1|) abc def</p>", DoStartOfWord("<p> (1|) abc def</p>"));
   EXPECT_EQ("<p> (1)| abc def</p>", DoStartOfWord("<p> (1)| abc def</p>"));
   EXPECT_EQ("<p> |(1) abc def</p>", DoStartOfWord("<p> (1) |abc def</p>"));
diff --git a/third_party/WebKit/Source/core/editing/iterators/SimplifiedBackwardsTextIterator.cpp b/third_party/WebKit/Source/core/editing/iterators/SimplifiedBackwardsTextIterator.cpp
index 7d9f23a99..340a802 100644
--- a/third_party/WebKit/Source/core/editing/iterators/SimplifiedBackwardsTextIterator.cpp
+++ b/third_party/WebKit/Source/core/editing/iterators/SimplifiedBackwardsTextIterator.cpp
@@ -52,9 +52,11 @@
 static int MaxOffsetIncludingCollapsedSpaces(Node* node) {
   int offset = CaretMaxOffset(node);
 
-  if (node->GetLayoutObject() && node->GetLayoutObject()->IsText())
+  if (node->GetLayoutObject() && node->GetLayoutObject()->IsText()) {
     offset +=
-        CollapsedSpaceLength(ToLayoutText(node->GetLayoutObject()), offset);
+        CollapsedSpaceLength(ToLayoutText(node->GetLayoutObject()), offset) +
+        ToLayoutText(node->GetLayoutObject())->TextStartOffset();
+  }
 
   return offset;
 }
@@ -244,7 +246,7 @@
     return true;
 
   position_end_offset_ = offset_;
-  offset_ = start_offset + offset_in_node;
+  offset_ = start_offset;
   position_node_ = node_;
   position_start_offset_ = offset_;
 
@@ -279,17 +281,21 @@
   LayoutTextFragment* fragment = ToLayoutTextFragment(layout_object);
   int offset_after_first_letter = fragment->Start();
   if (start_offset >= offset_after_first_letter) {
+    // We'll stop in remaining part.
     DCHECK(!should_handle_first_letter_);
     offset_in_node = offset_after_first_letter;
     return layout_object;
   }
 
   if (!should_handle_first_letter_ && offset_after_first_letter < offset_) {
+    // Enter into remaining part
     should_handle_first_letter_ = true;
     offset_in_node = offset_after_first_letter;
+    start_offset = offset_after_first_letter;
     return layout_object;
   }
 
+  // Enter into first-letter part
   should_handle_first_letter_ = false;
   offset_in_node = 0;
 
@@ -303,8 +309,12 @@
   LayoutText* first_letter_layout_object =
       ToLayoutText(pseudo_element_layout_object->SlowFirstChild());
 
-  offset_ = first_letter_layout_object->CaretMaxOffset();
-  offset_ += CollapsedSpaceLength(first_letter_layout_object, offset_);
+  const int end_offset =
+      end_node_ == node_ && end_offset_ < offset_after_first_letter
+          ? end_offset_
+          : first_letter_layout_object->CaretMaxOffset();
+  offset_ =
+      end_offset + CollapsedSpaceLength(first_letter_layout_object, end_offset);
 
   return first_letter_layout_object;
 }
diff --git a/third_party/WebKit/Source/core/editing/iterators/SimplifiedBackwardsTextIteratorTest.cpp b/third_party/WebKit/Source/core/editing/iterators/SimplifiedBackwardsTextIteratorTest.cpp
index 88d6268..0dd9df4f 100644
--- a/third_party/WebKit/Source/core/editing/iterators/SimplifiedBackwardsTextIteratorTest.cpp
+++ b/third_party/WebKit/Source/core/editing/iterators/SimplifiedBackwardsTextIteratorTest.cpp
@@ -5,13 +5,34 @@
 #include "core/editing/iterators/SimplifiedBackwardsTextIterator.h"
 
 #include "core/editing/EphemeralRange.h"
+#include "core/editing/SelectionTemplate.h"
 #include "core/editing/testing/EditingTestBase.h"
 #include "platform/wtf/Vector.h"
+#include "platform/wtf/text/StringBuilder.h"
 #include "platform/wtf/text/WTFString.h"
 
 namespace blink {
 
-class SimplifiedBackwardsTextIteratorTest : public EditingTestBase {};
+class SimplifiedBackwardsTextIteratorTest : public EditingTestBase {
+ protected:
+  std::string ExtractStringInRange(const std::string selection_text) {
+    const SelectionInDOMTree selection = SetSelectionTextToBody(selection_text);
+    StringBuilder builder;
+    bool is_first = true;
+    for (SimplifiedBackwardsTextIterator iterator(EphemeralRange(
+             selection.ComputeStartPosition(), selection.ComputeEndPosition()));
+         !iterator.AtEnd(); iterator.Advance()) {
+      BackwardsTextBuffer buffer;
+      iterator.CopyTextTo(&buffer);
+      if (!is_first)
+        builder.Append(", ", 2);
+      is_first = false;
+      builder.Append(buffer.Data(), buffer.Size());
+    }
+    CString utf8 = builder.ToString().Utf8();
+    return std::string(utf8.data(), utf8.length());
+  }
+};
 
 template <typename Strategy>
 static String ExtractString(const Element& element) {
@@ -25,6 +46,38 @@
   return String(buffer.Data(), buffer.Size());
 }
 
+TEST_F(SimplifiedBackwardsTextIteratorTest, CopyTextToWithFirstLetterPart) {
+  InsertStyleElement("p::first-letter {font-size: 200%}");
+  // TODO(editing-dev): |SimplifiedBackwardsTextIterator| should not account
+  // collapsed whitespace (http://crbug.com/760428)
+
+  // Simulate PreviousBoundary()
+  EXPECT_EQ(" , \n", ExtractStringInRange("^<p> |[(3)]678</p>"));
+  EXPECT_EQ(" [, \n", ExtractStringInRange("^<p> [|(3)]678</p>"));
+  EXPECT_EQ(" [(, \n", ExtractStringInRange("^<p> [(|3)]678</p>"));
+  EXPECT_EQ(" [(3, \n", ExtractStringInRange("^<p> [(3|)]678</p>"));
+  EXPECT_EQ(" [(3), \n", ExtractStringInRange("^<p> [(3)|]678</p>"));
+  EXPECT_EQ(" [(3)], \n", ExtractStringInRange("^<p> [(3)]|678</p>"));
+
+  EXPECT_EQ("6,  [(3)], \n, ab", ExtractStringInRange("^ab<p> [(3)]6|78</p>"))
+      << "From remaining part to outside";
+
+  EXPECT_EQ("(3)", ExtractStringInRange("<p> [^(3)|]678</p>"))
+      << "Iterate in first-letter part";
+
+  EXPECT_EQ("67, (3)]", ExtractStringInRange("<p> [^(3)]67|8</p>"))
+      << "From remaining part to first-letter part";
+
+  EXPECT_EQ("789", ExtractStringInRange("<p> [(3)]6^789|a</p>"))
+      << "Iterate in remaining part";
+
+  EXPECT_EQ("9, \n, 78", ExtractStringInRange("<p> [(3)]6^78</p>9|a"))
+      << "Enter into remaining part and stop in remaining part";
+
+  EXPECT_EQ("9, \n, 678, (3)]", ExtractStringInRange("<p> [^(3)]678</p>9|a"))
+      << "Enter into remaining part and stop in first-letter part";
+}
+
 TEST_F(SimplifiedBackwardsTextIteratorTest, Basic) {
   SetBodyContent("<p> [(3)]678</p>");
   const Element* const sample = GetDocument().QuerySelector("p");
diff --git a/third_party/WebKit/Source/platform/exported/WebRuntimeFeatures.cpp b/third_party/WebKit/Source/platform/exported/WebRuntimeFeatures.cpp
index fd8b0e0..73839bf 100644
--- a/third_party/WebKit/Source/platform/exported/WebRuntimeFeatures.cpp
+++ b/third_party/WebKit/Source/platform/exported/WebRuntimeFeatures.cpp
@@ -96,6 +96,10 @@
   RuntimeEnabledFeatures::SetCompositorTouchActionEnabled(enable);
 }
 
+void WebRuntimeFeatures::EnableCompositorImageAnimations(bool enable) {
+  RuntimeEnabledFeatures::SetCompositorImageAnimationsEnabled(enable);
+}
+
 void WebRuntimeFeatures::EnableCSSHexAlphaColor(bool enable) {
   RuntimeEnabledFeatures::SetCSSHexAlphaColorEnabled(enable);
 }
diff --git a/third_party/WebKit/Source/platform/graphics/BitmapImage.cpp b/third_party/WebKit/Source/platform/graphics/BitmapImage.cpp
index 18f0ecd7..722e42e 100644
--- a/third_party/WebKit/Source/platform/graphics/BitmapImage.cpp
+++ b/third_party/WebKit/Source/platform/graphics/BitmapImage.cpp
@@ -257,6 +257,14 @@
     }
   }
 
+  // If the image is being animated by the compositor, clear the cached_frame_
+  // on a data update to push it to the compositor. Since we never advance the
+  // animation here, the |cached_frame_index_| is always the first frame and the
+  // |cached_frame_| might have not have been cleared in the loop above.
+  if (RuntimeEnabledFeatures::CompositorImageAnimationsEnabled()
+      && MaybeAnimated())
+    cached_frame_ = PaintImage();
+
   // Feed all the data we've seen so far to the image decoder.
   all_data_received_ = all_data_received;
 
@@ -476,6 +484,9 @@
 }
 
 bool BitmapImage::ShouldAnimate() {
+  if (RuntimeEnabledFeatures::CompositorImageAnimationsEnabled())
+    return false;
+
   bool animated = RepetitionCount() != kAnimationNone && !animation_finished_ &&
                   GetImageObserver();
   if (animated && animation_policy_ == kImageAnimationPolicyNoAnimation)
diff --git a/third_party/WebKit/Source/platform/runtime_enabled_features.json5 b/third_party/WebKit/Source/platform/runtime_enabled_features.json5
index c8932de..8d4b8a2 100644
--- a/third_party/WebKit/Source/platform/runtime_enabled_features.json5
+++ b/third_party/WebKit/Source/platform/runtime_enabled_features.json5
@@ -166,6 +166,10 @@
       status: "stable",
     },
     {
+      name: "CompositorImageAnimations",
+      status: "test",
+    },
+    {
       name: "CompositorTouchAction",
       status: "test",
     },
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/task_duration_metric_reporter_unittest.cc b/third_party/WebKit/Source/platform/scheduler/renderer/task_duration_metric_reporter_unittest.cc
index be6a216d..8eab878 100644
--- a/third_party/WebKit/Source/platform/scheduler/renderer/task_duration_metric_reporter_unittest.cc
+++ b/third_party/WebKit/Source/platform/scheduler/renderer/task_duration_metric_reporter_unittest.cc
@@ -41,7 +41,7 @@
   MOCK_METHOD1(AddSamplesFromPickle, bool(base::PickleIterator*));
   MOCK_CONST_METHOD1(WriteHTMLGraph, void(std::string*));
   MOCK_CONST_METHOD1(WriteAscii, void(std::string*));
-  MOCK_CONST_METHOD1(SerializeInfoImpl, bool(base::Pickle*));
+  MOCK_CONST_METHOD1(SerializeInfoImpl, void(base::Pickle*));
   MOCK_CONST_METHOD1(GetParameters, void(base::DictionaryValue*));
   MOCK_CONST_METHOD3(GetCountAndBucketData,
                      void(base::HistogramBase::Count*,
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/bindings/testdata/test_interface.idl b/third_party/WebKit/Tools/Scripts/webkitpy/bindings/testdata/test_interface.idl
index 74ff3ba..f6e4b96 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/bindings/testdata/test_interface.idl
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/bindings/testdata/test_interface.idl
@@ -1,8 +1,8 @@
 [
     CustomToV8
  ] interface Node : EventTarget {
-    [Reflect]const unsigned short ELEMENT_NODE = 1;
-    [Clamp]attribute Node parentNode;
+    [Reflect] const unsigned short ELEMENT_NODE = 1;
+    attribute [Clamp] Node parentNode;
     [Custom] Node appendChild(Node newChild);
 };
 
diff --git a/third_party/WebKit/public/platform/WebRuntimeFeatures.h b/third_party/WebKit/public/platform/WebRuntimeFeatures.h
index eb160c55..6080d09 100644
--- a/third_party/WebKit/public/platform/WebRuntimeFeatures.h
+++ b/third_party/WebKit/public/platform/WebRuntimeFeatures.h
@@ -67,6 +67,8 @@
 
   BLINK_PLATFORM_EXPORT static void EnableCompositorTouchAction(bool);
 
+  BLINK_PLATFORM_EXPORT static void EnableCompositorImageAnimations(bool);
+
   BLINK_PLATFORM_EXPORT static void EnableDisplayList2dCanvas(bool);
   BLINK_PLATFORM_EXPORT static void ForceDisplayList2dCanvas(bool);
 
diff --git a/ui/events/gestures/gesture_recognizer_impl.cc b/ui/events/gestures/gesture_recognizer_impl.cc
index dbf8a24..446dc2c 100644
--- a/ui/events/gestures/gesture_recognizer_impl.cc
+++ b/ui/events/gestures/gesture_recognizer_impl.cc
@@ -40,6 +40,9 @@
 template <class Key, class T, class Value>
 bool RemoveValueFromMap(std::map<Key, T>* map, const Value& value) {
   bool removed = false;
+  // This is a bandaid fix for crbug/732232 that requires further investigation.
+  if (!map || map->empty())
+    return removed;
   for (auto i = map->begin(); i != map->end();) {
     if (i->second == value) {
       map->erase(i++);
diff --git a/ui/message_center/views/notification_view_md.cc b/ui/message_center/views/notification_view_md.cc
index 8b2269ec..eec2717 100644
--- a/ui/message_center/views/notification_view_md.cc
+++ b/ui/message_center/views/notification_view_md.cc
@@ -53,7 +53,7 @@
 constexpr int kActionsRowHorizontalSpacing = 8;
 constexpr gfx::Insets kActionButtonPadding(0, 12, 0, 12);
 constexpr gfx::Insets kStatusTextPadding(4, 0, 0, 0);
-constexpr gfx::Size kActionButtonMinSize(88, 32);
+constexpr gfx::Size kActionButtonMinSize(0, 32);
 // TODO(tetsui): Move |kIconViewSize| to public/cpp/message_center_constants.h
 // and merge with contradicting |kNotificationIconSize|.
 constexpr gfx::Size kIconViewSize(36, 36);
diff --git a/ui/ozone/public/ozone_platform.cc b/ui/ozone/public/ozone_platform.cc
index 70a5031..d0c5630dd 100644
--- a/ui/ozone/public/ozone_platform.cc
+++ b/ui/ozone/public/ozone_platform.cc
@@ -26,10 +26,7 @@
   g_platform_initialized_gpu = false;
 }
 
-OzonePlatform::~OzonePlatform() {
-  DCHECK_EQ(instance_, this);
-  instance_ = NULL;
-}
+OzonePlatform::~OzonePlatform() = default;
 
 // static
 void OzonePlatform::InitializeForUI(const InitParams& args) {
@@ -54,8 +51,9 @@
 
 // static
 void OzonePlatform::Shutdown() {
-  delete instance_;
-  // Destructor resets pointer.
+  auto* tmp = instance_;
+  instance_ = nullptr;
+  delete tmp;
 }
 
 // static