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 <algorithm> | 7 #include <algorithm> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/guid.h" | 10 #include "base/guid.h" |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 96 void OnIssueUpdated(const Issue* issue) override { ui_->SetIssue(issue); } | 96 void OnIssueUpdated(const Issue* issue) override { ui_->SetIssue(issue); } |
| 97 | 97 |
| 98 private: | 98 private: |
| 99 // Reference back to the owning MediaRouterUI instance. | 99 // Reference back to the owning MediaRouterUI instance. |
| 100 MediaRouterUI* ui_; | 100 MediaRouterUI* ui_; |
| 101 | 101 |
| 102 DISALLOW_COPY_AND_ASSIGN(UIIssuesObserver); | 102 DISALLOW_COPY_AND_ASSIGN(UIIssuesObserver); |
| 103 }; | 103 }; |
| 104 | 104 |
| 105 MediaRouterUI::UIMediaRoutesObserver::UIMediaRoutesObserver( | 105 MediaRouterUI::UIMediaRoutesObserver::UIMediaRoutesObserver( |
| 106 MediaRouter* router, const RoutesUpdatedCallback& callback) | 106 MediaRouter* router, |
| 107 : MediaRoutesObserver(router), callback_(callback) { | 107 const RoutesUpdatedCallback& callback) : |
| 108 UIMediaRoutesObserver(router, MediaSource::Id(), callback) { | |
| 109 } | |
| 110 | |
| 111 MediaRouterUI::UIMediaRoutesObserver::UIMediaRoutesObserver( | |
| 112 MediaRouter* router, const MediaSource::Id& source_id, | |
| 113 const RoutesUpdatedCallback& callback) | |
| 114 : MediaRoutesObserver(router, source_id), callback_(callback) { | |
| 108 DCHECK(!callback_.is_null()); | 115 DCHECK(!callback_.is_null()); |
| 109 } | 116 } |
| 110 | 117 |
| 111 MediaRouterUI::UIMediaRoutesObserver::~UIMediaRoutesObserver() {} | 118 MediaRouterUI::UIMediaRoutesObserver::~UIMediaRoutesObserver() {} |
| 112 | 119 |
| 113 void MediaRouterUI::UIMediaRoutesObserver::OnRoutesUpdated( | 120 void MediaRouterUI::UIMediaRoutesObserver::OnRoutesUpdated( |
| 114 const std::vector<MediaRoute>& routes) { | 121 const std::vector<MediaRoute>& routes, |
| 122 const std::vector<MediaRoute::Id>& joinable_route_ids) { | |
| 115 std::vector<MediaRoute> routes_for_display; | 123 std::vector<MediaRoute> routes_for_display; |
| 124 std::vector<MediaRoute::Id> joinable_route_ids_for_display; | |
| 116 for (const MediaRoute& route : routes) { | 125 for (const MediaRoute& route : routes) { |
| 117 if (route.for_display()) { | 126 if (route.for_display()) { |
| 118 #ifndef NDEBUG | 127 #ifndef NDEBUG |
| 119 for (const MediaRoute& existing_route : routes_for_display) { | 128 for (const MediaRoute& existing_route : routes_for_display) { |
| 120 if (existing_route.media_sink_id() == route.media_sink_id()) { | 129 if (existing_route.media_sink_id() == route.media_sink_id()) { |
| 121 DVLOG(2) << "Received another route for display with the same sink" | 130 DVLOG(2) << "Received another route for display with the same sink" |
| 122 << " id as an existing route. " << route.media_route_id() | 131 << " id as an existing route. " << route.media_route_id() |
| 123 << " has the same sink id as " | 132 << " has the same sink id as " |
| 124 << existing_route.media_sink_id() << "."; | 133 << existing_route.media_sink_id() << "."; |
| 125 } | 134 } |
| 126 } | 135 } |
| 127 #endif | 136 #endif |
| 137 if (ContainsValue(joinable_route_ids, route.media_route_id())) { | |
|
imcheng
2015/12/17 02:30:57
Do we need to hide the join button if the route wa
matt.boetger
2015/12/18 23:37:15
Perhaps. Right now that is an implementation deta
| |
| 138 joinable_route_ids_for_display.push_back(route.media_route_id()); | |
|
mark a. foltz
2015/12/16 07:17:35
Since the only way to connect to a remote route is
matt.boetger
2015/12/18 23:37:15
No, the MRP should not, but how are we going to en
imcheng
2015/12/29 00:24:42
BTW Vadim and I talked about removing forDisplay f
matt.boetger
2016/01/05 00:19:47
Acknowledged.
| |
| 139 } | |
| 140 | |
| 128 routes_for_display.push_back(route); | 141 routes_for_display.push_back(route); |
| 129 } | 142 } |
| 130 } | 143 } |
| 131 | 144 |
| 132 callback_.Run(routes_for_display); | 145 callback_.Run(routes_for_display, joinable_route_ids_for_display); |
| 133 } | 146 } |
| 134 | 147 |
| 135 MediaRouterUI::MediaRouterUI(content::WebUI* web_ui) | 148 MediaRouterUI::MediaRouterUI(content::WebUI* web_ui) |
| 136 : ConstrainedWebDialogUI(web_ui), | 149 : ConstrainedWebDialogUI(web_ui), |
| 137 handler_(new MediaRouterWebUIMessageHandler(this)), | 150 handler_(new MediaRouterWebUIMessageHandler(this)), |
| 138 ui_initialized_(false), | 151 ui_initialized_(false), |
| 139 requesting_route_for_default_source_(false), | 152 requesting_route_for_default_source_(false), |
| 140 current_route_request_id_(-1), | 153 current_route_request_id_(-1), |
| 141 route_request_counter_(0), | 154 route_request_counter_(0), |
| 142 initiator_(nullptr), | 155 initiator_(nullptr), |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 213 InitCommon(initiator); | 226 InitCommon(initiator); |
| 214 OnDefaultPresentationChanged(create_session_request_->presentation_request()); | 227 OnDefaultPresentationChanged(create_session_request_->presentation_request()); |
| 215 } | 228 } |
| 216 | 229 |
| 217 void MediaRouterUI::InitCommon(content::WebContents* initiator) { | 230 void MediaRouterUI::InitCommon(content::WebContents* initiator) { |
| 218 DCHECK(initiator); | 231 DCHECK(initiator); |
| 219 DCHECK(router_); | 232 DCHECK(router_); |
| 220 | 233 |
| 221 TRACE_EVENT_NESTABLE_ASYNC_INSTANT1("media_router", "UI", initiator, | 234 TRACE_EVENT_NESTABLE_ASYNC_INSTANT1("media_router", "UI", initiator, |
| 222 "MediaRouterUI::InitCommon", this); | 235 "MediaRouterUI::InitCommon", this); |
| 223 // Register for MediaRoute updates. | |
|
mark a. foltz
2015/12/16 07:17:35
How does the dialog get route updates when there i
matt.boetger
2015/12/18 23:37:15
Done.
| |
| 224 routes_observer_.reset(new UIMediaRoutesObserver( | |
| 225 router_, | |
| 226 base::Bind(&MediaRouterUI::OnRoutesUpdated, base::Unretained(this)))); | |
| 227 | |
| 228 // Create |collator_| before |query_result_manager_| so that |collator_| is | 236 // Create |collator_| before |query_result_manager_| so that |collator_| is |
| 229 // 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_|. |
| 230 UErrorCode error = U_ZERO_ERROR; | 238 UErrorCode error = U_ZERO_ERROR; |
| 231 const std::string& locale = g_browser_process->GetApplicationLocale(); | 239 const std::string& locale = g_browser_process->GetApplicationLocale(); |
| 232 collator_.reset( | 240 collator_.reset( |
| 233 icu::Collator::createInstance(icu::Locale(locale.c_str()), error)); | 241 icu::Collator::createInstance(icu::Locale(locale.c_str()), error)); |
| 234 if (U_FAILURE(error)) { | 242 if (U_FAILURE(error)) { |
| 235 DLOG(ERROR) << "Failed to create collator for locale " << locale; | 243 DLOG(ERROR) << "Failed to create collator for locale " << locale; |
| 236 collator_.reset(); | 244 collator_.reset(); |
| 237 } | 245 } |
| 238 | 246 |
| 239 query_result_manager_.reset(new QueryResultManager(router_)); | 247 query_result_manager_.reset(new QueryResultManager(router_)); |
| 240 query_result_manager_->AddObserver(this); | 248 query_result_manager_->AddObserver(this); |
| 241 | 249 |
| 242 // These modes are always available. | 250 // These modes are always available. |
| 243 query_result_manager_->StartSinksQuery(MediaCastMode::DESKTOP_MIRROR, | 251 query_result_manager_->StartSinksQuery(MediaCastMode::DESKTOP_MIRROR, |
| 244 MediaSourceForDesktop()); | 252 MediaSourceForDesktop()); |
| 245 initiator_ = initiator; | 253 initiator_ = initiator; |
| 246 MediaSource mirroring_source( | 254 MediaSource mirroring_source( |
| 247 MediaSourceForTab(SessionTabHelper::IdForTab(initiator))); | 255 MediaSourceForTab(SessionTabHelper::IdForTab(initiator))); |
| 248 query_result_manager_->StartSinksQuery(MediaCastMode::TAB_MIRROR, | 256 query_result_manager_->StartSinksQuery(MediaCastMode::TAB_MIRROR, |
| 249 mirroring_source); | 257 mirroring_source); |
| 250 UpdateCastModes(); | 258 UpdateCastModes(); |
| 251 } | 259 } |
| 252 | 260 |
| 253 void MediaRouterUI::OnDefaultPresentationChanged( | 261 void MediaRouterUI::OnDefaultPresentationChanged( |
| 254 const PresentationRequest& presentation_request) { | 262 const PresentationRequest& presentation_request) { |
| 263 MediaSource source = presentation_request.GetMediaSource(); | |
| 255 presentation_request_.reset(new PresentationRequest(presentation_request)); | 264 presentation_request_.reset(new PresentationRequest(presentation_request)); |
| 256 query_result_manager_->StartSinksQuery( | 265 query_result_manager_->StartSinksQuery(MediaCastMode::DEFAULT, source); |
| 257 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 | |
| 258 UpdateCastModes(); | 271 UpdateCastModes(); |
| 259 } | 272 } |
| 260 | 273 |
| 261 void MediaRouterUI::OnDefaultPresentationRemoved() { | 274 void MediaRouterUI::OnDefaultPresentationRemoved() { |
| 262 presentation_request_.reset(); | 275 presentation_request_.reset(); |
| 263 query_result_manager_->StopSinksQuery(MediaCastMode::DEFAULT); | 276 query_result_manager_->StopSinksQuery(MediaCastMode::DEFAULT); |
| 277 routes_observer_.reset(); | |
|
mark a. foltz
2015/12/16 07:17:35
Don't you need to instantiate a routes observer wi
matt.boetger
2015/12/18 23:37:15
Done.
| |
| 264 UpdateCastModes(); | 278 UpdateCastModes(); |
| 265 } | 279 } |
| 266 | 280 |
| 267 void MediaRouterUI::UpdateCastModes() { | 281 void MediaRouterUI::UpdateCastModes() { |
| 268 // Gets updated cast modes from |query_result_manager_| and forwards it to UI. | 282 // Gets updated cast modes from |query_result_manager_| and forwards it to UI. |
| 269 query_result_manager_->GetSupportedCastModes(&cast_modes_); | 283 query_result_manager_->GetSupportedCastModes(&cast_modes_); |
| 270 if (ui_initialized_) { | 284 if (ui_initialized_) { |
| 271 handler_->UpdateCastModes(cast_modes_, GetPresentationRequestSourceName()); | 285 handler_->UpdateCastModes(cast_modes_, GetPresentationRequestSourceName()); |
| 272 } | 286 } |
| 273 } | 287 } |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 285 ui_initialized_ = true; | 299 ui_initialized_ = true; |
| 286 | 300 |
| 287 // Register for Issue updates. | 301 // Register for Issue updates. |
| 288 if (!issues_observer_) | 302 if (!issues_observer_) |
| 289 issues_observer_.reset(new UIIssuesObserver(router_, this)); | 303 issues_observer_.reset(new UIIssuesObserver(router_, this)); |
| 290 issues_observer_->RegisterObserver(); | 304 issues_observer_->RegisterObserver(); |
| 291 } | 305 } |
| 292 | 306 |
| 293 bool MediaRouterUI::CreateRoute(const MediaSink::Id& sink_id, | 307 bool MediaRouterUI::CreateRoute(const MediaSink::Id& sink_id, |
| 294 MediaCastMode cast_mode) { | 308 MediaCastMode cast_mode) { |
| 309 return CreateRouteOrConnectRoute(sink_id, cast_mode, MediaRoute::Id()); | |
| 310 } | |
| 311 | |
| 312 bool MediaRouterUI::CreateRouteOrConnectRoute(const MediaSink::Id& sink_id, | |
| 313 MediaCastMode cast_mode, | |
| 314 const MediaRoute::Id& route_id) { | |
| 295 DCHECK(query_result_manager_.get()); | 315 DCHECK(query_result_manager_.get()); |
| 296 DCHECK(initiator_); | 316 DCHECK(initiator_); |
| 297 | 317 |
| 298 // Note that there is a rarely-encountered bug, where the MediaCastMode to | 318 // Note that there is a rarely-encountered bug, where the MediaCastMode to |
| 299 // MediaSource mapping could have been updated, between when the user clicked | 319 // MediaSource mapping could have been updated, between when the user clicked |
| 300 // on the UI to start a create route request, and when this function is | 320 // on the UI to start a create route request, and when this function is |
| 301 // called. However, since the user does not have visibility into the | 321 // called. However, since the user does not have visibility into the |
| 302 // MediaSource, and that it occurs very rarely in practice, we leave it as-is | 322 // MediaSource, and that it occurs very rarely in practice, we leave it as-is |
| 303 // for now. | 323 // for now. |
| 304 MediaSource source = query_result_manager_->GetSourceForCastMode(cast_mode); | 324 MediaSource source = query_result_manager_->GetSourceForCastMode(cast_mode); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 354 base::Bind(&PresentationServiceDelegateImpl::OnRouteResponse, | 374 base::Bind(&PresentationServiceDelegateImpl::OnRouteResponse, |
| 355 presentation_service_delegate_, *presentation_request_)); | 375 presentation_service_delegate_, *presentation_request_)); |
| 356 } | 376 } |
| 357 } | 377 } |
| 358 | 378 |
| 359 // Start the timer. | 379 // Start the timer. |
| 360 route_creation_timer_.Start( | 380 route_creation_timer_.Start( |
| 361 FROM_HERE, base::TimeDelta::FromSeconds(kCreateRouteTimeoutSeconds), this, | 381 FROM_HERE, base::TimeDelta::FromSeconds(kCreateRouteTimeoutSeconds), this, |
| 362 &MediaRouterUI::RouteCreationTimeout); | 382 &MediaRouterUI::RouteCreationTimeout); |
| 363 | 383 |
| 364 router_->CreateRoute(source.id(), sink_id, origin, initiator_, | 384 if (route_id.empty()) { |
| 365 route_response_callbacks); | 385 router_->CreateRoute(source.id(), sink_id, origin, initiator_, |
| 386 route_response_callbacks); | |
|
apacible
2015/12/18 22:34:19
nit: fix indentation here and L389.
matt.boetger
2015/12/18 23:37:15
Fixed on L389. Not sure what the problem is here
| |
| 387 } else { | |
| 388 router_->ConnectRouteByRouteId(source.id(), route_id, origin, | |
| 389 initiator_, route_response_callbacks); | |
| 390 } | |
| 366 return true; | 391 return true; |
| 367 } | 392 } |
| 368 | 393 |
| 394 bool MediaRouterUI::ConnectRemoteRoute(const MediaSink::Id& sink_id, | |
| 395 const MediaRoute::Id& route_id) { | |
|
apacible
2015/12/18 22:34:19
nit: fix indentation.
matt.boetger
2015/12/18 23:37:15
Done.
| |
| 396 return CreateRouteOrConnectRoute(sink_id, MediaCastMode::DEFAULT, route_id); | |
| 397 } | |
| 398 | |
| 369 void MediaRouterUI::CloseRoute(const MediaRoute::Id& route_id) { | 399 void MediaRouterUI::CloseRoute(const MediaRoute::Id& route_id) { |
| 370 router_->CloseRoute(route_id); | 400 router_->CloseRoute(route_id); |
| 371 } | 401 } |
| 372 | 402 |
| 373 void MediaRouterUI::AddIssue(const Issue& issue) { router_->AddIssue(issue); } | 403 void MediaRouterUI::AddIssue(const Issue& issue) { router_->AddIssue(issue); } |
| 374 | 404 |
| 375 void MediaRouterUI::ClearIssue(const std::string& issue_id) { | 405 void MediaRouterUI::ClearIssue(const std::string& issue_id) { |
| 376 router_->ClearIssue(issue_id); | 406 router_->ClearIssue(issue_id); |
| 377 } | 407 } |
| 378 | 408 |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 403 return sink1.sink.id() < sink2.sink.id(); | 433 return sink1.sink.id() < sink2.sink.id(); |
| 404 }); | 434 }); |
| 405 | 435 |
| 406 if (ui_initialized_) handler_->UpdateSinks(sinks_); | 436 if (ui_initialized_) handler_->UpdateSinks(sinks_); |
| 407 } | 437 } |
| 408 | 438 |
| 409 void MediaRouterUI::SetIssue(const Issue* issue) { | 439 void MediaRouterUI::SetIssue(const Issue* issue) { |
| 410 if (ui_initialized_) handler_->UpdateIssue(issue); | 440 if (ui_initialized_) handler_->UpdateIssue(issue); |
| 411 } | 441 } |
| 412 | 442 |
| 413 void MediaRouterUI::OnRoutesUpdated(const std::vector<MediaRoute>& routes) { | 443 void MediaRouterUI::OnRoutesUpdated( |
| 444 const std::vector<MediaRoute>& routes, | |
| 445 const std::vector<MediaRoute::Id>& joinable_route_ids) { | |
| 414 routes_ = routes; | 446 routes_ = routes; |
| 415 if (ui_initialized_) handler_->UpdateRoutes(routes_); | 447 joinable_route_ids_ = joinable_route_ids; |
| 448 if (ui_initialized_) handler_->UpdateRoutes(routes_, joinable_route_ids_); | |
| 416 } | 449 } |
| 417 | 450 |
| 418 void MediaRouterUI::OnRouteResponseReceived(const int route_request_id, | 451 void MediaRouterUI::OnRouteResponseReceived(const int route_request_id, |
| 419 const MediaSink::Id& sink_id, | 452 const MediaSink::Id& sink_id, |
| 420 const MediaRoute* route, | 453 const MediaRoute* route, |
| 421 const std::string& presentation_id, | 454 const std::string& presentation_id, |
| 422 const std::string& error) { | 455 const std::string& error) { |
| 423 DVLOG(1) << "OnRouteResponseReceived"; | 456 DVLOG(1) << "OnRouteResponseReceived"; |
| 424 // If we receive a new route that we aren't expecting, do nothing. | 457 // If we receive a new route that we aren't expecting, do nothing. |
| 425 if (route_request_id != current_route_request_id_) return; | 458 if (route_request_id != current_route_request_id_) return; |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 496 | 529 |
| 497 void MediaRouterUI::OnUIInitialDataReceived() { | 530 void MediaRouterUI::OnUIInitialDataReceived() { |
| 498 if (!start_time_.is_null()) { | 531 if (!start_time_.is_null()) { |
| 499 MediaRouterMetrics::RecordMediaRouterDialogLoaded( | 532 MediaRouterMetrics::RecordMediaRouterDialogLoaded( |
| 500 base::Time::Now() - start_time_); | 533 base::Time::Now() - start_time_); |
| 501 start_time_ = base::Time(); | 534 start_time_ = base::Time(); |
| 502 } | 535 } |
| 503 } | 536 } |
| 504 | 537 |
| 505 } // namespace media_router | 538 } // namespace media_router |
| OLD | NEW |