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

Side by Side Diff: chrome/browser/media/router/presentation_service_delegate_impl.cc

Issue 1132903002: [MediaRouter] Add implementation of PresentationServiceDelegate (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 6 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 2015 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/presentation_service_delegate_impl.h"
6
7 #include <string>
8
9 #include "base/containers/scoped_ptr_hash_map.h"
10 #include "base/guid.h"
11 #include "base/strings/string_util.h"
12 #include "base/strings/stringprintf.h"
13 #include "chrome/browser/media/router/create_session_request.h"
14 #include "chrome/browser/media/router/media_route.h"
15 #include "chrome/browser/media/router/media_router.h"
16 #include "chrome/browser/media/router/media_router_mojo_impl.h"
17 #include "chrome/browser/media/router/media_router_mojo_impl_factory.h"
18 #include "chrome/browser/media/router/media_sink.h"
19 #include "chrome/browser/media/router/media_source_helper.h"
20 #include "chrome/browser/media/router/presentation_media_sinks_observer.h"
21 #include "chrome/browser/sessions/session_tab_helper.h"
22 #include "content/public/browser/presentation_screen_availability_listener.h"
23 #include "content/public/browser/presentation_session.h"
24 #include "content/public/browser/render_frame_host.h"
25 #include "content/public/browser/render_process_host.h"
26
27 DEFINE_WEB_CONTENTS_USER_DATA_KEY(
28 media_router::PresentationServiceDelegateImpl);
29
30 using content::RenderFrameHost;
31
32 namespace media_router {
33
34 using RenderFrameHostId = std::pair<int, int>;
35
36 namespace {
37
38 using DelegateObserver = content::PresentationServiceDelegate::Observer;
39
40 // Returns the unique identifier for the supplied RenderViewHost.
41 RenderFrameHostId GetRenderFrameHostId(RenderFrameHost* render_view_host) {
42 int render_process_id = render_view_host->GetProcess()->GetID();
43 int render_frame_id = render_view_host->GetRoutingID();
44 return RenderFrameHostId(render_process_id, render_frame_id);
45 }
46
47 std::string GetDisplayNameForFrame(RenderFrameHostId render_frame_host_id) {
48 RenderFrameHost* render_view_host = RenderFrameHost::FromID(
49 render_frame_host_id.first, render_frame_host_id.second);
50 std::string host = render_view_host->GetLastCommittedURL().host();
51 if (StartsWithASCII(host, "www.", false))
52 host = host.substr(4);
53 return host;
54 }
55
56 } // namespace
57
58 // Used by PresentationServiceDelegateImpl to manage
59 // listeners and default presentation info in a render frame.
60 // Its lifetime:
61 // * PresentationFrameManager AddDelegateObserver
62 // * Reset 0+ times.
63 // * PresentationFrameManager.RemoveDelegateObserver.
64 class PresentationFrame {
65 public:
66 PresentationFrame(content::WebContents* web_contents, MediaRouter* router);
67 ~PresentationFrame();
68
69 // Mirror corresponding APIs in PresentationServiceDelegateImpl.
70 bool SetScreenAvailabilityListener(
71 content::PresentationScreenAvailabilityListener* listener);
72 bool RemoveScreenAvailabilityListener(
73 content::PresentationScreenAvailabilityListener* listener);
74 bool HasScreenAvailabilityListenerForTest(
75 const MediaSourceId& source_id) const;
76 void SetDefaultPresentationInfo(const std::string& default_presentation_url,
77 const std::string& default_presentation_id);
78 std::string GetDefaultPresentationId() const;
79 void Reset();
80
81 void OnDefaultPresentationStarted(
82 const content::PresentationSessionInfo& session) const;
83 void OnPresentationServiceDelegateDestroyed() const;
84
85 void set_delegate_observer(DelegateObserver* observer) {
86 delegate_observer_ = observer;
87 }
88
89 private:
90 MediaSource GetMediaSourceFromListener(
91 content::PresentationScreenAvailabilityListener* listener) const;
92
93 scoped_ptr<content::PresentationSessionInfo> default_presentation_info_;
94 scoped_ptr<PresentationMediaSinksObserver> sinks_observer_;
95
96 // References to the owning WebContents, and the corresponding MediaRouter.
97 const content::WebContents* web_contents_;
98 MediaRouter* router_;
99
100 DelegateObserver* delegate_observer_;
101 };
102
103 PresentationFrame::PresentationFrame(content::WebContents* web_contents,
104 MediaRouter* router)
105 : web_contents_(web_contents),
106 router_(router),
107 delegate_observer_(nullptr) {
108 DCHECK(web_contents_);
109 DCHECK(router_);
110 }
111
112 PresentationFrame::~PresentationFrame() {
113 }
114
115 void PresentationFrame::OnPresentationServiceDelegateDestroyed() const {
116 if (delegate_observer_)
117 delegate_observer_->OnDelegateDestroyed();
118 }
119
120 void PresentationFrame::OnDefaultPresentationStarted(
121 const content::PresentationSessionInfo& session) const {
122 if (delegate_observer_)
123 delegate_observer_->OnDefaultPresentationStarted(session);
124 }
125
126 bool PresentationFrame::SetScreenAvailabilityListener(
127 content::PresentationScreenAvailabilityListener* listener) {
128 if (sinks_observer_ && sinks_observer_->listener() == listener) {
129 return false;
130 }
131 MediaSource source(GetMediaSourceFromListener(listener));
132 sinks_observer_.reset(
133 new PresentationMediaSinksObserver(router_, listener, source));
134 return true;
135 }
136
137 bool PresentationFrame::RemoveScreenAvailabilityListener(
138 content::PresentationScreenAvailabilityListener* listener) {
139 if (sinks_observer_ && sinks_observer_->listener() == listener) {
140 sinks_observer_.reset();
141 return true;
142 }
143 return false;
144 }
145
146 bool PresentationFrame::HasScreenAvailabilityListenerForTest(
147 const MediaSourceId& source_id) const {
148 return sinks_observer_ && sinks_observer_->source().id() == source_id;
149 }
150
151 void PresentationFrame::Reset() {
152 sinks_observer_.reset();
153 default_presentation_info_.reset();
154 }
155
156 void PresentationFrame::SetDefaultPresentationInfo(
157 const std::string& default_presentation_url,
158 const std::string& default_presentation_id) {
159 if (default_presentation_url.empty() && default_presentation_id.empty()) {
160 default_presentation_info_.reset();
161 } else {
162 default_presentation_info_.reset(new content::PresentationSessionInfo(
163 default_presentation_url, default_presentation_id));
164 }
165 }
166
167 std::string PresentationFrame::GetDefaultPresentationId() const {
168 return default_presentation_info_
169 ? default_presentation_info_->presentation_id
170 : "";
171 }
172
173 MediaSource PresentationFrame::GetMediaSourceFromListener(
174 content::PresentationScreenAvailabilityListener* listener) const {
175 // If the default presentation URL is empty then fall back to tab mirroring.
176 std::string presentation_url(listener->GetPresentationUrl());
177 return presentation_url.empty()
178 ? MediaSourceForTab(SessionTabHelper::IdForTab(web_contents_))
179 : MediaSourceForPresentationUrl(presentation_url);
180 }
181
182 // Used by PresentationServiceDelegateImpl to manage PresentationFrames.
183 class PresentationFrameManager {
184 public:
185 PresentationFrameManager(content::WebContents* web_contents,
186 MediaRouter* router);
187 ~PresentationFrameManager();
188
189 // Mirror corresponding APIs in PresentationServiceDelegateImpl.
190 bool SetScreenAvailabilityListener(
191 const RenderFrameHostId& render_frame_host_id,
192 content::PresentationScreenAvailabilityListener* listener);
193 bool RemoveScreenAvailabilityListener(
194 const RenderFrameHostId& render_frame_host_id,
195 content::PresentationScreenAvailabilityListener* listener);
196 void SetDefaultPresentationInfo(const RenderFrameHostId& render_frame_host_id,
197 const std::string& default_presentation_url,
198 const std::string& default_presentation_id);
199 void AddDelegateObserver(const RenderFrameHostId& render_frame_host_id,
200 DelegateObserver* observer);
201 void RemoveDelegateObserver(const RenderFrameHostId& render_frame_host_id);
202 void Reset(const RenderFrameHostId& render_frame_host_id);
203 bool HasScreenAvailabilityListenerForTest(
204 const RenderFrameHostId& render_frame_host_id,
205 const MediaSourceId& source_id) const;
206 void SetMediaRouterForTest(MediaRouter* router);
207
208 // Returns default presentation ID, or empty string if no default
209 // presentation ID is set in the frame.
210 std::string GetDefaultPresentationId(
211 const RenderFrameHostId& render_frame_host_id) const;
212
213 void OnDefaultPresentationStarted(
214 const RenderFrameHostId& render_frame_host_id,
215 const content::PresentationSessionInfo& session) const;
216
217 private:
218 PresentationFrame* GetOrAddPresentationFrame(
219 const RenderFrameHostId& render_frame_host_id);
220
221 // Maps a frame identifier to a PresentationFrame object for frames
222 // that are using presentation API.
223 base::ScopedPtrHashMap<RenderFrameHostId, scoped_ptr<PresentationFrame>>
224 presentation_frames_;
225
226 // References to the owning WebContents, and the corresponding MediaRouter.
227 MediaRouter* router_;
228 content::WebContents* web_contents_;
229 };
230
231 PresentationFrameManager::PresentationFrameManager(
232 content::WebContents* web_contents,
233 MediaRouter* router)
234 : router_(router), web_contents_(web_contents) {
235 DCHECK(web_contents_);
236 DCHECK(router_);
237 }
238
239 PresentationFrameManager::~PresentationFrameManager() {
240 for (auto& frame : presentation_frames_)
241 frame.second->OnPresentationServiceDelegateDestroyed();
242 }
243
244 void PresentationFrameManager::OnDefaultPresentationStarted(
245 const RenderFrameHostId& render_frame_host_id,
246 const content::PresentationSessionInfo& session) const {
247 auto presentation_frame = presentation_frames_.get(render_frame_host_id);
248 if (presentation_frame)
249 presentation_frame->OnDefaultPresentationStarted(session);
250 }
251
252 bool PresentationFrameManager::SetScreenAvailabilityListener(
253 const RenderFrameHostId& render_frame_host_id,
254 content::PresentationScreenAvailabilityListener* listener) {
255 DCHECK(listener);
256 auto presentation_frame = GetOrAddPresentationFrame(render_frame_host_id);
257 return presentation_frame->SetScreenAvailabilityListener(listener);
258 }
259
260 bool PresentationFrameManager::RemoveScreenAvailabilityListener(
261 const RenderFrameHostId& render_frame_host_id,
262 content::PresentationScreenAvailabilityListener* listener) {
263 DCHECK(listener);
264 auto presentation_frame = presentation_frames_.get(render_frame_host_id);
265 return presentation_frame &&
266 presentation_frame->RemoveScreenAvailabilityListener(listener);
267 }
268
269 bool PresentationFrameManager::HasScreenAvailabilityListenerForTest(
270 const RenderFrameHostId& render_frame_host_id,
271 const MediaSourceId& source_id) const {
272 auto presentation_frame = presentation_frames_.get(render_frame_host_id);
273 return presentation_frame &&
274 presentation_frame->HasScreenAvailabilityListenerForTest(source_id);
275 }
276
277 void PresentationFrameManager::SetDefaultPresentationInfo(
278 const RenderFrameHostId& render_frame_host_id,
279 const std::string& default_presentation_url,
280 const std::string& default_presentation_id) {
281 auto presentation_frame = GetOrAddPresentationFrame(render_frame_host_id);
282 presentation_frame->SetDefaultPresentationInfo(default_presentation_url,
283 default_presentation_id);
284 }
285
286 std::string PresentationFrameManager::GetDefaultPresentationId(
287 const RenderFrameHostId& render_frame_host_id) const {
288 auto presentation_frame = presentation_frames_.get(render_frame_host_id);
289 return presentation_frame ? presentation_frame->GetDefaultPresentationId()
290 : "";
291 }
292
293 void PresentationFrameManager::AddDelegateObserver(
294 const RenderFrameHostId& render_frame_host_id,
295 DelegateObserver* observer) {
296 auto presentation_frame = GetOrAddPresentationFrame(render_frame_host_id);
297 presentation_frame->set_delegate_observer(observer);
298 }
299
300 void PresentationFrameManager::RemoveDelegateObserver(
301 const RenderFrameHostId& render_frame_host_id) {
302 auto presentation_frame = presentation_frames_.get(render_frame_host_id);
303 if (presentation_frame) {
304 presentation_frame->set_delegate_observer(nullptr);
305 presentation_frames_.erase(render_frame_host_id);
306 }
307 }
308
309 void PresentationFrameManager::Reset(
310 const RenderFrameHostId& render_frame_host_id) {
311 auto presentation_frame = presentation_frames_.get(render_frame_host_id);
312 if (presentation_frame)
313 presentation_frame->Reset();
314 }
315
316 PresentationFrame* PresentationFrameManager::GetOrAddPresentationFrame(
317 const RenderFrameHostId& render_frame_host_id) {
318 if (!presentation_frames_.contains(render_frame_host_id)) {
319 presentation_frames_.add(
320 render_frame_host_id,
321 scoped_ptr<PresentationFrame>(
322 new PresentationFrame(web_contents_, router_)));
323 }
324 return presentation_frames_.get(render_frame_host_id);
325 }
326
327 void PresentationFrameManager::SetMediaRouterForTest(MediaRouter* router) {
328 router_ = router;
329 }
330
331 PresentationServiceDelegateImpl::PresentationServiceDelegateImpl(
332 content::WebContents* web_contents)
333 : web_contents_(web_contents),
334 router_(MediaRouterMojoImplFactory::GetApiForBrowserContext(
335 web_contents_->GetBrowserContext())),
336 frame_manager_(new PresentationFrameManager(web_contents, router_)),
337 weak_factory_(this) {
338 DCHECK(web_contents_);
339 DCHECK(router_);
340 }
341
342 PresentationServiceDelegateImpl::~PresentationServiceDelegateImpl() {
343 }
344
345 void PresentationServiceDelegateImpl::AddObserver(int render_process_id,
346 int render_frame_id,
347 DelegateObserver* observer) {
348 DCHECK(observer);
349 frame_manager_->AddDelegateObserver(
350 RenderFrameHostId(render_process_id, render_frame_id), observer);
351 }
352
353 void PresentationServiceDelegateImpl::RemoveObserver(int render_process_id,
354 int render_frame_id) {
355 frame_manager_->RemoveDelegateObserver(
356 RenderFrameHostId(render_process_id, render_frame_id));
357 }
358
359 bool PresentationServiceDelegateImpl::AddScreenAvailabilityListener(
360 int render_process_id,
361 int render_frame_id,
362 content::PresentationScreenAvailabilityListener* listener) {
363 DCHECK(listener);
364 return frame_manager_->SetScreenAvailabilityListener(
365 RenderFrameHostId(render_process_id, render_frame_id), listener);
366 }
367
368 void PresentationServiceDelegateImpl::RemoveScreenAvailabilityListener(
369 int render_process_id,
370 int render_frame_id,
371 content::PresentationScreenAvailabilityListener* listener) {
372 DCHECK(listener);
373 frame_manager_->RemoveScreenAvailabilityListener(
374 RenderFrameHostId(render_process_id, render_frame_id), listener);
375 }
376
377 void PresentationServiceDelegateImpl::Reset(int render_process_id,
378 int render_frame_id) {
379 RenderFrameHostId render_frame_host_id(render_process_id, render_frame_id);
380 frame_manager_->Reset(render_frame_host_id);
381 if (IsMainFrame(render_process_id, render_frame_id))
382 UpdateDefaultMediaSourceAndNotifyObservers(MediaSource(), std::string());
383 }
384
385 void PresentationServiceDelegateImpl::SetDefaultPresentationUrl(
386 int render_process_id,
387 int render_frame_id,
388 const std::string& default_presentation_url,
389 const std::string& default_presentation_id) {
390 RenderFrameHostId render_frame_host_id(render_process_id, render_frame_id);
391 frame_manager_->SetDefaultPresentationInfo(
392 render_frame_host_id, default_presentation_url, default_presentation_id);
393 if (IsMainFrame(render_process_id, render_frame_id)) {
394 // This is the main frame, which means tab-level default presentation
395 // might have been updated.
396 MediaSource default_source;
397 if (!default_presentation_url.empty())
398 default_source = MediaSourceForPresentationUrl(default_presentation_url);
399
400 std::string default_frame_display_name(
401 GetDisplayNameForFrame(render_frame_host_id));
402 UpdateDefaultMediaSourceAndNotifyObservers(default_source,
403 default_frame_display_name);
404 }
405 }
406
407 bool PresentationServiceDelegateImpl::IsMainFrame(int render_process_id,
408 int render_frame_id) const {
409 RenderFrameHost* main_frame = web_contents_->GetMainFrame();
410 return main_frame &&
411 GetRenderFrameHostId(main_frame) ==
412 RenderFrameHostId(render_process_id, render_frame_id);
413 }
414
415 void PresentationServiceDelegateImpl::
416 UpdateDefaultMediaSourceAndNotifyObservers(
417 const MediaSource& default_source,
418 const std::string& default_frame_display_name) {
419 if (!default_source.Equals(default_source_) ||
420 default_frame_display_name != default_frame_display_name_) {
421 default_source_ = default_source;
422 default_frame_display_name_ = default_frame_display_name;
423 FOR_EACH_OBSERVER(DefaultMediaSourceObserver,
424 default_media_source_observers_,
425 OnDefaultMediaSourceChanged(default_source_,
426 default_frame_display_name_));
427 }
428 }
429
430 void PresentationServiceDelegateImpl::StartSession(
431 int render_process_id,
432 int render_frame_id,
433 const std::string& presentation_url,
434 const std::string& presentation_id,
435 const PresentationSessionSuccessCallback& success_cb,
436 const PresentationSessionErrorCallback& error_cb) {
437 // BUG=464205
438 NOTIMPLEMENTED();
439 }
440
441 void PresentationServiceDelegateImpl::JoinSession(
442 int render_process_id,
443 int render_frame_id,
444 const std::string& presentation_url,
445 const std::string& presentation_id,
446 const PresentationSessionSuccessCallback& success_cb,
447 const PresentationSessionErrorCallback& error_cb) {
448 // BUG=464205
449 NOTIMPLEMENTED();
450 }
451
452 void PresentationServiceDelegateImpl::ListenForSessionMessages(
453 int render_process_id,
454 int render_frame_id,
455 const PresentationSessionMessageCallback& message_cb) {
456 // BUG=464205
457 NOTIMPLEMENTED();
458 }
459
460 void PresentationServiceDelegateImpl::SendMessage(
461 int render_process_id,
462 int render_frame_id,
463 scoped_ptr<content::PresentationSessionMessage> message_request,
464 const SendMessageCallback& send_message_cb) {
465 // BUG=464205
466 NOTIMPLEMENTED();
467 }
468
469 void PresentationServiceDelegateImpl::OnRouteCreated(const MediaRoute& route) {
470 const MediaSource& source = route.media_source();
471 DCHECK(!source.Empty());
472 if (!default_source_.Equals(source))
473 return;
474 RenderFrameHost* main_frame = web_contents_->GetMainFrame();
475 if (!main_frame)
476 return;
477 RenderFrameHostId render_frame_host_id(GetRenderFrameHostId(main_frame));
478 // TODO(imcheng): Pass in valid default presentation ID once it is
479 // available from MediaRoute URN. BUG=493365
480 frame_manager_->OnDefaultPresentationStarted(
481 render_frame_host_id,
482 content::PresentationSessionInfo(PresentationUrlFromMediaSource(source),
483 std::string()));
484 }
485
486 void PresentationServiceDelegateImpl::AddDefaultMediaSourceObserver(
487 DefaultMediaSourceObserver* observer) {
488 default_media_source_observers_.AddObserver(observer);
489 }
490
491 void PresentationServiceDelegateImpl::RemoveDefaultMediaSourceObserver(
492 DefaultMediaSourceObserver* observer) {
493 default_media_source_observers_.RemoveObserver(observer);
494 }
495
496 void PresentationServiceDelegateImpl::SetMediaRouterForTest(
497 MediaRouter* router) {
498 router_ = router;
499 frame_manager_->SetMediaRouterForTest(router);
500 }
501
502 base::WeakPtr<PresentationServiceDelegateImpl>
503 PresentationServiceDelegateImpl::GetWeakPtr() {
504 return weak_factory_.GetWeakPtr();
505 }
506
507 bool PresentationServiceDelegateImpl::HasScreenAvailabilityListenerForTest(
508 int render_process_id,
509 int render_frame_id,
510 const MediaSourceId& source_id) const {
511 RenderFrameHostId render_frame_host_id(render_process_id, render_frame_id);
512 return frame_manager_->HasScreenAvailabilityListenerForTest(
513 render_frame_host_id, source_id);
514 }
515
516 } // namespace media_router
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698