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

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

Issue 1314413005: [Presentation API] 1-UA presentation support + presenter APIs. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase again to pick up Yuri's cl Created 5 years, 2 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
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/media/router/presentation_service_delegate_impl.h" 5 #include "chrome/browser/media/router/presentation_service_delegate_impl.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/containers/scoped_ptr_hash_map.h" 9 #include "base/containers/scoped_ptr_hash_map.h"
10 #include "base/containers/scoped_ptr_map.h" 10 #include "base/containers/scoped_ptr_map.h"
11 #include "base/containers/small_map.h" 11 #include "base/containers/small_map.h"
12 #include "base/guid.h"
13 #include "base/strings/string_util.h" 12 #include "base/strings/string_util.h"
14 #include "base/strings/stringprintf.h" 13 #include "base/strings/stringprintf.h"
15 #include "chrome/browser/media/router/create_presentation_session_request.h" 14 #include "chrome/browser/media/router/create_presentation_session_request.h"
16 #include "chrome/browser/media/router/media_route.h" 15 #include "chrome/browser/media/router/media_route.h"
17 #include "chrome/browser/media/router/media_router.h" 16 #include "chrome/browser/media/router/media_router.h"
18 #include "chrome/browser/media/router/media_router_dialog_controller.h" 17 #include "chrome/browser/media/router/media_router_dialog_controller.h"
19 #include "chrome/browser/media/router/media_router_factory.h" 18 #include "chrome/browser/media/router/media_router_factory.h"
20 #include "chrome/browser/media/router/media_sink.h" 19 #include "chrome/browser/media/router/media_sink.h"
21 #include "chrome/browser/media/router/media_source_helper.h" 20 #include "chrome/browser/media/router/media_source_helper.h"
21 #include "chrome/browser/media/router/offscreen_presentation_manager.h"
22 #include "chrome/browser/media/router/offscreen_presentation_manager_factory.h"
22 #include "chrome/browser/media/router/presentation_media_sinks_observer.h" 23 #include "chrome/browser/media/router/presentation_media_sinks_observer.h"
23 #include "chrome/browser/media/router/presentation_session_messages_observer.h" 24 #include "chrome/browser/media/router/presentation_session_messages_observer.h"
24 #include "chrome/browser/media/router/presentation_session_state_observer.h" 25 #include "chrome/browser/media/router/presentation_session_state_observer.h"
25 #include "chrome/browser/sessions/session_tab_helper.h" 26 #include "chrome/browser/sessions/session_tab_helper.h"
26 #include "content/public/browser/presentation_screen_availability_listener.h" 27 #include "content/public/browser/presentation_screen_availability_listener.h"
27 #include "content/public/browser/presentation_session.h" 28 #include "content/public/browser/presentation_session.h"
28 #include "content/public/browser/presentation_session_state_listener.h" 29 #include "content/public/browser/presentation_session_state_listener.h"
29 #include "content/public/browser/render_frame_host.h" 30 #include "content/public/browser/render_frame_host.h"
30 #include "content/public/browser/render_process_host.h" 31 #include "content/public/browser/render_process_host.h"
31 32
32 DEFINE_WEB_CONTENTS_USER_DATA_KEY( 33 DEFINE_WEB_CONTENTS_USER_DATA_KEY(
33 media_router::PresentationServiceDelegateImpl); 34 media_router::PresentationServiceDelegateImpl);
34 35
35 using content::RenderFrameHost; 36 using content::RenderFrameHost;
36 37
37 namespace media_router { 38 namespace media_router {
38 39
40 using OffscreenPresentationSession =
41 OffscreenPresentationManager::OffscreenPresentationSession;
42
39 namespace { 43 namespace {
40 44
41 using DelegateObserver = content::PresentationServiceDelegate::Observer; 45 using DelegateObserver = content::PresentationServiceDelegate::Observer;
42 using PresentationSessionErrorCallback = 46 using PresentationSessionErrorCallback =
43 content::PresentationServiceDelegate::PresentationSessionErrorCallback; 47 content::PresentationServiceDelegate::PresentationSessionErrorCallback;
44 using PresentationSessionSuccessCallback = 48 using PresentationSessionSuccessCallback =
45 content::PresentationServiceDelegate::PresentationSessionSuccessCallback; 49 content::PresentationServiceDelegate::PresentationSessionSuccessCallback;
46 50
47 // Returns the unique identifier for the supplied RenderFrameHost. 51 // Returns the unique identifier for the supplied RenderFrameHost.
48 RenderFrameHostId GetRenderFrameHostId(RenderFrameHost* render_frame_host) { 52 RenderFrameHostId GetRenderFrameHostId(RenderFrameHost* render_frame_host) {
(...skipping 14 matching lines...) Expand all
63 } // namespace 67 } // namespace
64 68
65 // Used by PresentationServiceDelegateImpl to manage 69 // Used by PresentationServiceDelegateImpl to manage
66 // listeners and default presentation info in a render frame. 70 // listeners and default presentation info in a render frame.
67 // Its lifetime: 71 // Its lifetime:
68 // * PresentationFrameManager AddDelegateObserver 72 // * PresentationFrameManager AddDelegateObserver
69 // * Reset 0+ times. 73 // * Reset 0+ times.
70 // * PresentationFrameManager.RemoveDelegateObserver. 74 // * PresentationFrameManager.RemoveDelegateObserver.
71 class PresentationFrame { 75 class PresentationFrame {
72 public: 76 public:
73 PresentationFrame(content::WebContents* web_contents, MediaRouter* router); 77 PresentationFrame(content::WebContents* web_contents,
78 const RenderFrameHostId& render_frame_host_id,
79 MediaRouter* router);
74 ~PresentationFrame(); 80 ~PresentationFrame();
75 81
76 // Mirror corresponding APIs in PresentationServiceDelegateImpl. 82 // Mirror corresponding APIs in PresentationServiceDelegateImpl.
77 bool SetScreenAvailabilityListener( 83 bool SetScreenAvailabilityListener(
78 content::PresentationScreenAvailabilityListener* listener); 84 content::PresentationScreenAvailabilityListener* listener);
79 bool RemoveScreenAvailabilityListener( 85 bool RemoveScreenAvailabilityListener(
80 content::PresentationScreenAvailabilityListener* listener); 86 content::PresentationScreenAvailabilityListener* listener);
81 bool HasScreenAvailabilityListenerForTest( 87 bool HasScreenAvailabilityListenerForTest(
82 const MediaSource::Id& source_id) const; 88 const MediaSource::Id& source_id) const;
83 std::string GetDefaultPresentationId() const; 89 std::string GetDefaultPresentationId() const;
90 void SendMessage(const content::PresentationSessionInfo& session,
91 scoped_ptr<content::PresentationSessionMessage> message,
92 const content::SendMessageCallback send_message_cb);
84 bool ListenForSessionStateChange( 93 bool ListenForSessionStateChange(
85 content::PresentationSessionStateListener* listener); 94 content::PresentationSessionStateListener* listener);
86 void ListenForSessionMessages( 95 void ListenForSessionMessages(
87 const content::PresentationSessionInfo& session, 96 const content::PresentationSessionInfo& session,
88 const content::PresentationSessionMessageCallback& message_cb); 97 const content::PresentationSessionMessageCallback& message_cb);
89 void Reset(); 98 void Reset();
90 99
91 const MediaRoute::Id GetRouteId(const std::string& presentation_id) const; 100 const MediaRoute::Id GetRouteId(const std::string& presentation_id) const;
92 const std::vector<MediaRoute::Id> GetRouteIds() const;
93 void OnPresentationSessionClosed(const std::string& presentation_id); 101 void OnPresentationSessionClosed(const std::string& presentation_id);
94 102
95 void OnPresentationSessionStarted( 103 void OnPresentationSessionStarted(
96 bool is_default_presentation, 104 bool is_default_presentation,
97 const content::PresentationSessionInfo& session, 105 const content::PresentationSessionInfo& session,
98 const MediaRoute::Id& route_id); 106 const MediaRoute& route);
99 void OnPresentationServiceDelegateDestroyed() const; 107 void OnPresentationServiceDelegateDestroyed() const;
100 108
101 void set_delegate_observer(DelegateObserver* observer) { 109 void set_delegate_observer(DelegateObserver* observer) {
102 delegate_observer_ = observer; 110 delegate_observer_ = observer;
103 } 111 }
104 112
105 private: 113 private:
106 MediaSource GetMediaSourceFromListener( 114 MediaSource GetMediaSourceFromListener(
107 content::PresentationScreenAvailabilityListener* listener) const; 115 content::PresentationScreenAvailabilityListener* listener) const;
116 // Gets the OffscreenPresentationSession associated with |presentation_id|
miu 2015/10/07 21:51:46 nit: add a line of whitespace above this line
imcheng 2015/10/10 04:39:43 Done.
117 // within this frame. Returns nullptr if |presentation_id| is not
118 // registered as an offscreen presentation.
119 OffscreenPresentationSession* FindOffscreenSession(
120 const std::string& presentation_id) const;
121
108 base::SmallMap<std::map<std::string, MediaRoute::Id>> 122 base::SmallMap<std::map<std::string, MediaRoute::Id>>
109 presentation_id_to_route_id_; 123 presentation_id_to_route_id_;
110 scoped_ptr<PresentationMediaSinksObserver> sinks_observer_; 124 scoped_ptr<PresentationMediaSinksObserver> sinks_observer_;
111 125
126 // Controller objects for offscreen presentations. Note that offscreen
127 // presentations are manipulated with these objects instead of the observers
128 // and MediaRouter objects below.
129 // Maps from presentation ID to the corresponding OffscreenController within
130 // this frame.
131 base::ScopedPtrMap<std::string, scoped_ptr<OffscreenPresentationSession>>
132 offscreen_presentation_sessions_;
133
134 // For non-offscreen presentations.
112 // Maps from presentation ID to the corresponding presentation session's 135 // Maps from presentation ID to the corresponding presentation session's
113 // state change observer within this frame. 136 // state change observer within this frame.
114 base::ScopedPtrMap<std::string, scoped_ptr<PresentationSessionStateObserver>> 137 base::ScopedPtrMap<std::string, scoped_ptr<PresentationSessionStateObserver>>
115 session_state_observers_; 138 session_state_observers_;
116 ScopedVector<PresentationSessionMessagesObserver> session_messages_observers_; 139 ScopedVector<PresentationSessionMessagesObserver> session_messages_observers_;
117 140
118 // References to the owning WebContents, and the corresponding MediaRouter. 141 // References to the owning WebContents.
119 const content::WebContents* web_contents_; 142 const content::WebContents* const web_contents_;
120 MediaRouter* router_; 143
144 // ID of owning RenderFrameHost.
145 const RenderFrameHostId render_frame_host_id_;
146
147 // References to MediaRouter / OffscreenPresentationManager owned by
148 // the associated BrowserContext. They (and the BrowserContext) are
149 // guaranteed to outlive this object.
150 MediaRouter* const router_;
151 OffscreenPresentationManager* const offscreen_presentation_manager_;
121 152
122 DelegateObserver* delegate_observer_; 153 DelegateObserver* delegate_observer_;
123 }; 154 };
124 155
125 PresentationFrame::PresentationFrame(content::WebContents* web_contents, 156 PresentationFrame::PresentationFrame(
126 MediaRouter* router) 157 content::WebContents* web_contents,
158 const RenderFrameHostId& render_frame_host_id,
159 MediaRouter* router)
127 : web_contents_(web_contents), 160 : web_contents_(web_contents),
161 render_frame_host_id_(render_frame_host_id),
128 router_(router), 162 router_(router),
163 offscreen_presentation_manager_(
164 OffscreenPresentationManagerFactory::GetOrCreateForBrowserContext(
165 web_contents_->GetBrowserContext())),
129 delegate_observer_(nullptr) { 166 delegate_observer_(nullptr) {
130 DCHECK(web_contents_); 167 DCHECK(web_contents_);
131 DCHECK(router_); 168 DCHECK(router_);
169 DCHECK(offscreen_presentation_manager_);
132 } 170 }
133 171
134 PresentationFrame::~PresentationFrame() { 172 PresentationFrame::~PresentationFrame() {
135 } 173 }
136 174
137 void PresentationFrame::OnPresentationServiceDelegateDestroyed() const { 175 void PresentationFrame::OnPresentationServiceDelegateDestroyed() const {
138 if (delegate_observer_) 176 if (delegate_observer_)
139 delegate_observer_->OnDelegateDestroyed(); 177 delegate_observer_->OnDelegateDestroyed();
140 } 178 }
141 179
142 void PresentationFrame::OnPresentationSessionStarted( 180 void PresentationFrame::OnPresentationSessionStarted(
143 bool is_default_presentation, 181 bool is_default_presentation,
144 const content::PresentationSessionInfo& session, 182 const content::PresentationSessionInfo& session,
145 const MediaRoute::Id& route_id) { 183 const MediaRoute& route) {
146 presentation_id_to_route_id_[session.presentation_id] = route_id; 184 const std::string& presentation_id = session.presentation_id;
185 presentation_id_to_route_id_[presentation_id] = route.media_route_id();
147 if (is_default_presentation && delegate_observer_) 186 if (is_default_presentation && delegate_observer_)
148 delegate_observer_->OnDefaultPresentationStarted(session); 187 delegate_observer_->OnDefaultPresentationStarted(session);
188 if (route.is_offscreen_presentation()) {
189 DCHECK(!ContainsKey(offscreen_presentation_sessions_, presentation_id));
190 scoped_ptr<OffscreenPresentationSession> offscreen_session =
191 offscreen_presentation_manager_->ConnectToOffscreenPresentation(
192 presentation_id, render_frame_host_id_);
193
194 // If |offscreen_session| is nullptr, then the receiver is most likely
195 // already gone, so the route will die soon. This should happen very rarely
196 // since the receiver has to unregister itself between when offscreen
197 // presentation was created and when the resulting route arrived at MR.
198 if (!offscreen_session) {
199 // TODO(imcheng): we should probably reject the route request in this
200 // case. crbug.com/513859
201 LOG(ERROR) << "CreateOffscreenPresentationConnection returned nullptr.";
miu 2015/10/07 21:51:46 nit: DLOG(ERROR) since this message does not help
imcheng 2015/10/10 04:39:43 Done.
202 } else {
203 offscreen_presentation_sessions_.insert(presentation_id,
204 offscreen_session.Pass());
205 }
206 }
149 } 207 }
150 208
151 void PresentationFrame::OnPresentationSessionClosed( 209 void PresentationFrame::OnPresentationSessionClosed(
152 const std::string& presentation_id) { 210 const std::string& presentation_id) {
153 auto it = presentation_id_to_route_id_.find(presentation_id); 211 auto it = presentation_id_to_route_id_.find(presentation_id);
154 if (it != presentation_id_to_route_id_.end()) { 212 if (it != presentation_id_to_route_id_.end()) {
155 presentation_id_to_route_id_.erase(it); 213 presentation_id_to_route_id_.erase(it);
156 } 214 }
157 // TODO(imcheng): Notify PresentationSessionStateObserver? 215 // TODO(imcheng): Notify PresentationSessionStateObserver?
158 } 216 }
159 217
160 const MediaRoute::Id PresentationFrame::GetRouteId( 218 const MediaRoute::Id PresentationFrame::GetRouteId(
161 const std::string& presentation_id) const { 219 const std::string& presentation_id) const {
162 auto it = presentation_id_to_route_id_.find(presentation_id); 220 auto it = presentation_id_to_route_id_.find(presentation_id);
163 return it != presentation_id_to_route_id_.end() ? it->second : ""; 221 return it != presentation_id_to_route_id_.end() ? it->second : "";
164 } 222 }
165 223
166 const std::vector<MediaRoute::Id> PresentationFrame::GetRouteIds() const {
167 std::vector<MediaRoute::Id> route_ids;
168 for (const auto& e : presentation_id_to_route_id_)
169 route_ids.push_back(e.second);
170 return route_ids;
171 }
172
173 bool PresentationFrame::SetScreenAvailabilityListener( 224 bool PresentationFrame::SetScreenAvailabilityListener(
174 content::PresentationScreenAvailabilityListener* listener) { 225 content::PresentationScreenAvailabilityListener* listener) {
175 if (sinks_observer_ && sinks_observer_->listener() == listener) 226 if (sinks_observer_ && sinks_observer_->listener() == listener)
176 return false; 227 return false;
177 228
178 MediaSource source(GetMediaSourceFromListener(listener)); 229 MediaSource source(GetMediaSourceFromListener(listener));
179 sinks_observer_.reset( 230 sinks_observer_.reset(
180 new PresentationMediaSinksObserver(router_, listener, source)); 231 new PresentationMediaSinksObserver(router_, listener, source));
181 232
182 if (!sinks_observer_->is_active()) { 233 if (!sinks_observer_->is_active()) {
(...skipping 18 matching lines...) Expand all
201 const MediaSource::Id& source_id) const { 252 const MediaSource::Id& source_id) const {
202 return sinks_observer_ && sinks_observer_->source().id() == source_id; 253 return sinks_observer_ && sinks_observer_->source().id() == source_id;
203 } 254 }
204 255
205 void PresentationFrame::Reset() { 256 void PresentationFrame::Reset() {
206 for (const auto& pid_route_id : presentation_id_to_route_id_) 257 for (const auto& pid_route_id : presentation_id_to_route_id_)
207 router_->OnPresentationSessionDetached(pid_route_id.second); 258 router_->OnPresentationSessionDetached(pid_route_id.second);
208 259
209 presentation_id_to_route_id_.clear(); 260 presentation_id_to_route_id_.clear();
210 sinks_observer_.reset(); 261 sinks_observer_.reset();
262 offscreen_presentation_sessions_.clear();
211 session_state_observers_.clear(); 263 session_state_observers_.clear();
212 session_messages_observers_.clear(); 264 session_messages_observers_.clear();
213 } 265 }
214 266
267 void PresentationFrame::SendMessage(
268 const content::PresentationSessionInfo& session,
269 scoped_ptr<content::PresentationSessionMessage> message,
270 const content::SendMessageCallback send_message_cb) {
271 auto it = presentation_id_to_route_id_.find(session.presentation_id);
272 if (it == presentation_id_to_route_id_.end()) {
273 DVLOG(2) << "ListenForSessionMessages: no route for "
274 << session.presentation_id;
275 return;
276 }
277
278 OffscreenPresentationSession* offscreen_session =
279 FindOffscreenSession(session.presentation_id);
280 if (offscreen_session) {
281 offscreen_session->SendMessage(message.Pass(), send_message_cb);
282 } else {
283 if (message->is_binary()) {
284 router_->SendRouteBinaryMessage(it->second, message->data.Pass(),
285 send_message_cb);
286 } else {
287 router_->SendRouteMessage(it->second, message->message, send_message_cb);
288 }
289 }
290 }
291
292 OffscreenPresentationSession* PresentationFrame::FindOffscreenSession(
293 const std::string& presentation_id) const {
294 auto offscreen_session_it =
295 offscreen_presentation_sessions_.find(presentation_id);
296 return offscreen_session_it != offscreen_presentation_sessions_.end()
297 ? offscreen_session_it->second
298 : nullptr;
299 }
300
215 bool PresentationFrame::ListenForSessionStateChange( 301 bool PresentationFrame::ListenForSessionStateChange(
216 content::PresentationSessionStateListener* listener) { 302 content::PresentationSessionStateListener* listener) {
217 std::string presentation_id(listener->GetSessionInfo().presentation_id); 303 std::string presentation_id(listener->GetSessionInfo().presentation_id);
218 auto it = presentation_id_to_route_id_.find(presentation_id); 304 auto it = presentation_id_to_route_id_.find(presentation_id);
219 if (it == presentation_id_to_route_id_.end()) { 305 if (it == presentation_id_to_route_id_.end()) {
220 DVLOG(2) << "ListenForSessionStateChange: no route for " << presentation_id; 306 DVLOG(2) << "ListenForSessionStateChange: no route for " << presentation_id;
221 return false; 307 return false;
222 } 308 }
223 309
224 if (ContainsKey(session_state_observers_, presentation_id)) { 310 OffscreenPresentationSession* offscreen_session =
225 DVLOG(2) << "ListenForSessionStateChange: already contains a state " 311 FindOffscreenSession(presentation_id);
226 << "observer for session " << presentation_id; 312 if (offscreen_session) {
227 return false; 313 offscreen_session->ListenForStateChanges(listener);
314 return true;
315 } else {
316 if (ContainsKey(session_state_observers_, presentation_id)) {
miu 2015/10/07 21:51:46 OOC, why can there only be one observer? Should |
imcheng 2015/10/10 04:39:43 The only caller is the renderer where Presentation
317 DVLOG(2) << "ListenForSessionStateChange: already contains a state "
318 << "observer for session " << presentation_id;
319 return false;
320 }
321
322 session_state_observers_.insert(
323 presentation_id, make_scoped_ptr(new PresentationSessionStateObserver(
324 listener, it->second, router_)));
325 return true;
228 } 326 }
229
230 session_state_observers_.insert(
231 presentation_id, make_scoped_ptr(new PresentationSessionStateObserver(
232 listener, it->second, router_)));
233 return true;
234 } 327 }
235 328
236 void PresentationFrame::ListenForSessionMessages( 329 void PresentationFrame::ListenForSessionMessages(
237 const content::PresentationSessionInfo& session, 330 const content::PresentationSessionInfo& session,
238 const content::PresentationSessionMessageCallback& message_cb) { 331 const content::PresentationSessionMessageCallback& message_cb) {
239 auto it = presentation_id_to_route_id_.find(session.presentation_id); 332 auto it = presentation_id_to_route_id_.find(session.presentation_id);
240 if (it == presentation_id_to_route_id_.end()) { 333 if (it == presentation_id_to_route_id_.end()) {
241 DVLOG(2) << "ListenForSessionMessages: no route for " 334 DVLOG(2) << "ListenForSessionMessages: no route for "
242 << session.presentation_id; 335 << session.presentation_id;
243 return; 336 return;
244 } 337 }
245 338
246 session_messages_observers_.push_back( 339 OffscreenPresentationSession* offscreen_session =
247 new PresentationSessionMessagesObserver(message_cb, it->second, router_)); 340 FindOffscreenSession(session.presentation_id);
341 if (offscreen_session) {
342 offscreen_session->ListenForMessages(message_cb);
343 } else {
344 session_messages_observers_.push_back(
345 new PresentationSessionMessagesObserver(message_cb, it->second,
346 router_));
347 }
248 } 348 }
249 349
250 MediaSource PresentationFrame::GetMediaSourceFromListener( 350 MediaSource PresentationFrame::GetMediaSourceFromListener(
251 content::PresentationScreenAvailabilityListener* listener) const { 351 content::PresentationScreenAvailabilityListener* listener) const {
252 // If the default presentation URL is empty then fall back to tab mirroring. 352 // If the default presentation URL is empty then fall back to tab mirroring.
253 std::string availability_url(listener->GetAvailabilityUrl()); 353 std::string availability_url(listener->GetAvailabilityUrl());
254 return availability_url.empty() 354 return availability_url.empty()
255 ? MediaSourceForTab(SessionTabHelper::IdForTab(web_contents_)) 355 ? MediaSourceForTab(SessionTabHelper::IdForTab(web_contents_))
256 : MediaSourceForPresentationUrl(availability_url); 356 : MediaSourceForPresentationUrl(availability_url);
257 } 357 }
258 358
259 // Used by PresentationServiceDelegateImpl to manage PresentationFrames. 359 // Used by PresentationServiceDelegateImpl to manage PresentationFrames.
260 class PresentationFrameManager { 360 class PresentationFrameManager {
261 public: 361 public:
262 PresentationFrameManager(content::WebContents* web_contents, 362 PresentationFrameManager(content::WebContents* web_contents,
263 MediaRouter* router); 363 MediaRouter* router);
264 ~PresentationFrameManager(); 364 ~PresentationFrameManager();
265 365
266 // Mirror corresponding APIs in PresentationServiceDelegateImpl. 366 // Mirror corresponding APIs in PresentationServiceDelegateImpl.
267 bool SetScreenAvailabilityListener( 367 bool SetScreenAvailabilityListener(
268 const RenderFrameHostId& render_frame_host_id, 368 const RenderFrameHostId& render_frame_host_id,
269 content::PresentationScreenAvailabilityListener* listener); 369 content::PresentationScreenAvailabilityListener* listener);
270 bool RemoveScreenAvailabilityListener( 370 bool RemoveScreenAvailabilityListener(
271 const RenderFrameHostId& render_frame_host_id, 371 const RenderFrameHostId& render_frame_host_id,
272 content::PresentationScreenAvailabilityListener* listener); 372 content::PresentationScreenAvailabilityListener* listener);
373 void SendMessage(const RenderFrameHostId& render_frame_host_id,
374 const content::PresentationSessionInfo& session,
375 scoped_ptr<content::PresentationSessionMessage> message,
376 const content::SendMessageCallback send_message_cb);
273 bool ListenForSessionStateChange( 377 bool ListenForSessionStateChange(
274 const RenderFrameHostId& render_frame_host_id, 378 const RenderFrameHostId& render_frame_host_id,
275 content::PresentationSessionStateListener* listener); 379 content::PresentationSessionStateListener* listener);
276 void ListenForSessionMessages( 380 void ListenForSessionMessages(
277 const RenderFrameHostId& render_frame_host_id, 381 const RenderFrameHostId& render_frame_host_id,
278 const content::PresentationSessionInfo& session, 382 const content::PresentationSessionInfo& session,
279 const content::PresentationSessionMessageCallback& message_cb); 383 const content::PresentationSessionMessageCallback& message_cb);
280 void AddDelegateObserver(const RenderFrameHostId& render_frame_host_id, 384 void AddDelegateObserver(const RenderFrameHostId& render_frame_host_id,
281 DelegateObserver* observer); 385 DelegateObserver* observer);
282 void RemoveDelegateObserver(const RenderFrameHostId& render_frame_host_id); 386 void RemoveDelegateObserver(const RenderFrameHostId& render_frame_host_id);
283 void Reset(const RenderFrameHostId& render_frame_host_id); 387 void Reset(const RenderFrameHostId& render_frame_host_id);
284 bool HasScreenAvailabilityListenerForTest( 388 bool HasScreenAvailabilityListenerForTest(
285 const RenderFrameHostId& render_frame_host_id, 389 const RenderFrameHostId& render_frame_host_id,
286 const MediaSource::Id& source_id) const; 390 const MediaSource::Id& source_id) const;
287 void SetMediaRouterForTest(MediaRouter* router); 391 void SetMediaRouterForTest(MediaRouter* router);
288 392
289 void OnPresentationSessionStarted( 393 void OnPresentationSessionStarted(
290 const RenderFrameHostId& render_frame_host_id, 394 const RenderFrameHostId& render_frame_host_id,
291 bool is_default_presentation, 395 bool is_default_presentation,
292 const content::PresentationSessionInfo& session, 396 const content::PresentationSessionInfo& session,
293 const MediaRoute::Id& route_id); 397 const MediaRoute& route);
294 398
295 void OnPresentationSessionClosed( 399 void OnPresentationSessionClosed(
296 const RenderFrameHostId& render_frame_host_id, 400 const RenderFrameHostId& render_frame_host_id,
297 const std::string& presentation_id); 401 const std::string& presentation_id);
298 const MediaRoute::Id GetRouteId(const RenderFrameHostId& render_frame_host_id, 402 const MediaRoute::Id GetRouteId(const RenderFrameHostId& render_frame_host_id,
299 const std::string& presentation_id) const; 403 const std::string& presentation_id) const;
300 const std::vector<MediaRoute::Id> GetRouteIds(
301 const RenderFrameHostId& render_frame_host_id) const;
302 404
303 private: 405 private:
304 PresentationFrame* GetOrAddPresentationFrame( 406 PresentationFrame* GetOrAddPresentationFrame(
305 const RenderFrameHostId& render_frame_host_id); 407 const RenderFrameHostId& render_frame_host_id);
306 408
307 // Maps a frame identifier to a PresentationFrame object for frames 409 // Maps a frame identifier to a PresentationFrame object for frames
308 // that are using presentation API. 410 // that are using presentation API.
309 base::ScopedPtrHashMap<RenderFrameHostId, scoped_ptr<PresentationFrame>> 411 base::ScopedPtrHashMap<RenderFrameHostId, scoped_ptr<PresentationFrame>>
310 presentation_frames_; 412 presentation_frames_;
311 413
312 // References to the owning WebContents, and the corresponding MediaRouter. 414 // References to the owning WebContents, and the corresponding MediaRouter.
415 content::WebContents* const web_contents_;
313 MediaRouter* router_; 416 MediaRouter* router_;
314 content::WebContents* web_contents_;
315 }; 417 };
316 418
317 PresentationFrameManager::PresentationFrameManager( 419 PresentationFrameManager::PresentationFrameManager(
318 content::WebContents* web_contents, 420 content::WebContents* web_contents,
319 MediaRouter* router) 421 MediaRouter* router)
320 : router_(router), web_contents_(web_contents) { 422 : web_contents_(web_contents), router_(router) {
321 DCHECK(web_contents_); 423 DCHECK(web_contents_);
322 DCHECK(router_); 424 DCHECK(router_);
323 } 425 }
324 426
325 PresentationFrameManager::~PresentationFrameManager() { 427 PresentationFrameManager::~PresentationFrameManager() {
326 for (auto& frame : presentation_frames_) 428 for (auto& frame : presentation_frames_)
327 frame.second->OnPresentationServiceDelegateDestroyed(); 429 frame.second->OnPresentationServiceDelegateDestroyed();
328 } 430 }
329 431
330 void PresentationFrameManager::OnPresentationSessionStarted( 432 void PresentationFrameManager::OnPresentationSessionStarted(
331 const RenderFrameHostId& render_frame_host_id, 433 const RenderFrameHostId& render_frame_host_id,
332 bool is_default_presentation, 434 bool is_default_presentation,
333 const content::PresentationSessionInfo& session, 435 const content::PresentationSessionInfo& session,
334 const MediaRoute::Id& route_id) { 436 const MediaRoute& route) {
335 auto presentation_frame = presentation_frames_.get(render_frame_host_id); 437 auto presentation_frame = presentation_frames_.get(render_frame_host_id);
336 if (presentation_frame) 438 if (presentation_frame) {
337 presentation_frame->OnPresentationSessionStarted(is_default_presentation, 439 presentation_frame->OnPresentationSessionStarted(is_default_presentation,
338 session, route_id); 440 session, route);
441 }
339 } 442 }
340 443
341 void PresentationFrameManager::OnPresentationSessionClosed( 444 void PresentationFrameManager::OnPresentationSessionClosed(
342 const RenderFrameHostId& render_frame_host_id, 445 const RenderFrameHostId& render_frame_host_id,
343 const std::string& presentation_id) { 446 const std::string& presentation_id) {
344 auto presentation_frame = presentation_frames_.get(render_frame_host_id); 447 auto presentation_frame = presentation_frames_.get(render_frame_host_id);
345 if (presentation_frame) 448 if (presentation_frame)
346 presentation_frame->OnPresentationSessionClosed(presentation_id); 449 presentation_frame->OnPresentationSessionClosed(presentation_id);
347 } 450 }
348 451
349 const MediaRoute::Id PresentationFrameManager::GetRouteId( 452 const MediaRoute::Id PresentationFrameManager::GetRouteId(
350 const RenderFrameHostId& render_frame_host_id, 453 const RenderFrameHostId& render_frame_host_id,
351 const std::string& presentation_id) const { 454 const std::string& presentation_id) const {
352 auto presentation_frame = presentation_frames_.get(render_frame_host_id); 455 auto presentation_frame = presentation_frames_.get(render_frame_host_id);
353 return presentation_frame ? presentation_frame->GetRouteId(presentation_id) 456 return presentation_frame ? presentation_frame->GetRouteId(presentation_id)
354 : ""; 457 : "";
355 } 458 }
356 459
357 const std::vector<MediaRoute::Id> PresentationFrameManager::GetRouteIds(
358 const RenderFrameHostId& render_frame_host_id) const {
359 auto presentation_frame = presentation_frames_.get(render_frame_host_id);
360 return presentation_frame ? presentation_frame->GetRouteIds()
361 : std::vector<MediaRoute::Id>();
362 }
363
364 bool PresentationFrameManager::SetScreenAvailabilityListener( 460 bool PresentationFrameManager::SetScreenAvailabilityListener(
365 const RenderFrameHostId& render_frame_host_id, 461 const RenderFrameHostId& render_frame_host_id,
366 content::PresentationScreenAvailabilityListener* listener) { 462 content::PresentationScreenAvailabilityListener* listener) {
367 DCHECK(listener); 463 DCHECK(listener);
368 auto presentation_frame = GetOrAddPresentationFrame(render_frame_host_id); 464 auto presentation_frame = GetOrAddPresentationFrame(render_frame_host_id);
369 return presentation_frame->SetScreenAvailabilityListener(listener); 465 return presentation_frame->SetScreenAvailabilityListener(listener);
370 } 466 }
371 467
372 bool PresentationFrameManager::RemoveScreenAvailabilityListener( 468 bool PresentationFrameManager::RemoveScreenAvailabilityListener(
373 const RenderFrameHostId& render_frame_host_id, 469 const RenderFrameHostId& render_frame_host_id,
374 content::PresentationScreenAvailabilityListener* listener) { 470 content::PresentationScreenAvailabilityListener* listener) {
375 DCHECK(listener); 471 DCHECK(listener);
376 auto presentation_frame = presentation_frames_.get(render_frame_host_id); 472 auto presentation_frame = presentation_frames_.get(render_frame_host_id);
377 return presentation_frame && 473 return presentation_frame &&
378 presentation_frame->RemoveScreenAvailabilityListener(listener); 474 presentation_frame->RemoveScreenAvailabilityListener(listener);
379 } 475 }
380 476
381 bool PresentationFrameManager::HasScreenAvailabilityListenerForTest( 477 bool PresentationFrameManager::HasScreenAvailabilityListenerForTest(
382 const RenderFrameHostId& render_frame_host_id, 478 const RenderFrameHostId& render_frame_host_id,
383 const MediaSource::Id& source_id) const { 479 const MediaSource::Id& source_id) const {
384 auto presentation_frame = presentation_frames_.get(render_frame_host_id); 480 auto presentation_frame = presentation_frames_.get(render_frame_host_id);
385 return presentation_frame && 481 return presentation_frame &&
386 presentation_frame->HasScreenAvailabilityListenerForTest(source_id); 482 presentation_frame->HasScreenAvailabilityListenerForTest(source_id);
387 } 483 }
388 484
485 void PresentationFrameManager::SendMessage(
486 const RenderFrameHostId& render_frame_host_id,
487 const content::PresentationSessionInfo& session,
488 scoped_ptr<content::PresentationSessionMessage> message,
489 const content::SendMessageCallback send_message_cb) {
490 PresentationFrame* presentation_frame =
491 presentation_frames_.get(render_frame_host_id);
492 if (!presentation_frame) {
493 DVLOG(2) << "SendMessage: PresentationFrame does not exist "
494 << "for: (" << render_frame_host_id.first << ", "
495 << render_frame_host_id.second << ")";
496 send_message_cb.Run(false);
497 return;
498 }
499
500 presentation_frame->SendMessage(session, message.Pass(), send_message_cb);
501 }
502
389 bool PresentationFrameManager::ListenForSessionStateChange( 503 bool PresentationFrameManager::ListenForSessionStateChange(
390 const RenderFrameHostId& render_frame_host_id, 504 const RenderFrameHostId& render_frame_host_id,
391 content::PresentationSessionStateListener* listener) { 505 content::PresentationSessionStateListener* listener) {
392 PresentationFrame* presentation_frame = 506 PresentationFrame* presentation_frame =
393 GetOrAddPresentationFrame(render_frame_host_id); 507 GetOrAddPresentationFrame(render_frame_host_id);
394 return presentation_frame->ListenForSessionStateChange(listener); 508 return presentation_frame->ListenForSessionStateChange(listener);
395 } 509 }
396 510
397 void PresentationFrameManager::ListenForSessionMessages( 511 void PresentationFrameManager::ListenForSessionMessages(
398 const RenderFrameHostId& render_frame_host_id, 512 const RenderFrameHostId& render_frame_host_id,
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 auto presentation_frame = presentation_frames_.get(render_frame_host_id); 544 auto presentation_frame = presentation_frames_.get(render_frame_host_id);
431 if (presentation_frame) 545 if (presentation_frame)
432 presentation_frame->Reset(); 546 presentation_frame->Reset();
433 } 547 }
434 548
435 PresentationFrame* PresentationFrameManager::GetOrAddPresentationFrame( 549 PresentationFrame* PresentationFrameManager::GetOrAddPresentationFrame(
436 const RenderFrameHostId& render_frame_host_id) { 550 const RenderFrameHostId& render_frame_host_id) {
437 if (!presentation_frames_.contains(render_frame_host_id)) { 551 if (!presentation_frames_.contains(render_frame_host_id)) {
438 presentation_frames_.add( 552 presentation_frames_.add(
439 render_frame_host_id, 553 render_frame_host_id,
440 scoped_ptr<PresentationFrame>( 554 scoped_ptr<PresentationFrame>(new PresentationFrame(
441 new PresentationFrame(web_contents_, router_))); 555 web_contents_, render_frame_host_id, router_)));
442 } 556 }
443 return presentation_frames_.get(render_frame_host_id); 557 return presentation_frames_.get(render_frame_host_id);
444 } 558 }
445 559
446 void PresentationFrameManager::SetMediaRouterForTest(MediaRouter* router) { 560 void PresentationFrameManager::SetMediaRouterForTest(MediaRouter* router) {
447 router_ = router; 561 router_ = router;
448 } 562 }
449 563
450 PresentationServiceDelegateImpl* 564 PresentationServiceDelegateImpl*
451 PresentationServiceDelegateImpl::GetOrCreateForWebContents( 565 PresentationServiceDelegateImpl::GetOrCreateForWebContents(
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
563 const MediaRoute* route, 677 const MediaRoute* route,
564 const std::string& presentation_id, 678 const std::string& presentation_id,
565 const std::string& error_text) { 679 const std::string& error_text) {
566 if (!route) { 680 if (!route) {
567 error_cb.Run(content::PresentationError( 681 error_cb.Run(content::PresentationError(
568 content::PRESENTATION_ERROR_NO_PRESENTATION_FOUND, error_text)); 682 content::PRESENTATION_ERROR_NO_PRESENTATION_FOUND, error_text));
569 } else { 683 } else {
570 DVLOG(1) << "OnJoinRouteResponse: " 684 DVLOG(1) << "OnJoinRouteResponse: "
571 << "route_id: " << route->media_route_id() 685 << "route_id: " << route->media_route_id()
572 << ", presentation URL: " << session.presentation_url 686 << ", presentation URL: " << session.presentation_url
573 << ", presentation ID: " << session.presentation_id; 687 << ", presentation ID: " << session.presentation_id
688 << ", offscreen? " << route->is_offscreen_presentation();
574 DCHECK_EQ(session.presentation_id, presentation_id); 689 DCHECK_EQ(session.presentation_id, presentation_id);
575 frame_manager_->OnPresentationSessionStarted( 690 RenderFrameHostId rfh_id(render_process_id, render_frame_id);
576 RenderFrameHostId(render_process_id, render_frame_id), false, session, 691 frame_manager_->OnPresentationSessionStarted(rfh_id, false, session,
577 route->media_route_id()); 692 *route);
578 success_cb.Run(session); 693 success_cb.Run(session);
579 } 694 }
580 } 695 }
581 696
582 void PresentationServiceDelegateImpl::OnStartSessionSucceeded( 697 void PresentationServiceDelegateImpl::OnStartSessionSucceeded(
583 int render_process_id, 698 int render_process_id,
584 int render_frame_id, 699 int render_frame_id,
585 const PresentationSessionSuccessCallback& success_cb, 700 const PresentationSessionSuccessCallback& success_cb,
586 const content::PresentationSessionInfo& new_session, 701 const content::PresentationSessionInfo& new_session,
587 const MediaRoute::Id& route_id) { 702 const MediaRoute& route) {
703 const MediaRoute::Id& route_id = route.media_route_id();
588 DVLOG(1) << "OnStartSessionSucceeded: " 704 DVLOG(1) << "OnStartSessionSucceeded: "
589 << "route_id: " << route_id 705 << "route_id: " << route_id
590 << ", presentation URL: " << new_session.presentation_url 706 << ", presentation URL: " << new_session.presentation_url
591 << ", presentation ID: " << new_session.presentation_id; 707 << ", presentation ID: " << new_session.presentation_id;
592 frame_manager_->OnPresentationSessionStarted( 708 RenderFrameHostId rfh_id(render_process_id, render_frame_id);
593 RenderFrameHostId(render_process_id, render_frame_id), false, new_session, 709 frame_manager_->OnPresentationSessionStarted(rfh_id, false, new_session,
594 route_id); 710 route);
595 success_cb.Run(new_session); 711 success_cb.Run(new_session);
596 } 712 }
597 713
598 void PresentationServiceDelegateImpl::StartSession( 714 void PresentationServiceDelegateImpl::StartSession(
599 int render_process_id, 715 int render_process_id,
600 int render_frame_id, 716 int render_frame_id,
601 const std::string& presentation_url, 717 const std::string& presentation_url,
602 const PresentationSessionSuccessCallback& success_cb, 718 const PresentationSessionSuccessCallback& success_cb,
603 const PresentationSessionErrorCallback& error_cb) { 719 const PresentationSessionErrorCallback& error_cb) {
604 if (presentation_url.empty() || !IsValidPresentationUrl(presentation_url)) { 720 if (presentation_url.empty() || !IsValidPresentationUrl(presentation_url)) {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
657 return; 773 return;
658 } 774 }
659 router_->CloseRoute(route_id); 775 router_->CloseRoute(route_id);
660 } 776 }
661 777
662 void PresentationServiceDelegateImpl::ListenForSessionMessages( 778 void PresentationServiceDelegateImpl::ListenForSessionMessages(
663 int render_process_id, 779 int render_process_id,
664 int render_frame_id, 780 int render_frame_id,
665 const content::PresentationSessionInfo& session, 781 const content::PresentationSessionInfo& session,
666 const content::PresentationSessionMessageCallback& message_cb) { 782 const content::PresentationSessionMessageCallback& message_cb) {
667 frame_manager_->ListenForSessionMessages( 783 RenderFrameHostId render_frame_host_id(render_process_id, render_frame_id);
668 RenderFrameHostId(render_process_id, render_frame_id), session, 784 frame_manager_->ListenForSessionMessages(render_frame_host_id, session,
669 message_cb); 785 message_cb);
670 } 786 }
671 787
672 void PresentationServiceDelegateImpl::SendMessage( 788 void PresentationServiceDelegateImpl::SendMessage(
673 int render_process_id, 789 int render_process_id,
674 int render_frame_id, 790 int render_frame_id,
675 const content::PresentationSessionInfo& session, 791 const content::PresentationSessionInfo& session,
676 scoped_ptr<content::PresentationSessionMessage> message, 792 scoped_ptr<content::PresentationSessionMessage> message,
677 const SendMessageCallback& send_message_cb) { 793 const content::SendMessageCallback& send_message_cb) {
678 const MediaRoute::Id& route_id = frame_manager_->GetRouteId( 794 RenderFrameHostId render_frame_host_id(render_process_id, render_frame_id);
679 RenderFrameHostId(render_process_id, render_frame_id), 795 frame_manager_->SendMessage(render_frame_host_id, session, message.Pass(),
680 session.presentation_id); 796 send_message_cb);
681 if (route_id.empty()) {
682 DVLOG(1) << "No active route for " << session.presentation_id;
683 send_message_cb.Run(false);
684 return;
685 }
686
687 if (message->is_binary()) {
688 router_->SendRouteBinaryMessage(route_id, message->data.Pass(),
689 send_message_cb);
690 } else {
691 router_->SendRouteMessage(route_id, message->message, send_message_cb);
692 }
693 } 797 }
694 798
695 bool PresentationServiceDelegateImpl::ListenForSessionStateChange( 799 bool PresentationServiceDelegateImpl::ListenForSessionStateChange(
696 int render_process_id, 800 int render_process_id,
697 int render_frame_id, 801 int render_frame_id,
698 content::PresentationSessionStateListener* listener) { 802 content::PresentationSessionStateListener* listener) {
699 return frame_manager_->ListenForSessionStateChange( 803 return frame_manager_->ListenForSessionStateChange(
700 RenderFrameHostId(render_process_id, render_frame_id), listener); 804 RenderFrameHostId(render_process_id, render_frame_id), listener);
701 } 805 }
702 806
807 void PresentationServiceDelegateImpl::GetPresentationReceiverSession(
808 int render_process_id,
809 int render_frame_id,
810 const content::PresentationReceiverSessionAvailableCallback& callback) {
811 // We only support receiver APIs in offscreen tabs created for offscreen
812 // presentations.
813 // See ReceiverPresentationServiceDelegateImpl for details.
814 NOTIMPLEMENTED();
815 callback.Run(nullptr);
816 }
817
818 std::vector<content::PresentationSessionInfo>
819 PresentationServiceDelegateImpl::GetPresentationReceiverSessions(
820 int render_process_id,
821 int render_frame_id) {
822 // See comment in |GetPresentationReceiverSession()|.
823 NOTIMPLEMENTED();
824 return std::vector<content::PresentationSessionInfo>();
825 }
826
703 void PresentationServiceDelegateImpl::OnRouteResponse( 827 void PresentationServiceDelegateImpl::OnRouteResponse(
704 const MediaRoute* route, 828 const MediaRoute* route,
705 const std::string& presentation_id, 829 const std::string& presentation_id,
706 const std::string& error) { 830 const std::string& error) {
707 if (!route) 831 if (!route)
708 return; 832 return;
833
709 const MediaSource& source = route->media_source(); 834 const MediaSource& source = route->media_source();
710 DCHECK(!source.Empty()); 835 DCHECK(!source.Empty());
711 if (!default_source_.Equals(source)) 836 if (!default_source_.Equals(source))
712 return; 837 return;
838
713 RenderFrameHost* main_frame = web_contents_->GetMainFrame(); 839 RenderFrameHost* main_frame = web_contents_->GetMainFrame();
714 if (!main_frame) 840 if (!main_frame)
715 return; 841 return;
842
716 RenderFrameHostId render_frame_host_id(GetRenderFrameHostId(main_frame)); 843 RenderFrameHostId render_frame_host_id(GetRenderFrameHostId(main_frame));
717 frame_manager_->OnPresentationSessionStarted( 844 content::PresentationSessionInfo session(
718 render_frame_host_id, true, 845 PresentationUrlFromMediaSource(source), presentation_id);
719 content::PresentationSessionInfo(PresentationUrlFromMediaSource(source), 846
720 presentation_id), 847 frame_manager_->OnPresentationSessionStarted(render_frame_host_id, true,
721 route->media_route_id()); 848 session, *route);
722 } 849 }
723 850
724 void PresentationServiceDelegateImpl::AddDefaultMediaSourceObserver( 851 void PresentationServiceDelegateImpl::AddDefaultMediaSourceObserver(
725 DefaultMediaSourceObserver* observer) { 852 DefaultMediaSourceObserver* observer) {
726 default_media_source_observers_.AddObserver(observer); 853 default_media_source_observers_.AddObserver(observer);
727 } 854 }
728 855
729 void PresentationServiceDelegateImpl::RemoveDefaultMediaSourceObserver( 856 void PresentationServiceDelegateImpl::RemoveDefaultMediaSourceObserver(
730 DefaultMediaSourceObserver* observer) { 857 DefaultMediaSourceObserver* observer) {
731 default_media_source_observers_.RemoveObserver(observer); 858 default_media_source_observers_.RemoveObserver(observer);
(...skipping 13 matching lines...) Expand all
745 bool PresentationServiceDelegateImpl::HasScreenAvailabilityListenerForTest( 872 bool PresentationServiceDelegateImpl::HasScreenAvailabilityListenerForTest(
746 int render_process_id, 873 int render_process_id,
747 int render_frame_id, 874 int render_frame_id,
748 const MediaSource::Id& source_id) const { 875 const MediaSource::Id& source_id) const {
749 RenderFrameHostId render_frame_host_id(render_process_id, render_frame_id); 876 RenderFrameHostId render_frame_host_id(render_process_id, render_frame_id);
750 return frame_manager_->HasScreenAvailabilityListenerForTest( 877 return frame_manager_->HasScreenAvailabilityListenerForTest(
751 render_frame_host_id, source_id); 878 render_frame_host_id, source_id);
752 } 879 }
753 880
754 } // namespace media_router 881 } // namespace media_router
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698