diff --git a/DEPS b/DEPS
index 9283bd6..0408441 100644
--- a/DEPS
+++ b/DEPS
@@ -130,7 +130,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': '3ac7c0f0224ef18ba45d6cb1017a48ac1d73c5ec',
+  'catapult_revision': 'dc9404644cac587e0bdc26f4430498f00e8ba3a2',
   # 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/chrome/browser/apps/guest_view/app_view_browsertest.cc b/chrome/browser/apps/guest_view/app_view_browsertest.cc
index ecf0bcc..41fa83c 100644
--- a/chrome/browser/apps/guest_view/app_view_browsertest.cc
+++ b/chrome/browser/apps/guest_view/app_view_browsertest.cc
@@ -196,7 +196,13 @@
 }
 
 // Tests that <appview> correctly handles multiple successive connects.
-IN_PROC_BROWSER_TEST_P(AppViewTest, TestAppViewMultipleConnects) {
+// TODO(crbug.com/794490) Reenable after fixing timeout issues.
+#if defined(OS_LINUX) && defined(ADDRESS_SANITIZER)
+#define MAYBE_TestAppViewMultipleConnects DISABLED_TestAppViewMultipleConnects
+#else
+#define MAYBE_TestAppViewMultipleConnects TestAppViewMultipleConnects
+#endif
+IN_PROC_BROWSER_TEST_P(AppViewTest, MAYBE_TestAppViewMultipleConnects) {
   const extensions::Extension* skeleton_app =
       InstallPlatformApp("app_view/shim/skeleton");
   TestHelper("testAppViewMultipleConnects",
diff --git a/chrome/browser/media/media_engagement_autoplay_browsertest.cc b/chrome/browser/media/media_engagement_autoplay_browsertest.cc
index 26f91432..a0b1539 100644
--- a/chrome/browser/media/media_engagement_autoplay_browsertest.cc
+++ b/chrome/browser/media/media_engagement_autoplay_browsertest.cc
@@ -3,10 +3,17 @@
 // found in the LICENSE file.
 
 #include "base/command_line.h"
+#include "base/files/file_util.h"
+#include "base/json/json_writer.h"
+#include "base/path_service.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/scoped_feature_list.h"
+#include "base/threading/thread_restrictions.h"
+#include "base/values.h"
+#include "build/build_config.h"
 #include "chrome/browser/content_settings/chrome_content_settings_utils.h"
 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
+#include "chrome/browser/media/media_engagement_preloaded_list.h"
 #include "chrome/browser/media/media_engagement_service.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
@@ -19,12 +26,32 @@
 
 namespace {
 
+base::FilePath GetPythonPath() {
+#if defined(OS_WIN)
+  // Windows bots do not have python installed and available on the PATH.
+  // Please see infra/doc/users/python.md
+  base::FilePath bot_path =
+      base::FilePath(FILE_PATH_LITERAL("c:/infra-system/bin/python.exe"));
+
+  if (base::PathExists(bot_path))
+    return bot_path;
+  return base::FilePath(FILE_PATH_LITERAL("python.exe"));
+#else
+  return base::FilePath(FILE_PATH_LITERAL("python"));
+#endif
+}
+
+const base::FilePath kTestDataPath = base::FilePath(
+    FILE_PATH_LITERAL("chrome/test/data/media/engagement/preload"));
+
 const char kMediaEngagementTestDataPath[] = "chrome/test/data/media/engagement";
 
 const base::string16 kAllowedTitle = base::ASCIIToUTF16("Allowed");
 
 const base::string16 kDeniedTitle = base::ASCIIToUTF16("Denied");
 
+const base::FilePath kEmptyDataPath = kTestDataPath.AppendASCII("empty.pb");
+
 }  // namespace
 
 // Class used to test that origins with a high Media Engagement score
@@ -51,10 +78,14 @@
 
     scoped_feature_list_.InitWithFeatures(
         {media::kRecordMediaEngagementScores,
-         media::kMediaEngagementBypassAutoplayPolicies},
+         media::kMediaEngagementBypassAutoplayPolicies,
+         media::kPreloadMediaEngagementData},
         {});
 
     InProcessBrowserTest::SetUp();
+
+    // Clear any preloaded MEI data.
+    ApplyEmptyPreloadedList();
   };
 
   void LoadTestPage(const std::string& page) {
@@ -88,6 +119,50 @@
 
   void ExpectAutoplayDenied() { EXPECT_EQ(kDeniedTitle, WaitAndGetTitle()); }
 
+  void ApplyPreloadedOrigin(GURL url) {
+    base::ScopedAllowBlockingForTesting allow_blocking;
+
+    // Get two temporary files.
+    base::FilePath input_path;
+    base::FilePath output_path;
+    EXPECT_TRUE(base::CreateTemporaryFile(&input_path));
+    EXPECT_TRUE(base::CreateTemporaryFile(&output_path));
+
+    // Write JSON file with the server origin in it.
+    base::ListValue list;
+    list.AppendString(url::Origin::Create(url).Serialize());
+    std::string json_data;
+    base::JSONWriter::Write(list, &json_data);
+    EXPECT_TRUE(
+        base::WriteFile(input_path, json_data.c_str(), json_data.size()));
+
+    // Get the path to the "generator" binary in the module path.
+    base::FilePath module_dir;
+    EXPECT_TRUE(PathService::Get(base::DIR_MODULE, &module_dir));
+
+    // Launch the generator and wait for it to finish.
+    base::CommandLine cmd(GetPythonPath());
+    cmd.AppendArg("tools/media_engagement_preload/make_dafsa.py");
+    cmd.AppendArgPath(input_path);
+    cmd.AppendArgPath(output_path);
+    base::Process process = base::LaunchProcess(cmd, base::LaunchOptions());
+    EXPECT_TRUE(process.WaitForExit(0));
+
+    // Load the preloaded list.
+    EXPECT_TRUE(
+        MediaEngagementPreloadedList::GetInstance()->LoadFromFile(output_path));
+  }
+
+  void ApplyEmptyPreloadedList() {
+    // Get the path relative to the source root.
+    base::FilePath source_root;
+    EXPECT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &source_root));
+
+    base::ScopedAllowBlockingForTesting allow_blocking;
+    EXPECT_TRUE(MediaEngagementPreloadedList::GetInstance()->LoadFromFile(
+        source_root.Append(kEmptyDataPath)));
+  }
+
  private:
   base::string16 WaitAndGetTitle() {
     content::TitleWatcher title_watcher(GetWebContents(), kAllowedTitle);
@@ -177,3 +252,64 @@
   LoadTestPage("engagement_autoplay_test.html");
   ExpectAutoplayAllowed();
 }
+
+IN_PROC_BROWSER_TEST_F(MediaEngagementAutoplayBrowserTest,
+                       UsePreloadedData_Allowed) {
+  // Autoplay should be blocked by default if we have a bad score.
+  SetScores(PrimaryOrigin(), 0, 0);
+  LoadTestPage("engagement_autoplay_test.html");
+  ExpectAutoplayDenied();
+
+  // Load the preloaded data and we should now be able to autoplay.
+  ApplyPreloadedOrigin(PrimaryOrigin());
+  LoadTestPage("engagement_autoplay_test.html");
+  ExpectAutoplayAllowed();
+
+  // If we now have a high MEI score we should still be allowed to autoplay.
+  SetScores(PrimaryOrigin(), 10, 10);
+  LoadTestPage("engagement_autoplay_test.html");
+  ExpectAutoplayAllowed();
+
+  // If we clear the preloaded data we should still be allowed to autoplay.
+  ApplyEmptyPreloadedList();
+  LoadTestPage("engagement_autoplay_test.html");
+  ExpectAutoplayAllowed();
+}
+
+IN_PROC_BROWSER_TEST_F(MediaEngagementAutoplayBrowserTest,
+                       UsePreloadedData_Denied) {
+  // Autoplay should be blocked by default if we have a bad score.
+  SetScores(PrimaryOrigin(), 0, 0);
+  LoadTestPage("engagement_autoplay_test.html");
+  ExpectAutoplayDenied();
+
+  // Load the preloaded data but we are not in that dataset so we should not be
+  // allowed to autoplay.
+  ApplyPreloadedOrigin(SecondaryOrigin());
+  LoadTestPage("engagement_autoplay_test.html");
+  ExpectAutoplayDenied();
+
+  // If we now have a high MEI score we should now be allowed to autoplay.
+  SetScores(PrimaryOrigin(), 10, 10);
+  LoadTestPage("engagement_autoplay_test.html");
+  ExpectAutoplayAllowed();
+
+  // If we clear the preloaded data we should still be allowed to autoplay.
+  ApplyEmptyPreloadedList();
+  LoadTestPage("engagement_autoplay_test.html");
+  ExpectAutoplayAllowed();
+}
+
+IN_PROC_BROWSER_TEST_F(MediaEngagementAutoplayBrowserTest,
+                       PreloadedDataAndHighVisits) {
+  // Autoplay should be denied due to a low score.
+  SetScores(PrimaryOrigin(), 10, 0);
+  LoadTestPage("engagement_autoplay_test.html");
+  ExpectAutoplayDenied();
+
+  // Load the preloaded data and even though we are in the dataset we should not
+  // be allowed to play.
+  ApplyPreloadedOrigin(PrimaryOrigin());
+  LoadTestPage("engagement_autoplay_test.html");
+  ExpectAutoplayDenied();
+}
diff --git a/chrome/browser/media/media_engagement_contents_observer.cc b/chrome/browser/media/media_engagement_contents_observer.cc
index c9acba8d..41173e0f 100644
--- a/chrome/browser/media/media_engagement_contents_observer.cc
+++ b/chrome/browser/media/media_engagement_contents_observer.cc
@@ -6,13 +6,14 @@
 
 #include "base/metrics/histogram.h"
 #include "base/metrics/histogram_macros.h"
-#include "build/build_config.h"
+#include "chrome/browser/media/media_engagement_preloaded_list.h"
 #include "chrome/browser/media/media_engagement_service.h"
 #include "chrome/browser/media/media_engagement_session.h"
 #include "chrome/browser/profiles/profile.h"
 #include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/web_contents.h"
+#include "media/base/media_switches.h"
 #include "third_party/WebKit/common/associated_interfaces/associated_interface_provider.h"
 #include "third_party/WebKit/public/platform/media_engagement.mojom.h"
 
@@ -490,7 +491,22 @@
     content::NavigationHandle* handle) {
   // TODO(beccahughes): Convert MEI API to using origin.
   GURL url = handle->GetWebContents()->GetURL();
-  if (service_->HasHighEngagement(url)) {
+  MediaEngagementScore score = service_->CreateEngagementScore(url);
+  bool has_high_engagement = score.high_score();
+
+  // If the preloaded feature flag is enabled and the number of visits is less
+  // than the number of visits required to have an MEI score we should check the
+  // global data.
+  if (!has_high_engagement &&
+      score.visits() < MediaEngagementScore::GetScoreMinVisits() &&
+      base::FeatureList::IsEnabled(media::kPreloadMediaEngagementData)) {
+    has_high_engagement =
+        MediaEngagementPreloadedList::GetInstance()->CheckOriginIsPresent(
+            url::Origin::Create(url));
+  }
+
+  // If we have high media engagement then we should send that to Blink.
+  if (has_high_engagement) {
     SendEngagementLevelToFrame(url::Origin::Create(handle->GetURL()),
                                handle->GetRenderFrameHost());
   }
diff --git a/chrome/browser/media/media_engagement_preloaded_list.cc b/chrome/browser/media/media_engagement_preloaded_list.cc
index a552e08a..3fcf426 100644
--- a/chrome/browser/media/media_engagement_preloaded_list.cc
+++ b/chrome/browser/media/media_engagement_preloaded_list.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/media/media_engagement_preloaded_list.h"
 
 #include "base/files/file_util.h"
+#include "base/macros.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/path_service.h"
 #include "base/strings/string_number_conversions.h"
@@ -20,11 +21,34 @@
 const char MediaEngagementPreloadedList::kHistogramLoadResultName[] =
     "Media.Engagement.PreloadedList.LoadResult";
 
-MediaEngagementPreloadedList::MediaEngagementPreloadedList() = default;
+// static
+MediaEngagementPreloadedList* MediaEngagementPreloadedList::GetInstance() {
+  CR_DEFINE_STATIC_LOCAL(MediaEngagementPreloadedList, instance, ());
+  return &instance;
+}
 
-MediaEngagementPreloadedList::~MediaEngagementPreloadedList() = default;
+MediaEngagementPreloadedList::MediaEngagementPreloadedList() {
+  // This class is allowed to be instantiated on any thread.
+  DETACH_FROM_SEQUENCE(sequence_checker_);
+}
+
+MediaEngagementPreloadedList::~MediaEngagementPreloadedList() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+}
+
+bool MediaEngagementPreloadedList::loaded() const {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  return is_loaded_;
+}
+
+bool MediaEngagementPreloadedList::empty() const {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  return dafsa_.empty();
+}
 
 bool MediaEngagementPreloadedList::LoadFromFile(const base::FilePath& path) {
+  DETACH_FROM_SEQUENCE(sequence_checker_);
+
   // Check the file exists.
   if (!base::PathExists(path)) {
     RecordLoadResult(LoadResult::kFileNotFound);
@@ -57,6 +81,8 @@
 
 bool MediaEngagementPreloadedList::CheckOriginIsPresent(
     const url::Origin& origin) const {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
   // Check if we have loaded the data.
   if (!loaded()) {
     RecordCheckResult(CheckResult::kListNotLoaded);
diff --git a/chrome/browser/media/media_engagement_preloaded_list.h b/chrome/browser/media/media_engagement_preloaded_list.h
index 23e74fc..7e78ffb 100644
--- a/chrome/browser/media/media_engagement_preloaded_list.h
+++ b/chrome/browser/media/media_engagement_preloaded_list.h
@@ -9,6 +9,7 @@
 #include <vector>
 
 #include "base/macros.h"
+#include "base/sequence_checker.h"
 
 namespace base {
 class FilePath;
@@ -20,6 +21,8 @@
 
 class MediaEngagementPreloadedList {
  public:
+  static MediaEngagementPreloadedList* GetInstance();
+
   MediaEngagementPreloadedList();
   ~MediaEngagementPreloadedList();
 
@@ -31,10 +34,10 @@
   bool CheckOriginIsPresent(const url::Origin& origin) const;
 
   // Check whether we have loaded a list.
-  bool loaded() const { return is_loaded_; }
+  bool loaded() const;
 
   // Check whether the list we have loaded is empty.
-  bool empty() const { return dafsa_.empty(); }
+  bool empty() const;
 
  protected:
   friend class MediaEngagementPreloadedListTest;
@@ -115,6 +118,8 @@
   // If a list has been successfully loaded.
   bool is_loaded_ = false;
 
+  SEQUENCE_CHECKER(sequence_checker_);
+
   DISALLOW_COPY_AND_ASSIGN(MediaEngagementPreloadedList);
 };
 
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index b4a2f1db..9abb57ea 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -355,6 +355,7 @@
 
   data_deps = [
     "//testing/buildbot/filters:browser_tests_filters",
+    "//tools/media_engagement_preload:generator",
   ]
 
   data = []
diff --git a/content/renderer/cache_storage/cache_storage_dispatcher.cc b/content/renderer/cache_storage/cache_storage_dispatcher.cc
index 8fb3a23..0504423 100644
--- a/content/renderer/cache_storage/cache_storage_dispatcher.cc
+++ b/content/renderer/cache_storage/cache_storage_dispatcher.cc
@@ -42,7 +42,7 @@
 
 namespace {
 
-CacheStorageDispatcher* const kHasBeenDeleted =
+CacheStorageDispatcher* const kDeletedCacheStorageDispatcherMarker =
     reinterpret_cast<CacheStorageDispatcher*>(0x1);
 
 ServiceWorkerFetchRequest FetchRequestFromWebRequest(
@@ -200,12 +200,14 @@
   ClearCallbacksMapWithErrors(&cache_keys_callbacks_);
   ClearCallbacksMapWithErrors(&cache_batch_callbacks_);
 
-  g_cache_storage_dispatcher_tls.Pointer()->Set(kHasBeenDeleted);
+  g_cache_storage_dispatcher_tls.Pointer()->Set(
+      kDeletedCacheStorageDispatcherMarker);
 }
 
 CacheStorageDispatcher* CacheStorageDispatcher::ThreadSpecificInstance(
     ThreadSafeSender* thread_safe_sender) {
-  if (g_cache_storage_dispatcher_tls.Pointer()->Get() == kHasBeenDeleted) {
+  if (g_cache_storage_dispatcher_tls.Pointer()->Get() ==
+      kDeletedCacheStorageDispatcherMarker) {
     NOTREACHED() << "Re-instantiating TLS CacheStorageDispatcher.";
     g_cache_storage_dispatcher_tls.Pointer()->Set(nullptr);
   }
diff --git a/content/renderer/indexed_db/indexed_db_dispatcher.cc b/content/renderer/indexed_db/indexed_db_dispatcher.cc
index 3e2acce..2beba1d 100644
--- a/content/renderer/indexed_db/indexed_db_dispatcher.cc
+++ b/content/renderer/indexed_db/indexed_db_dispatcher.cc
@@ -25,7 +25,7 @@
 
 namespace {
 
-IndexedDBDispatcher* const kHasBeenDeleted =
+IndexedDBDispatcher* const kDeletedIndexedDBDispatcherMarker =
     reinterpret_cast<IndexedDBDispatcher*>(0x1);
 
 }  // unnamed namespace
@@ -39,11 +39,12 @@
   mojo_owned_callback_state_.clear();
   mojo_owned_database_callback_state_.clear();
 
-  g_idb_dispatcher_tls.Pointer()->Set(kHasBeenDeleted);
+  g_idb_dispatcher_tls.Pointer()->Set(kDeletedIndexedDBDispatcherMarker);
 }
 
 IndexedDBDispatcher* IndexedDBDispatcher::ThreadSpecificInstance() {
-  if (g_idb_dispatcher_tls.Pointer()->Get() == kHasBeenDeleted) {
+  if (g_idb_dispatcher_tls.Pointer()->Get() ==
+      kDeletedIndexedDBDispatcherMarker) {
     NOTREACHED() << "Re-instantiating TLS IndexedDBDispatcher.";
     g_idb_dispatcher_tls.Pointer()->Set(nullptr);
   }
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 99ad0c11..c7cc232 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -3029,13 +3029,6 @@
 // blink::mojom::MediaEngagementClient implementation --------------------------
 
 void RenderFrameImpl::SetHasHighMediaEngagement(const url::Origin& origin) {
-  // Set the HasHighMediaEngagement bit on |frame| if the origin matches
-  // the one we were provided.
-  if (frame_ && url::Origin(frame_->GetSecurityOrigin()) == origin) {
-    frame_->SetHasHighMediaEngagement(true);
-    return;
-  }
-
   high_media_engagement_origin_ = origin;
 }
 
diff --git a/content/renderer/service_worker/service_worker_dispatcher.cc b/content/renderer/service_worker/service_worker_dispatcher.cc
index d4ce0f10..a38b326 100644
--- a/content/renderer/service_worker/service_worker_dispatcher.cc
+++ b/content/renderer/service_worker/service_worker_dispatcher.cc
@@ -38,7 +38,8 @@
 base::LazyInstance<ThreadLocalPointer<void>>::Leaky g_dispatcher_tls =
     LAZY_INSTANCE_INITIALIZER;
 
-void* const kHasBeenDeleted = reinterpret_cast<void*>(0x1);
+void* const kDeletedServiceWorkerDispatcherMarker =
+    reinterpret_cast<void*>(0x1);
 
 }  // namespace
 
@@ -55,7 +56,7 @@
     g_dispatcher_tls.Pointer()->Set(nullptr);
     return;
   }
-  g_dispatcher_tls.Pointer()->Set(kHasBeenDeleted);
+  g_dispatcher_tls.Pointer()->Set(kDeletedServiceWorkerDispatcherMarker);
 }
 
 void ServiceWorkerDispatcher::OnMessageReceived(const IPC::Message& msg) {
@@ -76,7 +77,8 @@
 ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance(
     scoped_refptr<ThreadSafeSender> thread_safe_sender,
     scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner) {
-  if (g_dispatcher_tls.Pointer()->Get() == kHasBeenDeleted) {
+  if (g_dispatcher_tls.Pointer()->Get() ==
+      kDeletedServiceWorkerDispatcherMarker) {
     NOTREACHED() << "Re-instantiating TLS ServiceWorkerDispatcher.";
     g_dispatcher_tls.Pointer()->Set(nullptr);
   }
@@ -92,7 +94,8 @@
 }
 
 ServiceWorkerDispatcher* ServiceWorkerDispatcher::GetThreadSpecificInstance() {
-  if (g_dispatcher_tls.Pointer()->Get() == kHasBeenDeleted)
+  if (g_dispatcher_tls.Pointer()->Get() ==
+      kDeletedServiceWorkerDispatcherMarker)
     return nullptr;
   return static_cast<ServiceWorkerDispatcher*>(
       g_dispatcher_tls.Pointer()->Get());
diff --git a/content/renderer/service_worker/web_service_worker_impl.cc b/content/renderer/service_worker/web_service_worker_impl.cc
index 0f7907b..4b6b93f3 100644
--- a/content/renderer/service_worker/web_service_worker_impl.cc
+++ b/content/renderer/service_worker/web_service_worker_impl.cc
@@ -26,18 +26,19 @@
 
 namespace {
 
-class HandleImpl : public blink::WebServiceWorker::Handle {
+class ServiceWorkerHandleImpl : public blink::WebServiceWorker::Handle {
  public:
-  explicit HandleImpl(const scoped_refptr<WebServiceWorkerImpl>& worker)
+  explicit ServiceWorkerHandleImpl(
+      const scoped_refptr<WebServiceWorkerImpl>& worker)
       : worker_(worker) {}
-  ~HandleImpl() override {}
+  ~ServiceWorkerHandleImpl() override {}
 
   blink::WebServiceWorker* ServiceWorker() override { return worker_.get(); }
 
  private:
   scoped_refptr<WebServiceWorkerImpl> worker_;
 
-  DISALLOW_COPY_AND_ASSIGN(HandleImpl);
+  DISALLOW_COPY_AND_ASSIGN(ServiceWorkerHandleImpl);
 };
 
 }  // namespace
@@ -105,7 +106,7 @@
     const scoped_refptr<WebServiceWorkerImpl>& worker) {
   if (!worker)
     return nullptr;
-  return std::make_unique<HandleImpl>(worker);
+  return std::make_unique<ServiceWorkerHandleImpl>(worker);
 }
 
 WebServiceWorkerImpl::~WebServiceWorkerImpl() {
diff --git a/content/renderer/service_worker/web_service_worker_registration_impl.cc b/content/renderer/service_worker/web_service_worker_registration_impl.cc
index bf5efd7..55b1cb704 100644
--- a/content/renderer/service_worker/web_service_worker_registration_impl.cc
+++ b/content/renderer/service_worker/web_service_worker_registration_impl.cc
@@ -24,12 +24,13 @@
 
 namespace {
 
-class HandleImpl : public blink::WebServiceWorkerRegistration::Handle {
+class ServiceWorkerRegistrationHandleImpl
+    : public blink::WebServiceWorkerRegistration::Handle {
  public:
-  explicit HandleImpl(
+  explicit ServiceWorkerRegistrationHandleImpl(
       scoped_refptr<WebServiceWorkerRegistrationImpl> registration)
       : registration_(std::move(registration)) {}
-  ~HandleImpl() override {}
+  ~ServiceWorkerRegistrationHandleImpl() override {}
 
   blink::WebServiceWorkerRegistration* Registration() override {
     return registration_.get();
@@ -38,7 +39,7 @@
  private:
   scoped_refptr<WebServiceWorkerRegistrationImpl> registration_;
 
-  DISALLOW_COPY_AND_ASSIGN(HandleImpl);
+  DISALLOW_COPY_AND_ASSIGN(ServiceWorkerRegistrationHandleImpl);
 };
 
 }  // namespace
@@ -380,7 +381,8 @@
     scoped_refptr<WebServiceWorkerRegistrationImpl> registration) {
   if (!registration)
     return nullptr;
-  return std::make_unique<HandleImpl>(std::move(registration));
+  return std::make_unique<ServiceWorkerRegistrationHandleImpl>(
+      std::move(registration));
 }
 
 // static
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm
index 2c281bb..ee8f223 100644
--- a/ios/chrome/browser/ui/browser_view_controller.mm
+++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -3295,7 +3295,8 @@
     // TODO(crbug.com/778822): This can be cleaned up when the new fullscreen
     // is enabled.
     if (IsSafeAreaCompatibleToolbarEnabled() &&
-        header.view == _toolbarCoordinator.toolbarViewController.view) {
+        header.view == _toolbarCoordinator.toolbarViewController.view &&
+        !IsIPadIdiom()) {
       self.toolbarOffsetConstraint.constant = yOrigin;
     }
     CGRect frame = [header.view frame];
diff --git a/ios/chrome/browser/ui/toolbar/clean/toolbar_view_controller.mm b/ios/chrome/browser/ui/toolbar/clean/toolbar_view_controller.mm
index c8c9b94..8460aa1 100644
--- a/ios/chrome/browser/ui/toolbar/clean/toolbar_view_controller.mm
+++ b/ios/chrome/browser/ui/toolbar/clean/toolbar_view_controller.mm
@@ -938,6 +938,7 @@
     [_locationBarView
         setContentHuggingPriority:UILayoutPriorityDefaultLow
                           forAxis:UILayoutConstraintAxisHorizontal];
+    _locationBarView.clipsToBounds = YES;
   }
   return _locationBarView;
 }
diff --git a/ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm b/ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm
index 75825ac..ca69e6a 100644
--- a/ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm
+++ b/ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm
@@ -252,6 +252,7 @@
                                         font:[MDCTypography subheadFont]
                                    textColor:textColor
                                    tintColor:tintColor];
+  _locationBarView.clipsToBounds = YES;
   _keyboardDelegate = [[ToolbarAssistiveKeyboardDelegateImpl alloc] init];
   _keyboardDelegate.dispatcher = dispatcher;
   _keyboardDelegate.omniboxTextField = _locationBarView.textField;
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc
index 5b41ef3..e207069 100644
--- a/media/base/media_switches.cc
+++ b/media/base/media_switches.cc
@@ -366,4 +366,9 @@
 const base::Feature kUseModernMediaControls{"UseModernMediaControls",
                                             base::FEATURE_DISABLED_BY_DEFAULT};
 
+// Allows Media Engagement to use preloaded data to decide whether an origin has
+// a high media engagement.
+const base::Feature kPreloadMediaEngagementData{
+    "PreloadMediaEngagementData", base::FEATURE_DISABLED_BY_DEFAULT};
+
 }  // namespace media
diff --git a/media/base/media_switches.h b/media/base/media_switches.h
index b5481ef..0586dfe 100644
--- a/media/base/media_switches.h
+++ b/media/base/media_switches.h
@@ -121,6 +121,7 @@
 MEDIA_EXPORT extern const base::Feature kNewRemotePlaybackPipeline;
 MEDIA_EXPORT extern const base::Feature kOverflowIconsForMediaControls;
 MEDIA_EXPORT extern const base::Feature kOverlayFullscreenVideo;
+MEDIA_EXPORT extern const base::Feature kPreloadMediaEngagementData;
 MEDIA_EXPORT extern const base::Feature kResumeBackgroundVideo;
 MEDIA_EXPORT extern const base::Feature kSpecCompliantCanPlayThrough;
 MEDIA_EXPORT extern const base::Feature kSupportExperimentalCdmInterface;
diff --git a/third_party/WebKit/Source/core/streams/ReadableStream.js b/third_party/WebKit/Source/core/streams/ReadableStream.js
index e23e893..02c8dc0f 100644
--- a/third_party/WebKit/Source/core/streams/ReadableStream.js
+++ b/third_party/WebKit/Source/core/streams/ReadableStream.js
@@ -427,6 +427,348 @@
     return promise;
   }
 
+  //
+  // Readable stream abstract operations
+  //
+
+  function AcquireReadableStreamDefaultReader(stream) {
+    return new ReadableStreamDefaultReader(stream);
+  }
+
+  function IsReadableStream(x) {
+    return hasOwnPropertyNoThrow(x, _controller);
+  }
+
+  function IsReadableStreamDisturbed(stream) {
+    return stream[_readableStreamBits] & DISTURBED;
+  }
+
+  function IsReadableStreamLocked(stream) {
+    return stream[_reader] !== undefined;
+  }
+
+  // Potential future optimization: use class instances for the underlying
+  // sources, so that we don't re-create
+  // closures every time.
+
+  // TODO(domenic): shouldClone argument from spec not supported yet
+  function ReadableStreamTee(stream) {
+    const reader = AcquireReadableStreamDefaultReader(stream);
+
+    let closedOrErrored = false;
+    let canceled1 = false;
+    let canceled2 = false;
+    let reason1;
+    let reason2;
+    const promise = v8.createPromise();
+
+    const branch1Stream = new ReadableStream({pull, cancel: cancel1});
+
+    const branch2Stream = new ReadableStream({pull, cancel: cancel2});
+
+    const branch1 = branch1Stream[_controller];
+    const branch2 = branch2Stream[_controller];
+
+    thenPromise(reader[_closedPromise], undefined, function(r) {
+      if (closedOrErrored === true) {
+        return;
+      }
+
+      ReadableStreamDefaultControllerError(branch1, r);
+      ReadableStreamDefaultControllerError(branch2, r);
+      closedOrErrored = true;
+    });
+
+    return [branch1Stream, branch2Stream];
+
+    function pull() {
+      return thenPromise(
+          ReadableStreamDefaultReaderRead(reader), function(result) {
+            const value = result.value;
+            const done = result.done;
+
+            if (done === true && closedOrErrored === false) {
+              if (canceled1 === false) {
+                ReadableStreamDefaultControllerClose(branch1);
+              }
+              if (canceled2 === false) {
+                ReadableStreamDefaultControllerClose(branch2);
+              }
+              closedOrErrored = true;
+            }
+
+            if (closedOrErrored === true) {
+              return;
+            }
+
+            if (canceled1 === false) {
+              ReadableStreamDefaultControllerEnqueue(branch1, value);
+            }
+
+            if (canceled2 === false) {
+              ReadableStreamDefaultControllerEnqueue(branch2, value);
+            }
+          });
+    }
+
+    function cancel1(reason) {
+      canceled1 = true;
+      reason1 = reason;
+
+      if (canceled2 === true) {
+        const compositeReason = [reason1, reason2];
+        const cancelResult = ReadableStreamCancel(stream, compositeReason);
+        resolvePromise(promise, cancelResult);
+      }
+
+      return promise;
+    }
+
+    function cancel2(reason) {
+      canceled2 = true;
+      reason2 = reason;
+
+      if (canceled1 === true) {
+        const compositeReason = [reason1, reason2];
+        const cancelResult = ReadableStreamCancel(stream, compositeReason);
+        resolvePromise(promise, cancelResult);
+      }
+
+      return promise;
+    }
+  }
+
+  //
+  // Abstract Operations Used By Controllers
+  //
+
+  function ReadableStreamAddReadRequest(stream) {
+    const promise = v8.createPromise();
+    stream[_reader][_readRequests].push(promise);
+    return promise;
+  }
+
+  function ReadableStreamCancel(stream, reason) {
+    stream[_readableStreamBits] |= DISTURBED;
+
+    const state = ReadableStreamGetState(stream);
+    if (state === STATE_CLOSED) {
+      return Promise_resolve(undefined);
+    }
+    if (state === STATE_ERRORED) {
+      return Promise_reject(stream[_storedError]);
+    }
+
+    ReadableStreamClose(stream);
+
+    const sourceCancelPromise =
+          ReadableStreamDefaultControllerCancel(stream[_controller], reason);
+    return thenPromise(sourceCancelPromise, () => undefined);
+  }
+
+  function ReadableStreamClose(stream) {
+    ReadableStreamSetState(stream, STATE_CLOSED);
+
+    const reader = stream[_reader];
+    if (reader === undefined) {
+      return undefined;
+    }
+
+    if (IsReadableStreamDefaultReader(reader) === true) {
+      reader[_readRequests].forEach(
+          request =>
+            resolvePromise(request, CreateIterResultObject(undefined, true)));
+      reader[_readRequests] = new binding.SimpleQueue();
+    }
+
+    resolvePromise(reader[_closedPromise], undefined);
+  }
+
+  function ReadableStreamError(stream, e) {
+    stream[_storedError] = e;
+    ReadableStreamSetState(stream, STATE_ERRORED);
+
+    const reader = stream[_reader];
+    if (reader === undefined) {
+      return undefined;
+    }
+
+    if (IsReadableStreamDefaultReader(reader) === true) {
+      reader[_readRequests].forEach(request => rejectPromise(request, e));
+      reader[_readRequests] = new binding.SimpleQueue();
+    }
+
+    rejectPromise(reader[_closedPromise], e);
+    markPromiseAsHandled(reader[_closedPromise]);
+  }
+
+  function ReadableStreamFulfillReadRequest(stream, chunk, done) {
+    const readRequest = stream[_reader][_readRequests].shift();
+    resolvePromise(readRequest, CreateIterResultObject(chunk, done));
+  }
+
+  function ReadableStreamGetNumReadRequests(stream) {
+    const reader = stream[_reader];
+    const readRequests = reader[_readRequests];
+    return readRequests.length;
+  }
+
+  //
+  // Class ReadableStreamDefaultReader
+  //
+
+  class ReadableStreamDefaultReader {
+    constructor(stream) {
+      if (IsReadableStream(stream) === false) {
+        throw new TypeError(errReaderConstructorBadArgument);
+      }
+      if (IsReadableStreamLocked(stream) === true) {
+        throw new TypeError(errReaderConstructorStreamAlreadyLocked);
+      }
+
+      ReadableStreamReaderGenericInitialize(this, stream);
+
+      this[_readRequests] = new binding.SimpleQueue();
+    }
+
+    get closed() {
+      if (IsReadableStreamDefaultReader(this) === false) {
+        return Promise_reject(new TypeError(streamErrors.illegalInvocation));
+      }
+
+      return this[_closedPromise];
+    }
+
+    cancel(reason) {
+      if (IsReadableStreamDefaultReader(this) === false) {
+        return Promise_reject(new TypeError(streamErrors.illegalInvocation));
+      }
+
+      const stream = this[_ownerReadableStream];
+      if (stream === undefined) {
+        return Promise_reject(new TypeError(errCancelReleasedReader));
+      }
+
+      return ReadableStreamReaderGenericCancel(this, reason);
+    }
+
+    read() {
+      if (IsReadableStreamDefaultReader(this) === false) {
+        return Promise_reject(new TypeError(streamErrors.illegalInvocation));
+      }
+
+      if (this[_ownerReadableStream] === undefined) {
+        return Promise_reject(new TypeError(errReadReleasedReader));
+      }
+
+      return ReadableStreamDefaultReaderRead(this);
+    }
+
+    releaseLock() {
+      if (IsReadableStreamDefaultReader(this) === false) {
+        throw new TypeError(streamErrors.illegalInvocation);
+      }
+
+      const stream = this[_ownerReadableStream];
+      if (stream === undefined) {
+        return undefined;
+      }
+
+      if (this[_readRequests].length > 0) {
+        throw new TypeError(errReleaseReaderWithPendingRead);
+      }
+
+      ReadableStreamReaderGenericRelease(this);
+    }
+  }
+
+  //
+  //  Readable Stream Reader Abstract Operations
+  //
+
+  function IsReadableStreamDefaultReader(x) {
+    return hasOwnPropertyNoThrow(x, _readRequests);
+  }
+
+  function ReadableStreamReaderGenericCancel(reader, reason) {
+    return ReadableStreamCancel(reader[_ownerReadableStream], reason);
+  }
+
+  function ReadableStreamReaderGenericInitialize(reader, stream) {
+    // TODO(yhirano): Remove this when we don't need hasPendingActivity in
+    // blink::UnderlyingSourceBase.
+    const controller = stream[_controller];
+    if (controller[_readableStreamDefaultControllerBits] &
+        EXTERNALLY_CONTROLLED) {
+      // The stream is created with an external controller (i.e. made in
+      // Blink).
+      const underlyingSource = controller[_underlyingSource];
+      callFunction(underlyingSource.notifyLockAcquired, underlyingSource);
+    }
+
+    reader[_ownerReadableStream] = stream;
+    stream[_reader] = reader;
+
+    switch (ReadableStreamGetState(stream)) {
+      case STATE_READABLE:
+        reader[_closedPromise] = v8.createPromise();
+        break;
+      case STATE_CLOSED:
+        reader[_closedPromise] = Promise_resolve(undefined);
+        break;
+      case STATE_ERRORED:
+        reader[_closedPromise] = Promise_reject(stream[_storedError]);
+        markPromiseAsHandled(reader[_closedPromise]);
+        break;
+    }
+  }
+
+  function ReadableStreamReaderGenericRelease(reader) {
+    // TODO(yhirano): Remove this when we don't need hasPendingActivity in
+    // blink::UnderlyingSourceBase.
+    const controller = reader[_ownerReadableStream][_controller];
+    if (controller[_readableStreamDefaultControllerBits] &
+        EXTERNALLY_CONTROLLED) {
+      // The stream is created with an external controller (i.e. made in
+      // Blink).
+      const underlyingSource = controller[_underlyingSource];
+      callFunction(underlyingSource.notifyLockReleased, underlyingSource);
+    }
+
+    if (ReadableStreamGetState(reader[_ownerReadableStream]) ===
+        STATE_READABLE) {
+      rejectPromise(
+          reader[_closedPromise],
+          new TypeError(errReleasedReaderClosedPromise));
+    } else {
+      reader[_closedPromise] =
+          Promise_reject(new TypeError(errReleasedReaderClosedPromise));
+    }
+    markPromiseAsHandled(reader[_closedPromise]);
+
+    reader[_ownerReadableStream][_reader] = undefined;
+    reader[_ownerReadableStream] = undefined;
+  }
+
+  function ReadableStreamDefaultReaderRead(reader) {
+    const stream = reader[_ownerReadableStream];
+    stream[_readableStreamBits] |= DISTURBED;
+
+    if (ReadableStreamGetState(stream) === STATE_CLOSED) {
+      return Promise_resolve(CreateIterResultObject(undefined, true));
+    }
+
+    if (ReadableStreamGetState(stream) === STATE_ERRORED) {
+      return Promise_reject(stream[_storedError]);
+    }
+
+    return ReadableStreamDefaultControllerPull(stream[_controller]);
+  }
+
+  //
+  // Class ReadableStreamDefaultController
+  //
+
   class ReadableStreamDefaultController {
     constructor(
         stream, underlyingSource, size, highWaterMark, isExternallyControlled) {
@@ -534,6 +876,7 @@
     }
   }
 
+  // [[CancelSteps]] in the standard.
   function ReadableStreamDefaultControllerCancel(controller, reason) {
     controller[_queue] = new binding.SimpleQueue();
 
@@ -542,6 +885,7 @@
         underlyingSource, 'cancel', reason, 'underlyingSource.cancel');
   }
 
+  // [[PullSteps]] in the standard.
   function ReadableStreamDefaultControllerPull(controller) {
     const stream = controller[_controlledReadableStream];
 
@@ -564,340 +908,14 @@
     return pendingPromise;
   }
 
-  function ReadableStreamAddReadRequest(stream) {
-    const promise = v8.createPromise();
-    stream[_reader][_readRequests].push(promise);
-    return promise;
-  }
-
-  class ReadableStreamDefaultReader {
-    constructor(stream) {
-      if (IsReadableStream(stream) === false) {
-        throw new TypeError(errReaderConstructorBadArgument);
-      }
-      if (IsReadableStreamLocked(stream) === true) {
-        throw new TypeError(errReaderConstructorStreamAlreadyLocked);
-      }
-
-      ReadableStreamReaderGenericInitialize(this, stream);
-
-      this[_readRequests] = new binding.SimpleQueue();
-    }
-
-    get closed() {
-      if (IsReadableStreamDefaultReader(this) === false) {
-        return Promise_reject(new TypeError(streamErrors.illegalInvocation));
-      }
-
-      return this[_closedPromise];
-    }
-
-    cancel(reason) {
-      if (IsReadableStreamDefaultReader(this) === false) {
-        return Promise_reject(new TypeError(streamErrors.illegalInvocation));
-      }
-
-      const stream = this[_ownerReadableStream];
-      if (stream === undefined) {
-        return Promise_reject(new TypeError(errCancelReleasedReader));
-      }
-
-      return ReadableStreamReaderGenericCancel(this, reason);
-    }
-
-    read() {
-      if (IsReadableStreamDefaultReader(this) === false) {
-        return Promise_reject(new TypeError(streamErrors.illegalInvocation));
-      }
-
-      if (this[_ownerReadableStream] === undefined) {
-        return Promise_reject(new TypeError(errReadReleasedReader));
-      }
-
-      return ReadableStreamDefaultReaderRead(this);
-    }
-
-    releaseLock() {
-      if (IsReadableStreamDefaultReader(this) === false) {
-        throw new TypeError(streamErrors.illegalInvocation);
-      }
-
-      const stream = this[_ownerReadableStream];
-      if (stream === undefined) {
-        return undefined;
-      }
-
-      if (this[_readRequests].length > 0) {
-        throw new TypeError(errReleaseReaderWithPendingRead);
-      }
-
-      ReadableStreamReaderGenericRelease(this);
-    }
-  }
-
-  function ReadableStreamReaderGenericCancel(reader, reason) {
-    return ReadableStreamCancel(reader[_ownerReadableStream], reason);
-  }
-
   //
-  // Readable stream abstract operations
+  // Readable Stream Default Controller Abstract Operations
   //
 
-  function AcquireReadableStreamDefaultReader(stream) {
-    return new ReadableStreamDefaultReader(stream);
-  }
-
-  function ReadableStreamCancel(stream, reason) {
-    stream[_readableStreamBits] |= DISTURBED;
-
-    const state = ReadableStreamGetState(stream);
-    if (state === STATE_CLOSED) {
-      return Promise_resolve(undefined);
-    }
-    if (state === STATE_ERRORED) {
-      return Promise_reject(stream[_storedError]);
-    }
-
-    ReadableStreamClose(stream);
-
-    const sourceCancelPromise =
-          ReadableStreamDefaultControllerCancel(stream[_controller], reason);
-    return thenPromise(sourceCancelPromise, () => undefined);
-  }
-
-  function ReadableStreamDefaultControllerClose(controller) {
-    const stream = controller[_controlledReadableStream];
-
-    controller[_readableStreamDefaultControllerBits] |= CLOSE_REQUESTED;
-
-    if (controller[_queue].length === 0) {
-      ReadableStreamClose(stream);
-    }
-  }
-
-  function ReadableStreamFulfillReadRequest(stream, chunk, done) {
-    const readRequest = stream[_reader][_readRequests].shift();
-    resolvePromise(readRequest, CreateIterResultObject(chunk, done));
-  }
-
-  function ReadableStreamDefaultControllerEnqueue(controller, chunk) {
-    const stream = controller[_controlledReadableStream];
-
-    if (IsReadableStreamLocked(stream) === true &&
-        ReadableStreamGetNumReadRequests(stream) > 0) {
-      ReadableStreamFulfillReadRequest(stream, chunk, false);
-    } else {
-      let chunkSize = 1;
-
-      const strategySize = controller[_strategySize];
-      if (strategySize !== undefined) {
-        try {
-          chunkSize = strategySize(chunk);
-        } catch (chunkSizeE) {
-          if (ReadableStreamGetState(stream) === STATE_READABLE) {
-            ReadableStreamDefaultControllerError(controller, chunkSizeE);
-          }
-          throw chunkSizeE;
-        }
-      }
-
-      try {
-        EnqueueValueWithSize(controller, chunk, chunkSize);
-      } catch (enqueueE) {
-        if (ReadableStreamGetState(stream) === STATE_READABLE) {
-          ReadableStreamDefaultControllerError(controller, enqueueE);
-        }
-        throw enqueueE;
-      }
-    }
-
-    ReadableStreamDefaultControllerCallPullIfNeeded(controller);
-  }
-
-  function ReadableStreamGetState(stream) {
-    return (stream[_readableStreamBits] & STATE_MASK) >> STATE_BITS_OFFSET;
-  }
-
-  function ReadableStreamSetState(stream, state) {
-    stream[_readableStreamBits] = (stream[_readableStreamBits] & ~STATE_MASK) |
-        (state << STATE_BITS_OFFSET);
-  }
-
-  function ReadableStreamDefaultControllerError(controller, e) {
-    controller[_queue] = new binding.SimpleQueue();
-    const stream = controller[_controlledReadableStream];
-    ReadableStreamError(stream, e);
-  }
-
-  function ReadableStreamError(stream, e) {
-    stream[_storedError] = e;
-    ReadableStreamSetState(stream, STATE_ERRORED);
-
-    const reader = stream[_reader];
-    if (reader === undefined) {
-      return undefined;
-    }
-
-    if (IsReadableStreamDefaultReader(reader) === true) {
-      reader[_readRequests].forEach(request => rejectPromise(request, e));
-      reader[_readRequests] = new binding.SimpleQueue();
-    }
-
-    rejectPromise(reader[_closedPromise], e);
-    markPromiseAsHandled(reader[_closedPromise]);
-  }
-
-  function ReadableStreamClose(stream) {
-    ReadableStreamSetState(stream, STATE_CLOSED);
-
-    const reader = stream[_reader];
-    if (reader === undefined) {
-      return undefined;
-    }
-
-    if (IsReadableStreamDefaultReader(reader) === true) {
-      reader[_readRequests].forEach(
-          request =>
-            resolvePromise(request, CreateIterResultObject(undefined, true)));
-      reader[_readRequests] = new binding.SimpleQueue();
-    }
-
-    resolvePromise(reader[_closedPromise], undefined);
-  }
-
-  function ReadableStreamDefaultControllerGetDesiredSize(controller) {
-    return controller[_strategyHWM] - controller[_queueTotalSize];
-  }
-
-  function ReadableStreamDefaultControllerHasBackpressure(controller) {
-    return !ReadableStreamDefaultControllerShouldCallPull(controller);
-  }
-
-  function ReadableStreamDefaultControllerCanCloseOrEnqueue(controller) {
-    if (controller[_readableStreamDefaultControllerBits] & CLOSE_REQUESTED) {
-      return false;
-    }
-    const state = ReadableStreamGetState(controller[_controlledReadableStream]);
-    return state === STATE_READABLE;
-  }
-
-  function IsReadableStream(x) {
-    return hasOwnPropertyNoThrow(x, _controller);
-  }
-
-  function IsReadableStreamDisturbed(stream) {
-    return stream[_readableStreamBits] & DISTURBED;
-  }
-
-  function IsReadableStreamLocked(stream) {
-    return stream[_reader] !== undefined;
-  }
-
   function IsReadableStreamDefaultController(x) {
     return hasOwnPropertyNoThrow(x, _controlledReadableStream);
   }
 
-  function IsReadableStreamDefaultReader(x) {
-    return hasOwnPropertyNoThrow(x, _readRequests);
-  }
-
-  function IsReadableStreamReadable(stream) {
-    return ReadableStreamGetState(stream) === STATE_READABLE;
-  }
-
-  function IsReadableStreamClosed(stream) {
-    return ReadableStreamGetState(stream) === STATE_CLOSED;
-  }
-
-  function IsReadableStreamErrored(stream) {
-    return ReadableStreamGetState(stream) === STATE_ERRORED;
-  }
-
-  // Used internally by enqueue() and also by TransformStream.
-  function getReadableStreamEnqueueError(stream, controller) {
-    if (controller[_readableStreamDefaultControllerBits] & CLOSE_REQUESTED) {
-      return new TypeError(errEnqueueCloseRequestedStream);
-    }
-
-    const state = ReadableStreamGetState(stream);
-    if (state === STATE_ERRORED) {
-      return new TypeError(errEnqueueErroredStream);
-    }
-    // assert(state === STATE_CLOSED, 'state is "closed"');
-    return new TypeError(errEnqueueClosedStream);
-  }
-
-  function ReadableStreamReaderGenericInitialize(reader, stream) {
-    // TODO(yhirano): Remove this when we don't need hasPendingActivity in
-    // blink::UnderlyingSourceBase.
-    const controller = stream[_controller];
-    if (controller[_readableStreamDefaultControllerBits] &
-        EXTERNALLY_CONTROLLED) {
-      // The stream is created with an external controller (i.e. made in
-      // Blink).
-      const underlyingSource = controller[_underlyingSource];
-      callFunction(underlyingSource.notifyLockAcquired, underlyingSource);
-    }
-
-    reader[_ownerReadableStream] = stream;
-    stream[_reader] = reader;
-
-    switch (ReadableStreamGetState(stream)) {
-      case STATE_READABLE:
-        reader[_closedPromise] = v8.createPromise();
-        break;
-      case STATE_CLOSED:
-        reader[_closedPromise] = Promise_resolve(undefined);
-        break;
-      case STATE_ERRORED:
-        reader[_closedPromise] = Promise_reject(stream[_storedError]);
-        markPromiseAsHandled(reader[_closedPromise]);
-        break;
-    }
-  }
-
-  function ReadableStreamReaderGenericRelease(reader) {
-    // TODO(yhirano): Remove this when we don't need hasPendingActivity in
-    // blink::UnderlyingSourceBase.
-    const controller = reader[_ownerReadableStream][_controller];
-    if (controller[_readableStreamDefaultControllerBits] &
-        EXTERNALLY_CONTROLLED) {
-      // The stream is created with an external controller (i.e. made in
-      // Blink).
-      const underlyingSource = controller[_underlyingSource];
-      callFunction(underlyingSource.notifyLockReleased, underlyingSource);
-    }
-
-    if (ReadableStreamGetState(reader[_ownerReadableStream]) ===
-        STATE_READABLE) {
-      rejectPromise(
-          reader[_closedPromise],
-          new TypeError(errReleasedReaderClosedPromise));
-    } else {
-      reader[_closedPromise] =
-          Promise_reject(new TypeError(errReleasedReaderClosedPromise));
-    }
-    markPromiseAsHandled(reader[_closedPromise]);
-
-    reader[_ownerReadableStream][_reader] = undefined;
-    reader[_ownerReadableStream] = undefined;
-  }
-
-  function ReadableStreamDefaultReaderRead(reader) {
-    const stream = reader[_ownerReadableStream];
-    stream[_readableStreamBits] |= DISTURBED;
-
-    if (ReadableStreamGetState(stream) === STATE_CLOSED) {
-      return Promise_resolve(CreateIterResultObject(undefined, true));
-    }
-
-    if (ReadableStreamGetState(stream) === STATE_ERRORED) {
-      return Promise_reject(stream[_storedError]);
-    }
-
-    return ReadableStreamDefaultControllerPull(stream[_controller]);
-  }
-
   function ReadableStreamDefaultControllerCallPullIfNeeded(controller) {
     const shouldPull =
           ReadableStreamDefaultControllerShouldCallPull(controller);
@@ -964,101 +982,113 @@
     return false;
   }
 
-  function ReadableStreamGetNumReadRequests(stream) {
-    const reader = stream[_reader];
-    const readRequests = reader[_readRequests];
-    return readRequests.length;
+  function ReadableStreamDefaultControllerClose(controller) {
+    const stream = controller[_controlledReadableStream];
+
+    controller[_readableStreamDefaultControllerBits] |= CLOSE_REQUESTED;
+
+    if (controller[_queue].length === 0) {
+      ReadableStreamClose(stream);
+    }
   }
 
-  // Potential future optimization: use class instances for the underlying
-  // sources, so that we don't re-create
-  // closures every time.
+  function ReadableStreamDefaultControllerEnqueue(controller, chunk) {
+    const stream = controller[_controlledReadableStream];
 
-  // TODO(domenic): shouldClone argument from spec not supported yet
-  function ReadableStreamTee(stream) {
-    const reader = AcquireReadableStreamDefaultReader(stream);
+    if (IsReadableStreamLocked(stream) === true &&
+        ReadableStreamGetNumReadRequests(stream) > 0) {
+      ReadableStreamFulfillReadRequest(stream, chunk, false);
+    } else {
+      let chunkSize = 1;
 
-    let closedOrErrored = false;
-    let canceled1 = false;
-    let canceled2 = false;
-    let reason1;
-    let reason2;
-    const promise = v8.createPromise();
-
-    const branch1Stream = new ReadableStream({pull, cancel: cancel1});
-
-    const branch2Stream = new ReadableStream({pull, cancel: cancel2});
-
-    const branch1 = branch1Stream[_controller];
-    const branch2 = branch2Stream[_controller];
-
-    thenPromise(reader[_closedPromise], undefined, function(r) {
-      if (closedOrErrored === true) {
-        return;
+      const strategySize = controller[_strategySize];
+      if (strategySize !== undefined) {
+        try {
+          chunkSize = strategySize(chunk);
+        } catch (chunkSizeE) {
+          if (ReadableStreamGetState(stream) === STATE_READABLE) {
+            ReadableStreamDefaultControllerError(controller, chunkSizeE);
+          }
+          throw chunkSizeE;
+        }
       }
 
-      ReadableStreamDefaultControllerError(branch1, r);
-      ReadableStreamDefaultControllerError(branch2, r);
-      closedOrErrored = true;
-    });
-
-    return [branch1Stream, branch2Stream];
-
-    function pull() {
-      return thenPromise(
-          ReadableStreamDefaultReaderRead(reader), function(result) {
-            const value = result.value;
-            const done = result.done;
-
-            if (done === true && closedOrErrored === false) {
-              if (canceled1 === false) {
-                ReadableStreamDefaultControllerClose(branch1);
-              }
-              if (canceled2 === false) {
-                ReadableStreamDefaultControllerClose(branch2);
-              }
-              closedOrErrored = true;
-            }
-
-            if (closedOrErrored === true) {
-              return;
-            }
-
-            if (canceled1 === false) {
-              ReadableStreamDefaultControllerEnqueue(branch1, value);
-            }
-
-            if (canceled2 === false) {
-              ReadableStreamDefaultControllerEnqueue(branch2, value);
-            }
-          });
-    }
-
-    function cancel1(reason) {
-      canceled1 = true;
-      reason1 = reason;
-
-      if (canceled2 === true) {
-        const compositeReason = [reason1, reason2];
-        const cancelResult = ReadableStreamCancel(stream, compositeReason);
-        resolvePromise(promise, cancelResult);
+      try {
+        EnqueueValueWithSize(controller, chunk, chunkSize);
+      } catch (enqueueE) {
+        if (ReadableStreamGetState(stream) === STATE_READABLE) {
+          ReadableStreamDefaultControllerError(controller, enqueueE);
+        }
+        throw enqueueE;
       }
-
-      return promise;
     }
 
-    function cancel2(reason) {
-      canceled2 = true;
-      reason2 = reason;
+    ReadableStreamDefaultControllerCallPullIfNeeded(controller);
+  }
 
-      if (canceled1 === true) {
-        const compositeReason = [reason1, reason2];
-        const cancelResult = ReadableStreamCancel(stream, compositeReason);
-        resolvePromise(promise, cancelResult);
-      }
+  function ReadableStreamDefaultControllerError(controller, e) {
+    controller[_queue] = new binding.SimpleQueue();
+    const stream = controller[_controlledReadableStream];
+    ReadableStreamError(stream, e);
+  }
 
-      return promise;
+  function ReadableStreamDefaultControllerGetDesiredSize(controller) {
+    return controller[_strategyHWM] - controller[_queueTotalSize];
+  }
+
+  function ReadableStreamDefaultControllerHasBackpressure(controller) {
+    return !ReadableStreamDefaultControllerShouldCallPull(controller);
+  }
+
+  function ReadableStreamDefaultControllerCanCloseOrEnqueue(controller) {
+    if (controller[_readableStreamDefaultControllerBits] & CLOSE_REQUESTED) {
+      return false;
     }
+    const state = ReadableStreamGetState(controller[_controlledReadableStream]);
+    return state === STATE_READABLE;
+  }
+
+  //
+  // Internal functions. Not part of the standard.
+  //
+
+  function ReadableStreamGetState(stream) {
+    return (stream[_readableStreamBits] & STATE_MASK) >> STATE_BITS_OFFSET;
+  }
+
+  function ReadableStreamSetState(stream, state) {
+    stream[_readableStreamBits] = (stream[_readableStreamBits] & ~STATE_MASK) |
+        (state << STATE_BITS_OFFSET);
+  }
+
+  //
+  // Functions exported for use by TransformStream. Not part of the standard.
+  //
+
+  function IsReadableStreamReadable(stream) {
+    return ReadableStreamGetState(stream) === STATE_READABLE;
+  }
+
+  function IsReadableStreamClosed(stream) {
+    return ReadableStreamGetState(stream) === STATE_CLOSED;
+  }
+
+  function IsReadableStreamErrored(stream) {
+    return ReadableStreamGetState(stream) === STATE_ERRORED;
+  }
+
+  // Used internally by enqueue() and also by TransformStream.
+  function getReadableStreamEnqueueError(stream, controller) {
+    if (controller[_readableStreamDefaultControllerBits] & CLOSE_REQUESTED) {
+      return new TypeError(errEnqueueCloseRequestedStream);
+    }
+
+    const state = ReadableStreamGetState(stream);
+    if (state === STATE_ERRORED) {
+      return new TypeError(errEnqueueErroredStream);
+    }
+    // assert(state === STATE_CLOSED, 'state is "closed"');
+    return new TypeError(errEnqueueClosedStream);
   }
 
   //
diff --git a/third_party/WebKit/Source/platform/exported/WebSecurityOrigin.cpp b/third_party/WebKit/Source/platform/exported/WebSecurityOrigin.cpp
index b8120eaa..32a666f 100644
--- a/third_party/WebKit/Source/platform/exported/WebSecurityOrigin.cpp
+++ b/third_party/WebKit/Source/platform/exported/WebSecurityOrigin.cpp
@@ -45,15 +45,6 @@
   return WebSecurityOrigin(SecurityOrigin::Create(url));
 }
 
-WebSecurityOrigin WebSecurityOrigin::CreateFromTupleWithSuborigin(
-    const WebString& protocol,
-    const WebString& host,
-    int port,
-    const WebString& suborigin) {
-  return WebSecurityOrigin(
-      SecurityOrigin::Create(protocol, host, port, suborigin));
-}
-
 WebSecurityOrigin WebSecurityOrigin::CreateUnique() {
   return WebSecurityOrigin(SecurityOrigin::CreateUnique());
 }
diff --git a/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.cpp b/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.cpp
index 90d25f8..33e4f70b 100644
--- a/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.cpp
+++ b/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.cpp
@@ -28,7 +28,9 @@
 
 #include "platform/weborigin/SecurityOrigin.h"
 
+#include <stdint.h>
 #include <memory>
+
 #include "net/base/url_util.h"
 #include "platform/runtime_enabled_features.h"
 #include "platform/weborigin/KURL.h"
@@ -48,8 +50,7 @@
 
 namespace blink {
 
-const int kInvalidPort = 0;
-const int kMaxAllowedPort = 65535;
+const uint16_t kInvalidPort = 0;
 
 static URLSecurityOriginMap* g_url_origin_map = nullptr;
 
@@ -535,10 +536,7 @@
 
 scoped_refptr<SecurityOrigin> SecurityOrigin::Create(const String& protocol,
                                                      const String& host,
-                                                     int port) {
-  if (port < 0 || port > kMaxAllowedPort)
-    return CreateUnique();
-
+                                                     uint16_t port) {
   DCHECK_EQ(host, DecodeURLEscapeSequences(host));
 
   String port_part = port ? ":" + String::Number(port) : String();
@@ -547,7 +545,7 @@
 
 scoped_refptr<SecurityOrigin> SecurityOrigin::Create(const String& protocol,
                                                      const String& host,
-                                                     int port,
+                                                     uint16_t port,
                                                      const String& suborigin) {
   scoped_refptr<SecurityOrigin> origin = Create(protocol, host, port);
   if (!suborigin.IsEmpty())
diff --git a/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.h b/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.h
index 6dbe401..685e5fec 100644
--- a/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.h
+++ b/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.h
@@ -29,7 +29,9 @@
 #ifndef SecurityOrigin_h
 #define SecurityOrigin_h
 
+#include <stdint.h>
 #include <memory>
+
 #include "base/gtest_prod_util.h"
 #include "platform/PlatformExport.h"
 #include "platform/weborigin/Suborigin.h"
@@ -53,10 +55,10 @@
   static scoped_refptr<SecurityOrigin> CreateFromString(const String&);
   static scoped_refptr<SecurityOrigin> Create(const String& protocol,
                                               const String& host,
-                                              int port);
+                                              uint16_t port);
   static scoped_refptr<SecurityOrigin> Create(const String& protocol,
                                               const String& host,
-                                              int port,
+                                              uint16_t port,
                                               const String& suborigin);
   static scoped_refptr<SecurityOrigin> CreateFromUrlOrigin(const url::Origin&);
   url::Origin ToUrlOrigin() const;
@@ -92,10 +94,10 @@
 
   // Returns 0 if the effective port of this origin is the default for its
   // scheme.
-  unsigned short Port() const { return port_; }
+  uint16_t Port() const { return port_; }
   // Returns the effective port, even if it is the default port for the
   // scheme (e.g. "http" => 80).
-  unsigned short EffectivePort() const { return effective_port_; }
+  uint16_t EffectivePort() const { return effective_port_; }
 
   // Returns true if a given URL is secure, based either directly on its
   // own protocol, or, when relevant, on the protocol of its "inner URL"
@@ -313,8 +315,8 @@
   String host_;
   String domain_;
   Suborigin suborigin_;
-  unsigned short port_;
-  unsigned short effective_port_;
+  uint16_t port_;
+  uint16_t effective_port_;
   const bool is_unique_;
   bool universal_access_;
   bool domain_was_set_in_dom_;
diff --git a/third_party/WebKit/Source/platform/weborigin/SecurityOriginTest.cpp b/third_party/WebKit/Source/platform/weborigin/SecurityOriginTest.cpp
index d007dd2..aa1b679 100644
--- a/third_party/WebKit/Source/platform/weborigin/SecurityOriginTest.cpp
+++ b/third_party/WebKit/Source/platform/weborigin/SecurityOriginTest.cpp
@@ -30,6 +30,8 @@
 
 #include "platform/weborigin/SecurityOrigin.h"
 
+#include <stdint.h>
+
 #include "platform/blob/BlobURL.h"
 #include "platform/testing/RuntimeEnabledFeaturesTestHelpers.h"
 #include "platform/weborigin/KURL.h"
@@ -43,7 +45,7 @@
 
 namespace blink {
 
-const int kMaxAllowedPort = 65535;
+const uint16_t kMaxAllowedPort = UINT16_MAX;
 
 class SecurityOriginTest : public ::testing::Test {
  public:
@@ -53,19 +55,8 @@
   }
 };
 
-TEST_F(SecurityOriginTest, InvalidPortsCreateUniqueOrigins) {
-  int ports[] = {-100, -1, kMaxAllowedPort + 1, 1000000};
-
-  for (size_t i = 0; i < WTF_ARRAY_LENGTH(ports); ++i) {
-    scoped_refptr<const SecurityOrigin> origin =
-        SecurityOrigin::Create("http", "example.com", ports[i]);
-    EXPECT_TRUE(origin->IsUnique())
-        << "Port " << ports[i] << " should have generated a unique origin.";
-  }
-}
-
 TEST_F(SecurityOriginTest, ValidPortsCreateNonUniqueOrigins) {
-  int ports[] = {0, 80, 443, 5000, kMaxAllowedPort};
+  uint16_t ports[] = {0, 80, 443, 5000, kMaxAllowedPort};
 
   for (size_t i = 0; i < WTF_ARRAY_LENGTH(ports); ++i) {
     scoped_refptr<const SecurityOrigin> origin =
@@ -436,7 +427,7 @@
   struct TestCase {
     const char* scheme;
     const char* host;
-    unsigned short port;
+    uint16_t port;
     const char* origin;
   } cases[] = {
       {"http", "example.com", 80, "http://example.com"},
@@ -561,7 +552,7 @@
     const char* const url;
     const char* const scheme;
     const char* const host;
-    unsigned short port;
+    uint16_t port;
   } cases[] = {
       // IP Addresses
       {"http://192.168.9.1/", "http", "192.168.9.1", 80},
diff --git a/third_party/WebKit/public/platform/WebSecurityOrigin.h b/third_party/WebKit/public/platform/WebSecurityOrigin.h
index 891a5a6..7307a78 100644
--- a/third_party/WebKit/public/platform/WebSecurityOrigin.h
+++ b/third_party/WebKit/public/platform/WebSecurityOrigin.h
@@ -124,14 +124,6 @@
 #endif
 
  private:
-  // Present only to facilitate conversion from 'url::Origin'; this constructor
-  // shouldn't be used anywhere else.
-  BLINK_PLATFORM_EXPORT static WebSecurityOrigin CreateFromTupleWithSuborigin(
-      const WebString& protocol,
-      const WebString& host,
-      int port,
-      const WebString& suborigin);
-
   WebPrivatePtr<const SecurityOrigin> private_;
 };
 
diff --git a/tools/media_engagement_preload/BUILD.gn b/tools/media_engagement_preload/BUILD.gn
new file mode 100644
index 0000000..e59e693a
--- /dev/null
+++ b/tools/media_engagement_preload/BUILD.gn
@@ -0,0 +1,58 @@
+# 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.
+
+generator_sources = [
+  "make_dafsa.py",
+  "media_engagement_preload_pb2.py",
+
+  # protobuf dependency
+  "../../third_party/protobuf/python/google/protobuf/descriptor_pb2.py",
+  "../../third_party/protobuf/python/google/protobuf/json_format.py",
+  "../../third_party/protobuf/python/google/protobuf/service.py",
+  "../../third_party/protobuf/python/google/protobuf/message.py",
+  "../../third_party/protobuf/python/google/protobuf/service_reflection.py",
+  "../../third_party/protobuf/python/google/protobuf/text_encoding.py",
+  "../../third_party/protobuf/python/google/protobuf/proto_builder.py",
+  "../../third_party/protobuf/python/google/protobuf/python_protobuf.h",
+  "../../third_party/protobuf/python/google/protobuf/descriptor.py",
+  "../../third_party/protobuf/python/google/protobuf/descriptor_database.py",
+  "../../third_party/protobuf/python/google/protobuf/message_factory.py",
+  "../../third_party/protobuf/python/google/protobuf/symbol_database.py",
+  "../../third_party/protobuf/python/google/protobuf/text_format.py",
+  "../../third_party/protobuf/python/google/protobuf/descriptor_pool.py",
+  "../../third_party/protobuf/python/google/protobuf/internal/more_extensions.proto",
+  "../../third_party/protobuf/python/google/protobuf/internal/wire_format.py",
+  "../../third_party/protobuf/python/google/protobuf/internal/testing_refleaks.py",
+  "../../third_party/protobuf/python/google/protobuf/internal/type_checkers.py",
+  "../../third_party/protobuf/python/google/protobuf/internal/missing_enum_values.proto",
+  "../../third_party/protobuf/python/google/protobuf/internal/more_messages.proto",
+  "../../third_party/protobuf/python/google/protobuf/internal/containers.py",
+  "../../third_party/protobuf/python/google/protobuf/internal/test_bad_identifiers.proto",
+  "../../third_party/protobuf/python/google/protobuf/internal/_parameterized.py",
+  "../../third_party/protobuf/python/google/protobuf/internal/message_listener.py",
+  "../../third_party/protobuf/python/google/protobuf/internal/enum_type_wrapper.py",
+  "../../third_party/protobuf/python/google/protobuf/internal/api_implementation.py",
+  "../../third_party/protobuf/python/google/protobuf/internal/encoder.py",
+  "../../third_party/protobuf/python/google/protobuf/internal/test_util.py",
+  "../../third_party/protobuf/python/google/protobuf/internal/well_known_types.py",
+  "../../third_party/protobuf/python/google/protobuf/internal/decoder.py",
+  "../../third_party/protobuf/python/google/protobuf/internal/api_implementation.cc",
+  "../../third_party/protobuf/python/google/protobuf/internal/python_message.py",
+  "../../third_party/protobuf/python/google/protobuf/internal/message_set_extensions.proto",
+  "../../third_party/protobuf/python/google/protobuf/internal/python_protobuf.cc",
+  "../../third_party/protobuf/python/google/protobuf/internal/more_extensions_dynamic.proto",
+  "../../third_party/protobuf/python/google/protobuf/internal/__init__.py",
+  "../../third_party/protobuf/python/google/protobuf/reflection.py",
+  "../../third_party/protobuf/python/google/protobuf/__init__.py",
+  "../../third_party/protobuf/python/google/__init__.py",
+  "../../third_party/protobuf/third_party/six/six.py",
+]
+
+copy("generator") {
+  sources = generator_sources
+
+  outputs = [
+    "$root_out_dir/{{source_root_relative_dir}}/{{source_file_part}}",
+  ]
+}
diff --git a/url/scheme_host_port.cc b/url/scheme_host_port.cc
index eb2905d..b9298bc 100644
--- a/url/scheme_host_port.cc
+++ b/url/scheme_host_port.cc
@@ -140,8 +140,12 @@
 
   // A valid GURL never returns PORT_INVALID.
   int port = url.EffectiveIntPort();
-  if (port == PORT_UNSPECIFIED)
+  if (port == PORT_UNSPECIFIED) {
     port = 0;
+  } else {
+    DCHECK_GE(port, 0);
+    DCHECK_LE(port, 65535);
+  }
 
   if (!IsValidInput(scheme, host, port, ALREADY_CANONICALIZED))
     return;