Commit f23b896e authored by imcheng's avatar imcheng Committed by Commit Bot

[MediaRouter] PresentationServiceDelegateImpl cleanup.

- Removed method declarations that are not defined.
- Removed PresentationFrameManager. There is not much reason to keep
  it since most of the logic is just delegating from PSDImpl.
- Push the URL validity check for screen availability to PSImpl.

BUG=736557

Review-Url: https://codereview.chromium.org/2958663002
Cr-Commit-Position: refs/heads/master@{#485437}
parent 2f6a4c5b
...@@ -70,16 +70,13 @@ url::Origin GetLastCommittedURLForFrame( ...@@ -70,16 +70,13 @@ url::Origin GetLastCommittedURLForFrame(
} // namespace } // namespace
// Used by PresentationServiceDelegateImpl to manage // PresentationFrame interfaces with MediaRouter to maintain the current state
// listeners and default presentation info in a render frame. // of Presentation API within a single render frame, such as the set of
// Its lifetime: // PresentationAvailability listeners and PresentationConnections.
// * Create an instance with |render_frame_host_id_| if no instance with the // Instances are lazily created when certain Presentation API is invoked on a
// same |render_frame_host_id_| exists in: // frame, and are owned by PresentationServiceDelegateImpl.
// PresentationFrameManager::OnPresentationConnection // Instances are destroyed when the corresponding frame navigates, or when it
// PresentationFrameManager::OnDefaultPresentationStarted // is destroyed.
// PresentationFrameManager::SetScreenAvailabilityListener
// * Destroy the instance in:
// PresentationFrameManager::Reset
class PresentationFrame { class PresentationFrame {
public: public:
PresentationFrame(const RenderFrameHostId& render_frame_host_id, PresentationFrame(const RenderFrameHostId& render_frame_host_id,
...@@ -94,31 +91,24 @@ class PresentationFrame { ...@@ -94,31 +91,24 @@ class PresentationFrame {
content::PresentationScreenAvailabilityListener* listener); content::PresentationScreenAvailabilityListener* listener);
bool HasScreenAvailabilityListenerForTest( bool HasScreenAvailabilityListenerForTest(
const MediaSource::Id& source_id) const; const MediaSource::Id& source_id) const;
std::string GetDefaultPresentationId() const;
void ListenForConnectionStateChange( void ListenForConnectionStateChange(
const content::PresentationInfo& connection, const content::PresentationInfo& connection,
const content::PresentationConnectionStateChangedCallback& const content::PresentationConnectionStateChangedCallback&
state_changed_cb); state_changed_cb);
void Reset(); void Reset();
void RemoveConnection(const std::string& presentation_id,
const MediaRoute::Id& route_id);
const MediaRoute::Id GetRouteId(const std::string& presentation_id) const; MediaRoute::Id GetRouteId(const std::string& presentation_id) const;
void OnPresentationConnection(
const content::PresentationInfo& presentation_info,
const MediaRoute& route);
void OnPresentationServiceDelegateDestroyed() const;
void AddPresentation(const content::PresentationInfo& presentation_info,
const MediaRoute& route);
void ConnectToPresentation( void ConnectToPresentation(
const content::PresentationInfo& presentation_info, const content::PresentationInfo& presentation_info,
content::PresentationConnectionPtr controller_connection_ptr, content::PresentationConnectionPtr controller_connection_ptr,
content::PresentationConnectionRequest receiver_connection_request); content::PresentationConnectionRequest receiver_connection_request);
void RemovePresentation(const std::string& presentation_id);
private: private:
MediaSource GetMediaSourceFromListener(
content::PresentationScreenAvailabilityListener* listener) const;
base::small_map<std::map<std::string, MediaRoute>> presentation_id_to_route_; base::small_map<std::map<std::string, MediaRoute>> presentation_id_to_route_;
base::small_map< base::small_map<
std::map<std::string, std::unique_ptr<PresentationMediaSinksObserver>>> std::map<std::string, std::unique_ptr<PresentationMediaSinksObserver>>>
...@@ -149,17 +139,9 @@ PresentationFrame::PresentationFrame( ...@@ -149,17 +139,9 @@ PresentationFrame::PresentationFrame(
DCHECK(router_); DCHECK(router_);
} }
PresentationFrame::~PresentationFrame() { PresentationFrame::~PresentationFrame() = default;
}
void PresentationFrame::OnPresentationConnection( MediaRoute::Id PresentationFrame::GetRouteId(
const content::PresentationInfo& presentation_info,
const MediaRoute& route) {
presentation_id_to_route_.insert(
std::make_pair(presentation_info.presentation_id, route));
}
const MediaRoute::Id PresentationFrame::GetRouteId(
const std::string& presentation_id) const { const std::string& presentation_id) const {
auto it = presentation_id_to_route_.find(presentation_id); auto it = presentation_id_to_route_.find(presentation_id);
return it != presentation_id_to_route_.end() ? it->second.media_route_id() return it != presentation_id_to_route_.end() ? it->second.media_route_id()
...@@ -168,7 +150,8 @@ const MediaRoute::Id PresentationFrame::GetRouteId( ...@@ -168,7 +150,8 @@ const MediaRoute::Id PresentationFrame::GetRouteId(
bool PresentationFrame::SetScreenAvailabilityListener( bool PresentationFrame::SetScreenAvailabilityListener(
content::PresentationScreenAvailabilityListener* listener) { content::PresentationScreenAvailabilityListener* listener) {
MediaSource source(GetMediaSourceFromListener(listener)); MediaSource source =
MediaSourceForPresentationUrl(listener->GetAvailabilityUrl());
if (!IsValidPresentationUrl(source.url())) { if (!IsValidPresentationUrl(source.url())) {
listener->OnScreenAvailabilityChanged( listener->OnScreenAvailabilityChanged(
blink::mojom::ScreenAvailability::SOURCE_NOT_SUPPORTED); blink::mojom::ScreenAvailability::SOURCE_NOT_SUPPORTED);
...@@ -195,7 +178,8 @@ bool PresentationFrame::SetScreenAvailabilityListener( ...@@ -195,7 +178,8 @@ bool PresentationFrame::SetScreenAvailabilityListener(
void PresentationFrame::RemoveScreenAvailabilityListener( void PresentationFrame::RemoveScreenAvailabilityListener(
content::PresentationScreenAvailabilityListener* listener) { content::PresentationScreenAvailabilityListener* listener) {
MediaSource source(GetMediaSourceFromListener(listener)); MediaSource source =
MediaSourceForPresentationUrl(listener->GetAvailabilityUrl());
auto sinks_observer_it = url_to_sinks_observer_.find(source.id()); auto sinks_observer_it = url_to_sinks_observer_.find(source.id());
if (sinks_observer_it != url_to_sinks_observer_.end() && if (sinks_observer_it != url_to_sinks_observer_.end() &&
sinks_observer_it->second->listener() == listener) { sinks_observer_it->second->listener() == listener) {
...@@ -227,47 +211,11 @@ void PresentationFrame::Reset() { ...@@ -227,47 +211,11 @@ void PresentationFrame::Reset() {
browser_connection_proxies_.clear(); browser_connection_proxies_.clear();
} }
void PresentationFrame::RemoveConnection(const std::string& presentation_id, void PresentationFrame::AddPresentation(
const MediaRoute::Id& route_id) { const content::PresentationInfo& presentation_info,
// Remove the presentation id mapping so a later call to Reset is a no-op. const MediaRoute& route) {
presentation_id_to_route_.erase(presentation_id); presentation_id_to_route_.insert(
std::make_pair(presentation_info.presentation_id, route));
browser_connection_proxies_.erase(route_id);
// We keep the PresentationConnectionStateChangedCallback registered with MR
// so the MRP can tell us when terminate() completed.
}
void PresentationFrame::ListenForConnectionStateChange(
const content::PresentationInfo& connection,
const content::PresentationConnectionStateChangedCallback&
state_changed_cb) {
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.media_route_id();
if (connection_state_subscriptions_.find(route_id) !=
connection_state_subscriptions_.end()) {
DLOG(ERROR) << __func__
<< "Already listening connection state change for route: "
<< route_id;
return;
}
connection_state_subscriptions_.insert(std::make_pair(
route_id, router_->AddPresentationConnectionStateChangedCallback(
route_id, state_changed_cb)));
}
MediaSource PresentationFrame::GetMediaSourceFromListener(
content::PresentationScreenAvailabilityListener* listener) const {
// If the default presentation URL is empty then fall back to tab mirroring.
return listener->GetAvailabilityUrl().is_empty()
? MediaSourceForTab(SessionTabHelper::IdForTab(web_contents_))
: MediaSourceForPresentationUrl(listener->GetAvailabilityUrl());
} }
void PresentationFrame::ConnectToPresentation( void PresentationFrame::ConnectToPresentation(
...@@ -311,296 +259,42 @@ void PresentationFrame::ConnectToPresentation( ...@@ -311,296 +259,42 @@ void PresentationFrame::ConnectToPresentation(
} }
} }
// Used by PresentationServiceDelegateImpl to manage PresentationFrames. void PresentationFrame::RemovePresentation(const std::string& presentation_id) {
class PresentationFrameManager { // Remove the presentation id mapping so a later call to Reset is a no-op.
public: auto it = presentation_id_to_route_.find(presentation_id);
PresentationFrameManager(content::WebContents* web_contents, if (it == presentation_id_to_route_.end())
MediaRouter* router); return;
~PresentationFrameManager();
// Mirror corresponding APIs in PresentationServiceDelegateImpl.
bool SetScreenAvailabilityListener(
const RenderFrameHostId& render_frame_host_id,
content::PresentationScreenAvailabilityListener* listener);
void RemoveScreenAvailabilityListener(
const RenderFrameHostId& render_frame_host_id,
content::PresentationScreenAvailabilityListener* listener);
void ListenForConnectionStateChange(
const RenderFrameHostId& render_frame_host_id,
const content::PresentationInfo& connection,
const content::PresentationConnectionStateChangedCallback&
state_changed_cb);
// Sets or clears the default presentation request and callback for the given
// frame. Also sets / clears the default presentation requests for the owning
// tab WebContents.
void SetDefaultPresentationUrls(
const RenderFrameHostId& render_frame_host_id,
const std::vector<GURL>& default_presentation_urls,
content::DefaultPresentationConnectionCallback callback);
void AddDelegateObserver(const RenderFrameHostId& render_frame_host_id,
DelegateObserver* observer);
void RemoveDelegateObserver(const RenderFrameHostId& render_frame_host_id);
void AddDefaultPresentationRequestObserver(
PresentationServiceDelegateImpl::DefaultPresentationRequestObserver*
observer);
void RemoveDefaultPresentationRequestObserver(
PresentationServiceDelegateImpl::DefaultPresentationRequestObserver*
observer);
void Reset(const RenderFrameHostId& render_frame_host_id);
void RemoveConnection(const RenderFrameHostId& render_frame_host_id,
const MediaRoute::Id& route_id,
const std::string& presentation_id);
bool HasScreenAvailabilityListenerForTest(
const RenderFrameHostId& render_frame_host_id,
const MediaSource::Id& source_id) const;
void SetMediaRouterForTest(MediaRouter* router);
void OnPresentationConnection(
const RenderFrameHostId& render_frame_host_id,
const content::PresentationInfo& presentation_info,
const MediaRoute& route);
void OnDefaultPresentationStarted(
const PresentationRequest& request,
const content::PresentationInfo& presentation_info,
const MediaRoute& route);
void ConnectToPresentation(
const RenderFrameHostId& render_frame_host_id,
const content::PresentationInfo& presentation_info,
content::PresentationConnectionPtr controller_connection_ptr,
content::PresentationConnectionRequest receiver_connection_request);
const MediaRoute::Id GetRouteId(const RenderFrameHostId& render_frame_host_id,
const std::string& presentation_id) const;
const PresentationRequest* default_presentation_request() const {
return default_presentation_request_.get();
}
private:
PresentationFrame* GetOrAddPresentationFrame(
const RenderFrameHostId& render_frame_host_id);
// Sets the default presentation request for the owning WebContents and
// notifies observers of changes.
void SetDefaultPresentationRequest(
const PresentationRequest& default_presentation_request);
// Clears the default presentation request for the owning WebContents and
// notifies observers of changes. Also resets
// |default_presentation_started_callback_|.
void ClearDefaultPresentationRequest();
bool IsMainFrame(const RenderFrameHostId& render_frame_host_id) const;
// Maps a frame identifier to a PresentationFrame object for frames
// that are using presentation API.
std::unordered_map<RenderFrameHostId, std::unique_ptr<PresentationFrame>,
RenderFrameHostIdHasher>
presentation_frames_;
// Default presentation request for the owning tab WebContents.
std::unique_ptr<PresentationRequest> default_presentation_request_;
// Callback to invoke when default presentation has started.
content::DefaultPresentationConnectionCallback
default_presentation_started_callback_;
// References to the observers listening for changes to this tab WebContent's
// default presentation.
base::ObserverList<
PresentationServiceDelegateImpl::DefaultPresentationRequestObserver>
default_presentation_request_observers_;
// References to the owning WebContents, and the corresponding MediaRouter.
MediaRouter* router_;
content::WebContents* web_contents_;
};
PresentationFrameManager::PresentationFrameManager(
content::WebContents* web_contents,
MediaRouter* router)
: router_(router), web_contents_(web_contents) {
DCHECK(web_contents_);
DCHECK(router_);
}
PresentationFrameManager::~PresentationFrameManager() {}
void PresentationFrameManager::OnPresentationConnection(
const RenderFrameHostId& render_frame_host_id,
const content::PresentationInfo& presentation_info,
const MediaRoute& route) {
auto* presentation_frame = GetOrAddPresentationFrame(render_frame_host_id);
presentation_frame->OnPresentationConnection(presentation_info, route);
}
void PresentationFrameManager::OnDefaultPresentationStarted(
const PresentationRequest& request,
const content::PresentationInfo& presentation_info,
const MediaRoute& route) {
OnPresentationConnection(request.render_frame_host_id(), presentation_info,
route);
if (default_presentation_request_ &&
default_presentation_request_->Equals(request)) {
default_presentation_started_callback_.Run(presentation_info);
}
}
void PresentationFrameManager::ConnectToPresentation(
const RenderFrameHostId& render_frame_host_id,
const content::PresentationInfo& presentation_info,
content::PresentationConnectionPtr controller_connection_ptr,
content::PresentationConnectionRequest receiver_connection_request) {
auto* presentation_frame = GetOrAddPresentationFrame(render_frame_host_id);
presentation_frame->ConnectToPresentation(
presentation_info, std::move(controller_connection_ptr),
std::move(receiver_connection_request));
}
const MediaRoute::Id PresentationFrameManager::GetRouteId(
const RenderFrameHostId& render_frame_host_id,
const std::string& presentation_id) const {
const auto it = presentation_frames_.find(render_frame_host_id);
return it != presentation_frames_.end()
? it->second->GetRouteId(presentation_id)
: MediaRoute::Id();
}
bool PresentationFrameManager::SetScreenAvailabilityListener(
const RenderFrameHostId& render_frame_host_id,
content::PresentationScreenAvailabilityListener* listener) {
DCHECK(listener);
auto* presentation_frame = GetOrAddPresentationFrame(render_frame_host_id);
return presentation_frame->SetScreenAvailabilityListener(listener);
}
void PresentationFrameManager::RemoveScreenAvailabilityListener(
const RenderFrameHostId& render_frame_host_id,
content::PresentationScreenAvailabilityListener* listener) {
DCHECK(listener);
const auto it = presentation_frames_.find(render_frame_host_id);
if (it != presentation_frames_.end())
it->second->RemoveScreenAvailabilityListener(listener);
}
bool PresentationFrameManager::HasScreenAvailabilityListenerForTest( auto route_id = it->second.media_route_id();
const RenderFrameHostId& render_frame_host_id, presentation_id_to_route_.erase(presentation_id);
const MediaSource::Id& source_id) const { browser_connection_proxies_.erase(route_id);
const auto it = presentation_frames_.find(render_frame_host_id); // We keep the PresentationConnectionStateChangedCallback registered with MR
return it != presentation_frames_.end() && // so the MRP can tell us when terminate() completed.
it->second->HasScreenAvailabilityListenerForTest(source_id);
} }
void PresentationFrameManager::ListenForConnectionStateChange( void PresentationFrame::ListenForConnectionStateChange(
const RenderFrameHostId& render_frame_host_id,
const content::PresentationInfo& connection, const content::PresentationInfo& connection,
const content::PresentationConnectionStateChangedCallback& const content::PresentationConnectionStateChangedCallback&
state_changed_cb) { state_changed_cb) {
const auto it = presentation_frames_.find(render_frame_host_id); auto it = presentation_id_to_route_.find(connection.presentation_id);
if (it != presentation_frames_.end()) if (it == presentation_id_to_route_.end()) {
it->second->ListenForConnectionStateChange(connection, state_changed_cb); DLOG(ERROR) << __func__ << "route id not found for presentation: "
} << connection.presentation_id;
void PresentationFrameManager::SetDefaultPresentationUrls(
const RenderFrameHostId& render_frame_host_id,
const std::vector<GURL>& default_presentation_urls,
content::DefaultPresentationConnectionCallback callback) {
if (!IsMainFrame(render_frame_host_id))
return; return;
if (default_presentation_urls.empty()) {
ClearDefaultPresentationRequest();
} else {
DCHECK(!callback.is_null());
const auto& frame_origin =
GetLastCommittedURLForFrame(render_frame_host_id);
PresentationRequest request(render_frame_host_id, default_presentation_urls,
frame_origin);
default_presentation_started_callback_ = callback;
SetDefaultPresentationRequest(request);
}
}
void PresentationFrameManager::AddDefaultPresentationRequestObserver(
PresentationServiceDelegateImpl::DefaultPresentationRequestObserver*
observer) {
default_presentation_request_observers_.AddObserver(observer);
}
void PresentationFrameManager::RemoveDefaultPresentationRequestObserver(
PresentationServiceDelegateImpl::DefaultPresentationRequestObserver*
observer) {
default_presentation_request_observers_.RemoveObserver(observer);
}
void PresentationFrameManager::Reset(
const RenderFrameHostId& render_frame_host_id) {
const auto it = presentation_frames_.find(render_frame_host_id);
if (it != presentation_frames_.end()) {
it->second->Reset();
presentation_frames_.erase(it);
}
if (default_presentation_request_ &&
render_frame_host_id ==
default_presentation_request_->render_frame_host_id()) {
ClearDefaultPresentationRequest();
} }
}
void PresentationFrameManager::RemoveConnection( const MediaRoute::Id& route_id = it->second.media_route_id();
const RenderFrameHostId& render_frame_host_id, if (connection_state_subscriptions_.find(route_id) !=
const MediaRoute::Id& route_id, connection_state_subscriptions_.end()) {
const std::string& presentation_id) { DLOG(ERROR) << __func__
const auto it = presentation_frames_.find(render_frame_host_id); << "Already listening connection state change for route: "
if (it != presentation_frames_.end()) << route_id;
it->second->RemoveConnection(route_id, presentation_id);
}
PresentationFrame* PresentationFrameManager::GetOrAddPresentationFrame(
const RenderFrameHostId& render_frame_host_id) {
std::unique_ptr<PresentationFrame>& presentation_frame =
presentation_frames_[render_frame_host_id];
if (!presentation_frame) {
presentation_frame.reset(new PresentationFrame(
render_frame_host_id, web_contents_, router_));
}
return presentation_frame.get();
}
void PresentationFrameManager::ClearDefaultPresentationRequest() {
default_presentation_started_callback_.Reset();
if (!default_presentation_request_)
return;
default_presentation_request_.reset();
for (auto& observer : default_presentation_request_observers_)
observer.OnDefaultPresentationRemoved();
}
bool PresentationFrameManager::IsMainFrame(
const RenderFrameHostId& render_frame_host_id) const {
RenderFrameHost* main_frame = web_contents_->GetMainFrame();
return main_frame && GetRenderFrameHostId(main_frame) == render_frame_host_id;
}
void PresentationFrameManager::SetDefaultPresentationRequest(
const PresentationRequest& default_presentation_request) {
if (default_presentation_request_ &&
default_presentation_request_->Equals(default_presentation_request))
return; return;
}
default_presentation_request_.reset( connection_state_subscriptions_.insert(std::make_pair(
new PresentationRequest(default_presentation_request)); route_id, router_->AddPresentationConnectionStateChangedCallback(
for (auto& observer : default_presentation_request_observers_) route_id, state_changed_cb)));
observer.OnDefaultPresentationChanged(*default_presentation_request_);
}
void PresentationFrameManager::SetMediaRouterForTest(MediaRouter* router) {
router_ = router;
} }
PresentationServiceDelegateImpl* PresentationServiceDelegateImpl*
...@@ -617,14 +311,12 @@ PresentationServiceDelegateImpl::PresentationServiceDelegateImpl( ...@@ -617,14 +311,12 @@ PresentationServiceDelegateImpl::PresentationServiceDelegateImpl(
: web_contents_(web_contents), : web_contents_(web_contents),
router_(MediaRouterFactory::GetApiForBrowserContext( router_(MediaRouterFactory::GetApiForBrowserContext(
web_contents_->GetBrowserContext())), web_contents_->GetBrowserContext())),
frame_manager_(new PresentationFrameManager(web_contents, router_)),
weak_factory_(this) { weak_factory_(this) {
DCHECK(web_contents_); DCHECK(web_contents_);
DCHECK(router_); DCHECK(router_);
} }
PresentationServiceDelegateImpl::~PresentationServiceDelegateImpl() { PresentationServiceDelegateImpl::~PresentationServiceDelegateImpl() = default;
}
void PresentationServiceDelegateImpl::AddObserver(int render_process_id, void PresentationServiceDelegateImpl::AddObserver(int render_process_id,
int render_frame_id, int render_frame_id,
...@@ -643,8 +335,9 @@ bool PresentationServiceDelegateImpl::AddScreenAvailabilityListener( ...@@ -643,8 +335,9 @@ bool PresentationServiceDelegateImpl::AddScreenAvailabilityListener(
int render_frame_id, int render_frame_id,
content::PresentationScreenAvailabilityListener* listener) { content::PresentationScreenAvailabilityListener* listener) {
DCHECK(listener); DCHECK(listener);
return frame_manager_->SetScreenAvailabilityListener( RenderFrameHostId render_frame_host_id(render_process_id, render_frame_id);
RenderFrameHostId(render_process_id, render_frame_id), listener); auto* presentation_frame = GetOrAddPresentationFrame(render_frame_host_id);
return presentation_frame->SetScreenAvailabilityListener(listener);
} }
void PresentationServiceDelegateImpl::RemoveScreenAvailabilityListener( void PresentationServiceDelegateImpl::RemoveScreenAvailabilityListener(
...@@ -652,14 +345,36 @@ void PresentationServiceDelegateImpl::RemoveScreenAvailabilityListener( ...@@ -652,14 +345,36 @@ void PresentationServiceDelegateImpl::RemoveScreenAvailabilityListener(
int render_frame_id, int render_frame_id,
content::PresentationScreenAvailabilityListener* listener) { content::PresentationScreenAvailabilityListener* listener) {
DCHECK(listener); DCHECK(listener);
frame_manager_->RemoveScreenAvailabilityListener( RenderFrameHostId render_frame_host_id(render_process_id, render_frame_id);
RenderFrameHostId(render_process_id, render_frame_id), listener); const auto it = presentation_frames_.find(render_frame_host_id);
if (it != presentation_frames_.end())
it->second->RemoveScreenAvailabilityListener(listener);
} }
void PresentationServiceDelegateImpl::Reset(int render_process_id, void PresentationServiceDelegateImpl::Reset(int render_process_id,
int render_frame_id) { int render_frame_id) {
RenderFrameHostId render_frame_host_id(render_process_id, render_frame_id); RenderFrameHostId render_frame_host_id(render_process_id, render_frame_id);
frame_manager_->Reset(render_frame_host_id); const auto it = presentation_frames_.find(render_frame_host_id);
if (it != presentation_frames_.end()) {
it->second->Reset();
presentation_frames_.erase(it);
}
if (default_presentation_request_ &&
render_frame_host_id ==
default_presentation_request_->render_frame_host_id()) {
ClearDefaultPresentationRequest();
}
}
PresentationFrame* PresentationServiceDelegateImpl::GetOrAddPresentationFrame(
const RenderFrameHostId& render_frame_host_id) {
auto& presentation_frame = presentation_frames_[render_frame_host_id];
if (!presentation_frame) {
presentation_frame.reset(
new PresentationFrame(render_frame_host_id, web_contents_, router_));
}
return presentation_frame.get();
} }
void PresentationServiceDelegateImpl::SetDefaultPresentationUrls( void PresentationServiceDelegateImpl::SetDefaultPresentationUrls(
...@@ -668,8 +383,20 @@ void PresentationServiceDelegateImpl::SetDefaultPresentationUrls( ...@@ -668,8 +383,20 @@ void PresentationServiceDelegateImpl::SetDefaultPresentationUrls(
const std::vector<GURL>& default_presentation_urls, const std::vector<GURL>& default_presentation_urls,
content::DefaultPresentationConnectionCallback callback) { content::DefaultPresentationConnectionCallback callback) {
RenderFrameHostId render_frame_host_id(render_process_id, render_frame_id); RenderFrameHostId render_frame_host_id(render_process_id, render_frame_id);
frame_manager_->SetDefaultPresentationUrls( if (!IsMainFrame(render_frame_host_id))
render_frame_host_id, default_presentation_urls, std::move(callback)); return;
if (default_presentation_urls.empty()) {
ClearDefaultPresentationRequest();
return;
}
DCHECK(!callback.is_null());
auto frame_origin = GetLastCommittedURLForFrame(render_frame_host_id);
PresentationRequest request(render_frame_host_id, default_presentation_urls,
frame_origin);
default_presentation_started_callback_ = std::move(callback);
SetDefaultPresentationRequest(request);
} }
void PresentationServiceDelegateImpl::OnJoinRouteResponse( void PresentationServiceDelegateImpl::OnJoinRouteResponse(
...@@ -691,9 +418,8 @@ void PresentationServiceDelegateImpl::OnJoinRouteResponse( ...@@ -691,9 +418,8 @@ void PresentationServiceDelegateImpl::OnJoinRouteResponse(
DCHECK_EQ(presentation_id, result.presentation_id()); DCHECK_EQ(presentation_id, result.presentation_id());
content::PresentationInfo presentation_info(presentation_url, content::PresentationInfo presentation_info(presentation_url,
result.presentation_id()); result.presentation_id());
frame_manager_->OnPresentationConnection( AddPresentation(RenderFrameHostId(render_process_id, render_frame_id),
RenderFrameHostId(render_process_id, render_frame_id), presentation_info, *result.route());
presentation_info, *result.route());
std::move(success_cb).Run(presentation_info); std::move(success_cb).Run(presentation_info);
} }
} }
...@@ -708,12 +434,27 @@ void PresentationServiceDelegateImpl::OnStartPresentationSucceeded( ...@@ -708,12 +434,27 @@ void PresentationServiceDelegateImpl::OnStartPresentationSucceeded(
<< "route_id: " << route.media_route_id() << "route_id: " << route.media_route_id()
<< ", presentation URL: " << new_presentation_info.presentation_url << ", presentation URL: " << new_presentation_info.presentation_url
<< ", presentation ID: " << new_presentation_info.presentation_id; << ", presentation ID: " << new_presentation_info.presentation_id;
frame_manager_->OnPresentationConnection( AddPresentation(RenderFrameHostId(render_process_id, render_frame_id),
RenderFrameHostId(render_process_id, render_frame_id), new_presentation_info, route);
new_presentation_info, route);
std::move(success_cb).Run(new_presentation_info); std::move(success_cb).Run(new_presentation_info);
} }
void PresentationServiceDelegateImpl::AddPresentation(
const RenderFrameHostId& render_frame_host_id,
const content::PresentationInfo& presentation_info,
const MediaRoute& route) {
auto* presentation_frame = GetOrAddPresentationFrame(render_frame_host_id);
presentation_frame->AddPresentation(presentation_info, route);
}
void PresentationServiceDelegateImpl::RemovePresentation(
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())
it->second->RemovePresentation(presentation_id);
}
void PresentationServiceDelegateImpl::StartPresentation( void PresentationServiceDelegateImpl::StartPresentation(
int render_process_id, int render_process_id,
int render_frame_id, int render_frame_id,
...@@ -745,7 +486,7 @@ void PresentationServiceDelegateImpl::StartPresentation( ...@@ -745,7 +486,7 @@ void PresentationServiceDelegateImpl::StartPresentation(
GetLastCommittedURLForFrame(render_frame_host_id), GetLastCommittedURLForFrame(render_frame_host_id),
base::BindOnce( base::BindOnce(
&PresentationServiceDelegateImpl::OnStartPresentationSucceeded, &PresentationServiceDelegateImpl::OnStartPresentationSucceeded,
weak_factory_.GetWeakPtr(), render_process_id, render_frame_id, GetWeakPtr(), render_process_id, render_frame_id,
std::move(success_cb)), std::move(success_cb)),
std::move(error_cb))); std::move(error_cb)));
MediaRouterDialogController* controller = MediaRouterDialogController* controller =
...@@ -774,7 +515,7 @@ void PresentationServiceDelegateImpl::ReconnectPresentation( ...@@ -774,7 +515,7 @@ void PresentationServiceDelegateImpl::ReconnectPresentation(
return; return;
} }
const url::Origin& origin = GetLastCommittedURLForFrame( auto origin = GetLastCommittedURLForFrame(
RenderFrameHostId(render_process_id, render_frame_id)); RenderFrameHostId(render_process_id, render_frame_id));
#if !defined(OS_ANDROID) #if !defined(OS_ANDROID)
...@@ -816,11 +557,10 @@ void PresentationServiceDelegateImpl::ReconnectPresentation( ...@@ -816,11 +557,10 @@ void PresentationServiceDelegateImpl::ReconnectPresentation(
const GURL& presentation_url = presentation_urls[0]; const GURL& presentation_url = presentation_urls[0];
bool incognito = web_contents_->GetBrowserContext()->IsOffTheRecord(); bool incognito = web_contents_->GetBrowserContext()->IsOffTheRecord();
std::vector<MediaRouteResponseCallback> route_response_callbacks; std::vector<MediaRouteResponseCallback> route_response_callbacks;
route_response_callbacks.push_back( route_response_callbacks.push_back(base::BindOnce(
base::BindOnce(&PresentationServiceDelegateImpl::OnJoinRouteResponse, &PresentationServiceDelegateImpl::OnJoinRouteResponse, GetWeakPtr(),
weak_factory_.GetWeakPtr(), render_process_id, render_process_id, render_frame_id, presentation_url, presentation_id,
render_frame_id, presentation_url, presentation_id, std::move(success_cb), std::move(error_cb)));
std::move(success_cb), std::move(error_cb)));
router_->JoinRoute(MediaSourceForPresentationUrl(presentation_url).id(), router_->JoinRoute(MediaSourceForPresentationUrl(presentation_url).id(),
presentation_id, origin, web_contents_, presentation_id, origin, web_contents_,
std::move(route_response_callbacks), base::TimeDelta(), std::move(route_response_callbacks), base::TimeDelta(),
...@@ -833,8 +573,7 @@ void PresentationServiceDelegateImpl::CloseConnection( ...@@ -833,8 +573,7 @@ void PresentationServiceDelegateImpl::CloseConnection(
int render_frame_id, int render_frame_id,
const std::string& presentation_id) { const std::string& presentation_id) {
const RenderFrameHostId rfh_id(render_process_id, render_frame_id); const RenderFrameHostId rfh_id(render_process_id, render_frame_id);
const MediaRoute::Id& route_id = auto route_id = GetRouteId(rfh_id, presentation_id);
frame_manager_->GetRouteId(rfh_id, presentation_id);
if (route_id.empty()) { if (route_id.empty()) {
DVLOG(1) << "No active route for: " << presentation_id; DVLOG(1) << "No active route for: " << presentation_id;
return; return;
...@@ -851,7 +590,7 @@ void PresentationServiceDelegateImpl::CloseConnection( ...@@ -851,7 +590,7 @@ void PresentationServiceDelegateImpl::CloseConnection(
} else { } else {
router_->DetachRoute(route_id); router_->DetachRoute(route_id);
} }
frame_manager_->RemoveConnection(rfh_id, presentation_id, route_id); RemovePresentation(rfh_id, presentation_id);
// TODO(mfoltz): close() should always succeed so there is no need to keep the // TODO(mfoltz): close() should always succeed so there is no need to keep the
// state_changed_cb around - remove it and fire the ChangeEvent on the // state_changed_cb around - remove it and fire the ChangeEvent on the
// PresentationConnection in Blink. // PresentationConnection in Blink.
...@@ -862,14 +601,13 @@ void PresentationServiceDelegateImpl::Terminate( ...@@ -862,14 +601,13 @@ void PresentationServiceDelegateImpl::Terminate(
int render_frame_id, int render_frame_id,
const std::string& presentation_id) { const std::string& presentation_id) {
const RenderFrameHostId rfh_id(render_process_id, render_frame_id); const RenderFrameHostId rfh_id(render_process_id, render_frame_id);
const MediaRoute::Id& route_id = auto route_id = GetRouteId(rfh_id, presentation_id);
frame_manager_->GetRouteId(rfh_id, presentation_id);
if (route_id.empty()) { if (route_id.empty()) {
DVLOG(1) << "No active route for: " << presentation_id; DVLOG(1) << "No active route for: " << presentation_id;
return; return;
} }
router_->TerminateRoute(route_id); router_->TerminateRoute(route_id);
frame_manager_->RemoveConnection(rfh_id, presentation_id, route_id); RemovePresentation(rfh_id, presentation_id);
} }
void PresentationServiceDelegateImpl::SendMessage( void PresentationServiceDelegateImpl::SendMessage(
...@@ -878,9 +616,9 @@ void PresentationServiceDelegateImpl::SendMessage( ...@@ -878,9 +616,9 @@ void PresentationServiceDelegateImpl::SendMessage(
const content::PresentationInfo& presentation_info, const content::PresentationInfo& presentation_info,
content::PresentationConnectionMessage message, content::PresentationConnectionMessage message,
SendMessageCallback send_message_cb) { SendMessageCallback send_message_cb) {
const MediaRoute::Id& route_id = frame_manager_->GetRouteId( auto route_id =
RenderFrameHostId(render_process_id, render_frame_id), GetRouteId(RenderFrameHostId(render_process_id, render_frame_id),
presentation_info.presentation_id); presentation_info.presentation_id);
if (route_id.empty()) { if (route_id.empty()) {
DVLOG(1) << "No active route for " << presentation_info.presentation_id; DVLOG(1) << "No active route for " << presentation_info.presentation_id;
std::move(send_message_cb).Run(false); std::move(send_message_cb).Run(false);
...@@ -904,9 +642,10 @@ void PresentationServiceDelegateImpl::ListenForConnectionStateChange( ...@@ -904,9 +642,10 @@ void PresentationServiceDelegateImpl::ListenForConnectionStateChange(
const content::PresentationInfo& connection, const content::PresentationInfo& connection,
const content::PresentationConnectionStateChangedCallback& const content::PresentationConnectionStateChangedCallback&
state_changed_cb) { state_changed_cb) {
frame_manager_->ListenForConnectionStateChange( RenderFrameHostId render_frame_host_id(render_process_id, render_frame_id);
RenderFrameHostId(render_process_id, render_frame_id), connection, const auto it = presentation_frames_.find(render_frame_host_id);
state_changed_cb); if (it != presentation_frames_.end())
it->second->ListenForConnectionStateChange(connection, state_changed_cb);
} }
void PresentationServiceDelegateImpl::ConnectToPresentation( void PresentationServiceDelegateImpl::ConnectToPresentation(
...@@ -916,9 +655,10 @@ void PresentationServiceDelegateImpl::ConnectToPresentation( ...@@ -916,9 +655,10 @@ void PresentationServiceDelegateImpl::ConnectToPresentation(
content::PresentationConnectionPtr controller_connection_ptr, content::PresentationConnectionPtr controller_connection_ptr,
content::PresentationConnectionRequest receiver_connection_request) { content::PresentationConnectionRequest receiver_connection_request) {
RenderFrameHostId render_frame_host_id(render_process_id, render_frame_id); RenderFrameHostId render_frame_host_id(render_process_id, render_frame_id);
frame_manager_->ConnectToPresentation(render_frame_host_id, presentation_info, auto* presentation_frame = GetOrAddPresentationFrame(render_frame_host_id);
std::move(controller_connection_ptr), presentation_frame->ConnectToPresentation(
std::move(receiver_connection_request)); presentation_info, std::move(controller_connection_ptr),
std::move(receiver_connection_request));
} }
void PresentationServiceDelegateImpl::OnRouteResponse( void PresentationServiceDelegateImpl::OnRouteResponse(
...@@ -932,28 +672,32 @@ void PresentationServiceDelegateImpl::OnRouteResponse( ...@@ -932,28 +672,32 @@ void PresentationServiceDelegateImpl::OnRouteResponse(
content::PresentationInfo presentation_info(result.presentation_url(), content::PresentationInfo presentation_info(result.presentation_url(),
result.presentation_id()); result.presentation_id());
frame_manager_->OnDefaultPresentationStarted( AddPresentation(presentation_request.render_frame_host_id(),
presentation_request, presentation_info, *result.route()); presentation_info, *result.route());
if (default_presentation_request_ &&
default_presentation_request_->Equals(presentation_request)) {
default_presentation_started_callback_.Run(presentation_info);
}
} }
void PresentationServiceDelegateImpl::AddDefaultPresentationRequestObserver( void PresentationServiceDelegateImpl::AddDefaultPresentationRequestObserver(
DefaultPresentationRequestObserver* observer) { DefaultPresentationRequestObserver* observer) {
frame_manager_->AddDefaultPresentationRequestObserver(observer); default_presentation_request_observers_.AddObserver(observer);
} }
void PresentationServiceDelegateImpl::RemoveDefaultPresentationRequestObserver( void PresentationServiceDelegateImpl::RemoveDefaultPresentationRequestObserver(
DefaultPresentationRequestObserver* observer) { DefaultPresentationRequestObserver* observer) {
frame_manager_->RemoveDefaultPresentationRequestObserver(observer); default_presentation_request_observers_.RemoveObserver(observer);
} }
PresentationRequest PresentationRequest
PresentationServiceDelegateImpl::GetDefaultPresentationRequest() const { PresentationServiceDelegateImpl::GetDefaultPresentationRequest() const {
DCHECK(HasDefaultPresentationRequest()); DCHECK(HasDefaultPresentationRequest());
return *frame_manager_->default_presentation_request(); return *default_presentation_request_;
} }
bool PresentationServiceDelegateImpl::HasDefaultPresentationRequest() const { bool PresentationServiceDelegateImpl::HasDefaultPresentationRequest() const {
return frame_manager_->default_presentation_request() != nullptr; return default_presentation_request_ != nullptr;
} }
base::WeakPtr<PresentationServiceDelegateImpl> base::WeakPtr<PresentationServiceDelegateImpl>
...@@ -964,7 +708,6 @@ PresentationServiceDelegateImpl::GetWeakPtr() { ...@@ -964,7 +708,6 @@ PresentationServiceDelegateImpl::GetWeakPtr() {
void PresentationServiceDelegateImpl::SetMediaRouterForTest( void PresentationServiceDelegateImpl::SetMediaRouterForTest(
MediaRouter* router) { MediaRouter* router) {
router_ = router; router_ = router;
frame_manager_->SetMediaRouterForTest(router);
} }
bool PresentationServiceDelegateImpl::HasScreenAvailabilityListenerForTest( bool PresentationServiceDelegateImpl::HasScreenAvailabilityListenerForTest(
...@@ -972,8 +715,47 @@ bool PresentationServiceDelegateImpl::HasScreenAvailabilityListenerForTest( ...@@ -972,8 +715,47 @@ bool PresentationServiceDelegateImpl::HasScreenAvailabilityListenerForTest(
int render_frame_id, int render_frame_id,
const MediaSource::Id& source_id) const { const MediaSource::Id& source_id) const {
RenderFrameHostId render_frame_host_id(render_process_id, render_frame_id); RenderFrameHostId render_frame_host_id(render_process_id, render_frame_id);
return frame_manager_->HasScreenAvailabilityListenerForTest( const auto it = presentation_frames_.find(render_frame_host_id);
render_frame_host_id, source_id); return it != presentation_frames_.end() &&
it->second->HasScreenAvailabilityListenerForTest(source_id);
}
void PresentationServiceDelegateImpl::SetDefaultPresentationRequest(
const PresentationRequest& default_presentation_request) {
if (default_presentation_request_ &&
default_presentation_request_->Equals(default_presentation_request))
return;
default_presentation_request_.reset(
new PresentationRequest(default_presentation_request));
for (auto& observer : default_presentation_request_observers_)
observer.OnDefaultPresentationChanged(*default_presentation_request_);
}
void PresentationServiceDelegateImpl::ClearDefaultPresentationRequest() {
default_presentation_started_callback_.Reset();
if (!default_presentation_request_)
return;
default_presentation_request_.reset();
for (auto& observer : default_presentation_request_observers_)
observer.OnDefaultPresentationRemoved();
}
// TODO(imcheng): Move this check to PresentationServiceImpl.
bool PresentationServiceDelegateImpl::IsMainFrame(
const RenderFrameHostId& render_frame_host_id) const {
RenderFrameHost* main_frame = web_contents_->GetMainFrame();
return main_frame && GetRenderFrameHostId(main_frame) == render_frame_host_id;
}
MediaRoute::Id PresentationServiceDelegateImpl::GetRouteId(
const RenderFrameHostId& render_frame_host_id,
const std::string& presentation_id) const {
const auto it = presentation_frames_.find(render_frame_host_id);
return it != presentation_frames_.end()
? it->second->GetRouteId(presentation_id)
: MediaRoute::Id();
} }
#if !defined(OS_ANDROID) #if !defined(OS_ANDROID)
......
...@@ -38,7 +38,7 @@ class Origin; ...@@ -38,7 +38,7 @@ class Origin;
namespace media_router { namespace media_router {
class MediaRoute; class MediaRoute;
class PresentationFrameManager; class PresentationFrame;
class RouteRequestResult; class RouteRequestResult;
// Implementation of PresentationServiceDelegate that interfaces an instance of // Implementation of PresentationServiceDelegate that interfaces an instance of
...@@ -147,7 +147,7 @@ class PresentationServiceDelegateImpl ...@@ -147,7 +147,7 @@ class PresentationServiceDelegateImpl
void RemoveDefaultPresentationRequestObserver( void RemoveDefaultPresentationRequestObserver(
DefaultPresentationRequestObserver* observer); DefaultPresentationRequestObserver* observer);
// Gets the default presentation request for the owning tab WebContents. It // Gets the default presentation request for the owning WebContents. It
// is an error to call this method if the default presentation request does // is an error to call this method if the default presentation request does
// not exist. // not exist.
PresentationRequest GetDefaultPresentationRequest() const; PresentationRequest GetDefaultPresentationRequest() const;
...@@ -186,10 +186,8 @@ class PresentationServiceDelegateImpl ...@@ -186,10 +186,8 @@ class PresentationServiceDelegateImpl
explicit PresentationServiceDelegateImpl(content::WebContents* web_contents); explicit PresentationServiceDelegateImpl(content::WebContents* web_contents);
// Returns |listener|'s presentation URL as a MediaSource. If |listener| does PresentationFrame* GetOrAddPresentationFrame(
// not have a persentation URL, returns the tab mirroring MediaSource. const RenderFrameHostId& render_frame_host_id);
MediaSource GetMediaSourceFromListener(
content::PresentationScreenAvailabilityListener* listener);
void OnJoinRouteResponse( void OnJoinRouteResponse(
int render_process_id, int render_process_id,
...@@ -207,6 +205,39 @@ class PresentationServiceDelegateImpl ...@@ -207,6 +205,39 @@ class PresentationServiceDelegateImpl
const content::PresentationInfo& new_presentation_info, const content::PresentationInfo& new_presentation_info,
const MediaRoute& route); const MediaRoute& route);
// Notifies the PresentationFrame of |render_frame_host_id| that a
// presentation and its corresponding MediaRoute has been created.
// The PresentationFrame will be created if it does not already exist.
// This must be called before |ConnectToPresentation()|.
void AddPresentation(const RenderFrameHostId& render_frame_host_id,
const content::PresentationInfo& presentation_info,
const MediaRoute& route);
// Notifies the PresentationFrame of |render_frame_host_id| that a
// presentation and its corresponding MediaRoute has been removed.
void RemovePresentation(const RenderFrameHostId& render_frame_host_id,
const std::string& presentation_id);
// Sets the default presentation request for the owning WebContents and
// notifies observers of changes.
void SetDefaultPresentationRequest(
const PresentationRequest& default_presentation_request);
// Clears the default presentation request for the owning WebContents and
// notifies observers of changes. Also resets
// |default_presentation_started_callback_|.
void ClearDefaultPresentationRequest();
// Returns |true| if the given frame is the main frame of the associated
// WebContents.
// NOTE: This method will be removed in an upcoming patch.
bool IsMainFrame(const RenderFrameHostId& render_frame_host_id) const;
// Returns the ID of the route corresponding to |presentation_id| in the given
// frame, or empty if no such route exist.
MediaRoute::Id GetRouteId(const RenderFrameHostId& render_frame_host_id,
const std::string& presentation_id) const;
#if !defined(OS_ANDROID) #if !defined(OS_ANDROID)
// Returns true if auto-join requests should be cancelled for |origin|. // Returns true if auto-join requests should be cancelled for |origin|.
bool ShouldCancelAutoJoinForOrigin(const url::Origin& origin) const; bool ShouldCancelAutoJoinForOrigin(const url::Origin& origin) const;
...@@ -217,7 +248,25 @@ class PresentationServiceDelegateImpl ...@@ -217,7 +248,25 @@ class PresentationServiceDelegateImpl
content::WebContents* const web_contents_; content::WebContents* const web_contents_;
MediaRouter* router_; MediaRouter* router_;
std::unique_ptr<PresentationFrameManager> frame_manager_; // References to the observers listening for changes to the default
// presentation of the associated WebContents.
base::ObserverList<DefaultPresentationRequestObserver>
default_presentation_request_observers_;
// Default presentation request for the owning WebContents.
std::unique_ptr<PresentationRequest> default_presentation_request_;
// Callback to invoke when the default presentation has started.
content::DefaultPresentationConnectionCallback
default_presentation_started_callback_;
// Maps a frame identifier to a PresentationFrame object for frames
// that are using Presentation API.
std::unordered_map<RenderFrameHostId,
std::unique_ptr<PresentationFrame>,
RenderFrameHostIdHasher>
presentation_frames_;
PresentationServiceDelegateObservers observers_; PresentationServiceDelegateObservers observers_;
base::WeakPtrFactory<PresentationServiceDelegateImpl> weak_factory_; base::WeakPtrFactory<PresentationServiceDelegateImpl> weak_factory_;
......
...@@ -125,7 +125,7 @@ void PresentationServiceImpl::SetClient( ...@@ -125,7 +125,7 @@ void PresentationServiceImpl::SetClient(
void PresentationServiceImpl::ListenForScreenAvailability(const GURL& url) { void PresentationServiceImpl::ListenForScreenAvailability(const GURL& url) {
DVLOG(2) << "ListenForScreenAvailability " << url.spec(); DVLOG(2) << "ListenForScreenAvailability " << url.spec();
if (!controller_delegate_) { if (!controller_delegate_ || !url.is_valid()) {
client_->OnScreenAvailabilityUpdated( client_->OnScreenAvailabilityUpdated(
url, blink::mojom::ScreenAvailability::UNAVAILABLE); url, blink::mojom::ScreenAvailability::UNAVAILABLE);
return; return;
...@@ -464,13 +464,13 @@ PresentationServiceImpl::ScreenAvailabilityListenerImpl:: ...@@ -464,13 +464,13 @@ PresentationServiceImpl::ScreenAvailabilityListenerImpl::
ScreenAvailabilityListenerImpl(const GURL& availability_url, ScreenAvailabilityListenerImpl(const GURL& availability_url,
PresentationServiceImpl* service) PresentationServiceImpl* service)
: availability_url_(availability_url), service_(service) { : availability_url_(availability_url), service_(service) {
DCHECK(availability_url_.is_valid());
DCHECK(service_); DCHECK(service_);
DCHECK(service_->client_.get()); DCHECK(service_->client_.get());
} }
PresentationServiceImpl::ScreenAvailabilityListenerImpl:: PresentationServiceImpl::ScreenAvailabilityListenerImpl::
~ScreenAvailabilityListenerImpl() { ~ScreenAvailabilityListenerImpl() = default;
}
GURL PresentationServiceImpl::ScreenAvailabilityListenerImpl:: GURL PresentationServiceImpl::ScreenAvailabilityListenerImpl::
GetAvailabilityUrl() const { GetAvailabilityUrl() const {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment