Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1483)

Unified Diff: chrome/browser/media/router/presentation_service_delegate_impl.cc

Issue 1314413005: [Presentation API] 1-UA presentation support + presenter APIs. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 5c1d26befe11dd62c98624d5abb6c882ba3b5e0a..7ea531f19b321055a2f4554770c8ed1891f8b820 100644
--- a/chrome/browser/media/router/presentation_service_delegate_impl.cc
+++ b/chrome/browser/media/router/presentation_service_delegate_impl.cc
@@ -9,7 +9,6 @@
#include "base/containers/scoped_ptr_hash_map.h"
#include "base/containers/scoped_ptr_map.h"
#include "base/containers/small_map.h"
-#include "base/guid.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "chrome/browser/media/router/create_presentation_session_request.h"
@@ -19,6 +18,8 @@
#include "chrome/browser/media/router/media_router_factory.h"
#include "chrome/browser/media/router/media_sink.h"
#include "chrome/browser/media/router/media_source_helper.h"
+#include "chrome/browser/media/router/offscreen_presentation_manager.h"
+#include "chrome/browser/media/router/offscreen_presentation_manager_factory.h"
#include "chrome/browser/media/router/presentation_media_sinks_observer.h"
#include "chrome/browser/media/router/presentation_session_messages_observer.h"
#include "chrome/browser/media/router/presentation_session_state_observer.h"
@@ -44,8 +45,6 @@ using PresentationSessionErrorCallback =
using PresentationSessionSuccessCallback =
content::PresentationServiceDelegate::PresentationSessionSuccessCallback;
-using RenderFrameHostId = std::pair<int, int>;
-
// Returns the unique identifier for the supplied RenderFrameHost.
RenderFrameHostId GetRenderFrameHostId(RenderFrameHost* render_frame_host) {
int render_process_id = render_frame_host->GetProcess()->GetID();
@@ -72,7 +71,11 @@ GURL GetLastCommittedURLForFrame(RenderFrameHostId render_frame_host_id) {
// * PresentationFrameManager.RemoveDelegateObserver.
class PresentationFrame {
public:
- PresentationFrame(content::WebContents* web_contents, MediaRouter* router);
+ PresentationFrame(
+ const RenderFrameHostId& render_frame_host_id,
miu 2015/09/27 00:22:08 I assume this argument refers to a specific Render
imcheng 2015/09/30 01:13:42 Done.
+ content::WebContents* web_contents,
+ MediaRouter* router,
+ OffscreenPresentationManager* offscreen_presentation_manager);
~PresentationFrame();
// Mirror corresponding APIs in PresentationServiceDelegateImpl.
@@ -83,6 +86,9 @@ class PresentationFrame {
bool HasScreenAvailabilityListenerForTest(
const MediaSource::Id& source_id) const;
std::string GetDefaultPresentationId() const;
+ void SendMessage(const content::PresentationSessionInfo& session,
+ scoped_ptr<content::PresentationSessionMessage> message,
+ const content::SendMessageCallback send_message_cb);
bool ListenForSessionStateChange(
content::PresentationSessionStateListener* listener);
void ListenForSessionMessages(
@@ -91,13 +97,12 @@ class PresentationFrame {
void Reset();
const MediaRoute::Id GetRouteId(const std::string& presentation_id) const;
- const std::vector<MediaRoute::Id> GetRouteIds() const;
void OnPresentationSessionClosed(const std::string& presentation_id);
void OnPresentationSessionStarted(
bool is_default_presentation,
const content::PresentationSessionInfo& session,
- const MediaRoute::Id& route_id);
+ const MediaRoute& route);
void OnPresentationServiceDelegateDestroyed() const;
void set_delegate_observer(DelegateObserver* observer) {
@@ -111,31 +116,51 @@ class PresentationFrame {
private:
MediaSource GetMediaSourceFromListener(
content::PresentationScreenAvailabilityListener* listener) const;
+ OffscreenController* FindOffscreenController(
+ const std::string& presentation_id) const;
+
base::SmallMap<std::map<std::string, MediaRoute::Id>>
presentation_id_to_route_id_;
std::string default_presentation_url_;
scoped_ptr<PresentationMediaSinksObserver> sinks_observer_;
+ // Controller objects for offscreen presentations. Note that offscreen
+ // presentations are manipulated with these objects instead of the observers
+ // and MediaRouter objects below.
+ // Maps from presentation ID to the corresponding OffscreenController within
+ // this frame.
+ base::ScopedPtrMap<std::string, scoped_ptr<OffscreenController>>
+ offscreen_controllers_;
+
+ // For non-offscreen presentations.
// Maps from presentation ID to the corresponding presentation session's
// state change observer within this frame.
base::ScopedPtrMap<std::string, scoped_ptr<PresentationSessionStateObserver>>
session_state_observers_;
ScopedVector<PresentationSessionMessagesObserver> session_messages_observers_;
+ const RenderFrameHostId render_frame_host_id_;
+
// References to the owning WebContents, and the corresponding MediaRouter.
- const content::WebContents* web_contents_;
- MediaRouter* router_;
+ const content::WebContents* const web_contents_;
+ MediaRouter* const router_;
+ OffscreenPresentationManager* const offscreen_presentation_manager_;
DelegateObserver* delegate_observer_;
};
-PresentationFrame::PresentationFrame(content::WebContents* web_contents,
- MediaRouter* router)
+PresentationFrame::PresentationFrame(
+ const RenderFrameHostId& render_frame_host_id,
+ content::WebContents* web_contents,
+ MediaRouter* router,
+ OffscreenPresentationManager* offscreen_presentation_manager)
: web_contents_(web_contents),
router_(router),
+ offscreen_presentation_manager_(offscreen_presentation_manager),
delegate_observer_(nullptr) {
DCHECK(web_contents_);
DCHECK(router_);
+ DCHECK(offscreen_presentation_manager_);
}
PresentationFrame::~PresentationFrame() {
@@ -149,10 +174,20 @@ void PresentationFrame::OnPresentationServiceDelegateDestroyed() const {
void PresentationFrame::OnPresentationSessionStarted(
bool is_default_presentation,
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_id_[session.presentation_id] =
+ route.media_route_id();
if (is_default_presentation && delegate_observer_)
delegate_observer_->OnDefaultPresentationStarted(session);
+ if (route.is_offscreen_presentation()) {
+ DCHECK(!ContainsKey(offscreen_controllers_, session.presentation_id));
+ scoped_ptr<OffscreenController> offscreen_controller =
+ offscreen_presentation_manager_->RegisterController(
+ session, render_frame_host_id_);
+ DCHECK(offscreen_controller);
+ offscreen_controllers_.insert(session.presentation_id,
+ offscreen_controller.Pass());
+ }
}
void PresentationFrame::OnPresentationSessionClosed(
@@ -170,13 +205,6 @@ const MediaRoute::Id PresentationFrame::GetRouteId(
return it != presentation_id_to_route_id_.end() ? it->second : "";
}
-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);
- return route_ids;
-}
-
bool PresentationFrame::SetScreenAvailabilityListener(
content::PresentationScreenAvailabilityListener* listener) {
if (sinks_observer_ && sinks_observer_->listener() == listener) {
@@ -208,12 +236,47 @@ void PresentationFrame::Reset() {
presentation_id_to_route_id_.clear();
sinks_observer_.reset();
+ offscreen_controllers_.clear();
+ session_state_observers_.clear();
default_presentation_url_.clear();
session_state_observers_.clear();
session_messages_observers_.clear();
}
-void PresentationFrame::ListenForSessionStateChange(
+void PresentationFrame::SendMessage(
+ const content::PresentationSessionInfo& session,
+ scoped_ptr<content::PresentationSessionMessage> message,
+ const content::SendMessageCallback send_message_cb) {
+ auto it = presentation_id_to_route_id_.find(session.presentation_id);
+ if (it == presentation_id_to_route_id_.end()) {
+ DVLOG(2) << "ListenForSessionMessages: no route for "
+ << session.presentation_id;
+ return;
+ }
+
+ OffscreenController* offscreen_controller =
+ FindOffscreenController(session.presentation_id);
+ if (offscreen_controller) {
+ offscreen_controller->SendMessage(message.Pass(), send_message_cb);
+ } else {
+ if (message->is_binary()) {
+ router_->SendRouteBinaryMessage(it->second, message->data.Pass(),
+ send_message_cb);
+ } else {
+ router_->SendRouteMessage(it->second, message->message, send_message_cb);
+ }
+ }
+}
+
+OffscreenController* PresentationFrame::FindOffscreenController(
+ const std::string& presentation_id) const {
+ auto offscreen_controller_it = offscreen_controllers_.find(presentation_id);
+ return offscreen_controller_it != offscreen_controllers_.end()
+ ? offscreen_controller_it->second
+ : nullptr;
+}
+
+bool PresentationFrame::ListenForSessionStateChange(
content::PresentationSessionStateListener* listener) {
std::string presentation_id(listener->GetSessionInfo().presentation_id);
auto it = presentation_id_to_route_id_.find(presentation_id);
@@ -222,16 +285,23 @@ void PresentationFrame::ListenForSessionStateChange(
return false;
}
- if (ContainsKey(session_state_observers_, presentation_id)) {
- DVLOG(2) << "ListenForSessionStateChange: already contains a state "
- << "observer for session " << presentation_id;
- return false;
+ OffscreenController* offscreen_controller =
+ FindOffscreenController(presentation_id);
+ if (offscreen_controller) {
+ offscreen_controller->ListenForStateChanges(listener);
+ return true;
+ } else {
+ if (ContainsKey(session_state_observers_, presentation_id)) {
+ DVLOG(2) << "ListenForSessionStateChange: already contains a state "
+ << "observer for session " << presentation_id;
+ return false;
+ }
+
+ session_state_observers_.insert(
+ presentation_id, make_scoped_ptr(new PresentationSessionStateObserver(
+ listener, it->second, router_)));
+ return true;
}
-
- session_state_observers_.insert(
- presentation_id, make_scoped_ptr(new PresentationSessionStateObserver(
- listener, it->second, router_)));
- return true;
}
void PresentationFrame::ListenForSessionMessages(
@@ -244,8 +314,15 @@ void PresentationFrame::ListenForSessionMessages(
return;
}
- session_messages_observers_.push_back(
- new PresentationSessionMessagesObserver(message_cb, it->second, router_));
+ OffscreenController* offscreen_controller =
+ FindOffscreenController(session.presentation_id);
+ if (offscreen_controller) {
+ offscreen_controller->ListenForMessages(message_cb);
+ } else {
+ session_messages_observers_.push_back(
+ new PresentationSessionMessagesObserver(message_cb, it->second,
+ router_));
+ }
}
MediaSource PresentationFrame::GetMediaSourceFromListener(
@@ -260,8 +337,10 @@ MediaSource PresentationFrame::GetMediaSourceFromListener(
// Used by PresentationServiceDelegateImpl to manage PresentationFrames.
class PresentationFrameManager {
public:
- PresentationFrameManager(content::WebContents* web_contents,
- MediaRouter* router);
+ PresentationFrameManager(
+ content::WebContents* web_contents,
+ MediaRouter* router,
+ OffscreenPresentationManager* offscreen_presentation_manager);
~PresentationFrameManager();
// Mirror corresponding APIs in PresentationServiceDelegateImpl.
@@ -272,7 +351,11 @@ class PresentationFrameManager {
const RenderFrameHostId& render_frame_host_id,
content::PresentationScreenAvailabilityListener* listener);
void SetDefaultPresentationUrl(const RenderFrameHostId& render_frame_host_id,
- const std::string& default_presentation_url);
+ const std::string& default_presentation_url);
+ void SendMessage(const RenderFrameHostId& render_frame_host_id,
+ const content::PresentationSessionInfo& session,
+ scoped_ptr<content::PresentationSessionMessage> message,
+ const content::SendMessageCallback send_message_cb);
bool ListenForSessionStateChange(
const RenderFrameHostId& render_frame_host_id,
content::PresentationSessionStateListener* listener);
@@ -293,15 +376,13 @@ class PresentationFrameManager {
const RenderFrameHostId& render_frame_host_id,
bool is_default_presentation,
const content::PresentationSessionInfo& session,
- const MediaRoute::Id& route_id);
+ const MediaRoute& route);
void OnPresentationSessionClosed(
const RenderFrameHostId& render_frame_host_id,
const std::string& presentation_id);
const MediaRoute::Id GetRouteId(const RenderFrameHostId& render_frame_host_id,
const std::string& presentation_id) const;
- const std::vector<MediaRoute::Id> GetRouteIds(
- const RenderFrameHostId& render_frame_host_id) const;
private:
PresentationFrame* GetOrAddPresentationFrame(
@@ -312,17 +393,23 @@ class PresentationFrameManager {
base::ScopedPtrHashMap<RenderFrameHostId, scoped_ptr<PresentationFrame>>
presentation_frames_;
- // References to the owning WebContents, and the corresponding MediaRouter.
+ // References to the owning WebContents, and the corresponding MediaRouter
+ // and OffscreenPresentationManager.
+ content::WebContents* const web_contents_;
MediaRouter* router_;
- content::WebContents* web_contents_;
+ OffscreenPresentationManager* const offscreen_presentation_manager_;
};
PresentationFrameManager::PresentationFrameManager(
content::WebContents* web_contents,
- MediaRouter* router)
- : router_(router), web_contents_(web_contents) {
+ MediaRouter* router,
+ OffscreenPresentationManager* offscreen_presentation_manager)
+ : web_contents_(web_contents),
+ router_(router),
+ offscreen_presentation_manager_(offscreen_presentation_manager) {
DCHECK(web_contents_);
DCHECK(router_);
+ DCHECK(offscreen_presentation_manager_);
}
PresentationFrameManager::~PresentationFrameManager() {
@@ -334,11 +421,12 @@ void PresentationFrameManager::OnPresentationSessionStarted(
const RenderFrameHostId& render_frame_host_id,
bool is_default_presentation,
const content::PresentationSessionInfo& session,
- const MediaRoute::Id& route_id) {
+ const MediaRoute& route) {
auto presentation_frame = presentation_frames_.get(render_frame_host_id);
- if (presentation_frame)
+ if (presentation_frame) {
presentation_frame->OnPresentationSessionStarted(is_default_presentation,
- session, route_id);
+ session, route);
+ }
}
void PresentationFrameManager::OnPresentationSessionClosed(
@@ -357,13 +445,6 @@ const MediaRoute::Id PresentationFrameManager::GetRouteId(
: "";
}
-const std::vector<MediaRoute::Id> PresentationFrameManager::GetRouteIds(
- const RenderFrameHostId& render_frame_host_id) const {
- auto presentation_frame = presentation_frames_.get(render_frame_host_id);
- return presentation_frame ? presentation_frame->GetRouteIds()
- : std::vector<MediaRoute::Id>();
-}
-
bool PresentationFrameManager::SetScreenAvailabilityListener(
const RenderFrameHostId& render_frame_host_id,
content::PresentationScreenAvailabilityListener* listener) {
@@ -396,7 +477,25 @@ void PresentationFrameManager::SetDefaultPresentationUrl(
presentation_frame->set_default_presentation_url(default_presentation_url);
}
-void PresentationFrameManager::ListenForSessionStateChange(
+void PresentationFrameManager::SendMessage(
+ const RenderFrameHostId& render_frame_host_id,
+ const content::PresentationSessionInfo& session,
+ scoped_ptr<content::PresentationSessionMessage> message,
+ const content::SendMessageCallback send_message_cb) {
+ PresentationFrame* presentation_frame =
+ presentation_frames_.get(render_frame_host_id);
+ if (!presentation_frame) {
+ DVLOG(2) << "SendMessage: PresentationFrame does not exist "
+ << "for: (" << render_frame_host_id.first << ", "
+ << render_frame_host_id.second << ")";
+ send_message_cb.Run(false);
+ return;
+ }
+
+ presentation_frame->SendMessage(session, message.Pass(), send_message_cb);
+}
+
+bool PresentationFrameManager::ListenForSessionStateChange(
const RenderFrameHostId& render_frame_host_id,
content::PresentationSessionStateListener* listener) {
PresentationFrame* presentation_frame =
@@ -448,7 +547,8 @@ PresentationFrame* PresentationFrameManager::GetOrAddPresentationFrame(
presentation_frames_.add(
render_frame_host_id,
scoped_ptr<PresentationFrame>(
- new PresentationFrame(web_contents_, router_)));
+ new PresentationFrame(render_frame_host_id, web_contents_, router_,
+ offscreen_presentation_manager_)));
}
return presentation_frames_.get(render_frame_host_id);
}
@@ -471,10 +571,17 @@ PresentationServiceDelegateImpl::PresentationServiceDelegateImpl(
: web_contents_(web_contents),
router_(MediaRouterFactory::GetApiForBrowserContext(
web_contents_->GetBrowserContext())),
- frame_manager_(new PresentationFrameManager(web_contents, router_)),
+ offscreen_presentation_manager_(
+ OffscreenPresentationManagerFactory::GetOrCreateForBrowserContext(
+ web_contents_->GetBrowserContext())),
+ frame_manager_(
+ new PresentationFrameManager(web_contents,
+ router_,
+ offscreen_presentation_manager_)),
weak_factory_(this) {
DCHECK(web_contents_);
DCHECK(router_);
+ DCHECK(offscreen_presentation_manager_);
}
PresentationServiceDelegateImpl::~PresentationServiceDelegateImpl() {
@@ -578,11 +685,12 @@ void PresentationServiceDelegateImpl::OnJoinRouteResponse(
DVLOG(1) << "OnJoinRouteResponse: "
<< "route_id: " << route->media_route_id()
<< ", presentation URL: " << session.presentation_url
- << ", presentation ID: " << session.presentation_id;
+ << ", presentation ID: " << session.presentation_id
+ << ", offscreen? " << route->is_offscreen_presentation();
DCHECK_EQ(session.presentation_id, presentation_id);
- frame_manager_->OnPresentationSessionStarted(
- RenderFrameHostId(render_process_id, render_frame_id), false, session,
- route->media_route_id());
+ RenderFrameHostId rfh_id(render_process_id, render_frame_id);
+ frame_manager_->OnPresentationSessionStarted(rfh_id, false, session,
+ *route);
success_cb.Run(session);
}
}
@@ -592,14 +700,15 @@ void PresentationServiceDelegateImpl::OnStartSessionSucceeded(
int render_frame_id,
const PresentationSessionSuccessCallback& success_cb,
const content::PresentationSessionInfo& new_session,
- const MediaRoute::Id& route_id) {
+ const MediaRoute& route) {
+ const MediaRoute::Id& route_id = route.media_route_id();
DVLOG(1) << "OnStartSessionSucceeded: "
<< "route_id: " << route_id
<< ", presentation URL: " << new_session.presentation_url
<< ", presentation ID: " << new_session.presentation_id;
- frame_manager_->OnPresentationSessionStarted(
- RenderFrameHostId(render_process_id, render_frame_id), false, new_session,
- route_id);
+ RenderFrameHostId rfh_id(render_process_id, render_frame_id);
+ frame_manager_->OnPresentationSessionStarted(rfh_id, false, new_session,
+ route);
success_cb.Run(new_session);
}
@@ -672,9 +781,12 @@ void PresentationServiceDelegateImpl::ListenForSessionMessages(
int render_frame_id,
const content::PresentationSessionInfo& session,
const content::PresentationSessionMessageCallback& message_cb) {
- frame_manager_->ListenForSessionMessages(
- RenderFrameHostId(render_process_id, render_frame_id), session,
- message_cb);
+ DCHECK(!session.presentation_id.empty());
+ DCHECK(!session.presentation_url.empty());
+
+ RenderFrameHostId render_frame_host_id(render_process_id, render_frame_id);
+ frame_manager_->ListenForSessionMessages(render_frame_host_id, session,
+ message_cb);
}
void PresentationServiceDelegateImpl::SendMessage(
@@ -682,22 +794,13 @@ void PresentationServiceDelegateImpl::SendMessage(
int render_frame_id,
const content::PresentationSessionInfo& session,
scoped_ptr<content::PresentationSessionMessage> message,
- const SendMessageCallback& send_message_cb) {
- const MediaRoute::Id& route_id = frame_manager_->GetRouteId(
- RenderFrameHostId(render_process_id, render_frame_id),
- session.presentation_id);
- if (route_id.empty()) {
- DVLOG(1) << "No active route for " << session.presentation_id;
- send_message_cb.Run(false);
- return;
- }
+ const content::SendMessageCallback& send_message_cb) {
+ DCHECK(!session.presentation_id.empty());
+ DCHECK(!session.presentation_url.empty());
- if (message->is_binary()) {
- router_->SendRouteBinaryMessage(route_id, message->data.Pass(),
- send_message_cb);
- } else {
- router_->SendRouteMessage(route_id, message->message, send_message_cb);
- }
+ RenderFrameHostId render_frame_host_id(render_process_id, render_frame_id);
+ frame_manager_->SendMessage(render_frame_host_id, session, message.Pass(),
+ send_message_cb);
}
bool PresentationServiceDelegateImpl::ListenForSessionStateChange(
@@ -708,25 +811,49 @@ bool PresentationServiceDelegateImpl::ListenForSessionStateChange(
RenderFrameHostId(render_process_id, render_frame_id), listener);
}
+void PresentationServiceDelegateImpl::GetPresentationReceiverSession(
+ int render_process_id,
+ int render_frame_id,
+ const content::PresentationReceiverSessionAvailableCallback&
+ success_callback,
+ const base::Callback<void(const std::string&)>& error_callback) {
+ // We only have receivers in offscreen tabs, which are created in incognito
+ // Profiles. See ReceiverPresentationServiceDelegateImpl.
+ NOTIMPLEMENTED();
+ error_callback.Run("Not a presenter frame");
+}
+
+std::vector<content::PresentationSessionInfo>
+PresentationServiceDelegateImpl::GetPresentationReceiverSessions(
+ int render_process_id,
+ int render_frame_id) {
+ // See comment on GetPresentationReceiverSession().
+ NOTIMPLEMENTED();
+ return std::vector<content::PresentationSessionInfo>();
+}
+
void PresentationServiceDelegateImpl::OnRouteResponse(
const MediaRoute* route,
const std::string& presentation_id,
const std::string& error) {
if (!route)
return;
+
const MediaSource& source = route->media_source();
DCHECK(!source.Empty());
if (!default_source_.Equals(source))
return;
+
RenderFrameHost* main_frame = web_contents_->GetMainFrame();
if (!main_frame)
return;
+
RenderFrameHostId render_frame_host_id(GetRenderFrameHostId(main_frame));
- frame_manager_->OnPresentationSessionStarted(
- render_frame_host_id, true,
- content::PresentationSessionInfo(PresentationUrlFromMediaSource(source),
- presentation_id),
- route->media_route_id());
+ content::PresentationSessionInfo session(
+ PresentationUrlFromMediaSource(source), presentation_id);
+
+ frame_manager_->OnPresentationSessionStarted(render_frame_host_id, true,
+ session, *route);
}
void PresentationServiceDelegateImpl::AddDefaultMediaSourceObserver(

Powered by Google App Engine
This is Rietveld 408576698