Use per-frame task runners instead of per-thread task runners at media

JavaScript Execution on per-thread task runners must be forbidden for
bfcache. This CL passes per-frame task runners for such tasks like mojo
bindings.

This is part of https://chromium-review.googlesource.com/c/chromium/src/+/1379794

Bug: 870606
Change-Id: Iea22b5af3874f34453b8eaa0e9941cf482d9c9b8
Reviewed-on: https://chromium-review.googlesource.com/c/1400430
Reviewed-by: Kentaro Hara <haraken@chromium.org>
Reviewed-by: Mounir Lamouri <mlamouri@chromium.org>
Reviewed-by: Alexander Timin <altimin@chromium.org>
Reviewed-by: Xiaohan Wang <xhwang@chromium.org>
Commit-Queue: Hajime Hoshi <hajimehoshi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#621929}
diff --git a/content/renderer/media/stream/user_media_client_impl.cc b/content/renderer/media/stream/user_media_client_impl.cc
index 7455cec..a211cf3 100644
--- a/content/renderer/media/stream/user_media_client_impl.cc
+++ b/content/renderer/media/stream/user_media_client_impl.cc
@@ -126,7 +126,8 @@
               std::move(media_stream_device_observer),
               base::BindRepeating(
                   &UserMediaClientImpl::GetMediaDevicesDispatcher,
-                  base::Unretained(this))),
+                  base::Unretained(this)),
+              render_frame->GetTaskRunner(blink::TaskType::kInternalMedia)),
           std::move(task_runner)) {}
 
 UserMediaClientImpl::~UserMediaClientImpl() {
diff --git a/content/renderer/media/stream/user_media_client_impl_unittest.cc b/content/renderer/media/stream/user_media_client_impl_unittest.cc
index aad158d2..b80b301 100644
--- a/content/renderer/media/stream/user_media_client_impl_unittest.cc
+++ b/content/renderer/media/stream/user_media_client_impl_unittest.cc
@@ -302,7 +302,8 @@
             std::move(media_stream_device_observer),
             base::BindRepeating(
                 &UserMediaProcessorUnderTest::media_devices_dispatcher,
-                base::Unretained(this))),
+                base::Unretained(this)),
+            blink::scheduler::GetSingleThreadTaskRunnerForTesting()),
         factory_(dependency_factory),
         media_devices_dispatcher_(std::move(media_devices_dispatcher)),
         state_(state) {}
diff --git a/content/renderer/media/stream/user_media_processor.cc b/content/renderer/media/stream/user_media_processor.cc
index 67c397f..43c8984 100644
--- a/content/renderer/media/stream/user_media_processor.cc
+++ b/content/renderer/media/stream/user_media_processor.cc
@@ -420,11 +420,13 @@
     RenderFrameImpl* render_frame,
     PeerConnectionDependencyFactory* dependency_factory,
     std::unique_ptr<MediaStreamDeviceObserver> media_stream_device_observer,
-    MediaDevicesDispatcherCallback media_devices_dispatcher_cb)
+    MediaDevicesDispatcherCallback media_devices_dispatcher_cb,
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner)
     : dependency_factory_(dependency_factory),
       media_stream_device_observer_(std::move(media_stream_device_observer)),
       media_devices_dispatcher_cb_(std::move(media_devices_dispatcher_cb)),
       render_frame_(render_frame),
+      task_runner_(std::move(task_runner)),
       weak_factory_(this) {
   DCHECK(dependency_factory_);
   DCHECK(media_stream_device_observer_.get());
@@ -940,9 +942,9 @@
   // See OnAudioSourceStarted for more details.
   pending_local_sources_.push_back(source);
 
-  MediaStreamSource::ConstraintsCallback source_ready = base::Bind(
-      &UserMediaProcessor::OnAudioSourceStartedOnAudioThread,
-      base::ThreadTaskRunnerHandle::Get(), weak_factory_.GetWeakPtr());
+  MediaStreamSource::ConstraintsCallback source_ready = base::BindRepeating(
+      &UserMediaProcessor::OnAudioSourceStartedOnAudioThread, task_runner_,
+      weak_factory_.GetWeakPtr());
 
   MediaStreamAudioSource* const audio_source =
       CreateAudioSource(device, std::move(source_ready));
@@ -1131,7 +1133,7 @@
   // the UserMediaClientImpl/UserMediaProcessor are destroyed if the JavaScript
   // code request the frame to be destroyed within the scope of the callback.
   // Therefore, post a task to complete the request with a clean stack.
-  base::ThreadTaskRunnerHandle::Get()->PostTask(
+  task_runner_->PostTask(
       FROM_HERE,
       base::BindOnce(&UserMediaProcessor::DelayedGetUserMediaRequestSucceeded,
                      weak_factory_.GetWeakPtr(), stream, web_request));
@@ -1158,7 +1160,7 @@
   // the UserMediaClientImpl/UserMediaProcessor are destroyed if the JavaScript
   // code request the frame to be destroyed within the scope of the callback.
   // Therefore, post a task to complete the request with a clean stack.
-  base::ThreadTaskRunnerHandle::Get()->PostTask(
+  task_runner_->PostTask(
       FROM_HERE,
       base::BindOnce(&UserMediaProcessor::DelayedGetUserMediaRequestFailed,
                      weak_factory_.GetWeakPtr(),
diff --git a/content/renderer/media/stream/user_media_processor.h b/content/renderer/media/stream/user_media_processor.h
index ed9ef90..0f1eaa6 100644
--- a/content/renderer/media/stream/user_media_processor.h
+++ b/content/renderer/media/stream/user_media_processor.h
@@ -72,7 +72,8 @@
       RenderFrameImpl* render_frame,
       PeerConnectionDependencyFactory* dependency_factory,
       std::unique_ptr<MediaStreamDeviceObserver> media_stream_device_observer,
-      MediaDevicesDispatcherCallback media_devices_dispatcher_cb);
+      MediaDevicesDispatcherCallback media_devices_dispatcher_cb,
+      scoped_refptr<base::SingleThreadTaskRunner> task_runner);
   ~UserMediaProcessor() override;
 
   // It can be assumed that the output of CurrentRequest() remains the same
@@ -303,6 +304,7 @@
   base::OnceClosure request_completed_cb_;
 
   RenderFrameImpl* const render_frame_;
+  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
 
   SEQUENCE_CHECKER(sequence_checker_);
 
diff --git a/media/blink/webcontentdecryptionmoduleaccess_impl.cc b/media/blink/webcontentdecryptionmoduleaccess_impl.cc
index 85597e7e..fdc2b25 100644
--- a/media/blink/webcontentdecryptionmoduleaccess_impl.cc
+++ b/media/blink/webcontentdecryptionmoduleaccess_impl.cc
@@ -71,14 +71,15 @@
 }
 
 void WebContentDecryptionModuleAccessImpl::CreateContentDecryptionModule(
-    blink::WebContentDecryptionModuleResult result) {
+    blink::WebContentDecryptionModuleResult result,
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
   // This method needs to run asynchronously, as it may need to load the CDM.
   // As this object's lifetime is controlled by MediaKeySystemAccess on the
   // blink side, copy all values needed by CreateCdm() in case the blink object
   // gets garbage-collected.
   std::unique_ptr<blink::WebContentDecryptionModuleResult> result_copy(
       new blink::WebContentDecryptionModuleResult(result));
-  base::ThreadTaskRunnerHandle::Get()->PostTask(
+  task_runner->PostTask(
       FROM_HERE,
       base::BindOnce(&CreateCdm, client_, key_system_, security_origin_,
                      cdm_config_, base::Passed(&result_copy)));
diff --git a/media/blink/webcontentdecryptionmoduleaccess_impl.h b/media/blink/webcontentdecryptionmoduleaccess_impl.h
index b01e186..821d1f3 100644
--- a/media/blink/webcontentdecryptionmoduleaccess_impl.h
+++ b/media/blink/webcontentdecryptionmoduleaccess_impl.h
@@ -33,7 +33,8 @@
   blink::WebString GetKeySystem() override;
   blink::WebMediaKeySystemConfiguration GetConfiguration() override;
   void CreateContentDecryptionModule(
-      blink::WebContentDecryptionModuleResult result) override;
+      blink::WebContentDecryptionModuleResult result,
+      scoped_refptr<base::SingleThreadTaskRunner> task_runner) override;
 
  private:
   WebContentDecryptionModuleAccessImpl(
diff --git a/third_party/blink/public/platform/web_content_decryption_module_access.h b/third_party/blink/public/platform/web_content_decryption_module_access.h
index 03190db..21d8a46a 100644
--- a/third_party/blink/public/platform/web_content_decryption_module_access.h
+++ b/third_party/blink/public/platform/web_content_decryption_module_access.h
@@ -5,6 +5,7 @@
 #ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_CONTENT_DECRYPTION_MODULE_ACCESS_H_
 #define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_CONTENT_DECRYPTION_MODULE_ACCESS_H_
 
+#include "base/single_thread_task_runner.h"
 #include "third_party/blink/public/platform/web_common.h"
 #include "third_party/blink/public/platform/web_string.h"
 
@@ -17,7 +18,8 @@
  public:
   virtual ~WebContentDecryptionModuleAccess();
   virtual void CreateContentDecryptionModule(
-      WebContentDecryptionModuleResult) = 0;
+      WebContentDecryptionModuleResult,
+      scoped_refptr<base::SingleThreadTaskRunner>) = 0;
   virtual WebMediaKeySystemConfiguration GetConfiguration() = 0;
   virtual WebString GetKeySystem() = 0;
 };
diff --git a/third_party/blink/renderer/modules/encryptedmedia/media_key_system_access.cc b/third_party/blink/renderer/modules/encryptedmedia/media_key_system_access.cc
index 2c6ab31..8d7506f 100644
--- a/third_party/blink/renderer/modules/encryptedmedia/media_key_system_access.cc
+++ b/third_party/blink/renderer/modules/encryptedmedia/media_key_system_access.cc
@@ -171,7 +171,9 @@
   // 2.3 If cdm fails to load or initialize, reject promise with a new
   //     DOMException whose name is the appropriate error name.
   //     (Done if completeWithException() called).
-  access_->CreateContentDecryptionModule(helper->Result());
+  access_->CreateContentDecryptionModule(
+      helper->Result(), ExecutionContext::From(script_state)
+                            ->GetTaskRunner(TaskType::kInternalMedia));
 
   // 3. Return promise.
   return promise;