Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4581)

Unified Diff: chrome/browser/media/router/media_remoting_connector.cc

Issue 2138013003: media::mojom::Remoter and CastRemotingConnector/Sender (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Split-out some interfaces in prep for landing multi-part changes. Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/media/router/media_remoting_connector.cc
diff --git a/chrome/browser/media/router/media_remoting_connector.cc b/chrome/browser/media/router/media_remoting_connector.cc
new file mode 100644
index 0000000000000000000000000000000000000000..3de578657e2e92eaf6842d18f36963eefe12ff62
--- /dev/null
+++ b/chrome/browser/media/router/media_remoting_connector.cc
@@ -0,0 +1,231 @@
+// Copyright 2016 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 "chrome/browser/media/router/media_remoting_connector.h"
+
+#include "chrome/browser/media/router/media_remoting_provider.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
+
+DEFINE_WEB_CONTENTS_USER_DATA_KEY(media_router::MediaRemotingConnector);
+
+using content::RenderFrameHost;
+using content::WebContents;
+
+namespace media_router {
+
+class MediaRemotingConnector::FrameMediaRemoter : public media::mojom::Remoter {
+ public:
+ // |render_frame_host| represents the source frame for the remoted
+ // media. Binds |this| to the given Mojo interface |request|.
+ FrameMediaRemoter(RenderFrameHost* render_frame_host,
+ mojo::InterfaceRequest<media::mojom::Remoter> request)
+ : host_(render_frame_host),
+ binding_(this, std::move(request)) {
+ DCHECK(host_);
+ }
+
+ ~FrameMediaRemoter() final {
+ if (client_.is_bound()) {
+ if (auto* connector = MediaRemotingConnector::GetIfExists(host_))
+ connector->DeregisterFrameRemoter(this);
+ client_.reset();
+ }
+ }
+
+ media::mojom::RemoterClient* client() const { return client_.get(); }
+
+ void OnMessageFromRemote(mojo::Array<uint8_t> message) {
+ client_->OnMessageFromRemote(std::move(message));
+ }
+
+ // media::mojom::Remoter implementation.
+
+ void RegisterClient(media::mojom::RemoterClientPtr client) final {
+ WebContents* const contents = WebContents::FromRenderFrameHost(host_);
+ if (!contents)
+ return;
+
+ MediaRemotingConnector* const connector =
+ MediaRemotingConnector::Get(contents);
+ if (client_.is_bound())
+ connector->DeregisterFrameRemoter(this);
+ client_ = std::move(client);
+ if (client_.is_bound()) {
+ client_.set_connection_error_handler(base::Bind(
+ &FrameMediaRemoter::OnConnectionError, base::Unretained(this)));
+ connector->RegisterFrameRemoter(this);
+ }
+ }
+
+ void StartMediaServices(mojo::ScopedDataPipeConsumerHandle audio_pipe,
+ mojo::ScopedDataPipeConsumerHandle video_pipe,
+ const StartMediaServicesCallback& callback) final {
+ if (auto* connector = MediaRemotingConnector::GetIfExists(host_)) {
+ connector->StartMediaServices(
+ this, std::move(audio_pipe), std::move(video_pipe), callback);
+ return;
+ }
+ callback.Run(false, MOJO_HANDLE_INVALID, MOJO_HANDLE_INVALID);
+ }
+
+ void StopMediaServices(const mojo::String& error_reason) final {
+ if (auto* connector = MediaRemotingConnector::GetIfExists(host_))
+ connector->StopMediaServices(this, error_reason);
+ }
+
+ void SendMessageToRemote(mojo::Array<uint8_t> message) final {
+ if (auto* connector = MediaRemotingConnector::GetIfExists(host_))
+ connector->SendMessageToRemote(this, std::move(message));
+ }
+
+ void SendBufferToRemote(uint32_t pipe_id,
+ media::mojom::DecoderBufferPtr buffer) final {
+ if (auto* connector = MediaRemotingConnector::GetIfExists(host_))
+ connector->SendBufferToRemote(this, pipe_id, std::move(buffer));
+ }
+
+ private:
+ void OnConnectionError() {
+ if (auto* connector = MediaRemotingConnector::GetIfExists(host_))
+ connector->DeregisterFrameRemoter(this);
+ }
+
+ RenderFrameHost* const host_;
+ const mojo::StrongBinding<media::mojom::Remoter> binding_;
+
+ media::mojom::RemoterClientPtr client_;
+
+ DISALLOW_COPY_AND_ASSIGN(FrameMediaRemoter);
+};
+
+// static
+MediaRemotingConnector* MediaRemotingConnector::Get(WebContents* contents) {
+ MediaRemotingConnector* connector = FromWebContents(contents);
+ if (connector)
+ return connector;
+ connector = new MediaRemotingConnector(contents);
+ // The following transfers ownership of |connector| to WebContents.
+ contents->SetUserData(UserDataKey(), connector);
+ return connector;
+}
+
+// static
+MediaRemotingConnector* MediaRemotingConnector::GetIfExists(
+ RenderFrameHost* render_frame_host) {
+ if (auto* contents = WebContents::FromRenderFrameHost(render_frame_host))
+ return FromWebContents(contents);
+ return nullptr;
+}
+
+// static
+void MediaRemotingConnector::CreateRemoter(
+ RenderFrameHost* render_frame_host,
+ mojo::InterfaceRequest<media::mojom::Remoter> request) {
+ // The FrameMediaRemoter instance self-destructs when the bound pipe
+ // encounters an error or is closed on the other end.
+ new FrameMediaRemoter(render_frame_host, std::move(request));
+}
+
+MediaRemotingConnector::MediaRemotingConnector(WebContents* contents)
+ : provider_(nullptr), active_remoter_(nullptr) {}
+
+MediaRemotingConnector::~MediaRemotingConnector() {
+ if (provider_)
+ SetProvider(nullptr);
+}
+
+void MediaRemotingConnector::SetProvider(MediaRemotingProvider* provider) {
+ // Disconnect the prior provider.
+ if (provider_) {
+ for (FrameMediaRemoter* remoter : remoters_) {
+ if (auto* client = remoter->client())
+ client->OnRemoteServicesGone();
+ }
+ if (active_remoter_)
+ StopMediaServices(active_remoter_, mojo::String(nullptr));
+ }
+
+ provider_ = provider;
+
+ // Notify the RemoterClients that a new provider of remoting services is
+ // available and ready.
+ if (provider_) {
+ auto* const capabilities = provider_->GetRemoteCapabilities();
+ DCHECK(capabilities);
+ for (FrameMediaRemoter* remoter : remoters_) {
+ if (auto* client = remoter->client())
+ client->OnRemoteServicesAvailable(capabilities->Clone());
+ }
+ }
+}
+
+void MediaRemotingConnector::RegisterFrameRemoter(FrameMediaRemoter* remoter) {
+ DCHECK(remoters_.find(remoter) == remoters_.end());
+ DCHECK(remoter->client());
+ remoters_.insert(remoter);
+ if (provider_) {
+ auto* const capabilities = provider_->GetRemoteCapabilities();
+ DCHECK(capabilities);
+ remoter->client()->OnRemoteServicesAvailable(capabilities->Clone());
+ }
+}
+
+void MediaRemotingConnector::DeregisterFrameRemoter(
+ FrameMediaRemoter* remoter) {
+ if (auto* client = remoter->client())
+ client->OnRemoteServicesGone();
+ if (remoter == active_remoter_)
+ StopMediaServices(remoter, mojo::String(nullptr));
+ remoters_.erase(remoter);
+}
+
+void MediaRemotingConnector::StartMediaServices(
+ FrameMediaRemoter* remoter,
+ mojo::ScopedDataPipeConsumerHandle audio_pipe,
+ mojo::ScopedDataPipeConsumerHandle video_pipe,
+ const base::Callback<void(bool, uint32_t, uint32_t)>& callback) {
+ DCHECK(remoters_.find(remoter) != remoters_.end());
+ DCHECK(remoter->client());
+ const uint32_t audio_pipe_id = audio_pipe->value();
+ const uint32_t video_pipe_id = video_pipe->value();
+ if (!active_remoter_ && provider_ &&
+ provider_->StartMediaServices(
+ std::move(audio_pipe), std::move(video_pipe),
+ base::Bind(&FrameMediaRemoter::OnMessageFromRemote,
+ base::Unretained(remoter)))) {
+ active_remoter_ = remoter;
+ DCHECK_NE(audio_pipe_id, video_pipe_id);
+ callback.Run(true, audio_pipe_id, video_pipe_id);
+ return;
+ }
+ callback.Run(false, MOJO_HANDLE_INVALID, MOJO_HANDLE_INVALID);
+}
+
+void MediaRemotingConnector::StopMediaServices(
+ FrameMediaRemoter* remoter, const mojo::String& error_reason) {
+ if (active_remoter_ != remoter)
+ return;
+ if (provider_)
+ provider_->StopMediaServices(error_reason);
+ active_remoter_ = nullptr;
+ if (auto* client = remoter->client())
+ client->OnMediaServicesStopped("");
+}
+
+void MediaRemotingConnector::SendMessageToRemote(
+ FrameMediaRemoter* remoter, mojo::Array<uint8_t> message) {
+ if (active_remoter_ != remoter || !provider_)
+ return;
+ provider_->SendMessageToRemote(std::move(message));
+}
+
+void MediaRemotingConnector::SendBufferToRemote(
+ FrameMediaRemoter* remoter, uint32_t pipe_id,
+ media::mojom::DecoderBufferPtr buffer) {
+ if (active_remoter_ != remoter || !provider_)
+ return;
+ provider_->SendBufferToRemote(pipe_id, std::move(buffer));
+}
+
+} // namespace media_router
« no previous file with comments | « chrome/browser/media/router/media_remoting_connector.h ('k') | chrome/browser/media/router/media_remoting_provider.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698