Index: chrome/browser/media/router/presentation_service_delegate_impl.cc |
diff --git a/chrome/browser/media/router/presentation_service_delegate_impl.cc b/chrome/browser/media/router/presentation_service_delegate_impl.cc |
index 263f937eeb2871d3f3a67b2d785bcda3f001db71..fe5f936bcfa9ec0e8717e0f1104d1f37b2afc450 100644 |
--- a/chrome/browser/media/router/presentation_service_delegate_impl.cc |
+++ b/chrome/browser/media/router/presentation_service_delegate_impl.cc |
@@ -14,6 +14,7 @@ |
#include "base/memory/ptr_util.h" |
#include "base/strings/string_util.h" |
#include "base/strings/stringprintf.h" |
+#include "chrome/browser/media/router/browser_presentation_connection_proxy.h" |
#include "chrome/browser/media/router/create_presentation_connection_request.h" |
#include "chrome/browser/media/router/media_route.h" |
#include "chrome/browser/media/router/media_router.h" |
@@ -147,13 +148,17 @@ class PresentationFrame { |
void OnPresentationSessionStarted( |
const content::PresentationSessionInfo& session, |
- const MediaRoute::Id& route_id); |
+ const MediaRoute& route); |
+ |
+ bool IsOffscreenPresentation(const std::string& presentation_id); |
+ void OnBrowserConnectionAvailable( |
+ const content::PresentationSessionInfo& session, |
+ content::PresentationConnectionPtr controller); |
private: |
MediaSource GetMediaSourceFromListener( |
content::PresentationScreenAvailabilityListener* listener) const; |
- base::SmallMap<std::map<std::string, MediaRoute::Id>> |
- presentation_id_to_route_id_; |
+ base::SmallMap<std::map<std::string, MediaRoute>> presentation_id_to_route_; |
base::SmallMap< |
std::map<std::string, std::unique_ptr<PresentationMediaSinksObserver>>> |
url_to_sinks_observer_; |
@@ -165,11 +170,13 @@ class PresentationFrame { |
MediaRoute::Id, |
std::unique_ptr<PresentationSessionMessagesObserver>> |
session_messages_observers_; |
+ std::set<std::unique_ptr<BrowserPresentationConnectionProxy>> |
+ browser_connection_proxies_; |
RenderFrameHostId render_frame_host_id_; |
// References to the owning WebContents, and the corresponding MediaRouter. |
- const content::WebContents* web_contents_; |
+ content::WebContents* web_contents_; |
MediaRouter* router_; |
}; |
@@ -189,20 +196,22 @@ PresentationFrame::~PresentationFrame() { |
void PresentationFrame::OnPresentationSessionStarted( |
const content::PresentationSessionInfo& session, |
- const MediaRoute::Id& route_id) { |
- presentation_id_to_route_id_[session.presentation_id] = route_id; |
+ const MediaRoute& route) { |
+ presentation_id_to_route_.insert( |
+ std::make_pair(session.presentation_id, route)); |
} |
const MediaRoute::Id PresentationFrame::GetRouteId( |
const std::string& presentation_id) const { |
- auto it = presentation_id_to_route_id_.find(presentation_id); |
- return it != presentation_id_to_route_id_.end() ? it->second : ""; |
+ auto it = presentation_id_to_route_.find(presentation_id); |
+ return it != presentation_id_to_route_.end() ? it->second.media_route_id() |
+ : ""; |
} |
const std::vector<MediaRoute::Id> PresentationFrame::GetRouteIds() const { |
std::vector<MediaRoute::Id> route_ids; |
- for (const auto& e : presentation_id_to_route_id_) |
- route_ids.push_back(e.second); |
+ for (const auto& e : presentation_id_to_route_) |
+ route_ids.push_back(e.second.media_route_id()); |
return route_ids; |
} |
@@ -244,10 +253,16 @@ bool PresentationFrame::HasScreenAvailabilityListenerForTest( |
} |
void PresentationFrame::Reset() { |
- for (const auto& pid_route_id : presentation_id_to_route_id_) |
- router_->DetachRoute(pid_route_id.second); |
+ auto offscreen_presentation_manager = OffscreenPresentationManagerFactory:: |
+ GetOrCreateForControllerBrowserContext(web_contents_); |
- presentation_id_to_route_id_.clear(); |
+ for (const auto& pid_route : presentation_id_to_route_) { |
+ offscreen_presentation_manager->UnregisterOffscreenPresentationController( |
+ pid_route.first, render_frame_host_id_); |
+ router_->DetachRoute(pid_route.second.media_route_id()); |
+ } |
+ |
+ presentation_id_to_route_.clear(); |
url_to_sinks_observer_.clear(); |
connection_state_subscriptions_.clear(); |
session_messages_observers_.clear(); |
@@ -256,7 +271,7 @@ void PresentationFrame::Reset() { |
void PresentationFrame::RemoveConnection(const std::string& presentation_id, |
const MediaRoute::Id& route_id) { |
// Remove the presentation id mapping so a later call to Reset is a no-op. |
- presentation_id_to_route_id_.erase(presentation_id); |
+ presentation_id_to_route_.erase(presentation_id); |
// We no longer need to observe route messages. |
session_messages_observers_.erase(route_id); |
@@ -269,14 +284,14 @@ void PresentationFrame::ListenForConnectionStateChange( |
const content::PresentationSessionInfo& connection, |
const content::PresentationConnectionStateChangedCallback& |
state_changed_cb) { |
- auto it = presentation_id_to_route_id_.find(connection.presentation_id); |
- if (it == presentation_id_to_route_id_.end()) { |
+ auto it = presentation_id_to_route_.find(connection.presentation_id); |
+ if (it == presentation_id_to_route_.end()) { |
DLOG(ERROR) << __func__ << "route id not found for presentation: " |
<< connection.presentation_id; |
return; |
} |
- const MediaRoute::Id& route_id = it->second; |
+ const MediaRoute::Id& route_id = it->second.media_route_id(); |
if (connection_state_subscriptions_.find(route_id) != |
connection_state_subscriptions_.end()) { |
DLOG(ERROR) << __func__ |
@@ -287,20 +302,26 @@ void PresentationFrame::ListenForConnectionStateChange( |
connection_state_subscriptions_.insert(std::make_pair( |
route_id, router_->AddPresentationConnectionStateChangedCallback( |
- it->second, state_changed_cb))); |
+ route_id, state_changed_cb))); |
} |
void PresentationFrame::ListenForSessionMessages( |
const content::PresentationSessionInfo& session, |
const content::PresentationSessionMessageCallback& message_cb) { |
- auto it = presentation_id_to_route_id_.find(session.presentation_id); |
- if (it == presentation_id_to_route_id_.end()) { |
+ auto it = presentation_id_to_route_.find(session.presentation_id); |
+ if (it == presentation_id_to_route_.end()) { |
DVLOG(2) << "ListenForSessionMessages: no route for " |
<< session.presentation_id; |
return; |
} |
- const MediaRoute::Id& route_id = it->second; |
+ if (it->second.is_offscreen_presentation()) { |
+ DVLOG(2) << "ListenForSessionMessages: do not listen for offscreen " |
+ << "presentation [id]: " << session.presentation_id; |
+ return; |
+ } |
+ |
+ const MediaRoute::Id& route_id = it->second.media_route_id(); |
if (session_messages_observers_.find(route_id) != |
session_messages_observers_.end()) { |
DLOG(ERROR) << __func__ |
@@ -311,7 +332,7 @@ void PresentationFrame::ListenForSessionMessages( |
session_messages_observers_.insert(std::make_pair( |
imcheng
2016/11/29 00:33:22
It looks like we should be able to invoke one of t
zhaobin
2017/01/13 00:05:49
Yes, we can do a lot of refactoring after introduc
|
route_id, base::MakeUnique<PresentationSessionMessagesObserver>( |
- router_, it->second, message_cb))); |
+ router_, route_id, message_cb))); |
} |
MediaSource PresentationFrame::GetMediaSourceFromListener( |
@@ -322,6 +343,29 @@ MediaSource PresentationFrame::GetMediaSourceFromListener( |
: MediaSourceForPresentationUrl(listener->GetAvailabilityUrl()); |
} |
+bool PresentationFrame::IsOffscreenPresentation( |
+ const std::string& presentation_id) { |
+ DCHECK(base::ContainsKey(presentation_id_to_route_, presentation_id)); |
+ auto it = presentation_id_to_route_.find(presentation_id); |
+ return it->second.is_offscreen_presentation(); |
+} |
+ |
+void PresentationFrame::OnBrowserConnectionAvailable( |
+ const content::PresentationSessionInfo& session, |
+ content::PresentationConnectionPtr controller) { |
+ DCHECK(controller); |
+ DCHECK(base::ContainsKey(presentation_id_to_route_, session.presentation_id)); |
+ auto it = presentation_id_to_route_.find(session.presentation_id); |
+ |
+ std::unique_ptr<BrowserPresentationConnectionProxy> proxy = |
+ base::MakeUnique<BrowserPresentationConnectionProxy>(session, router_, |
+ &it->second); |
+ controller->SetTargetConnection(proxy->Bind()); |
+ proxy->SetTargetConnection(std::move(controller)); |
+ |
+ browser_connection_proxies_.insert(std::move(proxy)); |
+} |
+ |
// Used by PresentationServiceDelegateImpl to manage PresentationFrames. |
class PresentationFrameManager { |
public: |
@@ -374,11 +418,18 @@ class PresentationFrameManager { |
void OnPresentationSessionStarted( |
const RenderFrameHostId& render_frame_host_id, |
const content::PresentationSessionInfo& session, |
- const MediaRoute::Id& route_id); |
+ const MediaRoute& route); |
void OnDefaultPresentationSessionStarted( |
const PresentationRequest& request, |
const content::PresentationSessionInfo& session, |
- const MediaRoute::Id& route_id); |
+ const MediaRoute& route); |
+ |
+ bool IsOffscreenPresentation(const RenderFrameHostId& render_frame_host_id, |
+ const std::string& presentation_id); |
+ void OnBrowserConnectionAvailable( |
+ const RenderFrameHostId& render_frame_host_id, |
+ const content::PresentationSessionInfo& session, |
+ content::PresentationConnectionPtr controller); |
const MediaRoute::Id GetRouteId(const RenderFrameHostId& render_frame_host_id, |
const std::string& presentation_id) const; |
@@ -442,18 +493,18 @@ PresentationFrameManager::~PresentationFrameManager() {} |
void PresentationFrameManager::OnPresentationSessionStarted( |
const RenderFrameHostId& render_frame_host_id, |
const content::PresentationSessionInfo& session, |
- const MediaRoute::Id& route_id) { |
+ const MediaRoute& route) { |
auto* presentation_frame = GetOrAddPresentationFrame(render_frame_host_id); |
- presentation_frame->OnPresentationSessionStarted(session, route_id); |
+ presentation_frame->OnPresentationSessionStarted(session, route); |
} |
void PresentationFrameManager::OnDefaultPresentationSessionStarted( |
const PresentationRequest& request, |
const content::PresentationSessionInfo& session, |
- const MediaRoute::Id& route_id) { |
+ const MediaRoute& route) { |
const auto it = presentation_frames_.find(request.render_frame_host_id()); |
if (it != presentation_frames_.end()) |
- it->second->OnPresentationSessionStarted(session, route_id); |
+ it->second->OnPresentationSessionStarted(session, route); |
if (default_presentation_request_ && |
default_presentation_request_->Equals(request)) { |
@@ -461,6 +512,25 @@ void PresentationFrameManager::OnDefaultPresentationSessionStarted( |
} |
} |
+bool PresentationFrameManager::IsOffscreenPresentation( |
+ const RenderFrameHostId& render_frame_host_id, |
+ const std::string& presentation_id) { |
+ const auto it = presentation_frames_.find(render_frame_host_id); |
+ if (it != presentation_frames_.end()) |
+ return it->second->IsOffscreenPresentation(presentation_id); |
+ return false; |
+} |
+ |
+void PresentationFrameManager::OnBrowserConnectionAvailable( |
+ const RenderFrameHostId& render_frame_host_id, |
+ const content::PresentationSessionInfo& session, |
+ content::PresentationConnectionPtr controller) { |
+ const auto it = presentation_frames_.find(render_frame_host_id); |
+ if (it != presentation_frames_.end()) |
+ return it->second->OnBrowserConnectionAvailable(session, |
+ std::move(controller)); |
+} |
+ |
const MediaRoute::Id PresentationFrameManager::GetRouteId( |
const RenderFrameHostId& render_frame_host_id, |
const std::string& presentation_id) const { |
@@ -720,7 +790,7 @@ void PresentationServiceDelegateImpl::OnJoinRouteResponse( |
result.route()->is_offscreen_presentation()); |
frame_manager_->OnPresentationSessionStarted( |
RenderFrameHostId(render_process_id, render_frame_id), session, |
- result.route()->media_route_id()); |
+ *result.route()); |
success_cb.Run(session); |
} |
} |
@@ -739,7 +809,7 @@ void PresentationServiceDelegateImpl::OnStartSessionSucceeded( |
<< ", is_offscreen_presentation: " << new_session.is_offscreen; |
frame_manager_->OnPresentationSessionStarted( |
RenderFrameHostId(render_process_id, render_frame_id), new_session, |
- route_id); |
+ route); |
success_cb.Run(new_session); |
} |
@@ -890,18 +960,25 @@ void PresentationServiceDelegateImpl::ListenForConnectionStateChange( |
state_changed_cb); |
} |
-void PresentationServiceDelegateImpl::ConnectToOffscreenPresentation( |
+void PresentationServiceDelegateImpl::ConnectToPresentation( |
int render_process_id, |
int render_frame_id, |
const content::PresentationSessionInfo& session, |
content::PresentationConnectionPtr connection) { |
RenderFrameHostId render_frame_host_id(render_process_id, render_frame_id); |
- auto* const offscreen_presentation_manager = |
- OffscreenPresentationManagerFactory:: |
- GetOrCreateForControllerBrowserContext(web_contents_); |
- offscreen_presentation_manager->RegisterOffscreenPresentationController( |
- session.presentation_id, session.presentation_url, render_frame_host_id, |
- std::move(connection)); |
+ |
+ if (frame_manager_->IsOffscreenPresentation(render_frame_host_id, |
+ session.presentation_id)) { |
+ auto* const offscreen_presentation_manager = |
+ OffscreenPresentationManagerFactory:: |
+ GetOrCreateForControllerBrowserContext(web_contents_); |
+ offscreen_presentation_manager->RegisterOffscreenPresentationController( |
+ session.presentation_id, session.presentation_url, render_frame_host_id, |
+ std::move(connection)); |
+ } else { |
+ frame_manager_->OnBrowserConnectionAvailable(render_frame_host_id, session, |
+ std::move(connection)); |
+ } |
} |
void PresentationServiceDelegateImpl::OnRouteResponse( |
@@ -914,7 +991,7 @@ void PresentationServiceDelegateImpl::OnRouteResponse( |
presentation_request.presentation_url(), result.presentation_id(), |
result.route()->is_offscreen_presentation()); |
frame_manager_->OnDefaultPresentationSessionStarted( |
- presentation_request, session_info, result.route()->media_route_id()); |
+ presentation_request, session_info, *result.route()); |
} |
void PresentationServiceDelegateImpl::AddDefaultPresentationRequestObserver( |