OLD | NEW |
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/ui/webui/media_router/media_router_ui.h" | 5 #include "chrome/browser/ui/webui/media_router/media_router_ui.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/guid.h" | 9 #include "base/guid.h" |
10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
11 #include "base/strings/utf_string_conversions.h" | 11 #include "base/strings/utf_string_conversions.h" |
12 #include "chrome/browser/media/router/create_presentation_connection_request.h" | 12 #include "chrome/browser/media/router/create_presentation_session_request.h" |
13 #include "chrome/browser/media/router/issue.h" | 13 #include "chrome/browser/media/router/issue.h" |
14 #include "chrome/browser/media/router/issues_observer.h" | 14 #include "chrome/browser/media/router/issues_observer.h" |
15 #include "chrome/browser/media/router/media_route.h" | 15 #include "chrome/browser/media/router/media_route.h" |
16 #include "chrome/browser/media/router/media_router.h" | 16 #include "chrome/browser/media/router/media_router.h" |
17 #include "chrome/browser/media/router/media_router_factory.h" | 17 #include "chrome/browser/media/router/media_router_factory.h" |
18 #include "chrome/browser/media/router/media_router_mojo_impl.h" | 18 #include "chrome/browser/media/router/media_router_mojo_impl.h" |
19 #include "chrome/browser/media/router/media_routes_observer.h" | 19 #include "chrome/browser/media/router/media_routes_observer.h" |
20 #include "chrome/browser/media/router/media_sink.h" | 20 #include "chrome/browser/media/router/media_sink.h" |
21 #include "chrome/browser/media/router/media_sinks_observer.h" | 21 #include "chrome/browser/media/router/media_sinks_observer.h" |
22 #include "chrome/browser/media/router/media_source.h" | 22 #include "chrome/browser/media/router/media_source.h" |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 web_ui->AddMessageHandler(handler_); | 156 web_ui->AddMessageHandler(handler_); |
157 } | 157 } |
158 | 158 |
159 MediaRouterUI::~MediaRouterUI() { | 159 MediaRouterUI::~MediaRouterUI() { |
160 if (issues_observer_) | 160 if (issues_observer_) |
161 issues_observer_->UnregisterObserver(); | 161 issues_observer_->UnregisterObserver(); |
162 | 162 |
163 if (query_result_manager_.get()) | 163 if (query_result_manager_.get()) |
164 query_result_manager_->RemoveObserver(this); | 164 query_result_manager_->RemoveObserver(this); |
165 if (presentation_service_delegate_.get()) | 165 if (presentation_service_delegate_.get()) |
166 presentation_service_delegate_->RemoveDefaultPresentationRequestObserver( | 166 presentation_service_delegate_->RemoveDefaultMediaSourceObserver(this); |
167 this); | 167 // If |presentation_request_| still exists, then it means presentation route |
168 // If |create_session_request_| still exists, then it means presentation route | |
169 // request was never attempted. | 168 // request was never attempted. |
170 if (create_session_request_) { | 169 if (presentation_request_) { |
171 create_session_request_->InvokeErrorCallback(content::PresentationError( | 170 presentation_request_->InvokeErrorCallback(content::PresentationError( |
172 content::PRESENTATION_ERROR_SESSION_REQUEST_CANCELLED, | 171 content::PRESENTATION_ERROR_SESSION_REQUEST_CANCELLED, |
173 "Dialog closed.")); | 172 "Dialog closed.")); |
174 } | 173 } |
175 } | 174 } |
176 | 175 |
177 void MediaRouterUI::InitWithDefaultMediaSource( | 176 void MediaRouterUI::InitWithDefaultMediaSource( |
178 const base::WeakPtr<PresentationServiceDelegateImpl>& delegate) { | 177 const base::WeakPtr<PresentationServiceDelegateImpl>& delegate) { |
179 DCHECK(delegate); | 178 DCHECK(delegate); |
180 DCHECK(!presentation_service_delegate_); | 179 DCHECK(!presentation_service_delegate_); |
181 DCHECK(!query_result_manager_.get()); | 180 DCHECK(!query_result_manager_.get()); |
182 | 181 |
183 presentation_service_delegate_ = delegate; | 182 presentation_service_delegate_ = delegate; |
184 presentation_service_delegate_->AddDefaultPresentationRequestObserver(this); | 183 presentation_service_delegate_->AddDefaultMediaSourceObserver(this); |
185 InitCommon(presentation_service_delegate_->web_contents()); | 184 InitCommon(presentation_service_delegate_->web_contents(), |
186 if (presentation_service_delegate_->HasDefaultPresentationRequest()) { | 185 presentation_service_delegate_->default_source(), |
187 OnDefaultPresentationChanged( | 186 presentation_service_delegate_->default_frame_url()); |
188 presentation_service_delegate_->GetDefaultPresentationRequest()); | |
189 } | |
190 } | 187 } |
191 | 188 |
192 void MediaRouterUI::InitWithPresentationSessionRequest( | 189 void MediaRouterUI::InitWithPresentationSessionRequest( |
193 content::WebContents* initiator, | 190 content::WebContents* initiator, |
194 const base::WeakPtr<PresentationServiceDelegateImpl>& delegate, | 191 const base::WeakPtr<PresentationServiceDelegateImpl>& delegate, |
195 scoped_ptr<CreatePresentationConnectionRequest> create_session_request) { | 192 scoped_ptr<CreatePresentationSessionRequest> presentation_request) { |
196 DCHECK(initiator); | 193 DCHECK(initiator); |
197 DCHECK(create_session_request); | 194 DCHECK(presentation_request); |
198 DCHECK(!create_session_request_); | 195 DCHECK(!presentation_request_); |
199 DCHECK(!query_result_manager_); | 196 DCHECK(!query_result_manager_); |
200 | 197 |
201 create_session_request_ = create_session_request.Pass(); | 198 presentation_request_ = presentation_request.Pass(); |
202 presentation_service_delegate_ = delegate; | 199 presentation_service_delegate_ = delegate; |
203 InitCommon(initiator); | 200 InitCommon(initiator, presentation_request_->media_source(), |
204 OnDefaultPresentationChanged(create_session_request_->presentation_request()); | 201 presentation_request_->frame_url()); |
205 } | 202 } |
206 | 203 |
207 void MediaRouterUI::InitCommon(content::WebContents* initiator) { | 204 void MediaRouterUI::InitCommon(content::WebContents* initiator, |
| 205 const MediaSource& default_source, |
| 206 const GURL& default_frame_url) { |
208 DCHECK(initiator); | 207 DCHECK(initiator); |
209 DCHECK(router_); | 208 DCHECK(router_); |
210 | 209 |
211 // Register for MediaRoute updates. | 210 // Register for MediaRoute updates. |
212 routes_observer_.reset(new UIMediaRoutesObserver( | 211 routes_observer_.reset(new UIMediaRoutesObserver( |
213 router_, | 212 router_, |
214 base::Bind(&MediaRouterUI::OnRoutesUpdated, base::Unretained(this)))); | 213 base::Bind(&MediaRouterUI::OnRoutesUpdated, base::Unretained(this)))); |
215 | 214 |
216 query_result_manager_.reset(new QueryResultManager(router_)); | 215 query_result_manager_.reset(new QueryResultManager(router_)); |
217 query_result_manager_->AddObserver(this); | 216 query_result_manager_->AddObserver(this); |
218 | 217 |
219 // These modes are always available. | 218 // These modes are always available. |
220 query_result_manager_->StartSinksQuery( | 219 query_result_manager_->StartSinksQuery( |
221 MediaCastMode::DESKTOP_MIRROR, MediaSourceForDesktop()); | 220 MediaCastMode::DESKTOP_MIRROR, MediaSourceForDesktop()); |
222 initiator_ = initiator; | 221 initiator_ = initiator; |
223 MediaSource mirroring_source( | 222 MediaSource mirroring_source( |
224 MediaSourceForTab(SessionTabHelper::IdForTab(initiator))); | 223 MediaSourceForTab(SessionTabHelper::IdForTab(initiator))); |
225 query_result_manager_->StartSinksQuery( | 224 query_result_manager_->StartSinksQuery( |
226 MediaCastMode::TAB_MIRROR, mirroring_source); | 225 MediaCastMode::TAB_MIRROR, mirroring_source); |
| 226 |
| 227 OnDefaultMediaSourceChanged(default_source, default_frame_url); |
227 } | 228 } |
228 | 229 |
229 void MediaRouterUI::OnDefaultPresentationChanged( | 230 void MediaRouterUI::OnDefaultMediaSourceChanged(const MediaSource& source, |
230 const PresentationRequest& presentation_request) { | 231 const GURL& frame_url) { |
231 presentation_request_.reset(new PresentationRequest(presentation_request)); | 232 if (source.Empty()) { |
232 query_result_manager_->StartSinksQuery( | 233 query_result_manager_->StopSinksQuery(MediaCastMode::DEFAULT); |
233 MediaCastMode::DEFAULT, presentation_request_->GetMediaSource()); | 234 } else { |
234 UpdateCastModes(); | 235 query_result_manager_->StartSinksQuery(MediaCastMode::DEFAULT, source); |
| 236 } |
| 237 UpdateSourceHostAndCastModes(frame_url); |
235 } | 238 } |
236 | 239 |
237 void MediaRouterUI::OnDefaultPresentationRemoved() { | 240 void MediaRouterUI::UpdateSourceHostAndCastModes(const GURL& frame_url) { |
238 presentation_request_.reset(); | 241 DCHECK(query_result_manager_); |
239 query_result_manager_->StopSinksQuery(MediaCastMode::DEFAULT); | 242 frame_url_ = frame_url; |
240 UpdateCastModes(); | |
241 } | |
242 | |
243 void MediaRouterUI::UpdateCastModes() { | |
244 // Gets updated cast modes from |query_result_manager_| and forwards it to UI. | |
245 query_result_manager_->GetSupportedCastModes(&cast_modes_); | 243 query_result_manager_->GetSupportedCastModes(&cast_modes_); |
246 if (ui_initialized_) { | 244 if (ui_initialized_) |
247 handler_->UpdateCastModes( | 245 handler_->UpdateCastModes(cast_modes_, GetHostFromURL(frame_url_)); |
248 cast_modes_, presentation_request_ | |
249 ? GetHostFromURL(presentation_request_->frame_url()) | |
250 : std::string()); | |
251 } | |
252 } | 246 } |
253 | 247 |
254 void MediaRouterUI::Close() { | 248 void MediaRouterUI::Close() { |
255 ConstrainedWebDialogDelegate* delegate = GetConstrainedDelegate(); | 249 ConstrainedWebDialogDelegate* delegate = GetConstrainedDelegate(); |
256 if (delegate) { | 250 if (delegate) { |
257 delegate->GetWebDialogDelegate()->OnDialogClosed(std::string()); | 251 delegate->GetWebDialogDelegate()->OnDialogClosed(std::string()); |
258 delegate->OnDialogCloseFromWebUI(); | 252 delegate->OnDialogCloseFromWebUI(); |
259 } | 253 } |
260 } | 254 } |
261 | 255 |
262 void MediaRouterUI::UIInitialized() { | 256 void MediaRouterUI::UIInitialized() { |
263 ui_initialized_ = true; | 257 ui_initialized_ = true; |
264 | 258 |
265 // Register for Issue updates. | 259 // Register for Issue updates. |
266 if (!issues_observer_) | 260 if (!issues_observer_) |
267 issues_observer_.reset(new UIIssuesObserver(router_, this)); | 261 issues_observer_.reset(new UIIssuesObserver(router_, this)); |
268 issues_observer_->RegisterObserver(); | 262 issues_observer_->RegisterObserver(); |
269 } | 263 } |
270 | 264 |
271 bool MediaRouterUI::CreateRoute(const MediaSink::Id& sink_id, | 265 bool MediaRouterUI::CreateRoute(const MediaSink::Id& sink_id, |
272 MediaCastMode cast_mode) { | 266 MediaCastMode cast_mode) { |
273 DCHECK(query_result_manager_.get()); | 267 DCHECK(query_result_manager_.get()); |
274 DCHECK(initiator_); | 268 DCHECK(initiator_); |
275 | 269 |
276 // Note that there is a rarely-encountered bug, where the MediaCastMode to | 270 // Note that there is a rarely-encountered bug, where the MediaCastMode to |
277 // MediaSource mapping could have been updated, between when the user clicked | 271 // MediaSource mapping could have been updated, between when the user |
278 // on the UI to start a create route request, and when this function is | 272 // clicked on the UI to start a create route request, |
279 // called. However, since the user does not have visibility into the | 273 // and when this function is called. |
280 // MediaSource, and that it occurs very rarely in practice, we leave it as-is | 274 // However, since the user does not have visibility into the MediaSource, and |
281 // for now. | 275 // that it occurs very rarely in practice, we leave it as-is for now. |
282 MediaSource source = query_result_manager_->GetSourceForCastMode(cast_mode); | 276 MediaSource source = query_result_manager_->GetSourceForCastMode(cast_mode); |
283 if (source.Empty()) { | 277 if (source.Empty()) { |
284 LOG(ERROR) << "No corresponding MediaSource for cast mode " << cast_mode; | 278 LOG(ERROR) << "No corresponding MediaSource for cast mode " << cast_mode; |
285 return false; | 279 return false; |
286 } | 280 } |
287 | 281 |
288 requesting_route_for_default_source_ = cast_mode == MediaCastMode::DEFAULT; | 282 requesting_route_for_default_source_ = cast_mode == MediaCastMode::DEFAULT; |
289 if (requesting_route_for_default_source_ && !presentation_request_) { | |
290 DLOG(ERROR) << "Requested to create a route for presentation, but " | |
291 << "presentation request is missing."; | |
292 return false; | |
293 } | |
294 | |
295 current_route_request_id_ = ++route_request_counter_; | 283 current_route_request_id_ = ++route_request_counter_; |
296 GURL origin; | 284 GURL origin; |
| 285 // TODO(imcheng): What is the origin if not creating route in DEFAULT mode? |
297 if (requesting_route_for_default_source_) { | 286 if (requesting_route_for_default_source_) { |
298 origin = presentation_request_->frame_url().GetOrigin(); | 287 origin = frame_url_.GetOrigin(); |
299 } else { | 288 } else { |
300 // Requesting route for mirroring. Use a placeholder URL as origin. | 289 // Requesting route for mirroring. Use a placeholder URL as origin. |
301 origin = GURL(chrome::kChromeUIMediaRouterURL); | 290 origin = GURL(chrome::kChromeUIMediaRouterURL); |
302 } | 291 } |
303 DCHECK(origin.is_valid()); | 292 DCHECK(origin.is_valid()); |
304 | 293 |
305 DVLOG(1) << "DoCreateRoute: origin: " << origin; | 294 DVLOG(1) << "DoCreateRoute: origin: " << origin; |
306 | 295 |
307 // There are 3 cases. In all cases the MediaRouterUI will need to be notified. | 296 // There are 3 cases. In all cases the MediaRouterUI will need to be notified. |
308 // (1) Non-presentation route request (e.g., mirroring). No additional | 297 // (1) Non-presentation route request (e.g., mirroring). No additional |
309 // notification necessary. | 298 // notification necessary. |
310 // (2) Presentation route request for a Presentation API startSession call. | 299 // (2) Presentation route request for a Presentation API startSession call. |
311 // The startSession (CreatePresentationConnectionRequest) will need to be | 300 // The startSession (CreatePresentationSessionRequest) will need to be |
312 // answered with the | 301 // answered with the |
313 // route response. | 302 // route response. |
314 // (3) Browser-initiated presentation route request. If successful, | 303 // (3) Browser-initiated presentation route request. If successful, |
315 // PresentationServiceDelegateImpl will have to be notified. Note that we | 304 // PresentationServiceDelegateImpl will have to be notified. Note that we |
316 // treat subsequent route requests from a Presentation API-initiated dialogs | 305 // treat subsequent route requests from a Presentation API-initiated dialogs |
317 // as browser-initiated. | 306 // as browser-initiated. |
318 std::vector<MediaRouteResponseCallback> route_response_callbacks; | 307 std::vector<MediaRouteResponseCallback> route_response_callbacks; |
319 route_response_callbacks.push_back( | 308 route_response_callbacks.push_back( |
320 base::Bind(&MediaRouterUI::OnRouteResponseReceived, | 309 base::Bind(&MediaRouterUI::OnRouteResponseReceived, |
321 weak_factory_.GetWeakPtr(), current_route_request_id_, | 310 weak_factory_.GetWeakPtr(), current_route_request_id_, |
322 sink_id)); | 311 sink_id)); |
323 if (requesting_route_for_default_source_) { | 312 if (requesting_route_for_default_source_) { |
324 if (create_session_request_) { | 313 if (presentation_request_) { |
325 // |create_session_request_| will be nullptr after this call, as the | 314 // |presentation_request_| will be nullptr after this call, as the |
326 // object will be transferred to the callback. | 315 // object will be transferred to the callback. |
327 route_response_callbacks.push_back( | 316 route_response_callbacks.push_back( |
328 base::Bind(&CreatePresentationConnectionRequest::HandleRouteResponse, | 317 base::Bind(&CreatePresentationSessionRequest::HandleRouteResponse, |
329 base::Passed(&create_session_request_))); | 318 base::Passed(&presentation_request_))); |
330 } else if (presentation_service_delegate_) { | 319 } else if (presentation_service_delegate_) { |
331 route_response_callbacks.push_back( | 320 route_response_callbacks.push_back( |
332 base::Bind(&PresentationServiceDelegateImpl::OnRouteResponse, | 321 base::Bind(&PresentationServiceDelegateImpl::OnRouteResponse, |
333 presentation_service_delegate_, *presentation_request_)); | 322 presentation_service_delegate_)); |
334 } | 323 } |
335 } | 324 } |
336 | 325 |
337 // Start the timer. | 326 // Start the timer. |
338 route_creation_timer_.Start( | 327 route_creation_timer_.Start( |
339 FROM_HERE, base::TimeDelta::FromSeconds(kCreateRouteTimeoutSeconds), | 328 FROM_HERE, base::TimeDelta::FromSeconds(kCreateRouteTimeoutSeconds), |
340 this, &MediaRouterUI::RouteCreationTimeout); | 329 this, &MediaRouterUI::RouteCreationTimeout); |
341 | 330 |
342 router_->CreateRoute(source.id(), sink_id, origin, | 331 router_->CreateRoute(source.id(), sink_id, origin, |
343 initiator_, | 332 initiator_, |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
420 | 409 |
421 std::string MediaRouterUI::GetFrameURLHost() const { | 410 std::string MediaRouterUI::GetFrameURLHost() const { |
422 return GetHostFromURL(frame_url_); | 411 return GetHostFromURL(frame_url_); |
423 } | 412 } |
424 | 413 |
425 const std::string& MediaRouterUI::GetRouteProviderExtensionId() const { | 414 const std::string& MediaRouterUI::GetRouteProviderExtensionId() const { |
426 return router_->media_route_provider_extension_id(); | 415 return router_->media_route_provider_extension_id(); |
427 } | 416 } |
428 | 417 |
429 } // namespace media_router | 418 } // namespace media_router |
OLD | NEW |