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

Side by Side 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/media/router/media_remoting_connector.h"
6
7 #include "chrome/browser/media/router/media_remoting_provider.h"
8 #include "mojo/public/cpp/bindings/strong_binding.h"
9
10 DEFINE_WEB_CONTENTS_USER_DATA_KEY(media_router::MediaRemotingConnector);
11
12 using content::RenderFrameHost;
13 using content::WebContents;
14
15 namespace media_router {
16
17 class MediaRemotingConnector::FrameMediaRemoter : public media::mojom::Remoter {
18 public:
19 // |render_frame_host| represents the source frame for the remoted
20 // media. Binds |this| to the given Mojo interface |request|.
21 FrameMediaRemoter(RenderFrameHost* render_frame_host,
22 mojo::InterfaceRequest<media::mojom::Remoter> request)
23 : host_(render_frame_host),
24 binding_(this, std::move(request)) {
25 DCHECK(host_);
26 }
27
28 ~FrameMediaRemoter() final {
29 if (client_.is_bound()) {
30 if (auto* connector = MediaRemotingConnector::GetIfExists(host_))
31 connector->DeregisterFrameRemoter(this);
32 client_.reset();
33 }
34 }
35
36 media::mojom::RemoterClient* client() const { return client_.get(); }
37
38 void OnMessageFromRemote(mojo::Array<uint8_t> message) {
39 client_->OnMessageFromRemote(std::move(message));
40 }
41
42 // media::mojom::Remoter implementation.
43
44 void RegisterClient(media::mojom::RemoterClientPtr client) final {
45 WebContents* const contents = WebContents::FromRenderFrameHost(host_);
46 if (!contents)
47 return;
48
49 MediaRemotingConnector* const connector =
50 MediaRemotingConnector::Get(contents);
51 if (client_.is_bound())
52 connector->DeregisterFrameRemoter(this);
53 client_ = std::move(client);
54 if (client_.is_bound()) {
55 client_.set_connection_error_handler(base::Bind(
56 &FrameMediaRemoter::OnConnectionError, base::Unretained(this)));
57 connector->RegisterFrameRemoter(this);
58 }
59 }
60
61 void StartMediaServices(mojo::ScopedDataPipeConsumerHandle audio_pipe,
62 mojo::ScopedDataPipeConsumerHandle video_pipe,
63 const StartMediaServicesCallback& callback) final {
64 if (auto* connector = MediaRemotingConnector::GetIfExists(host_)) {
65 connector->StartMediaServices(
66 this, std::move(audio_pipe), std::move(video_pipe), callback);
67 return;
68 }
69 callback.Run(false, MOJO_HANDLE_INVALID, MOJO_HANDLE_INVALID);
70 }
71
72 void StopMediaServices(const mojo::String& error_reason) final {
73 if (auto* connector = MediaRemotingConnector::GetIfExists(host_))
74 connector->StopMediaServices(this, error_reason);
75 }
76
77 void SendMessageToRemote(mojo::Array<uint8_t> message) final {
78 if (auto* connector = MediaRemotingConnector::GetIfExists(host_))
79 connector->SendMessageToRemote(this, std::move(message));
80 }
81
82 void SendBufferToRemote(uint32_t pipe_id,
83 media::mojom::DecoderBufferPtr buffer) final {
84 if (auto* connector = MediaRemotingConnector::GetIfExists(host_))
85 connector->SendBufferToRemote(this, pipe_id, std::move(buffer));
86 }
87
88 private:
89 void OnConnectionError() {
90 if (auto* connector = MediaRemotingConnector::GetIfExists(host_))
91 connector->DeregisterFrameRemoter(this);
92 }
93
94 RenderFrameHost* const host_;
95 const mojo::StrongBinding<media::mojom::Remoter> binding_;
96
97 media::mojom::RemoterClientPtr client_;
98
99 DISALLOW_COPY_AND_ASSIGN(FrameMediaRemoter);
100 };
101
102 // static
103 MediaRemotingConnector* MediaRemotingConnector::Get(WebContents* contents) {
104 MediaRemotingConnector* connector = FromWebContents(contents);
105 if (connector)
106 return connector;
107 connector = new MediaRemotingConnector(contents);
108 // The following transfers ownership of |connector| to WebContents.
109 contents->SetUserData(UserDataKey(), connector);
110 return connector;
111 }
112
113 // static
114 MediaRemotingConnector* MediaRemotingConnector::GetIfExists(
115 RenderFrameHost* render_frame_host) {
116 if (auto* contents = WebContents::FromRenderFrameHost(render_frame_host))
117 return FromWebContents(contents);
118 return nullptr;
119 }
120
121 // static
122 void MediaRemotingConnector::CreateRemoter(
123 RenderFrameHost* render_frame_host,
124 mojo::InterfaceRequest<media::mojom::Remoter> request) {
125 // The FrameMediaRemoter instance self-destructs when the bound pipe
126 // encounters an error or is closed on the other end.
127 new FrameMediaRemoter(render_frame_host, std::move(request));
128 }
129
130 MediaRemotingConnector::MediaRemotingConnector(WebContents* contents)
131 : provider_(nullptr), active_remoter_(nullptr) {}
132
133 MediaRemotingConnector::~MediaRemotingConnector() {
134 if (provider_)
135 SetProvider(nullptr);
136 }
137
138 void MediaRemotingConnector::SetProvider(MediaRemotingProvider* provider) {
139 // Disconnect the prior provider.
140 if (provider_) {
141 for (FrameMediaRemoter* remoter : remoters_) {
142 if (auto* client = remoter->client())
143 client->OnRemoteServicesGone();
144 }
145 if (active_remoter_)
146 StopMediaServices(active_remoter_, mojo::String(nullptr));
147 }
148
149 provider_ = provider;
150
151 // Notify the RemoterClients that a new provider of remoting services is
152 // available and ready.
153 if (provider_) {
154 auto* const capabilities = provider_->GetRemoteCapabilities();
155 DCHECK(capabilities);
156 for (FrameMediaRemoter* remoter : remoters_) {
157 if (auto* client = remoter->client())
158 client->OnRemoteServicesAvailable(capabilities->Clone());
159 }
160 }
161 }
162
163 void MediaRemotingConnector::RegisterFrameRemoter(FrameMediaRemoter* remoter) {
164 DCHECK(remoters_.find(remoter) == remoters_.end());
165 DCHECK(remoter->client());
166 remoters_.insert(remoter);
167 if (provider_) {
168 auto* const capabilities = provider_->GetRemoteCapabilities();
169 DCHECK(capabilities);
170 remoter->client()->OnRemoteServicesAvailable(capabilities->Clone());
171 }
172 }
173
174 void MediaRemotingConnector::DeregisterFrameRemoter(
175 FrameMediaRemoter* remoter) {
176 if (auto* client = remoter->client())
177 client->OnRemoteServicesGone();
178 if (remoter == active_remoter_)
179 StopMediaServices(remoter, mojo::String(nullptr));
180 remoters_.erase(remoter);
181 }
182
183 void MediaRemotingConnector::StartMediaServices(
184 FrameMediaRemoter* remoter,
185 mojo::ScopedDataPipeConsumerHandle audio_pipe,
186 mojo::ScopedDataPipeConsumerHandle video_pipe,
187 const base::Callback<void(bool, uint32_t, uint32_t)>& callback) {
188 DCHECK(remoters_.find(remoter) != remoters_.end());
189 DCHECK(remoter->client());
190 const uint32_t audio_pipe_id = audio_pipe->value();
191 const uint32_t video_pipe_id = video_pipe->value();
192 if (!active_remoter_ && provider_ &&
193 provider_->StartMediaServices(
194 std::move(audio_pipe), std::move(video_pipe),
195 base::Bind(&FrameMediaRemoter::OnMessageFromRemote,
196 base::Unretained(remoter)))) {
197 active_remoter_ = remoter;
198 DCHECK_NE(audio_pipe_id, video_pipe_id);
199 callback.Run(true, audio_pipe_id, video_pipe_id);
200 return;
201 }
202 callback.Run(false, MOJO_HANDLE_INVALID, MOJO_HANDLE_INVALID);
203 }
204
205 void MediaRemotingConnector::StopMediaServices(
206 FrameMediaRemoter* remoter, const mojo::String& error_reason) {
207 if (active_remoter_ != remoter)
208 return;
209 if (provider_)
210 provider_->StopMediaServices(error_reason);
211 active_remoter_ = nullptr;
212 if (auto* client = remoter->client())
213 client->OnMediaServicesStopped("");
214 }
215
216 void MediaRemotingConnector::SendMessageToRemote(
217 FrameMediaRemoter* remoter, mojo::Array<uint8_t> message) {
218 if (active_remoter_ != remoter || !provider_)
219 return;
220 provider_->SendMessageToRemote(std::move(message));
221 }
222
223 void MediaRemotingConnector::SendBufferToRemote(
224 FrameMediaRemoter* remoter, uint32_t pipe_id,
225 media::mojom::DecoderBufferPtr buffer) {
226 if (active_remoter_ != remoter || !provider_)
227 return;
228 provider_->SendBufferToRemote(pipe_id, std::move(buffer));
229 }
230
231 } // namespace media_router
OLDNEW
« 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