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