| 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 <algorithm> | 7 #include <algorithm> |
| 8 #include <string> | 8 #include <string> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 98 void OnIssueUpdated(const Issue* issue) override { ui_->SetIssue(issue); } | 98 void OnIssueUpdated(const Issue* issue) override { ui_->SetIssue(issue); } |
| 99 | 99 |
| 100 private: | 100 private: |
| 101 // Reference back to the owning MediaRouterUI instance. | 101 // Reference back to the owning MediaRouterUI instance. |
| 102 MediaRouterUI* ui_; | 102 MediaRouterUI* ui_; |
| 103 | 103 |
| 104 DISALLOW_COPY_AND_ASSIGN(UIIssuesObserver); | 104 DISALLOW_COPY_AND_ASSIGN(UIIssuesObserver); |
| 105 }; | 105 }; |
| 106 | 106 |
| 107 MediaRouterUI::UIMediaRoutesObserver::UIMediaRoutesObserver( | 107 MediaRouterUI::UIMediaRoutesObserver::UIMediaRoutesObserver( |
| 108 MediaRouter* router, const RoutesUpdatedCallback& callback) | 108 MediaRouter* router, const MediaSource::Id& source_id, |
| 109 : MediaRoutesObserver(router), callback_(callback) { | 109 const RoutesUpdatedCallback& callback) |
| 110 : MediaRoutesObserver(router, source_id), callback_(callback) { |
| 110 DCHECK(!callback_.is_null()); | 111 DCHECK(!callback_.is_null()); |
| 111 } | 112 } |
| 112 | 113 |
| 113 MediaRouterUI::UIMediaRoutesObserver::~UIMediaRoutesObserver() {} | 114 MediaRouterUI::UIMediaRoutesObserver::~UIMediaRoutesObserver() {} |
| 114 | 115 |
| 115 void MediaRouterUI::UIMediaRoutesObserver::OnRoutesUpdated( | 116 void MediaRouterUI::UIMediaRoutesObserver::OnRoutesUpdated( |
| 116 const std::vector<MediaRoute>& routes) { | 117 const std::vector<MediaRoute>& routes, |
| 118 const std::vector<MediaRoute::Id>& joinable_route_ids) { |
| 117 std::vector<MediaRoute> routes_for_display; | 119 std::vector<MediaRoute> routes_for_display; |
| 120 std::vector<MediaRoute::Id> joinable_route_ids_for_display; |
| 118 for (const MediaRoute& route : routes) { | 121 for (const MediaRoute& route : routes) { |
| 119 if (route.for_display()) { | 122 if (route.for_display()) { |
| 120 #ifndef NDEBUG | 123 #ifndef NDEBUG |
| 121 for (const MediaRoute& existing_route : routes_for_display) { | 124 for (const MediaRoute& existing_route : routes_for_display) { |
| 122 if (existing_route.media_sink_id() == route.media_sink_id()) { | 125 if (existing_route.media_sink_id() == route.media_sink_id()) { |
| 123 DVLOG(2) << "Received another route for display with the same sink" | 126 DVLOG(2) << "Received another route for display with the same sink" |
| 124 << " id as an existing route. " << route.media_route_id() | 127 << " id as an existing route. " << route.media_route_id() |
| 125 << " has the same sink id as " | 128 << " has the same sink id as " |
| 126 << existing_route.media_sink_id() << "."; | 129 << existing_route.media_sink_id() << "."; |
| 127 } | 130 } |
| 128 } | 131 } |
| 129 #endif | 132 #endif |
| 133 if (ContainsValue(joinable_route_ids, route.media_route_id())) { |
| 134 joinable_route_ids_for_display.push_back(route.media_route_id()); |
| 135 } |
| 136 |
| 130 routes_for_display.push_back(route); | 137 routes_for_display.push_back(route); |
| 131 } | 138 } |
| 132 } | 139 } |
| 133 | 140 |
| 134 callback_.Run(routes_for_display); | 141 callback_.Run(routes_for_display, joinable_route_ids_for_display); |
| 135 } | 142 } |
| 136 | 143 |
| 137 MediaRouterUI::MediaRouterUI(content::WebUI* web_ui) | 144 MediaRouterUI::MediaRouterUI(content::WebUI* web_ui) |
| 138 : ConstrainedWebDialogUI(web_ui), | 145 : ConstrainedWebDialogUI(web_ui), |
| 139 handler_(new MediaRouterWebUIMessageHandler(this)), | 146 handler_(new MediaRouterWebUIMessageHandler(this)), |
| 140 ui_initialized_(false), | 147 ui_initialized_(false), |
| 141 current_route_request_id_(-1), | 148 current_route_request_id_(-1), |
| 142 route_request_counter_(0), | 149 route_request_counter_(0), |
| 143 initiator_(nullptr), | 150 initiator_(nullptr), |
| 144 router_(nullptr), | 151 router_(nullptr), |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 190 DCHECK(delegate); | 197 DCHECK(delegate); |
| 191 DCHECK(!presentation_service_delegate_); | 198 DCHECK(!presentation_service_delegate_); |
| 192 DCHECK(!query_result_manager_.get()); | 199 DCHECK(!query_result_manager_.get()); |
| 193 | 200 |
| 194 presentation_service_delegate_ = delegate; | 201 presentation_service_delegate_ = delegate; |
| 195 presentation_service_delegate_->AddDefaultPresentationRequestObserver(this); | 202 presentation_service_delegate_->AddDefaultPresentationRequestObserver(this); |
| 196 InitCommon(presentation_service_delegate_->web_contents()); | 203 InitCommon(presentation_service_delegate_->web_contents()); |
| 197 if (presentation_service_delegate_->HasDefaultPresentationRequest()) { | 204 if (presentation_service_delegate_->HasDefaultPresentationRequest()) { |
| 198 OnDefaultPresentationChanged( | 205 OnDefaultPresentationChanged( |
| 199 presentation_service_delegate_->GetDefaultPresentationRequest()); | 206 presentation_service_delegate_->GetDefaultPresentationRequest()); |
| 207 } else { |
| 208 // Register for MediaRoute updates without a media source. |
| 209 routes_observer_.reset(new UIMediaRoutesObserver(router_, MediaSource::Id(), |
| 210 base::Bind(&MediaRouterUI::OnRoutesUpdated, base::Unretained(this)))); |
| 200 } | 211 } |
| 201 } | 212 } |
| 202 | 213 |
| 203 void MediaRouterUI::InitWithPresentationSessionRequest( | 214 void MediaRouterUI::InitWithPresentationSessionRequest( |
| 204 content::WebContents* initiator, | 215 content::WebContents* initiator, |
| 205 const base::WeakPtr<PresentationServiceDelegateImpl>& delegate, | 216 const base::WeakPtr<PresentationServiceDelegateImpl>& delegate, |
| 206 scoped_ptr<CreatePresentationConnectionRequest> create_session_request) { | 217 scoped_ptr<CreatePresentationConnectionRequest> create_session_request) { |
| 207 DCHECK(initiator); | 218 DCHECK(initiator); |
| 208 DCHECK(create_session_request); | 219 DCHECK(create_session_request); |
| 209 DCHECK(!create_session_request_); | 220 DCHECK(!create_session_request_); |
| 210 DCHECK(!query_result_manager_); | 221 DCHECK(!query_result_manager_); |
| 211 | 222 |
| 212 create_session_request_ = std::move(create_session_request); | 223 create_session_request_ = std::move(create_session_request); |
| 213 presentation_service_delegate_ = delegate; | 224 presentation_service_delegate_ = delegate; |
| 214 InitCommon(initiator); | 225 InitCommon(initiator); |
| 215 OnDefaultPresentationChanged(create_session_request_->presentation_request()); | 226 OnDefaultPresentationChanged(create_session_request_->presentation_request()); |
| 216 } | 227 } |
| 217 | 228 |
| 218 void MediaRouterUI::InitCommon(content::WebContents* initiator) { | 229 void MediaRouterUI::InitCommon(content::WebContents* initiator) { |
| 219 DCHECK(initiator); | 230 DCHECK(initiator); |
| 220 DCHECK(router_); | 231 DCHECK(router_); |
| 221 | 232 |
| 222 TRACE_EVENT_NESTABLE_ASYNC_INSTANT1("media_router", "UI", initiator, | 233 TRACE_EVENT_NESTABLE_ASYNC_INSTANT1("media_router", "UI", initiator, |
| 223 "MediaRouterUI::InitCommon", this); | 234 "MediaRouterUI::InitCommon", this); |
| 224 // Register for MediaRoute updates. | |
| 225 routes_observer_.reset(new UIMediaRoutesObserver( | |
| 226 router_, | |
| 227 base::Bind(&MediaRouterUI::OnRoutesUpdated, base::Unretained(this)))); | |
| 228 | 235 |
| 229 // Create |collator_| before |query_result_manager_| so that |collator_| is | 236 // Create |collator_| before |query_result_manager_| so that |collator_| is |
| 230 // already set up when we get a callback from |query_result_manager_|. | 237 // already set up when we get a callback from |query_result_manager_|. |
| 231 UErrorCode error = U_ZERO_ERROR; | 238 UErrorCode error = U_ZERO_ERROR; |
| 232 const std::string& locale = g_browser_process->GetApplicationLocale(); | 239 const std::string& locale = g_browser_process->GetApplicationLocale(); |
| 233 collator_.reset( | 240 collator_.reset( |
| 234 icu::Collator::createInstance(icu::Locale(locale.c_str()), error)); | 241 icu::Collator::createInstance(icu::Locale(locale.c_str()), error)); |
| 235 if (U_FAILURE(error)) { | 242 if (U_FAILURE(error)) { |
| 236 DLOG(ERROR) << "Failed to create collator for locale " << locale; | 243 DLOG(ERROR) << "Failed to create collator for locale " << locale; |
| 237 collator_.reset(); | 244 collator_.reset(); |
| 238 } | 245 } |
| 239 | 246 |
| 240 query_result_manager_.reset(new QueryResultManager(router_)); | 247 query_result_manager_.reset(new QueryResultManager(router_)); |
| 241 query_result_manager_->AddObserver(this); | 248 query_result_manager_->AddObserver(this); |
| 242 | 249 |
| 243 // These modes are always available. | 250 // These modes are always available. |
| 244 query_result_manager_->StartSinksQuery(MediaCastMode::DESKTOP_MIRROR, | 251 query_result_manager_->StartSinksQuery(MediaCastMode::DESKTOP_MIRROR, |
| 245 MediaSourceForDesktop()); | 252 MediaSourceForDesktop()); |
| 246 initiator_ = initiator; | 253 initiator_ = initiator; |
| 247 MediaSource mirroring_source( | 254 MediaSource mirroring_source( |
| 248 MediaSourceForTab(SessionTabHelper::IdForTab(initiator))); | 255 MediaSourceForTab(SessionTabHelper::IdForTab(initiator))); |
| 249 query_result_manager_->StartSinksQuery(MediaCastMode::TAB_MIRROR, | 256 query_result_manager_->StartSinksQuery(MediaCastMode::TAB_MIRROR, |
| 250 mirroring_source); | 257 mirroring_source); |
| 251 UpdateCastModes(); | 258 UpdateCastModes(); |
| 252 } | 259 } |
| 253 | 260 |
| 254 void MediaRouterUI::OnDefaultPresentationChanged( | 261 void MediaRouterUI::OnDefaultPresentationChanged( |
| 255 const PresentationRequest& presentation_request) { | 262 const PresentationRequest& presentation_request) { |
| 263 MediaSource source = presentation_request.GetMediaSource(); |
| 256 presentation_request_.reset(new PresentationRequest(presentation_request)); | 264 presentation_request_.reset(new PresentationRequest(presentation_request)); |
| 257 query_result_manager_->StartSinksQuery( | 265 query_result_manager_->StartSinksQuery(MediaCastMode::DEFAULT, source); |
| 258 MediaCastMode::DEFAULT, presentation_request_->GetMediaSource()); | 266 // Register for MediaRoute updates. |
| 267 routes_observer_.reset(new UIMediaRoutesObserver( |
| 268 router_, source.id(), |
| 269 base::Bind(&MediaRouterUI::OnRoutesUpdated, base::Unretained(this)))); |
| 270 |
| 259 UpdateCastModes(); | 271 UpdateCastModes(); |
| 260 } | 272 } |
| 261 | 273 |
| 262 void MediaRouterUI::OnDefaultPresentationRemoved() { | 274 void MediaRouterUI::OnDefaultPresentationRemoved() { |
| 263 presentation_request_.reset(); | 275 presentation_request_.reset(); |
| 264 query_result_manager_->StopSinksQuery(MediaCastMode::DEFAULT); | 276 query_result_manager_->StopSinksQuery(MediaCastMode::DEFAULT); |
| 277 // Register for MediaRoute updates without a media source. |
| 278 routes_observer_.reset(new UIMediaRoutesObserver( |
| 279 router_, MediaSource::Id(), |
| 280 base::Bind(&MediaRouterUI::OnRoutesUpdated, base::Unretained(this)))); |
| 265 UpdateCastModes(); | 281 UpdateCastModes(); |
| 266 } | 282 } |
| 267 | 283 |
| 268 void MediaRouterUI::UpdateCastModes() { | 284 void MediaRouterUI::UpdateCastModes() { |
| 269 // Gets updated cast modes from |query_result_manager_| and forwards it to UI. | 285 // Gets updated cast modes from |query_result_manager_| and forwards it to UI. |
| 270 query_result_manager_->GetSupportedCastModes(&cast_modes_); | 286 query_result_manager_->GetSupportedCastModes(&cast_modes_); |
| 271 if (ui_initialized_) { | 287 if (ui_initialized_) { |
| 272 handler_->UpdateCastModes(cast_modes_, GetPresentationRequestSourceName()); | 288 handler_->UpdateCastModes(cast_modes_, GetPresentationRequestSourceName()); |
| 273 } | 289 } |
| 274 } | 290 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 286 ui_initialized_ = true; | 302 ui_initialized_ = true; |
| 287 | 303 |
| 288 // Register for Issue updates. | 304 // Register for Issue updates. |
| 289 if (!issues_observer_) | 305 if (!issues_observer_) |
| 290 issues_observer_.reset(new UIIssuesObserver(router_, this)); | 306 issues_observer_.reset(new UIIssuesObserver(router_, this)); |
| 291 issues_observer_->RegisterObserver(); | 307 issues_observer_->RegisterObserver(); |
| 292 } | 308 } |
| 293 | 309 |
| 294 bool MediaRouterUI::CreateRoute(const MediaSink::Id& sink_id, | 310 bool MediaRouterUI::CreateRoute(const MediaSink::Id& sink_id, |
| 295 MediaCastMode cast_mode) { | 311 MediaCastMode cast_mode) { |
| 312 return CreateOrConnectRoute(sink_id, cast_mode, MediaRoute::Id()); |
| 313 } |
| 314 |
| 315 bool MediaRouterUI::CreateOrConnectRoute(const MediaSink::Id& sink_id, |
| 316 MediaCastMode cast_mode, |
| 317 const MediaRoute::Id& route_id) { |
| 296 DCHECK(query_result_manager_.get()); | 318 DCHECK(query_result_manager_.get()); |
| 297 DCHECK(initiator_); | 319 DCHECK(initiator_); |
| 298 | 320 |
| 299 // Note that there is a rarely-encountered bug, where the MediaCastMode to | 321 // Note that there is a rarely-encountered bug, where the MediaCastMode to |
| 300 // MediaSource mapping could have been updated, between when the user clicked | 322 // MediaSource mapping could have been updated, between when the user clicked |
| 301 // on the UI to start a create route request, and when this function is | 323 // on the UI to start a create route request, and when this function is |
| 302 // called. However, since the user does not have visibility into the | 324 // called. However, since the user does not have visibility into the |
| 303 // MediaSource, and that it occurs very rarely in practice, we leave it as-is | 325 // MediaSource, and that it occurs very rarely in practice, we leave it as-is |
| 304 // for now. | 326 // for now. |
| 305 MediaSource source = query_result_manager_->GetSourceForCastMode(cast_mode); | 327 MediaSource source = query_result_manager_->GetSourceForCastMode(cast_mode); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 355 base::Bind(&PresentationServiceDelegateImpl::OnRouteResponse, | 377 base::Bind(&PresentationServiceDelegateImpl::OnRouteResponse, |
| 356 presentation_service_delegate_, *presentation_request_)); | 378 presentation_service_delegate_, *presentation_request_)); |
| 357 } | 379 } |
| 358 } | 380 } |
| 359 | 381 |
| 360 // Start the timer. | 382 // Start the timer. |
| 361 route_creation_timer_.Start( | 383 route_creation_timer_.Start( |
| 362 FROM_HERE, base::TimeDelta::FromSeconds(kCreateRouteTimeoutSeconds), this, | 384 FROM_HERE, base::TimeDelta::FromSeconds(kCreateRouteTimeoutSeconds), this, |
| 363 &MediaRouterUI::RouteCreationTimeout); | 385 &MediaRouterUI::RouteCreationTimeout); |
| 364 | 386 |
| 365 router_->CreateRoute(source.id(), sink_id, origin, initiator_, | 387 if (route_id.empty()) { |
| 366 route_response_callbacks); | 388 router_->CreateRoute(source.id(), sink_id, origin, initiator_, |
| 389 route_response_callbacks); |
| 390 } else { |
| 391 router_->ConnectRouteByRouteId(source.id(), route_id, origin, |
| 392 initiator_, route_response_callbacks); |
| 393 } |
| 367 return true; | 394 return true; |
| 368 } | 395 } |
| 369 | 396 |
| 397 bool MediaRouterUI::ConnectRoute(const MediaSink::Id& sink_id, |
| 398 const MediaRoute::Id& route_id) { |
| 399 return CreateOrConnectRoute(sink_id, MediaCastMode::DEFAULT, route_id); |
| 400 } |
| 401 |
| 370 void MediaRouterUI::CloseRoute(const MediaRoute::Id& route_id) { | 402 void MediaRouterUI::CloseRoute(const MediaRoute::Id& route_id) { |
| 371 router_->TerminateRoute(route_id); | 403 router_->TerminateRoute(route_id); |
| 372 } | 404 } |
| 373 | 405 |
| 374 void MediaRouterUI::AddIssue(const Issue& issue) { router_->AddIssue(issue); } | 406 void MediaRouterUI::AddIssue(const Issue& issue) { router_->AddIssue(issue); } |
| 375 | 407 |
| 376 void MediaRouterUI::ClearIssue(const std::string& issue_id) { | 408 void MediaRouterUI::ClearIssue(const std::string& issue_id) { |
| 377 router_->ClearIssue(issue_id); | 409 router_->ClearIssue(issue_id); |
| 378 } | 410 } |
| 379 | 411 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 404 return sink1.sink.id() < sink2.sink.id(); | 436 return sink1.sink.id() < sink2.sink.id(); |
| 405 }); | 437 }); |
| 406 | 438 |
| 407 if (ui_initialized_) handler_->UpdateSinks(sinks_); | 439 if (ui_initialized_) handler_->UpdateSinks(sinks_); |
| 408 } | 440 } |
| 409 | 441 |
| 410 void MediaRouterUI::SetIssue(const Issue* issue) { | 442 void MediaRouterUI::SetIssue(const Issue* issue) { |
| 411 if (ui_initialized_) handler_->UpdateIssue(issue); | 443 if (ui_initialized_) handler_->UpdateIssue(issue); |
| 412 } | 444 } |
| 413 | 445 |
| 414 void MediaRouterUI::OnRoutesUpdated(const std::vector<MediaRoute>& routes) { | 446 void MediaRouterUI::OnRoutesUpdated( |
| 447 const std::vector<MediaRoute>& routes, |
| 448 const std::vector<MediaRoute::Id>& joinable_route_ids) { |
| 415 routes_ = routes; | 449 routes_ = routes; |
| 416 if (ui_initialized_) handler_->UpdateRoutes(routes_); | 450 joinable_route_ids_ = joinable_route_ids; |
| 451 if (ui_initialized_) handler_->UpdateRoutes(routes_, joinable_route_ids_); |
| 417 } | 452 } |
| 418 | 453 |
| 419 void MediaRouterUI::OnRouteResponseReceived(const int route_request_id, | 454 void MediaRouterUI::OnRouteResponseReceived(const int route_request_id, |
| 420 const MediaSink::Id& sink_id, | 455 const MediaSink::Id& sink_id, |
| 421 const MediaRoute* route, | 456 const MediaRoute* route, |
| 422 const std::string& presentation_id, | 457 const std::string& presentation_id, |
| 423 const std::string& error) { | 458 const std::string& error) { |
| 424 DVLOG(1) << "OnRouteResponseReceived"; | 459 DVLOG(1) << "OnRouteResponseReceived"; |
| 425 // If we receive a new route that we aren't expecting, do nothing. | 460 // If we receive a new route that we aren't expecting, do nothing. |
| 426 if (route_request_id != current_route_request_id_) return; | 461 if (route_request_id != current_route_request_id_) return; |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 495 | 530 |
| 496 void MediaRouterUI::OnUIInitialDataReceived() { | 531 void MediaRouterUI::OnUIInitialDataReceived() { |
| 497 if (!start_time_.is_null()) { | 532 if (!start_time_.is_null()) { |
| 498 MediaRouterMetrics::RecordMediaRouterDialogLoaded( | 533 MediaRouterMetrics::RecordMediaRouterDialogLoaded( |
| 499 base::Time::Now() - start_time_); | 534 base::Time::Now() - start_time_); |
| 500 start_time_ = base::Time(); | 535 start_time_ = base::Time(); |
| 501 } | 536 } |
| 502 } | 537 } |
| 503 | 538 |
| 504 } // namespace media_router | 539 } // namespace media_router |
| OLD | NEW |