chore: cherry-pick 88f263f401b4 from chromium (#26198)

This commit is contained in:
Jeremy Rose
2020-10-28 13:54:51 -07:00
committed by GitHub
parent ff3e6dfa73
commit 31db3524f0
2 changed files with 307 additions and 0 deletions

View File

@@ -135,3 +135,4 @@ cherry-pick-52dceba66599.patch
cherry-pick-abc6ab85e704.patch
avoid_use-after-free.patch
cherry-pick-3b5f65c0aeca.patch
cherry-pick-88f263f401b4.patch

View File

@@ -0,0 +1,306 @@
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 883455ac252d4cc3cd42bac10c22ffe8eb690ad3..6c6fbb25e32322391249b1a1cc6da9daa91e1346 100644
--- a/media/blink/multibuffer_data_source.cc
+++ b/media/blink/multibuffer_data_source.cc
@@ -143,7 +143,7 @@ MultibufferDataSource::MultibufferDataSource(
DCHECK(url_data_.get());
url_data_->Use();
url_data_->OnRedirect(
- base::Bind(&MultibufferDataSource::OnRedirect, weak_ptr_));
+ base::Bind(&MultibufferDataSource::OnRedirected, weak_ptr_));
}
MultibufferDataSource::~MultibufferDataSource() {
@@ -216,10 +216,10 @@ void MultibufferDataSource::Initialize(const 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(
@@ -232,38 +232,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::Bind(&MultibufferDataSource::OnRedirect, weak_ptr_));
+ url_data_->OnRedirect(
+ base::Bind(&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) {
@@ -284,6 +285,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 b42e494db5b9deae0e7c3345f182a25d834946d1..9cd4664d9ae10a8c140b9efb932440347129ff20 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:
typedef base::Callback<void(bool)> DownloadingCB;
+ typedef base::Callback<void()> RedirectCB;
// 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 9d72af0afe84ffc7c9736d4d1b58939b896da28e..6a9a30e650a0d5bded86d66ddb2c09f6b9ee18f2 100644
--- a/media/blink/webmediaplayer_impl.cc
+++ b/media/blink/webmediaplayer_impl.cc
@@ -720,6 +720,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(
@@ -2498,6 +2500,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 897264966ce8a7f4fa729d41de8589210d2b06f6..5e8995d43c46d00a9782930efea96c24788c3e37 100644
--- a/media/blink/webmediaplayer_impl.h
+++ b/media/blink/webmediaplayer_impl.h
@@ -365,6 +365,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 233ca1eb5653fd906cc5b6d9124ff38a988439cb..90672d89b51e918109b02fa950c12b3486df35be 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/modules/mediacapturefromelement/html_audio_element_capturer_source_unittest.cc b/third_party/blink/renderer/modules/mediacapturefromelement/html_audio_element_capturer_source_unittest.cc
index 0d8917bab474f16a51eca50f1373577ba679bb29..b6b8f0da70aa346430ef47396dbcaf419b7a93a3 100644
--- a/third_party/blink/renderer/modules/mediacapturefromelement/html_audio_element_capturer_source_unittest.cc
+++ b/third_party/blink/renderer/modules/mediacapturefromelement/html_audio_element_capturer_source_unittest.cc
@@ -181,4 +181,36 @@ TEST_F(HTMLAudioElementCapturerSourceTest,
track()->RemoveSink(&sink);
}
+TEST_F(HTMLAudioElementCapturerSourceTest, TaintedPlayerDeliversMutedAudio) {
+ testing::InSequence s;
+
+ base::RunLoop run_loop;
+ base::OnceClosure quit_closure = run_loop.QuitClosure();
+
+ MockMediaStreamAudioSink sink;
+ track()->AddSink(&sink);
+ EXPECT_CALL(sink, OnSetFormat(testing::_)).Times(1);
+ EXPECT_CALL(
+ sink,
+ OnData(testing::AllOf(
+ testing::Property(&media::AudioBus::channels,
+ kNumChannelsForTest),
+ testing::Property(&media::AudioBus::frames,
+ kAudioTrackSamplesPerBuffer),
+ testing::Property(&media::AudioBus::AreFramesZero, true)),
+ testing::_))
+ .Times(1)
+ .WillOnce([&](const auto&, auto) { std::move(quit_closure).Run(); });
+
+ audio_source_->TaintOrigin();
+
+ std::unique_ptr<media::AudioBus> bus =
+ media::AudioBus::Create(kNumChannelsForTest, kAudioTrackSamplesPerBuffer);
+ InjectAudio(bus.get());
+ run_loop.Run();
+
+ track()->Stop();
+ track()->RemoveSink(&sink);
+}
+
} // namespace blink
diff --git a/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl.cc b/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl.cc
index 979fb044f71f61d8c6df803d709be58cef41f8f0..6613f25b277539bfaefffa3503789361da8eae1c 100644
--- a/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl.cc
+++ b/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl.cc
@@ -87,11 +87,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_;
@@ -287,6 +294,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));
@@ -320,6 +331,10 @@ int WebAudioSourceProviderImpl::TeeFilter::Render(
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_);