mirror of
https://github.com/electron/electron.git
synced 2026-05-02 03:00:22 -04:00
266 lines
11 KiB
Diff
266 lines
11 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Will Cassella <cassew@google.com>
|
|
Date: Thu, 24 Sep 2020 22:54:27 +0000
|
|
Subject: Add callback to WebMediaPlayerImpl to notify when a redirect occurs
|
|
|
|
(cherry picked from commit 8b18bcfd9aa8096c4551ec34c0225b6017cd211e)
|
|
|
|
Bug: 1128657
|
|
Change-Id: I9548e1f3bfe5693871a56e23c3373f45147e52e0
|
|
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2422091
|
|
Reviewed-by: Dale Curtis <dalecurtis@chromium.org>
|
|
Reviewed-by: Guido Urdaneta <guidou@chromium.org>
|
|
Commit-Queue: Guido Urdaneta <guidou@chromium.org>
|
|
Cr-Original-Commit-Position: refs/heads/master@{#809217}
|
|
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2425223
|
|
Commit-Queue: Will Cassella <cassew@google.com>
|
|
Cr-Commit-Position: refs/branch-heads/4240@{#993}
|
|
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
|
|
|
|
diff --git a/media/blink/multibuffer_data_source.cc b/media/blink/multibuffer_data_source.cc
|
|
index 0f6ae1fb8b4ff9f24ce3f407b7359e016fc6de5f..4ec77cf8a6b56002e601fb89eb0dee059f3ab31b 100644
|
|
--- a/media/blink/multibuffer_data_source.cc
|
|
+++ b/media/blink/multibuffer_data_source.cc
|
|
@@ -145,7 +145,7 @@ MultibufferDataSource::MultibufferDataSource(
|
|
DCHECK(url_data_.get());
|
|
url_data_->Use();
|
|
url_data_->OnRedirect(
|
|
- base::BindOnce(&MultibufferDataSource::OnRedirect, weak_ptr_));
|
|
+ base::BindOnce(&MultibufferDataSource::OnRedirected, weak_ptr_));
|
|
}
|
|
|
|
MultibufferDataSource::~MultibufferDataSource() {
|
|
@@ -219,10 +219,10 @@ void MultibufferDataSource::Initialize(InitializeCB init_cb) {
|
|
}
|
|
}
|
|
|
|
-void MultibufferDataSource::OnRedirect(
|
|
- const scoped_refptr<UrlData>& destination) {
|
|
- if (!destination) {
|
|
- // A failure occured.
|
|
+void MultibufferDataSource::OnRedirected(
|
|
+ const scoped_refptr<UrlData>& new_destination) {
|
|
+ if (!new_destination) {
|
|
+ // A failure occurred.
|
|
failed_ = true;
|
|
if (init_cb_) {
|
|
render_task_runner_->PostTask(
|
|
@@ -235,38 +235,39 @@ void MultibufferDataSource::OnRedirect(
|
|
StopLoader();
|
|
return;
|
|
}
|
|
- if (url_data_->url().GetOrigin() != destination->url().GetOrigin()) {
|
|
+ if (url_data_->url().GetOrigin() != new_destination->url().GetOrigin()) {
|
|
single_origin_ = false;
|
|
}
|
|
SetReader(nullptr);
|
|
- url_data_ = std::move(destination);
|
|
+ url_data_ = std::move(new_destination);
|
|
|
|
- if (url_data_) {
|
|
- url_data_->OnRedirect(
|
|
- base::BindOnce(&MultibufferDataSource::OnRedirect, weak_ptr_));
|
|
+ url_data_->OnRedirect(
|
|
+ base::BindOnce(&MultibufferDataSource::OnRedirected, weak_ptr_));
|
|
|
|
- if (init_cb_) {
|
|
- CreateResourceLoader(0, kPositionNotSpecified);
|
|
- if (reader_->Available()) {
|
|
- render_task_runner_->PostTask(
|
|
- FROM_HERE,
|
|
- base::BindOnce(&MultibufferDataSource::StartCallback, weak_ptr_));
|
|
- } else {
|
|
- reader_->Wait(1, base::BindOnce(&MultibufferDataSource::StartCallback,
|
|
- weak_ptr_));
|
|
- }
|
|
- } else if (read_op_) {
|
|
- CreateResourceLoader(read_op_->position(), kPositionNotSpecified);
|
|
- if (reader_->Available()) {
|
|
- render_task_runner_->PostTask(
|
|
- FROM_HERE,
|
|
- base::BindOnce(&MultibufferDataSource::ReadTask, weak_ptr_));
|
|
- } else {
|
|
- reader_->Wait(
|
|
- 1, base::BindOnce(&MultibufferDataSource::ReadTask, weak_ptr_));
|
|
- }
|
|
+ if (init_cb_) {
|
|
+ CreateResourceLoader(0, kPositionNotSpecified);
|
|
+ if (reader_->Available()) {
|
|
+ render_task_runner_->PostTask(
|
|
+ FROM_HERE,
|
|
+ base::BindOnce(&MultibufferDataSource::StartCallback, weak_ptr_));
|
|
+ } else {
|
|
+ reader_->Wait(
|
|
+ 1, base::BindOnce(&MultibufferDataSource::StartCallback, weak_ptr_));
|
|
+ }
|
|
+ } else if (read_op_) {
|
|
+ CreateResourceLoader(read_op_->position(), kPositionNotSpecified);
|
|
+ if (reader_->Available()) {
|
|
+ render_task_runner_->PostTask(
|
|
+ FROM_HERE,
|
|
+ base::BindOnce(&MultibufferDataSource::ReadTask, weak_ptr_));
|
|
+ } else {
|
|
+ reader_->Wait(
|
|
+ 1, base::BindOnce(&MultibufferDataSource::ReadTask, weak_ptr_));
|
|
}
|
|
}
|
|
+
|
|
+ if (redirect_cb_)
|
|
+ redirect_cb_.Run();
|
|
}
|
|
|
|
void MultibufferDataSource::SetPreload(Preload preload) {
|
|
@@ -287,6 +288,10 @@ bool MultibufferDataSource::IsCorsCrossOrigin() const {
|
|
return url_data_->is_cors_cross_origin();
|
|
}
|
|
|
|
+void MultibufferDataSource::OnRedirect(RedirectCB callback) {
|
|
+ redirect_cb_ = std::move(callback);
|
|
+}
|
|
+
|
|
bool MultibufferDataSource::HasAccessControl() const {
|
|
return url_data_->has_access_control();
|
|
}
|
|
diff --git a/media/blink/multibuffer_data_source.h b/media/blink/multibuffer_data_source.h
|
|
index 3da5a7bba5e7cc0f54998a81649f4dd9d78aa7be..da316964ff1543086865d7c85597f381ca8a3296 100644
|
|
--- a/media/blink/multibuffer_data_source.h
|
|
+++ b/media/blink/multibuffer_data_source.h
|
|
@@ -38,6 +38,7 @@ class MultiBufferReader;
|
|
class MEDIA_BLINK_EXPORT MultibufferDataSource : public DataSource {
|
|
public:
|
|
using DownloadingCB = base::RepeatingCallback<void(bool)>;
|
|
+ using RedirectCB = base::RepeatingCallback<void()>;
|
|
|
|
// Used to specify video preload states. They are "hints" to the browser about
|
|
// how aggressively the browser should load and buffer data.
|
|
@@ -82,6 +83,9 @@ class MEDIA_BLINK_EXPORT MultibufferDataSource : public DataSource {
|
|
// This must be called after the response arrives.
|
|
bool IsCorsCrossOrigin() const;
|
|
|
|
+ // Provides a callback to be run when the underlying url is redirected.
|
|
+ void OnRedirect(RedirectCB callback);
|
|
+
|
|
// Returns true if the response includes an Access-Control-Allow-Origin
|
|
// header (that is not "null").
|
|
bool HasAccessControl() const;
|
|
@@ -128,7 +132,7 @@ class MEDIA_BLINK_EXPORT MultibufferDataSource : public DataSource {
|
|
bool cancel_on_defer_for_testing() const { return cancel_on_defer_; }
|
|
|
|
protected:
|
|
- void OnRedirect(const scoped_refptr<UrlData>& destination);
|
|
+ void OnRedirected(const scoped_refptr<UrlData>& new_destination);
|
|
|
|
// A factory method to create a BufferedResourceLoader based on the read
|
|
// parameters.
|
|
@@ -243,6 +247,9 @@ class MEDIA_BLINK_EXPORT MultibufferDataSource : public DataSource {
|
|
// go between different origins.
|
|
bool single_origin_;
|
|
|
|
+ // Callback used when a redirect occurs.
|
|
+ RedirectCB redirect_cb_;
|
|
+
|
|
// Close the connection when we have enough data.
|
|
bool cancel_on_defer_;
|
|
|
|
diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc
|
|
index bf58056d7826e2d56e927ceaf07cb14090cf5e9f..189c71a54e313acae735471d3c67f9895c4c2cf3 100644
|
|
--- a/media/blink/webmediaplayer_impl.cc
|
|
+++ b/media/blink/webmediaplayer_impl.cc
|
|
@@ -764,6 +764,8 @@ void WebMediaPlayerImpl::DoLoad(LoadType load_type,
|
|
base::BindRepeating(&WebMediaPlayerImpl::NotifyDownloading,
|
|
weak_this_));
|
|
data_source_.reset(mb_data_source_);
|
|
+ mb_data_source_->OnRedirect(base::BindRepeating(
|
|
+ &WebMediaPlayerImpl::OnDataSourceRedirected, weak_this_));
|
|
mb_data_source_->SetPreload(preload_);
|
|
mb_data_source_->SetIsClientAudioElement(client_->IsAudioElement());
|
|
mb_data_source_->Initialize(
|
|
@@ -2589,6 +2591,16 @@ void WebMediaPlayerImpl::DataSourceInitialized(bool success) {
|
|
StartPipeline();
|
|
}
|
|
|
|
+void WebMediaPlayerImpl::OnDataSourceRedirected() {
|
|
+ DVLOG(1) << __func__;
|
|
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
|
|
+ DCHECK(mb_data_source_);
|
|
+
|
|
+ if (WouldTaintOrigin()) {
|
|
+ audio_source_provider_->TaintOrigin();
|
|
+ }
|
|
+}
|
|
+
|
|
void WebMediaPlayerImpl::NotifyDownloading(bool is_downloading) {
|
|
DVLOG(1) << __func__ << "(" << is_downloading << ")";
|
|
if (!is_downloading && network_state_ == WebMediaPlayer::kNetworkStateLoading)
|
|
diff --git a/media/blink/webmediaplayer_impl.h b/media/blink/webmediaplayer_impl.h
|
|
index 69e853bb93eb53cdd20d40b7b01050ac2094cffc..72627e8a97781515065aeb564d829679cb4dfe41 100644
|
|
--- a/media/blink/webmediaplayer_impl.h
|
|
+++ b/media/blink/webmediaplayer_impl.h
|
|
@@ -379,6 +379,9 @@ class MEDIA_BLINK_EXPORT WebMediaPlayerImpl
|
|
// Called after asynchronous initialization of a data source completed.
|
|
void DataSourceInitialized(bool success);
|
|
|
|
+ // Called if the |MultiBufferDataSource| is redirected.
|
|
+ void OnDataSourceRedirected();
|
|
+
|
|
// Called when the data source is downloading or paused.
|
|
void NotifyDownloading(bool is_downloading);
|
|
|
|
diff --git a/third_party/blink/public/platform/webaudiosourceprovider_impl.h b/third_party/blink/public/platform/webaudiosourceprovider_impl.h
|
|
index 5383074dcbffbb77a102de6fb551628ff5b964b8..bbf2a0b3d28282587625d6a5cd0103f6a5378b54 100644
|
|
--- a/third_party/blink/public/platform/webaudiosourceprovider_impl.h
|
|
+++ b/third_party/blink/public/platform/webaudiosourceprovider_impl.h
|
|
@@ -75,6 +75,7 @@ class BLINK_PLATFORM_EXPORT WebAudioSourceProviderImpl
|
|
bool CurrentThreadIsRenderingThread() override;
|
|
void SwitchOutputDevice(const std::string& device_id,
|
|
media::OutputDeviceStatusCB callback) override;
|
|
+ void TaintOrigin();
|
|
|
|
// These methods allow a client to get a copy of the rendered audio.
|
|
void SetCopyAudioCallback(CopyAudioCB callback);
|
|
diff --git a/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl.cc b/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl.cc
|
|
index a38efb3e55b268d3a40e14dea8d66478015a3369..37ceac48d3d7f49ba49ad623cd5c7e632aa89279 100644
|
|
--- a/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl.cc
|
|
+++ b/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl.cc
|
|
@@ -80,6 +80,10 @@ class WebAudioSourceProviderImpl::TeeFilter
|
|
const int num_rendered_frames = renderer_->Render(
|
|
delay, delay_timestamp, prior_frames_skipped, audio_bus);
|
|
|
|
+ // Zero out frames after rendering
|
|
+ if (origin_tainted_.IsSet())
|
|
+ audio_bus->Zero();
|
|
+
|
|
// Avoid taking the copy lock for the vast majority of cases.
|
|
if (copy_required_) {
|
|
base::AutoLock auto_lock(copy_lock_);
|
|
@@ -113,11 +117,18 @@ class WebAudioSourceProviderImpl::TeeFilter
|
|
copy_audio_bus_callback_ = std::move(callback);
|
|
}
|
|
|
|
+ void TaintOrigin() { origin_tainted_.Set(); }
|
|
+
|
|
private:
|
|
AudioRendererSink::RenderCallback* renderer_ = nullptr;
|
|
int channels_ = 0;
|
|
int sample_rate_ = 0;
|
|
|
|
+ // Indicates whether the audio source is tainted, and output should be muted.
|
|
+ // This can happen if the media element source is a cross-origin source which
|
|
+ // the page is not allowed to access due to CORS restrictions.
|
|
+ base::AtomicFlag origin_tainted_;
|
|
+
|
|
// The vast majority of the time we're operating in passthrough mode. So only
|
|
// acquire a lock to read |copy_audio_bus_callback_| when necessary.
|
|
std::atomic<bool> copy_required_;
|
|
@@ -317,6 +328,10 @@ void WebAudioSourceProviderImpl::SwitchOutputDevice(
|
|
sink_->SwitchOutputDevice(device_id, std::move(callback));
|
|
}
|
|
|
|
+void WebAudioSourceProviderImpl::TaintOrigin() {
|
|
+ tee_filter_->TaintOrigin();
|
|
+}
|
|
+
|
|
void WebAudioSourceProviderImpl::SetCopyAudioCallback(CopyAudioCB callback) {
|
|
DCHECK(!callback.is_null());
|
|
tee_filter_->SetCopyAudioCallback(std::move(callback));
|