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

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: Addresses Wez's comments 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_sink.h"
17 #include "chrome/browser/media/router/media_source_helper.h"
18 #include "chrome/browser/media/router/presentation_helper.h"
19 #include "chrome/browser/media/router/presentation_media_sinks_observer.h"
20 #include "chrome/browser/sessions/session_tab_helper.h"
21 #include "content/public/browser/presentation_screen_availability_listener.h"
22 #include "content/public/browser/presentation_session.h"
23 #include "content/public/browser/render_frame_host.h"
24 #include "content/public/browser/render_process_host.h"
25
26 DEFINE_WEB_CONTENTS_USER_DATA_KEY(
27 media_router::PresentationServiceDelegateImpl);
28
29 using content::RenderFrameHost;
30
31 namespace media_router {
32
33 using RenderFrameHostId = std::pair<int, int>;
34
35 namespace {
36
37 // Returns the unique identifier for the supplied RenderViewHost.
38 RenderFrameHostId GetRenderFrameHostId(RenderFrameHost* render_view_host) {
39 int render_process_id = render_view_host->GetProcess()->GetID();
40 int render_frame_id = render_view_host->GetRoutingID();
41 return RenderFrameHostId(render_process_id, render_frame_id);
42 }
43
44 std::string GetDisplayNameForFrame(RenderFrameHostId render_frame_host_id) {
45 RenderFrameHost* render_view_host = RenderFrameHost::FromID(
46 render_frame_host_id.first, render_frame_host_id.second);
47 std::string host = render_view_host->GetLastCommittedURL().host();
48 if (StartsWithASCII(host, "www.", false))
49 host = host.substr(4);
50 return host;
51 }
52
53 } // namespace
54
55 // Used by PresentationServiceDelegateImpl to manage
56 // listeners and default presentation info in a render frame.
57 // Its lifetime:
58 // * PresentationFrameManager AddDelegateObserver
59 // * Reset 0+ times.
60 // * PresentationFrameManager.RemoveDelegateObserver.
61 class PresentationFrame {
62 public:
63 using DelegateObserver = content::PresentationServiceDelegate::Observer;
64
65 PresentationFrame(content::WebContents* web_contents, MediaRouter* router);
66 ~PresentationFrame();
67
68 // Mirror corresponding APIs in PresentationServiceDelegateImpl.
mark a. foltz 2015/06/01 19:18:12 Why doesn't this implement content::PresentationSe
haibinlu 2015/06/01 21:44:58 PresentationFrame/Manager do not implement StartSe
mark a. foltz 2015/06/02 00:18:39 Acknowledged.
69 bool SetScreenAvailabilityListener(
70 content::PresentationScreenAvailabilityListener* listener);
71 bool RemoveScreenAvailabilityListener(
72 content::PresentationScreenAvailabilityListener* listener);
73 bool HasScreenAvailabilityListenerForTest(
74 const MediaSourceId& source_id) const;
75 void SetDefaultPresentationInfo(const std::string& default_presentation_url,
76 const std::string& default_presentation_id);
77 std::string GetDefaultPresentationId() const;
78 void Reset();
79
80 void OnDefaultPresentationStarted(
81 const content::PresentationSessionInfo& session) const;
82 void OnPresentationServiceDelegateDestroyed() const;
83
84 void set_delegate_observer(DelegateObserver* observer) {
85 delegate_observer_ = observer;
86 }
87
88 private:
89 MediaSource GetMediaSourceFromListener(
90 content::PresentationScreenAvailabilityListener* listener) const;
91
92 scoped_ptr<content::PresentationSessionInfo> default_presentation_info_;
93 scoped_ptr<PresentationMediaSinksObserver> sink_observer_;
mark a. foltz 2015/06/01 19:18:12 nit: sinks_observer_
haibinlu 2015/06/01 21:44:58 Done.
94
95 // References to the owning WebContents, and the corresponding MediaRouter.
96 const content::WebContents* web_contents_;
97 MediaRouter* router_;
98
99 DelegateObserver* delegate_observer_;
100 };
101
102 PresentationFrame::PresentationFrame(content::WebContents* web_contents,
103 MediaRouter* router)
104 : web_contents_(web_contents),
105 router_(router),
106 delegate_observer_(nullptr) {
107 DCHECK(web_contents_);
108 DCHECK(router_);
109 }
110
111 PresentationFrame::~PresentationFrame() {
112 }
113
114 void PresentationFrame::OnPresentationServiceDelegateDestroyed() const {
115 if (delegate_observer_)
116 delegate_observer_->OnDelegateDestroyed();
117 }
118
119 void PresentationFrame::OnDefaultPresentationStarted(
120 const content::PresentationSessionInfo& session) const {
121 if (delegate_observer_)
122 delegate_observer_->OnDefaultPresentationStarted(session);
123 }
124
125 bool PresentationFrame::SetScreenAvailabilityListener(
126 content::PresentationScreenAvailabilityListener* listener) {
127 if (sink_observer_ && sink_observer_->listener() == listener) {
128 return false;
129 }
130 MediaSource source(GetMediaSourceFromListener(listener));
131 sink_observer_.reset(
132 new PresentationMediaSinksObserver(router_, listener, source));
133 return true;
134 }
135
136 bool PresentationFrame::RemoveScreenAvailabilityListener(
137 content::PresentationScreenAvailabilityListener* listener) {
138 if (sink_observer_ && sink_observer_->listener() == listener) {
139 sink_observer_.reset();
140 return true;
141 }
142 return false;
143 }
144
145 bool PresentationFrame::HasScreenAvailabilityListenerForTest(
146 const MediaSourceId& source_id) const {
147 return sink_observer_ && sink_observer_->source().id() == source_id;
148 }
149
150 void PresentationFrame::Reset() {
151 sink_observer_.reset();
152 default_presentation_info_.reset();
153 }
154
155 void PresentationFrame::SetDefaultPresentationInfo(
156 const std::string& default_presentation_url,
157 const std::string& default_presentation_id) {
158 if (default_presentation_url.empty() && default_presentation_id.empty()) {
159 default_presentation_info_.reset();
160 } else {
161 default_presentation_info_.reset(new content::PresentationSessionInfo(
162 default_presentation_url, default_presentation_id));
163 }
164 }
165
166 std::string PresentationFrame::GetDefaultPresentationId() const {
167 if (default_presentation_info_)
168 return default_presentation_info_->presentation_id;
mark a. foltz 2015/06/01 19:18:12 return default_presentation_info_ ? default_presen
haibinlu 2015/06/01 21:44:58 wez@ prefers "if() return a; return b;" style. I a
mark a. foltz 2015/06/02 00:18:39 Ok, we have different preferences on that front.
169 return "";
170 }
171
172 MediaSource PresentationFrame::GetMediaSourceFromListener(
173 content::PresentationScreenAvailabilityListener* listener) const {
174 // If the default presentation URL is empty then fall back to tab mirroring.
175 std::string presentation_url(listener->GetPresentationUrl());
176 if (presentation_url.empty())
mark a. foltz 2015/06/01 19:18:12 Ditto
haibinlu 2015/06/01 21:44:58 wez@ prefers "if() return a; return b;" style. I a
177 return MediaSourceForTab(SessionTabHelper::IdForTab(web_contents_));
178 return MediaSourceForPresentationUrl(presentation_url);
179 }
180
181 // Used by PresentationServiceDelegateImpl to manage PresentationFrames.
182 class PresentationFrameManager {
183 public:
184 using DelegateObserver = content::PresentationServiceDelegate::Observer;
mark a. foltz 2015/06/01 19:18:13 Repeated definition. Move to file level?
haibinlu 2015/06/01 21:44:58 Done.
185
186 PresentationFrameManager(content::WebContents* web_contents,
187 MediaRouter* router);
188 ~PresentationFrameManager();
189
190 // Mirror corresponding APIs in PresentationServiceDelegateImpl.
191 bool SetScreenAvailabilityListener(
192 const RenderFrameHostId& render_frame_host_id,
193 content::PresentationScreenAvailabilityListener* listener);
194 bool RemoveScreenAvailabilityListener(
195 const RenderFrameHostId& render_frame_host_id,
196 content::PresentationScreenAvailabilityListener* listener);
197 void SetDefaultPresentationInfo(const RenderFrameHostId& render_frame_host_id,
198 const std::string& default_presentation_url,
199 const std::string& default_presentation_id);
200 void AddDelegateObserver(const RenderFrameHostId& render_frame_host_id,
201 DelegateObserver* observer);
202 void RemoveDelegateObserver(const RenderFrameHostId& render_frame_host_id);
203 void Reset(const RenderFrameHostId& render_frame_host_id);
204 bool HasScreenAvailabilityListenerForTest(
205 const RenderFrameHostId& render_frame_host_id,
206 const MediaSourceId& source_id) const;
207 void SetMediaRouterForTest(MediaRouter* router);
208
209 // Returns default presentation ID, or empty string if no default
210 // presentation ID is set in the frame.
211 std::string GetDefaultPresentationId(
212 const RenderFrameHostId& render_frame_host_id) const;
213
214 void OnDefaultPresentationStarted(
215 const RenderFrameHostId& render_frame_host_id,
216 const content::PresentationSessionInfo& session) const;
217
218 private:
219 PresentationFrame* GetOrAddFrame(
220 const RenderFrameHostId& render_frame_host_id);
221
222 // Maps a frame identifier to a PresentationFrame object for frames
223 // that are using presentation API.
224 base::ScopedPtrHashMap<RenderFrameHostId, scoped_ptr<PresentationFrame>>
225 presentation_frames_;
226
227 // References to the owning WebContents, and the corresponding MediaRouter.
228 MediaRouter* router_;
229 content::WebContents* web_contents_;
230 };
231
232 PresentationFrameManager::PresentationFrameManager(
233 content::WebContents* web_contents,
234 MediaRouter* router)
235 : router_(router), web_contents_(web_contents) {
236 DCHECK(web_contents_);
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 = GetOrAddFrame(render_frame_host_id);
mark a. foltz 2015/06/01 19:18:12 GetOrAddPresentationFrame? (We aren't creating a D
haibinlu 2015/06/01 21:44:58 Done.
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 = GetOrAddFrame(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 if (presentation_frame)
290 return presentation_frame->GetDefaultPresentationId();
291 return "";
292 }
293
294 void PresentationFrameManager::AddDelegateObserver(
295 const RenderFrameHostId& render_frame_host_id,
296 content::PresentationServiceDelegate::Observer* observer) {
297 auto presentation_frame = GetOrAddFrame(render_frame_host_id);
298 presentation_frame->set_delegate_observer(observer);
299 }
300
301 void PresentationFrameManager::RemoveDelegateObserver(
302 const RenderFrameHostId& render_frame_host_id) {
303 auto presentation_frame = presentation_frames_.get(render_frame_host_id);
304 if (presentation_frame) {
305 presentation_frame->set_delegate_observer(nullptr);
306 presentation_frames_.erase(render_frame_host_id);
307 }
308 }
309
310 void PresentationFrameManager::Reset(
311 const RenderFrameHostId& render_frame_host_id) {
312 auto presentation_frame = presentation_frames_.get(render_frame_host_id);
313 if (presentation_frame)
314 presentation_frame->Reset();
315 }
316
317 PresentationFrame* PresentationFrameManager::GetOrAddFrame(
318 const RenderFrameHostId& render_frame_host_id) {
319 if (!presentation_frames_.contains(render_frame_host_id)) {
320 presentation_frames_.add(
321 render_frame_host_id,
322 scoped_ptr<PresentationFrame>(
323 new PresentationFrame(web_contents_, router_)));
324 }
325 return presentation_frames_.get(render_frame_host_id);
326 }
327
328 void PresentationFrameManager::SetMediaRouterForTest(MediaRouter* router) {
329 router_ = router;
330 }
331
332 // TODO(haibinlu): Get router from MediaRouterMojoImplFactory once it lands.
333 // BUG=464205
mark a. foltz 2015/06/01 19:18:12 https://codereview.chromium.org/1143603004/ has la
haibinlu 2015/06/01 21:44:58 Done.
334 PresentationServiceDelegateImpl::PresentationServiceDelegateImpl(
335 content::WebContents* web_contents)
336 : frame_manager_(new PresentationFrameManager(web_contents, nullptr)),
337 web_contents_(web_contents),
338 router_(nullptr),
339 weak_factory_(this) {
340 }
341
342 PresentationServiceDelegateImpl::~PresentationServiceDelegateImpl() {
343 }
344
345 void PresentationServiceDelegateImpl::AddObserver(
346 int render_process_id,
347 int render_frame_id,
348 content::PresentationServiceDelegate::Observer* observer) {
349 DCHECK(observer);
350 frame_manager_->AddDelegateObserver(
351 RenderFrameHostId(render_process_id, render_frame_id), observer);
352 }
353
354 void PresentationServiceDelegateImpl::RemoveObserver(int render_process_id,
355 int render_frame_id) {
356 frame_manager_->RemoveDelegateObserver(
357 RenderFrameHostId(render_process_id, render_frame_id));
358 }
359
360 bool PresentationServiceDelegateImpl::AddScreenAvailabilityListener(
361 int render_process_id,
362 int render_frame_id,
363 content::PresentationScreenAvailabilityListener* listener) {
364 DCHECK(listener);
365 return frame_manager_->SetScreenAvailabilityListener(
366 RenderFrameHostId(render_process_id, render_frame_id), listener);
367 }
368
369 void PresentationServiceDelegateImpl::RemoveScreenAvailabilityListener(
370 int render_process_id,
371 int render_frame_id,
372 content::PresentationScreenAvailabilityListener* listener) {
373 DCHECK(listener);
374 frame_manager_->RemoveScreenAvailabilityListener(
375 RenderFrameHostId(render_process_id, render_frame_id), listener);
376 }
377
378 void PresentationServiceDelegateImpl::Reset(int render_process_id,
379 int render_frame_id) {
380 RenderFrameHostId render_frame_host_id(render_process_id, render_frame_id);
381 frame_manager_->Reset(render_frame_host_id);
382 if (IsMainFrame(render_process_id, render_frame_id))
383 UpdateDefaultMediaSourceAndNotifyObservers(MediaSource(), std::string());
384 }
385
386 void PresentationServiceDelegateImpl::SetDefaultPresentationUrl(
387 int render_process_id,
388 int render_frame_id,
389 const std::string& default_presentation_url,
390 const std::string& default_presentation_id) {
391 RenderFrameHostId render_frame_host_id(render_process_id, render_frame_id);
392 frame_manager_->SetDefaultPresentationInfo(
393 render_frame_host_id, default_presentation_url, default_presentation_id);
394 if (IsMainFrame(render_process_id, render_frame_id)) {
395 // This is the main frame, which means tab-level default presentation
396 // might have been updated.
397 MediaSource default_source;
398 if (!default_presentation_url.empty())
399 default_source = MediaSourceForPresentationUrl(default_presentation_url);
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