summaryrefslogtreecommitdiff
path: root/chromium/fuchsia/engine/renderer
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/fuchsia/engine/renderer')
-rw-r--r--chromium/fuchsia/engine/renderer/cast_streaming_demuxer.cc352
-rw-r--r--chromium/fuchsia/engine/renderer/cast_streaming_demuxer.h84
-rw-r--r--chromium/fuchsia/engine/renderer/cast_streaming_receiver.cc128
-rw-r--r--chromium/fuchsia/engine/renderer/cast_streaming_receiver.h63
-rw-r--r--chromium/fuchsia/engine/renderer/on_load_script_injector.cc5
-rw-r--r--chromium/fuchsia/engine/renderer/on_load_script_injector.h3
-rw-r--r--chromium/fuchsia/engine/renderer/url_request_rules_receiver.cc16
-rw-r--r--chromium/fuchsia/engine/renderer/url_request_rules_receiver.h22
-rw-r--r--chromium/fuchsia/engine/renderer/web_engine_content_renderer_client.cc47
-rw-r--r--chromium/fuchsia/engine/renderer/web_engine_content_renderer_client.h21
-rw-r--r--chromium/fuchsia/engine/renderer/web_engine_render_frame_observer.cc25
-rw-r--r--chromium/fuchsia/engine/renderer/web_engine_render_frame_observer.h50
-rw-r--r--chromium/fuchsia/engine/renderer/web_engine_url_loader_throttle_provider.cc5
13 files changed, 764 insertions, 57 deletions
diff --git a/chromium/fuchsia/engine/renderer/cast_streaming_demuxer.cc b/chromium/fuchsia/engine/renderer/cast_streaming_demuxer.cc
new file mode 100644
index 00000000000..92937f33b35
--- /dev/null
+++ b/chromium/fuchsia/engine/renderer/cast_streaming_demuxer.cc
@@ -0,0 +1,352 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "fuchsia/engine/renderer/cast_streaming_demuxer.h"
+
+#include "base/bind.h"
+#include "base/sequence_checker.h"
+#include "base/single_thread_task_runner.h"
+#include "fuchsia/engine/renderer/cast_streaming_receiver.h"
+#include "media/base/audio_decoder_config.h"
+#include "media/base/decoder_buffer.h"
+#include "media/base/timestamp_constants.h"
+#include "media/base/video_decoder_config.h"
+#include "media/mojo/common/mojo_decoder_buffer_converter.h"
+
+namespace {
+
+// media::DemuxerStream shared audio/video implementation for Cast Streaming.
+// Receives buffer metadata over a Mojo service and reads the buffers over a
+// Mojo data pipe from the browser process.
+class CastStreamingDemuxerStream : public media::DemuxerStream,
+ public mojom::CastStreamingBufferReceiver {
+ public:
+ CastStreamingDemuxerStream(
+ mojo::PendingReceiver<mojom::CastStreamingBufferReceiver>
+ pending_receiver,
+ mojo::ScopedDataPipeConsumerHandle consumer)
+ : receiver_(this, std::move(pending_receiver)),
+ decoder_buffer_reader_(std::move(consumer)) {
+ DVLOG(1) << __func__;
+
+ // Mojo service disconnection means the Cast Streaming Session ended and no
+ // further buffer will be received. kAborted will be returned to the media
+ // pipeline for every subsequent DemuxerStream::Read() attempt.
+ receiver_.set_disconnect_handler(base::BindOnce(
+ &CastStreamingDemuxerStream::OnMojoDisconnect, base::Unretained(this)));
+ }
+ ~CastStreamingDemuxerStream() override {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ }
+
+ // mojom::CastStreamingBufferReceiver implementation.
+ void ProvideBuffer(media::mojom::DecoderBufferPtr buffer) final {
+ DVLOG(3) << __func__;
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ pending_buffer_metadata_.push_back(std::move(buffer));
+ GetNextBuffer();
+ }
+
+ void AbortPendingRead() {
+ DVLOG(3) << __func__;
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ if (pending_read_cb_)
+ std::move(pending_read_cb_).Run(Status::kAborted, nullptr);
+ }
+
+ private:
+ void CompletePendingRead() {
+ DVLOG(3) << __func__;
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ if (!pending_read_cb_ || !current_buffer_)
+ return;
+
+ if (current_buffer_->end_of_stream()) {
+ std::move(pending_read_cb_).Run(Status::kAborted, nullptr);
+ return;
+ }
+
+ std::move(pending_read_cb_).Run(Status::kOk, std::move(current_buffer_));
+ GetNextBuffer();
+ }
+
+ void GetNextBuffer() {
+ DVLOG(3) << __func__;
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+ if (current_buffer_ || pending_buffer_metadata_.empty())
+ return;
+
+ media::mojom::DecoderBufferPtr buffer =
+ std::move(pending_buffer_metadata_.front());
+ pending_buffer_metadata_.pop_front();
+ decoder_buffer_reader_.ReadDecoderBuffer(
+ std::move(buffer),
+ base::BindOnce(&CastStreamingDemuxerStream::OnBufferRead,
+ base::Unretained(this)));
+ }
+
+ void OnBufferRead(scoped_refptr<media::DecoderBuffer> buffer) {
+ DVLOG(3) << __func__;
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+ // Stop processing the pending buffer. OnMojoDisconnect() will trigger
+ // sending kAborted on subsequent Read() calls. This can happen if this
+ // object was in the process of reading a buffer off the data pipe when the
+ // Mojo connection ended.
+ if (!receiver_.is_bound())
+ return;
+
+ DCHECK(!current_buffer_);
+ current_buffer_ = buffer;
+ CompletePendingRead();
+ }
+
+ void OnMojoDisconnect() {
+ DVLOG(1) << __func__;
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+ receiver_.reset();
+ pending_buffer_metadata_.clear();
+ current_buffer_ = media::DecoderBuffer::CreateEOSBuffer();
+ CompletePendingRead();
+ }
+
+ // DemuxerStream implementation.
+ void Read(ReadCB read_cb) final {
+ DVLOG(3) << __func__;
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK(pending_read_cb_.is_null());
+ pending_read_cb_ = std::move(read_cb);
+ CompletePendingRead();
+ }
+ bool IsReadPending() const final { return !pending_read_cb_.is_null(); }
+ Liveness liveness() const final { return Liveness::LIVENESS_LIVE; }
+ bool SupportsConfigChanges() final { return false; }
+
+ mojo::Receiver<CastStreamingBufferReceiver> receiver_;
+ media::MojoDecoderBufferReader decoder_buffer_reader_;
+
+ ReadCB pending_read_cb_;
+ base::circular_deque<media::mojom::DecoderBufferPtr> pending_buffer_metadata_;
+ scoped_refptr<media::DecoderBuffer> current_buffer_;
+
+ SEQUENCE_CHECKER(sequence_checker_);
+};
+
+} // namespace
+
+class CastStreamingAudioDemuxerStream : public CastStreamingDemuxerStream {
+ public:
+ explicit CastStreamingAudioDemuxerStream(
+ mojom::AudioStreamInfoPtr audio_stream_info)
+ : CastStreamingDemuxerStream(
+ std::move(audio_stream_info->buffer_receiver),
+ std::move(audio_stream_info->data_pipe)),
+ config_(audio_stream_info->decoder_config) {
+ DVLOG(1) << __func__
+ << ": config info: " << config_.AsHumanReadableString();
+ }
+ ~CastStreamingAudioDemuxerStream() final = default;
+
+ private:
+ // DemuxerStream implementation.
+ media::AudioDecoderConfig audio_decoder_config() final { return config_; }
+ media::VideoDecoderConfig video_decoder_config() final {
+ NOTREACHED();
+ return media::VideoDecoderConfig();
+ }
+ Type type() const final { return Type::AUDIO; }
+
+ media::AudioDecoderConfig config_;
+};
+
+class CastStreamingVideoDemuxerStream : public CastStreamingDemuxerStream {
+ public:
+ explicit CastStreamingVideoDemuxerStream(
+ mojom::VideoStreamInfoPtr video_stream_info)
+ : CastStreamingDemuxerStream(
+ std::move(video_stream_info->buffer_receiver),
+ std::move(video_stream_info->data_pipe)),
+ config_(video_stream_info->decoder_config) {
+ DVLOG(1) << __func__
+ << ": config info: " << config_.AsHumanReadableString();
+ }
+ ~CastStreamingVideoDemuxerStream() final = default;
+
+ private:
+ // DemuxerStream implementation.
+ media::AudioDecoderConfig audio_decoder_config() final {
+ NOTREACHED();
+ return media::AudioDecoderConfig();
+ }
+ media::VideoDecoderConfig video_decoder_config() final { return config_; }
+ Type type() const final { return Type::VIDEO; }
+
+ media::VideoDecoderConfig config_;
+};
+
+CastStreamingDemuxer::CastStreamingDemuxer(
+ CastStreamingReceiver* receiver,
+ const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner)
+ : media_task_runner_(media_task_runner),
+ original_task_runner_(base::SequencedTaskRunnerHandle::Get()),
+ receiver_(receiver) {
+ DVLOG(1) << __func__;
+ DCHECK(receiver_);
+}
+
+CastStreamingDemuxer::~CastStreamingDemuxer() {
+ DVLOG(1) << __func__;
+ DCHECK(media_task_runner_->BelongsToCurrentThread());
+
+ if (was_initialization_successful_) {
+ original_task_runner_->PostTask(
+ FROM_HERE, base::BindOnce(&CastStreamingReceiver::OnDemuxerDestroyed,
+ base::Unretained(receiver_)));
+ }
+}
+
+void CastStreamingDemuxer::OnStreamsInitialized(
+ mojom::AudioStreamInfoPtr audio_stream_info,
+ mojom::VideoStreamInfoPtr video_stream_info) {
+ DVLOG(1) << __func__;
+ DCHECK(!media_task_runner_->BelongsToCurrentThread());
+
+ media_task_runner_->PostTask(
+ FROM_HERE,
+ base::BindOnce(&CastStreamingDemuxer::OnStreamsInitializedOnMediaThread,
+ base::Unretained(this), std::move(audio_stream_info),
+ std::move(video_stream_info)));
+}
+
+void CastStreamingDemuxer::OnStreamsInitializedOnMediaThread(
+ mojom::AudioStreamInfoPtr audio_stream_info,
+ mojom::VideoStreamInfoPtr video_stream_info) {
+ DVLOG(1) << __func__;
+ DCHECK(media_task_runner_->BelongsToCurrentThread());
+ DCHECK(initialized_cb_);
+
+ if (!audio_stream_info && !video_stream_info) {
+ std::move(initialized_cb_)
+ .Run(media::PipelineStatus::DEMUXER_ERROR_COULD_NOT_OPEN);
+ return;
+ }
+
+ if (audio_stream_info) {
+ audio_stream_ = std::make_unique<CastStreamingAudioDemuxerStream>(
+ std::move(audio_stream_info));
+ }
+ if (video_stream_info) {
+ video_stream_ = std::make_unique<CastStreamingVideoDemuxerStream>(
+ std::move(video_stream_info));
+ }
+ was_initialization_successful_ = true;
+
+ std::move(initialized_cb_).Run(media::PipelineStatus::PIPELINE_OK);
+}
+
+std::vector<media::DemuxerStream*> CastStreamingDemuxer::GetAllStreams() {
+ DVLOG(1) << __func__;
+ DCHECK(media_task_runner_->BelongsToCurrentThread());
+
+ std::vector<media::DemuxerStream*> streams;
+ if (video_stream_)
+ streams.push_back(video_stream_.get());
+ if (audio_stream_)
+ streams.push_back(audio_stream_.get());
+ return streams;
+}
+
+std::string CastStreamingDemuxer::GetDisplayName() const {
+ return "CastStreamingDemuxer";
+}
+
+void CastStreamingDemuxer::Initialize(media::DemuxerHost* host,
+ media::PipelineStatusCallback status_cb) {
+ DVLOG(1) << __func__;
+ DCHECK(media_task_runner_->BelongsToCurrentThread());
+ host_ = host;
+
+ // Live streams have infinite duration.
+ host_->SetDuration(media::kInfiniteDuration);
+ initialized_cb_ = std::move(status_cb);
+
+ original_task_runner_->PostTask(
+ FROM_HERE,
+ base::BindOnce(&CastStreamingReceiver::SetDemuxer,
+ base::Unretained(receiver_), base::Unretained(this)));
+}
+
+void CastStreamingDemuxer::AbortPendingReads() {
+ DVLOG(2) << __func__;
+ DCHECK(media_task_runner_->BelongsToCurrentThread());
+
+ if (audio_stream_)
+ audio_stream_->AbortPendingRead();
+ if (video_stream_)
+ video_stream_->AbortPendingRead();
+}
+
+// Not supported.
+void CastStreamingDemuxer::StartWaitingForSeek(base::TimeDelta seek_time) {}
+
+// Not supported.
+void CastStreamingDemuxer::CancelPendingSeek(base::TimeDelta seek_time) {}
+
+// Not supported.
+void CastStreamingDemuxer::Seek(base::TimeDelta time,
+ media::PipelineStatusCallback status_cb) {
+ std::move(status_cb).Run(media::PipelineStatus::PIPELINE_OK);
+}
+
+void CastStreamingDemuxer::Stop() {
+ DVLOG(1) << __func__;
+ DCHECK(media_task_runner_->BelongsToCurrentThread());
+
+ if (audio_stream_)
+ audio_stream_.reset();
+ if (video_stream_)
+ video_stream_.reset();
+}
+
+base::TimeDelta CastStreamingDemuxer::GetStartTime() const {
+ return base::TimeDelta();
+}
+
+// Not supported.
+base::Time CastStreamingDemuxer::GetTimelineOffset() const {
+ return base::Time();
+}
+
+// Not supported.
+int64_t CastStreamingDemuxer::GetMemoryUsage() const {
+ return 0;
+}
+
+base::Optional<media::container_names::MediaContainerName>
+CastStreamingDemuxer::GetContainerForMetrics() const {
+ // Cast Streaming frames have no container.
+ return base::nullopt;
+}
+
+// Not supported.
+void CastStreamingDemuxer::OnEnabledAudioTracksChanged(
+ const std::vector<media::MediaTrack::Id>& track_ids,
+ base::TimeDelta curr_time,
+ TrackChangeCB change_completed_cb) {
+ DLOG(WARNING) << "Track changes are not supported.";
+ std::vector<media::DemuxerStream*> streams;
+ std::move(change_completed_cb).Run(media::DemuxerStream::AUDIO, streams);
+}
+
+// Not supported.
+void CastStreamingDemuxer::OnSelectedVideoTrackChanged(
+ const std::vector<media::MediaTrack::Id>& track_ids,
+ base::TimeDelta curr_time,
+ TrackChangeCB change_completed_cb) {
+ DLOG(WARNING) << "Track changes are not supported.";
+ std::vector<media::DemuxerStream*> streams;
+ std::move(change_completed_cb).Run(media::DemuxerStream::VIDEO, streams);
+}
diff --git a/chromium/fuchsia/engine/renderer/cast_streaming_demuxer.h b/chromium/fuchsia/engine/renderer/cast_streaming_demuxer.h
new file mode 100644
index 00000000000..849320655bd
--- /dev/null
+++ b/chromium/fuchsia/engine/renderer/cast_streaming_demuxer.h
@@ -0,0 +1,84 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef FUCHSIA_ENGINE_RENDERER_CAST_STREAMING_DEMUXER_H_
+#define FUCHSIA_ENGINE_RENDERER_CAST_STREAMING_DEMUXER_H_
+
+#include "fuchsia/engine/cast_streaming_session.mojom.h"
+#include "media/base/demuxer.h"
+#include "mojo/public/cpp/bindings/associated_receiver.h"
+
+namespace base {
+class SingleThreadTaskRunner;
+}
+
+class CastStreamingReceiver;
+class CastStreamingAudioDemuxerStream;
+class CastStreamingVideoDemuxerStream;
+
+// media::Demuxer implementation for a Cast Streaming Receiver.
+// This object is instantiated on the main thread, whose task runner is stored
+// as |original_task_runner_|. OnStreamsInitialized() is the only method called
+// on the main thread. Every other method is called on the media thread, whose
+// task runner is |media_task_runner_|.
+// |original_task_runner_| is used to post method calls to |receiver_|, which is
+// guaranteed to outlive this object.
+// TODO(crbug.com/1082821): Simplify the CastStreamingDemuxer initialization
+// sequence when the CastStreamingReceiver Component has been implemented.
+class CastStreamingDemuxer : public media::Demuxer {
+ public:
+ CastStreamingDemuxer(
+ CastStreamingReceiver* receiver,
+ const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner);
+ ~CastStreamingDemuxer() final;
+
+ CastStreamingDemuxer(const CastStreamingDemuxer&) = delete;
+ CastStreamingDemuxer& operator=(const CastStreamingDemuxer&) = delete;
+
+ void OnStreamsInitialized(mojom::AudioStreamInfoPtr audio_stream_info,
+ mojom::VideoStreamInfoPtr video_stream_info);
+
+ private:
+ void OnStreamsInitializedOnMediaThread(
+ mojom::AudioStreamInfoPtr audio_stream_info,
+ mojom::VideoStreamInfoPtr video_stream_info);
+
+ // media::Demuxer implementation.
+ std::vector<media::DemuxerStream*> GetAllStreams() final;
+ std::string GetDisplayName() const final;
+ void Initialize(media::DemuxerHost* host,
+ media::PipelineStatusCallback status_cb) final;
+ void AbortPendingReads() final;
+ void StartWaitingForSeek(base::TimeDelta seek_time) final;
+ void CancelPendingSeek(base::TimeDelta seek_time) final;
+ void Seek(base::TimeDelta time,
+ media::PipelineStatusCallback status_cb) final;
+ void Stop() final;
+ base::TimeDelta GetStartTime() const final;
+ base::Time GetTimelineOffset() const final;
+ int64_t GetMemoryUsage() const final;
+ base::Optional<media::container_names::MediaContainerName>
+ GetContainerForMetrics() const final;
+ void OnEnabledAudioTracksChanged(
+ const std::vector<media::MediaTrack::Id>& track_ids,
+ base::TimeDelta curr_time,
+ TrackChangeCB change_completed_cb) final;
+ void OnSelectedVideoTrackChanged(
+ const std::vector<media::MediaTrack::Id>& track_ids,
+ base::TimeDelta curr_time,
+ TrackChangeCB change_completed_cb) final;
+
+ scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
+ scoped_refptr<base::SequencedTaskRunner> original_task_runner_;
+ media::DemuxerHost* host_ = nullptr;
+ std::unique_ptr<CastStreamingAudioDemuxerStream> audio_stream_;
+ std::unique_ptr<CastStreamingVideoDemuxerStream> video_stream_;
+
+ // Set to true if the Demuxer was successfully initialized.
+ bool was_initialization_successful_ = false;
+ media::PipelineStatusCallback initialized_cb_;
+ CastStreamingReceiver* const receiver_;
+};
+
+#endif // FUCHSIA_ENGINE_RENDERER_LIBCAST_STREAMING_DEMUXER_H_
diff --git a/chromium/fuchsia/engine/renderer/cast_streaming_receiver.cc b/chromium/fuchsia/engine/renderer/cast_streaming_receiver.cc
new file mode 100644
index 00000000000..98654200d90
--- /dev/null
+++ b/chromium/fuchsia/engine/renderer/cast_streaming_receiver.cc
@@ -0,0 +1,128 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "fuchsia/engine/renderer/cast_streaming_receiver.h"
+
+#include "content/public/renderer/render_frame.h"
+#include "fuchsia/engine/renderer/cast_streaming_demuxer.h"
+#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
+#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
+
+CastStreamingReceiver::CastStreamingReceiver(
+ content::RenderFrame* render_frame) {
+ DVLOG(1) << __func__;
+ DCHECK(render_frame);
+
+ // It is fine to use an unretained pointer to |this| here as the
+ // AssociatedInterfaceRegistry, owned by |render_frame| will be torn-down at
+ // the same time as |this|.
+ render_frame->GetAssociatedInterfaceRegistry()->AddInterface(
+ base::BindRepeating(&CastStreamingReceiver::BindToReceiver,
+ base::Unretained(this)));
+}
+
+CastStreamingReceiver::~CastStreamingReceiver() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+}
+
+void CastStreamingReceiver::SetDemuxer(CastStreamingDemuxer* demuxer) {
+ DVLOG(1) << __func__;
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK(demuxer);
+
+ if (demuxer_) {
+ // We do not support more than one active CastStreamingDemuxer in the same
+ // RenderFrame. Return early here.
+ demuxer->OnStreamsInitialized(mojom::AudioStreamInfoPtr(),
+ mojom::VideoStreamInfoPtr());
+ return;
+ }
+
+ DCHECK(!is_demuxer_initialized_);
+
+ if (IsBound()) {
+ demuxer_ = demuxer;
+ MaybeCallEnableReceiverCallback();
+ } else {
+ // The Cast Streaming Sender disconnected after |demuxer| was instantiated
+ // but before |demuxer| was initialized on the media thread.
+ demuxer->OnStreamsInitialized(mojom::AudioStreamInfoPtr(),
+ mojom::VideoStreamInfoPtr());
+ }
+}
+
+void CastStreamingReceiver::OnDemuxerDestroyed() {
+ DVLOG(1) << __func__;
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK(demuxer_);
+
+ demuxer_ = nullptr;
+ is_demuxer_initialized_ = false;
+ cast_streaming_receiver_receiver_.reset();
+}
+
+void CastStreamingReceiver::BindToReceiver(
+ mojo::PendingAssociatedReceiver<mojom::CastStreamingReceiver> receiver) {
+ DVLOG(1) << __func__;
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK(!cast_streaming_receiver_receiver_.is_bound());
+
+ cast_streaming_receiver_receiver_.Bind(std::move(receiver));
+
+ // Mojo service disconnection means the Cast Streaming Session ended or the
+ // Cast Streaming Sender disconnected.
+ cast_streaming_receiver_receiver_.set_disconnect_handler(base::BindOnce(
+ &CastStreamingReceiver::OnReceiverDisconnected, base::Unretained(this)));
+}
+
+bool CastStreamingReceiver::IsBound() const {
+ DVLOG(2) << __func__;
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+ return cast_streaming_receiver_receiver_.is_bound();
+}
+
+void CastStreamingReceiver::MaybeCallEnableReceiverCallback() {
+ DVLOG(2) << __func__;
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+ if (enable_receiver_callback_ && demuxer_)
+ std::move(enable_receiver_callback_).Run();
+}
+
+void CastStreamingReceiver::OnReceiverDisconnected() {
+ DVLOG(1) << __func__;
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+ cast_streaming_receiver_receiver_.reset();
+ enable_receiver_callback_.Reset();
+
+ if (demuxer_ && !is_demuxer_initialized_) {
+ OnStreamsInitialized(mojom::AudioStreamInfoPtr(),
+ mojom::VideoStreamInfoPtr());
+ }
+}
+
+void CastStreamingReceiver::EnableReceiver(EnableReceiverCallback callback) {
+ DVLOG(1) << __func__;
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK(!enable_receiver_callback_);
+ DCHECK(callback);
+
+ enable_receiver_callback_ = std::move(callback);
+ MaybeCallEnableReceiverCallback();
+}
+
+void CastStreamingReceiver::OnStreamsInitialized(
+ mojom::AudioStreamInfoPtr audio_stream_info,
+ mojom::VideoStreamInfoPtr video_stream_info) {
+ DVLOG(1) << __func__;
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK(!is_demuxer_initialized_);
+ DCHECK(demuxer_);
+
+ is_demuxer_initialized_ = true;
+ demuxer_->OnStreamsInitialized(std::move(audio_stream_info),
+ std::move(video_stream_info));
+}
diff --git a/chromium/fuchsia/engine/renderer/cast_streaming_receiver.h b/chromium/fuchsia/engine/renderer/cast_streaming_receiver.h
new file mode 100644
index 00000000000..a95a4aededf
--- /dev/null
+++ b/chromium/fuchsia/engine/renderer/cast_streaming_receiver.h
@@ -0,0 +1,63 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef FUCHSIA_ENGINE_RENDERER_CAST_STREAMING_RECEIVER_H_
+#define FUCHSIA_ENGINE_RENDERER_CAST_STREAMING_RECEIVER_H_
+
+#include "base/sequence_checker.h"
+#include "fuchsia/engine/cast_streaming_session.mojom.h"
+#include "mojo/public/cpp/bindings/associated_receiver.h"
+#include "mojo/public/cpp/bindings/pending_associated_receiver.h"
+
+namespace content {
+class RenderFrame;
+} // namespace content
+
+class CastStreamingDemuxer;
+
+// Handles the Cast Streaming Session lifetime in the renderer process.
+// Owned by WebEngineRenderFrameObserver, this object will be destroyed on
+// RenderFrame destruction. This is guaranteed to outlive the
+// CastStreamingDemuxer that uses it as the RenderFrame destruction will have
+// triggered the destruction of the media pipeline and the CastStreamingDemuxer
+// before the call to content::RenderFrameObserver::OnDestruct(), which triggers
+// this object destruction.
+class CastStreamingReceiver : public mojom::CastStreamingReceiver {
+ public:
+ explicit CastStreamingReceiver(content::RenderFrame* frame);
+ ~CastStreamingReceiver() final;
+
+ CastStreamingReceiver(const CastStreamingReceiver&) = delete;
+ CastStreamingReceiver& operator=(const CastStreamingReceiver&) = delete;
+
+ void SetDemuxer(CastStreamingDemuxer* demuxer);
+ void OnDemuxerDestroyed();
+
+ // Returns true if a Mojo connection is active.
+ bool IsBound() const;
+
+ private:
+ void BindToReceiver(
+ mojo::PendingAssociatedReceiver<mojom::CastStreamingReceiver> receiver);
+
+ void MaybeCallEnableReceiverCallback();
+
+ void OnReceiverDisconnected();
+
+ // mojom::CastStreamingReceiver implementation.
+ void EnableReceiver(EnableReceiverCallback callback) final;
+ void OnStreamsInitialized(mojom::AudioStreamInfoPtr audio_stream_info,
+ mojom::VideoStreamInfoPtr video_stream_info) final;
+
+ mojo::AssociatedReceiver<mojom::CastStreamingReceiver>
+ cast_streaming_receiver_receiver_{this};
+
+ EnableReceiverCallback enable_receiver_callback_;
+ CastStreamingDemuxer* demuxer_ = nullptr;
+ bool is_demuxer_initialized_ = false;
+
+ SEQUENCE_CHECKER(sequence_checker_);
+};
+
+#endif // FUCHSIA_ENGINE_RENDERER_CAST_STREAMING_RECEIVER_H_
diff --git a/chromium/fuchsia/engine/renderer/on_load_script_injector.cc b/chromium/fuchsia/engine/renderer/on_load_script_injector.cc
index b966fbacc1e..6fd0a6db314 100644
--- a/chromium/fuchsia/engine/renderer/on_load_script_injector.cc
+++ b/chromium/fuchsia/engine/renderer/on_load_script_injector.cc
@@ -28,12 +28,7 @@ void OnLoadScriptInjector::BindToReceiver(
}
void OnLoadScriptInjector::DidCommitProvisionalLoad(
- bool is_same_document_navigation,
ui::PageTransition transition) {
- // Ignore pushState or document fragment navigation.
- if (is_same_document_navigation)
- return;
-
// Don't inject anything for subframes.
if (!render_frame()->IsMainFrame())
return;
diff --git a/chromium/fuchsia/engine/renderer/on_load_script_injector.h b/chromium/fuchsia/engine/renderer/on_load_script_injector.h
index 80bd6b98d76..3e5364e8948 100644
--- a/chromium/fuchsia/engine/renderer/on_load_script_injector.h
+++ b/chromium/fuchsia/engine/renderer/on_load_script_injector.h
@@ -30,8 +30,7 @@ class OnLoadScriptInjector : public content::RenderFrameObserver,
// RenderFrameObserver override:
void OnDestruct() override;
- void DidCommitProvisionalLoad(bool is_same_document_navigation,
- ui::PageTransition transition) override;
+ void DidCommitProvisionalLoad(ui::PageTransition transition) override;
private:
// Called by OnDestruct(), when the RenderFrame is destroyed.
diff --git a/chromium/fuchsia/engine/renderer/url_request_rules_receiver.cc b/chromium/fuchsia/engine/renderer/url_request_rules_receiver.cc
index 0b0874954d0..c1da8c7bb99 100644
--- a/chromium/fuchsia/engine/renderer/url_request_rules_receiver.cc
+++ b/chromium/fuchsia/engine/renderer/url_request_rules_receiver.cc
@@ -11,13 +11,8 @@
#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
UrlRequestRulesReceiver::UrlRequestRulesReceiver(
- content::RenderFrame* render_frame,
- base::OnceCallback<void(int)> on_render_frame_deleted_callback)
- : content::RenderFrameObserver(render_frame),
- on_render_frame_deleted_callback_(
- std::move(on_render_frame_deleted_callback)) {
+ content::RenderFrame* render_frame) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- DCHECK(on_render_frame_deleted_callback_);
DCHECK(render_frame);
// It is fine to use an unretained pointer to |this| here as the
@@ -54,12 +49,3 @@ UrlRequestRulesReceiver::GetCachedRules() {
base::AutoLock auto_lock(lock_);
return cached_rules_;
}
-
-void UrlRequestRulesReceiver::OnDestruct() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
- // The RenderFrame corresponding to this object was destroyed, which means
- // the AssociatedInterfaceRegsitry is also gone. It is expected that
- // |on_render_frame_deleted_callback_| will delete |this|.
- std::move(on_render_frame_deleted_callback_).Run(routing_id());
-}
diff --git a/chromium/fuchsia/engine/renderer/url_request_rules_receiver.h b/chromium/fuchsia/engine/renderer/url_request_rules_receiver.h
index 8b2db7b10c1..98125825f38 100644
--- a/chromium/fuchsia/engine/renderer/url_request_rules_receiver.h
+++ b/chromium/fuchsia/engine/renderer/url_request_rules_receiver.h
@@ -19,22 +19,18 @@ namespace content {
class RenderFrame;
} // namespace content
-// Provides rewriting rules for network requests. UrlRequestRulesReceiver
-// objects are owned by their respective WebEngineContentRendererClient and they
-// will be destroyed on RenderFrame destruction. This is guaranteed to outlive
-// any WebEngineURLLoaderThrottle that uses it as the RenderFrame destruction
-// will have triggered the destruction of all pending
-// WebEngineURLLoaderThrottles.
+// Provides rewriting rules for network requests. Owned by
+// WebEngineRenderFrameObserver, this object will be destroyed on RenderFrame
+// destruction. This is guaranteed to outlive any WebEngineURLLoaderThrottle
+// that uses it as the RenderFrame destruction will have triggered the
+// destruction of all pending WebEngineURLLoaderThrottles.
// This class should only be used on the IO thread, with the exception of the
// GetCachedRules() implementation, which can be called from any sequence.
class UrlRequestRulesReceiver
: public mojom::UrlRequestRulesReceiver,
- public WebEngineURLLoaderThrottle::CachedRulesProvider,
- public content::RenderFrameObserver {
+ public WebEngineURLLoaderThrottle::CachedRulesProvider {
public:
- UrlRequestRulesReceiver(
- content::RenderFrame* render_frame,
- base::OnceCallback<void(int)> on_render_frame_deleted_callback);
+ UrlRequestRulesReceiver(content::RenderFrame* render_frame);
~UrlRequestRulesReceiver() override;
private:
@@ -48,9 +44,6 @@ class UrlRequestRulesReceiver
scoped_refptr<WebEngineURLLoaderThrottle::UrlRequestRewriteRules>
GetCachedRules() override;
- // content::RenderFrameObserver implementation.
- void OnDestruct() override;
-
base::Lock lock_;
// This is accessed by WebEngineURLLoaderThrottles, which can be off-sequence
@@ -61,7 +54,6 @@ class UrlRequestRulesReceiver
mojo::AssociatedReceiver<mojom::UrlRequestRulesReceiver>
url_request_rules_receiver_{this};
- base::OnceCallback<void(int)> on_render_frame_deleted_callback_;
SEQUENCE_CHECKER(sequence_checker_);
DISALLOW_COPY_AND_ASSIGN(UrlRequestRulesReceiver);
diff --git a/chromium/fuchsia/engine/renderer/web_engine_content_renderer_client.cc b/chromium/fuchsia/engine/renderer/web_engine_content_renderer_client.cc
index 2fc77c0d567..35d3f37a2fd 100644
--- a/chromium/fuchsia/engine/renderer/web_engine_content_renderer_client.cc
+++ b/chromium/fuchsia/engine/renderer/web_engine_content_renderer_client.cc
@@ -9,6 +9,8 @@
#include "components/cdm/renderer/widevine_key_system_properties.h"
#include "components/media_control/renderer/media_playback_options.h"
#include "content/public/renderer/render_frame.h"
+#include "fuchsia/engine/common/cast_streaming.h"
+#include "fuchsia/engine/renderer/cast_streaming_demuxer.h"
#include "fuchsia/engine/renderer/on_load_script_injector.h"
#include "fuchsia/engine/renderer/web_engine_url_loader_throttle_provider.h"
#include "fuchsia/engine/switches.h"
@@ -110,16 +112,16 @@ WebEngineContentRendererClient::WebEngineContentRendererClient() = default;
WebEngineContentRendererClient::~WebEngineContentRendererClient() = default;
-UrlRequestRulesReceiver*
-WebEngineContentRendererClient::GetUrlRequestRulesReceiverForRenderFrameId(
+WebEngineRenderFrameObserver*
+WebEngineContentRendererClient::GetWebEngineRenderFrameObserverForRenderFrameId(
int render_frame_id) const {
- auto iter = url_request_receivers_by_id_.find(render_frame_id);
- DCHECK(iter != url_request_receivers_by_id_.end());
+ auto iter = render_frame_id_to_observer_map_.find(render_frame_id);
+ DCHECK(iter != render_frame_id_to_observer_map_.end());
return iter->second.get();
}
void WebEngineContentRendererClient::OnRenderFrameDeleted(int render_frame_id) {
- size_t count = url_request_receivers_by_id_.erase(render_frame_id);
+ size_t count = render_frame_id_to_observer_map_.erase(render_frame_id);
DCHECK_EQ(count, 1u);
}
@@ -130,13 +132,14 @@ void WebEngineContentRendererClient::RenderFrameCreated(
new OnLoadScriptInjector(render_frame);
int render_frame_id = render_frame->GetRoutingID();
- auto rules_receiver = std::make_unique<UrlRequestRulesReceiver>(
- content::RenderFrame::FromRoutingID(render_frame_id),
+
+ auto render_frame_observer = std::make_unique<WebEngineRenderFrameObserver>(
+ render_frame,
base::BindOnce(&WebEngineContentRendererClient::OnRenderFrameDeleted,
base::Unretained(this)));
- auto iter = url_request_receivers_by_id_.emplace(render_frame_id,
- std::move(rules_receiver));
- DCHECK(iter.second);
+ auto render_frame_observer_iter = render_frame_id_to_observer_map_.emplace(
+ render_frame_id, std::move(render_frame_observer));
+ DCHECK(render_frame_observer_iter.second);
// Lifetime is tied to |render_frame| via content::RenderFrameObserver.
new media_control::MediaPlaybackOptions(render_frame);
@@ -235,6 +238,30 @@ bool WebEngineContentRendererClient::DeferMediaLoad(
return RunClosureWhenInForeground(render_frame, std::move(closure));
}
+std::unique_ptr<media::Demuxer>
+WebEngineContentRendererClient::OverrideDemuxerForUrl(
+ content::RenderFrame* render_frame,
+ const GURL& url,
+ scoped_refptr<base::SingleThreadTaskRunner> media_task_runner) {
+ if (IsCastStreamingEnabled() && IsCastStreamingMediaSourceUrl(url)) {
+ auto iter =
+ render_frame_id_to_observer_map_.find(render_frame->GetRoutingID());
+ DCHECK(iter != render_frame_id_to_observer_map_.end());
+ // Do not create a CastStreamingDemuxer if the Cast Streaming MessagePort
+ // was not set in the browser process. This will manifest as an unbound
+ // CastStreamingReceiver object in the renderer process.
+ // TODO(crbug.com/1082821): Simplify the instantiation conditions for the
+ // CastStreamingDemuxer once the CastStreamingReceiver Component has been
+ // implemented.
+ if (iter->second->cast_streaming_receiver()->IsBound()) {
+ return std::make_unique<CastStreamingDemuxer>(
+ iter->second->cast_streaming_receiver(), media_task_runner);
+ }
+ }
+
+ return nullptr;
+}
+
bool WebEngineContentRendererClient::RunClosureWhenInForeground(
content::RenderFrame* render_frame,
base::OnceClosure closure) {
diff --git a/chromium/fuchsia/engine/renderer/web_engine_content_renderer_client.h b/chromium/fuchsia/engine/renderer/web_engine_content_renderer_client.h
index 93b3a110a9e..8c16a116bef 100644
--- a/chromium/fuchsia/engine/renderer/web_engine_content_renderer_client.h
+++ b/chromium/fuchsia/engine/renderer/web_engine_content_renderer_client.h
@@ -7,20 +7,21 @@
#include "base/macros.h"
#include "content/public/renderer/content_renderer_client.h"
-#include "fuchsia/engine/renderer/url_request_rules_receiver.h"
+#include "fuchsia/engine/renderer/web_engine_render_frame_observer.h"
class WebEngineContentRendererClient : public content::ContentRendererClient {
public:
WebEngineContentRendererClient();
~WebEngineContentRendererClient() override;
- // Returns the UrlRequestRulesReceiver corresponding to |render_frame_id|.
- UrlRequestRulesReceiver* GetUrlRequestRulesReceiverForRenderFrameId(
+ // Returns the WebEngineRenderFrameObserver corresponding to
+ // |render_frame_id|.
+ WebEngineRenderFrameObserver* GetWebEngineRenderFrameObserverForRenderFrameId(
int render_frame_id) const;
private:
- // Called by UrlRequestRulesReceivers when their corresponding RenderFrame is
- // in the process of being deleted.
+ // Called by WebEngineRenderFrameObserver when its corresponding RenderFrame
+ // is in the process of being deleted.
void OnRenderFrameDeleted(int render_frame_id);
// content::ContentRendererClient overrides.
@@ -35,13 +36,17 @@ class WebEngineContentRendererClient : public content::ContentRendererClient {
bool DeferMediaLoad(content::RenderFrame* render_frame,
bool has_played_media_before,
base::OnceClosure closure) override;
+ std::unique_ptr<media::Demuxer> OverrideDemuxerForUrl(
+ content::RenderFrame* render_frame,
+ const GURL& url,
+ scoped_refptr<base::SingleThreadTaskRunner> media_task_runner) override;
bool RunClosureWhenInForeground(content::RenderFrame* render_frame,
base::OnceClosure closure);
- // Map of rules receivers per RenderFrame ID.
- std::map<int, std::unique_ptr<UrlRequestRulesReceiver>>
- url_request_receivers_by_id_;
+ // Map of RenderFrame ID to WebEngineRenderFrameObserver.
+ std::map<int, std::unique_ptr<WebEngineRenderFrameObserver>>
+ render_frame_id_to_observer_map_;
DISALLOW_COPY_AND_ASSIGN(WebEngineContentRendererClient);
};
diff --git a/chromium/fuchsia/engine/renderer/web_engine_render_frame_observer.cc b/chromium/fuchsia/engine/renderer/web_engine_render_frame_observer.cc
new file mode 100644
index 00000000000..8120227565b
--- /dev/null
+++ b/chromium/fuchsia/engine/renderer/web_engine_render_frame_observer.cc
@@ -0,0 +1,25 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "fuchsia/engine/renderer/web_engine_render_frame_observer.h"
+
+#include "content/public/renderer/render_frame.h"
+
+WebEngineRenderFrameObserver::WebEngineRenderFrameObserver(
+ content::RenderFrame* render_frame,
+ base::OnceCallback<void(int)> on_render_frame_deleted_callback)
+ : content::RenderFrameObserver(render_frame),
+ url_request_rules_receiver_(render_frame),
+ cast_streaming_receiver_(render_frame),
+ on_render_frame_deleted_callback_(
+ std::move(on_render_frame_deleted_callback)) {
+ DCHECK(render_frame);
+ DCHECK(on_render_frame_deleted_callback_);
+}
+
+WebEngineRenderFrameObserver::~WebEngineRenderFrameObserver() = default;
+
+void WebEngineRenderFrameObserver::OnDestruct() {
+ std::move(on_render_frame_deleted_callback_).Run(routing_id());
+}
diff --git a/chromium/fuchsia/engine/renderer/web_engine_render_frame_observer.h b/chromium/fuchsia/engine/renderer/web_engine_render_frame_observer.h
new file mode 100644
index 00000000000..5e3f5c5c8fe
--- /dev/null
+++ b/chromium/fuchsia/engine/renderer/web_engine_render_frame_observer.h
@@ -0,0 +1,50 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef FUCHSIA_ENGINE_RENDERER_WEB_ENGINE_RENDER_FRAME_OBSERVER_H_
+#define FUCHSIA_ENGINE_RENDERER_WEB_ENGINE_RENDER_FRAME_OBSERVER_H_
+
+#include "base/callback.h"
+#include "content/public/renderer/render_frame_observer.h"
+#include "fuchsia/engine/renderer/cast_streaming_receiver.h"
+#include "fuchsia/engine/renderer/url_request_rules_receiver.h"
+
+namespace content {
+class RenderFrame;
+} // namespace content
+
+// This class owns WebEngine-specific objects whose lifespan is tied to a
+// RenderFrame. Owned by WebEngineContentRendererClient, this object will be
+// destroyed on RenderFrame destruction, triggering the destruction of all of
+// the objects it exposes.
+class WebEngineRenderFrameObserver : public content::RenderFrameObserver {
+ public:
+ // |on_render_frame_deleted_callback| must delete |this|.
+ WebEngineRenderFrameObserver(
+ content::RenderFrame* render_frame,
+ base::OnceCallback<void(int)> on_render_frame_deleted_callback);
+ ~WebEngineRenderFrameObserver() final;
+
+ WebEngineRenderFrameObserver(const WebEngineRenderFrameObserver&) = delete;
+ WebEngineRenderFrameObserver& operator=(const WebEngineRenderFrameObserver&) =
+ delete;
+
+ UrlRequestRulesReceiver* url_request_rules_receiver() {
+ return &url_request_rules_receiver_;
+ }
+ CastStreamingReceiver* cast_streaming_receiver() {
+ return &cast_streaming_receiver_;
+ }
+
+ private:
+ // content::RenderFrameObserver implementation.
+ void OnDestruct() final;
+
+ UrlRequestRulesReceiver url_request_rules_receiver_;
+ CastStreamingReceiver cast_streaming_receiver_;
+
+ base::OnceCallback<void(int)> on_render_frame_deleted_callback_;
+};
+
+#endif // FUCHSIA_ENGINE_RENDERER_WEB_ENGINE_RENDER_FRAME_OBSERVER_H_
diff --git a/chromium/fuchsia/engine/renderer/web_engine_url_loader_throttle_provider.cc b/chromium/fuchsia/engine/renderer/web_engine_url_loader_throttle_provider.cc
index 5b24b461406..95e8e64d510 100644
--- a/chromium/fuchsia/engine/renderer/web_engine_url_loader_throttle_provider.cc
+++ b/chromium/fuchsia/engine/renderer/web_engine_url_loader_throttle_provider.cc
@@ -33,8 +33,9 @@ WebEngineURLLoaderThrottleProvider::CreateThrottles(
std::vector<std::unique_ptr<blink::URLLoaderThrottle>> throttles;
throttles.emplace_back(std::make_unique<WebEngineURLLoaderThrottle>(
- content_renderer_client_->GetUrlRequestRulesReceiverForRenderFrameId(
- render_frame_id)));
+ content_renderer_client_
+ ->GetWebEngineRenderFrameObserverForRenderFrameId(render_frame_id)
+ ->url_request_rules_receiver()));
return throttles;
}