| 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/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 #include <unordered_map> | 8 #include <unordered_map> |
| 9 #include <utility> | 9 #include <utility> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 149 void RemoveConnection(const std::string& presentation_id, | 149 void RemoveConnection(const std::string& presentation_id, |
| 150 const MediaRoute::Id& route_id); | 150 const MediaRoute::Id& route_id); |
| 151 | 151 |
| 152 const MediaRoute::Id GetRouteId(const std::string& presentation_id) const; | 152 const MediaRoute::Id GetRouteId(const std::string& presentation_id) const; |
| 153 | 153 |
| 154 void OnPresentationSessionStarted( | 154 void OnPresentationSessionStarted( |
| 155 const content::PresentationSessionInfo& session, | 155 const content::PresentationSessionInfo& session, |
| 156 const MediaRoute& route); | 156 const MediaRoute& route); |
| 157 void OnPresentationServiceDelegateDestroyed() const; | 157 void OnPresentationServiceDelegateDestroyed() const; |
| 158 | 158 |
| 159 bool IsOffscreenPresentation(const std::string& presentation_id) const; | |
| 160 void ConnectToPresentation( | 159 void ConnectToPresentation( |
| 161 const content::PresentationSessionInfo& session, | 160 const content::PresentationSessionInfo& session, |
| 162 content::PresentationConnectionPtr controller_connection_ptr, | 161 content::PresentationConnectionPtr controller_connection_ptr, |
| 163 content::PresentationConnectionRequest receiver_connection_request); | 162 content::PresentationConnectionRequest receiver_connection_request); |
| 164 | 163 |
| 165 private: | 164 private: |
| 166 MediaSource GetMediaSourceFromListener( | 165 MediaSource GetMediaSourceFromListener( |
| 167 content::PresentationScreenAvailabilityListener* listener) const; | 166 content::PresentationScreenAvailabilityListener* listener) const; |
| 168 base::SmallMap<std::map<std::string, MediaRoute>> presentation_id_to_route_; | 167 base::SmallMap<std::map<std::string, MediaRoute>> presentation_id_to_route_; |
| 169 base::SmallMap< | 168 base::SmallMap< |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 247 } | 246 } |
| 248 return false; | 247 return false; |
| 249 } | 248 } |
| 250 | 249 |
| 251 bool PresentationFrame::HasScreenAvailabilityListenerForTest( | 250 bool PresentationFrame::HasScreenAvailabilityListenerForTest( |
| 252 const MediaSource::Id& source_id) const { | 251 const MediaSource::Id& source_id) const { |
| 253 return url_to_sinks_observer_.find(source_id) != url_to_sinks_observer_.end(); | 252 return url_to_sinks_observer_.find(source_id) != url_to_sinks_observer_.end(); |
| 254 } | 253 } |
| 255 | 254 |
| 256 void PresentationFrame::Reset() { | 255 void PresentationFrame::Reset() { |
| 257 auto* offscreen_presentation_manager = | |
| 258 OffscreenPresentationManagerFactory::GetOrCreateForWebContents( | |
| 259 web_contents_); | |
| 260 | 256 |
| 261 for (const auto& pid_route : presentation_id_to_route_) { | 257 for (const auto& pid_route : presentation_id_to_route_) { |
| 262 if (IsOffscreenPresentation(pid_route.first)) { | 258 if (pid_route.second.is_offscreen_presentation()) { |
| 259 auto* offscreen_presentation_manager = |
| 260 OffscreenPresentationManagerFactory::GetOrCreateForWebContents( |
| 261 web_contents_); |
| 263 offscreen_presentation_manager->UnregisterOffscreenPresentationController( | 262 offscreen_presentation_manager->UnregisterOffscreenPresentationController( |
| 264 pid_route.first, render_frame_host_id_); | 263 pid_route.first, render_frame_host_id_); |
| 264 } else { |
| 265 router_->DetachRoute(pid_route.second.media_route_id()); |
| 265 } | 266 } |
| 266 router_->DetachRoute(pid_route.second.media_route_id()); | |
| 267 } | 267 } |
| 268 | 268 |
| 269 presentation_id_to_route_.clear(); | 269 presentation_id_to_route_.clear(); |
| 270 url_to_sinks_observer_.clear(); | 270 url_to_sinks_observer_.clear(); |
| 271 connection_state_subscriptions_.clear(); | 271 connection_state_subscriptions_.clear(); |
| 272 session_messages_observers_.clear(); | 272 session_messages_observers_.clear(); |
| 273 browser_connection_proxies_.clear(); | 273 browser_connection_proxies_.clear(); |
| 274 } | 274 } |
| 275 | 275 |
| 276 void PresentationFrame::RemoveConnection(const std::string& presentation_id, | 276 void PresentationFrame::RemoveConnection(const std::string& presentation_id, |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 342 } | 342 } |
| 343 | 343 |
| 344 MediaSource PresentationFrame::GetMediaSourceFromListener( | 344 MediaSource PresentationFrame::GetMediaSourceFromListener( |
| 345 content::PresentationScreenAvailabilityListener* listener) const { | 345 content::PresentationScreenAvailabilityListener* listener) const { |
| 346 // If the default presentation URL is empty then fall back to tab mirroring. | 346 // If the default presentation URL is empty then fall back to tab mirroring. |
| 347 return listener->GetAvailabilityUrl().is_empty() | 347 return listener->GetAvailabilityUrl().is_empty() |
| 348 ? MediaSourceForTab(SessionTabHelper::IdForTab(web_contents_)) | 348 ? MediaSourceForTab(SessionTabHelper::IdForTab(web_contents_)) |
| 349 : MediaSourceForPresentationUrl(listener->GetAvailabilityUrl()); | 349 : MediaSourceForPresentationUrl(listener->GetAvailabilityUrl()); |
| 350 } | 350 } |
| 351 | 351 |
| 352 bool PresentationFrame::IsOffscreenPresentation( | |
| 353 const std::string& presentation_id) const { | |
| 354 const auto it = presentation_id_to_route_.find(presentation_id); | |
| 355 if (it == presentation_id_to_route_.end()) { | |
| 356 DLOG(WARNING) << "No route for [presentation_id]: " << presentation_id; | |
| 357 return false; | |
| 358 } | |
| 359 | |
| 360 return it->second.is_offscreen_presentation(); | |
| 361 } | |
| 362 | |
| 363 void PresentationFrame::ConnectToPresentation( | 352 void PresentationFrame::ConnectToPresentation( |
| 364 const content::PresentationSessionInfo& session, | 353 const content::PresentationSessionInfo& session, |
| 365 content::PresentationConnectionPtr controller_connection_ptr, | 354 content::PresentationConnectionPtr controller_connection_ptr, |
| 366 content::PresentationConnectionRequest receiver_connection_request) { | 355 content::PresentationConnectionRequest receiver_connection_request) { |
| 367 const auto pid_route_it = | 356 const auto pid_route_it = |
| 368 presentation_id_to_route_.find(session.presentation_id); | 357 presentation_id_to_route_.find(session.presentation_id); |
| 369 | 358 |
| 370 if (pid_route_it == presentation_id_to_route_.end()) { | 359 if (pid_route_it == presentation_id_to_route_.end()) { |
| 371 DLOG(WARNING) << "No route for [presentation_id]: " | 360 DLOG(WARNING) << "No route for [presentation_id]: " |
| 372 << session.presentation_id; | 361 << session.presentation_id; |
| 373 return; | 362 return; |
| 374 } | 363 } |
| 375 | 364 |
| 376 if (IsOffscreenPresentation(session.presentation_id)) { | 365 if (pid_route_it->second.is_offscreen_presentation()) { |
| 377 auto* const offscreen_presentation_manager = | 366 auto* offscreen_presentation_manager = |
| 378 OffscreenPresentationManagerFactory::GetOrCreateForWebContents( | 367 OffscreenPresentationManagerFactory::GetOrCreateForWebContents( |
| 379 web_contents_); | 368 web_contents_); |
| 380 offscreen_presentation_manager->RegisterOffscreenPresentationController( | 369 offscreen_presentation_manager->RegisterOffscreenPresentationController( |
| 381 session.presentation_id, session.presentation_url, | 370 session.presentation_id, session.presentation_url, |
| 382 render_frame_host_id_, std::move(controller_connection_ptr), | 371 render_frame_host_id_, std::move(controller_connection_ptr), |
| 383 std::move(receiver_connection_request)); | 372 std::move(receiver_connection_request), pid_route_it->second); |
| 384 } else { | 373 } else { |
| 385 DVLOG(2) | 374 DVLOG(2) |
| 386 << "Creating BrowserPresentationConnectionProxy for [presentation_id]: " | 375 << "Creating BrowserPresentationConnectionProxy for [presentation_id]: " |
| 387 << session.presentation_id; | 376 << session.presentation_id; |
| 388 MediaRoute::Id route_id = pid_route_it->second.media_route_id(); | 377 MediaRoute::Id route_id = pid_route_it->second.media_route_id(); |
| 389 auto* proxy = new BrowserPresentationConnectionProxy( | 378 auto* proxy = new BrowserPresentationConnectionProxy( |
| 390 router_, route_id, std::move(receiver_connection_request), | 379 router_, route_id, std::move(receiver_connection_request), |
| 391 std::move(controller_connection_ptr)); | 380 std::move(controller_connection_ptr)); |
| 392 | 381 |
| 393 browser_connection_proxies_.insert( | 382 browser_connection_proxies_.insert( |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 545 presentation_frame->ConnectToPresentation( | 534 presentation_frame->ConnectToPresentation( |
| 546 session, std::move(controller_connection_ptr), | 535 session, std::move(controller_connection_ptr), |
| 547 std::move(receiver_connection_request)); | 536 std::move(receiver_connection_request)); |
| 548 } | 537 } |
| 549 | 538 |
| 550 const MediaRoute::Id PresentationFrameManager::GetRouteId( | 539 const MediaRoute::Id PresentationFrameManager::GetRouteId( |
| 551 const RenderFrameHostId& render_frame_host_id, | 540 const RenderFrameHostId& render_frame_host_id, |
| 552 const std::string& presentation_id) const { | 541 const std::string& presentation_id) const { |
| 553 const auto it = presentation_frames_.find(render_frame_host_id); | 542 const auto it = presentation_frames_.find(render_frame_host_id); |
| 554 return it != presentation_frames_.end() | 543 return it != presentation_frames_.end() |
| 555 ? it->second->GetRouteId(presentation_id) : MediaRoute::Id(); | 544 ? it->second->GetRouteId(presentation_id) |
| 545 : MediaRoute::Id(); |
| 556 } | 546 } |
| 557 | 547 |
| 558 bool PresentationFrameManager::SetScreenAvailabilityListener( | 548 bool PresentationFrameManager::SetScreenAvailabilityListener( |
| 559 const RenderFrameHostId& render_frame_host_id, | 549 const RenderFrameHostId& render_frame_host_id, |
| 560 content::PresentationScreenAvailabilityListener* listener) { | 550 content::PresentationScreenAvailabilityListener* listener) { |
| 561 DCHECK(listener); | 551 DCHECK(listener); |
| 562 auto* presentation_frame = GetOrAddPresentationFrame(render_frame_host_id); | 552 auto* presentation_frame = GetOrAddPresentationFrame(render_frame_host_id); |
| 563 return presentation_frame->SetScreenAvailabilityListener(listener); | 553 return presentation_frame->SetScreenAvailabilityListener(listener); |
| 564 } | 554 } |
| 565 | 555 |
| (...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 877 #if !defined(OS_ANDROID) | 867 #if !defined(OS_ANDROID) |
| 878 if (IsAutoJoinPresentationId(presentation_id) && | 868 if (IsAutoJoinPresentationId(presentation_id) && |
| 879 ShouldCancelAutoJoinForOrigin(origin)) { | 869 ShouldCancelAutoJoinForOrigin(origin)) { |
| 880 error_cb.Run(content::PresentationError( | 870 error_cb.Run(content::PresentationError( |
| 881 content::PRESENTATION_ERROR_SESSION_REQUEST_CANCELLED, | 871 content::PRESENTATION_ERROR_SESSION_REQUEST_CANCELLED, |
| 882 "Auto-join request cancelled by user preferences.")); | 872 "Auto-join request cancelled by user preferences.")); |
| 883 return; | 873 return; |
| 884 } | 874 } |
| 885 #endif // !defined(OS_ANDROID) | 875 #endif // !defined(OS_ANDROID) |
| 886 | 876 |
| 887 // TODO(crbug.com/627655): Handle multiple URLs. | 877 auto* offscreen_presentation_manager = |
| 888 const GURL& presentation_url = presentation_urls[0]; | 878 OffscreenPresentationManagerFactory::GetOrCreateForWebContents( |
| 889 bool incognito = web_contents_->GetBrowserContext()->IsOffTheRecord(); | 879 web_contents_); |
| 890 std::vector<MediaRouteResponseCallback> route_response_callbacks; | 880 // Check offscreen presentation across frames. |
| 891 route_response_callbacks.push_back( | 881 if (offscreen_presentation_manager->IsOffscreenPresentation( |
| 892 base::Bind(&PresentationServiceDelegateImpl::OnJoinRouteResponse, | 882 presentation_id)) { |
| 893 weak_factory_.GetWeakPtr(), render_process_id, render_frame_id, | 883 auto* route = offscreen_presentation_manager->GetRoute(presentation_id); |
| 894 presentation_url, presentation_id, success_cb, error_cb)); | 884 |
| 895 router_->JoinRoute(MediaSourceForPresentationUrl(presentation_url).id(), | 885 if (!route) { |
| 896 presentation_id, origin, web_contents_, | 886 LOG(WARNING) << "No route found for [presentation_id]: " |
| 897 route_response_callbacks, base::TimeDelta(), incognito); | 887 << presentation_id; |
| 888 return; |
| 889 } |
| 890 |
| 891 if (!base::ContainsValue(presentation_urls, route->media_source().url())) { |
| 892 DVLOG(2) << "Presentation URLs do not match URL of current presentation:" |
| 893 << route->media_source().url(); |
| 894 return; |
| 895 } |
| 896 |
| 897 auto result = RouteRequestResult::FromSuccess(*route, presentation_id); |
| 898 OnJoinRouteResponse(render_process_id, render_frame_id, |
| 899 presentation_urls[0], presentation_id, success_cb, |
| 900 error_cb, *result); |
| 901 } else { |
| 902 // TODO(crbug.com/627655): Handle multiple URLs. |
| 903 const GURL& presentation_url = presentation_urls[0]; |
| 904 bool incognito = web_contents_->GetBrowserContext()->IsOffTheRecord(); |
| 905 std::vector<MediaRouteResponseCallback> route_response_callbacks; |
| 906 route_response_callbacks.push_back(base::Bind( |
| 907 &PresentationServiceDelegateImpl::OnJoinRouteResponse, |
| 908 weak_factory_.GetWeakPtr(), render_process_id, render_frame_id, |
| 909 presentation_url, presentation_id, success_cb, error_cb)); |
| 910 router_->JoinRoute(MediaSourceForPresentationUrl(presentation_url).id(), |
| 911 presentation_id, origin, web_contents_, |
| 912 route_response_callbacks, base::TimeDelta(), incognito); |
| 913 } |
| 898 } | 914 } |
| 899 | 915 |
| 900 void PresentationServiceDelegateImpl::CloseConnection( | 916 void PresentationServiceDelegateImpl::CloseConnection( |
| 901 int render_process_id, | 917 int render_process_id, |
| 902 int render_frame_id, | 918 int render_frame_id, |
| 903 const std::string& presentation_id) { | 919 const std::string& presentation_id) { |
| 904 const RenderFrameHostId rfh_id(render_process_id, render_frame_id); | 920 const RenderFrameHostId rfh_id(render_process_id, render_frame_id); |
| 905 const MediaRoute::Id& route_id = | 921 const MediaRoute::Id& route_id = |
| 906 frame_manager_->GetRouteId(rfh_id, presentation_id); | 922 frame_manager_->GetRouteId(rfh_id, presentation_id); |
| 907 if (route_id.empty()) { | 923 if (route_id.empty()) { |
| 908 DVLOG(1) << "No active route for: " << presentation_id; | 924 DVLOG(1) << "No active route for: " << presentation_id; |
| 909 return; | 925 return; |
| 910 } | 926 } |
| 911 | 927 |
| 912 router_->DetachRoute(route_id); | 928 auto* offscreen_presentation_manager = |
| 929 OffscreenPresentationManagerFactory::GetOrCreateForWebContents( |
| 930 web_contents_); |
| 931 |
| 932 if (offscreen_presentation_manager->IsOffscreenPresentation( |
| 933 presentation_id)) { |
| 934 offscreen_presentation_manager->UnregisterOffscreenPresentationController( |
| 935 presentation_id, rfh_id); |
| 936 } else { |
| 937 router_->DetachRoute(route_id); |
| 938 } |
| 913 frame_manager_->RemoveConnection(rfh_id, presentation_id, route_id); | 939 frame_manager_->RemoveConnection(rfh_id, presentation_id, route_id); |
| 914 // TODO(mfoltz): close() should always succeed so there is no need to keep the | 940 // TODO(mfoltz): close() should always succeed so there is no need to keep the |
| 915 // state_changed_cb around - remove it and fire the ChangeEvent on the | 941 // state_changed_cb around - remove it and fire the ChangeEvent on the |
| 916 // PresentationConnection in Blink. | 942 // PresentationConnection in Blink. |
| 917 } | 943 } |
| 918 | 944 |
| 919 void PresentationServiceDelegateImpl::Terminate( | 945 void PresentationServiceDelegateImpl::Terminate( |
| 920 int render_process_id, | 946 int render_process_id, |
| 921 int render_frame_id, | 947 int render_frame_id, |
| 922 const std::string& presentation_id) { | 948 const std::string& presentation_id) { |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1051 const base::ListValue* origins = | 1077 const base::ListValue* origins = |
| 1052 Profile::FromBrowserContext(web_contents_->GetBrowserContext()) | 1078 Profile::FromBrowserContext(web_contents_->GetBrowserContext()) |
| 1053 ->GetPrefs() | 1079 ->GetPrefs() |
| 1054 ->GetList(prefs::kMediaRouterTabMirroringSources); | 1080 ->GetList(prefs::kMediaRouterTabMirroringSources); |
| 1055 return origins && | 1081 return origins && |
| 1056 origins->Find(base::Value(origin.Serialize())) != origins->end(); | 1082 origins->Find(base::Value(origin.Serialize())) != origins->end(); |
| 1057 } | 1083 } |
| 1058 #endif // !defined(OS_ANDROID) | 1084 #endif // !defined(OS_ANDROID) |
| 1059 | 1085 |
| 1060 } // namespace media_router | 1086 } // namespace media_router |
| OLD | NEW |