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

Unified Diff: chrome/browser/media/router/one_ua_presentation_router.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/one_ua_presentation_router.cc
diff --git a/chrome/browser/media/router/one_ua_presentation_router.cc b/chrome/browser/media/router/one_ua_presentation_router.cc
new file mode 100644
index 0000000000000000000000000000000000000000..168c92ac1d6b97ed9645139c661fa918c2871818
--- /dev/null
+++ b/chrome/browser/media/router/one_ua_presentation_router.cc
@@ -0,0 +1,346 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/media/router/one_ua_presentation_router.h"
+
+using content::PresentationSessionInfo;
+using content::PresenterSessionAvailableCallback;
+
+namespace media_router {
+
+OneUAPresentationRouter::~OneUAPresentationRouter() {}
+
+void OneUAPresentationRouter::RegisterPresenter(
+ const std::string& presentation_id,
+ const RenderFrameHostId& presenter_frame_id) {
+ DCHECK(!ContainsKey(presenter_frames_, presenter_frame_id));
+ presenter_frames_[presenter_frame_id] = presentation_id;
+
+ auto* presentation_info = GetOrCreateOneUAPresentationInfo(presentation_id);
+ presentation_info->presenter_frame_id = presenter_frame_id;
+ // We wait until the controller side has registered before setting up the
+ // route.
+}
+
+void OneUAPresentationRouter::UnregisterPresenter(
+ const RenderFrameHostId& presenter_frame_id) {
+ DCHECK(ContainsKey(presenter_frames_, presenter_frame_id));
+ auto it = presenter_frames_.find(presenter_frame_id);
+ std::string presentation_id = it->second;
+ presenter_frames_.erase(it);
+
+ auto* presentation_info = GetOneUAPresentationInfo(presentation_id);
+ DCHECK(presentation_info);
+ DCHECK(presenter_frame_id == presentation_info->presenter_frame_id);
+ RemovePresenterAndNotifyStateChange(presentation_info);
+ if (presentation_info->IsEmpty())
+ one_ua_presentations_.erase(presentation_id);
+}
+
+void OneUAPresentationRouter::RegisterController(
+ const content::PresentationSessionInfo& session,
+ const RenderFrameHostId& controller_frame_id) {
+ const std::string& presentation_id = session.presentation_id;
+ auto* presentation_info = GetOrCreateOneUAPresentationInfo(presentation_id);
+
+ auto& route = presentation_info->route;
+
+ // Check that this (presentation, controller) is not already registered.
+ DCHECK(!route.controller);
+ DCHECK(!route.presenter);
+
+ route.controller.reset(
+ new OneUAPresentationSession(controller_frame_id, session));
+ content::PresentationSessionInfo presenter_session(std::string(),
+ presentation_id);
+ route.presenter.reset(
+ new OneUAPresentationSession(controller_frame_id, presenter_session));
+
+ // Resolve pending getSession() request.
+ // Note: session objects for presenters do not contain presentation URLs.
+ if (!presentation_info->session_callback.is_null()) {
+ presentation_info->session_callback.Run(presenter_session);
+ presentation_info->session_callback.Reset();
+ }
+}
+
+void OneUAPresentationRouter::UnregisterController(
+ const std::string& presentation_id,
+ const RenderFrameHostId& controller_frame_id) {
+ auto* presentation_info = GetOneUAPresentationInfo(presentation_id);
+ DCHECK(presentation_info);
+ DCHECK(controller_frame_id ==
+ presentation_info->route.controller->controller_frame_id);
+ RemoveControllerAndNotifyStateChange(presentation_info);
+
+ if (presentation_info->IsEmpty())
+ one_ua_presentations_.erase(presentation_id);
+}
+
+bool OneUAPresentationRouter::IsPresenter(
+ const RenderFrameHostId& frame_id) const {
+ return ContainsKey(presenter_frames_, frame_id);
+}
+
+bool OneUAPresentationRouter::IsController(
+ const std::string& presentation_id,
+ const RenderFrameHostId& frame_id) const {
+ auto* presentation_info = GetOneUAPresentationInfo(presentation_id);
+ if (!presentation_info)
+ return false;
+
+ const auto& route = presentation_info->route;
+ if (!route.controller)
+ return false;
+ return frame_id == route.controller->controller_frame_id;
+}
+
+void OneUAPresentationRouter::GetSinglePresenterSession(
+ const RenderFrameHostId& presenter_frame_id,
+ const PresenterSessionAvailableCallback& callback) {
+ DCHECK(!callback.is_null());
+ DCHECK(IsPresenter(presenter_frame_id));
+
+ const std::string& presentation_id = presenter_frames_[presenter_frame_id];
+ auto* presentation_info = GetOneUAPresentationInfo(presentation_id);
+ DCHECK(presentation_info);
+ DCHECK(presenter_frame_id == presentation_info->presenter_frame_id);
+
+ // Resolve with the first route.
+ const auto& route = presentation_info->route;
+ if (route.presenter) {
+ callback.Run(route.presenter->session);
+ return;
+ } else {
+ presentation_info->session_callback = callback;
+ }
+}
+
+std::vector<content::PresentationSessionInfo>
+OneUAPresentationRouter::GetPresenterSessions(
+ const RenderFrameHostId& presenter_frame_id) const {
+ DCHECK(IsPresenter(presenter_frame_id));
+
+ auto it = presenter_frames_.find(presenter_frame_id);
+ DCHECK(it != presenter_frames_.end());
+ const std::string& presentation_id = it->second;
+ auto* presentation_info = GetOneUAPresentationInfo(presentation_id);
+ DCHECK(presentation_info);
+
+ std::vector<content::PresentationSessionInfo> sessions;
+ // TODO(imcheng): Support multiple controllers.
+ if (presentation_info->route.presenter)
+ sessions.push_back(presentation_info->route.presenter->session);
+ return sessions;
+}
+
+void OneUAPresentationRouter::SendMessage(
+ const PresentationSessionInfo& session,
+ scoped_ptr<content::PresentationSessionMessage> message,
+ const content::SendMessageCallback& callback) {
+ const std::string& presentation_id = session.presentation_id;
+ auto* presentation_info = GetOneUAPresentationInfo(presentation_id);
+ if (!presentation_info) {
+ LOG(ERROR) << "SendMessage: Unknown 1UA presentation " << presentation_id;
+ callback.Run(false);
+ return;
+ }
+
+ bool from_presenter = session.presentation_url.empty();
+ auto& route = presentation_info->route;
+ // From presenter to controller.
+ if (from_presenter) {
+ auto* controller = route.controller.get();
+ if (controller && !controller->message_callback.is_null()) {
+ ScopedVector<content::PresentationSessionMessage> messages;
+ messages.push_back(message.release());
+ controller->message_callback.Run(messages.Pass(), true);
+ }
+ } else {
+ auto* presenter = route.presenter.get();
+ // From controller to presenter.
+ if (presenter && !presenter->message_callback.is_null()) {
+ ScopedVector<content::PresentationSessionMessage> messages;
+ messages.push_back(message.release());
+ presenter->message_callback.Run(messages.Pass(), true);
+ }
+ }
+
+ callback.Run(true);
+}
+
+void OneUAPresentationRouter::ListenForMessages(
+ const PresentationSessionInfo& session,
+ const content::PresentationSessionMessageCallback& callback) {
+ const std::string& presentation_id = session.presentation_id;
+ auto* presentation_info = GetOneUAPresentationInfo(presentation_id);
+ if (!presentation_info) {
+ LOG(ERROR) << "ListenForMessages: Unknown 1UA presentation "
+ << presentation_id;
+ return;
+ }
+
+ bool from_presenter = session.presentation_url.empty();
+ auto& route = presentation_info->route;
+ if (from_presenter) {
+ auto* presenter = route.presenter.get();
+ if (!presenter) {
+ LOG(ERROR) << "ListenForMessages: presenter frame not found for "
+ << presentation_id;
+ return;
+ }
+ DVLOG_IF(2, !presenter->message_callback.is_null())
+ << "Overwriting presenter frame message callback for "
+ << presentation_id;
+ presenter->message_callback = callback;
+ } else {
+ auto* controller = route.controller.get();
+ if (!controller) {
+ LOG(ERROR) << "ListenForMessages: controller frame not found for "
+ << presentation_id;
+ return;
+ }
+ DVLOG_IF(2, !controller->message_callback.is_null())
+ << "Overwriting controller frame message callback for "
+ << presentation_id;
+ controller->message_callback = callback;
+ }
+}
+
+void OneUAPresentationRouter::ListenForStateChanges(
+ const PresentationSessionInfo& session,
+ const content::SessionStateChangedCallback& callback) {
+ const std::string& presentation_id = session.presentation_id;
+ auto* presentation_info = GetOneUAPresentationInfo(presentation_id);
+ if (!presentation_info) {
+ LOG(ERROR) << "ListenForMessages: Unknown 1UA presentation "
+ << presentation_id;
+ return;
+ }
+
+ bool from_presenter = session.presentation_url.empty();
+ auto& route = presentation_info->route;
+ if (from_presenter) {
+ auto* presenter = route.presenter.get();
+ if (!presenter) {
+ LOG(ERROR) << "ListenForMessages: presenter frame not found for "
+ << presentation_id;
+ return;
+ }
+ DVLOG_IF(2, !presenter->state_change_callback.is_null())
+ << "Overwriting presenter frame state change callback for "
+ << presentation_id;
+ presenter->state_change_callback = callback;
+ } else {
+ auto* controller = route.controller.get();
+ if (!controller) {
+ LOG(ERROR) << "ListenForMessages: controller frame not found for "
+ << presentation_id;
+ return;
+ }
+ DVLOG_IF(2, !controller->state_change_callback.is_null())
+ << "Overwriting controller frame state change callback for "
+ << presentation_id;
+ controller->state_change_callback = callback;
+ }
+}
+
+void OneUAPresentationRouter::Reset(const RenderFrameHostId& frame_id) {
+ if (IsPresenter(frame_id))
+ UnregisterPresenter(frame_id);
+
+ for (auto it = one_ua_presentations_.begin();
+ it != one_ua_presentations_.end();
+ /* no-op */) {
+ auto* presentation_info = it->second;
+ auto* controller = presentation_info->route.controller.get();
+ if (controller && controller->controller_frame_id == frame_id) {
+ RemovePresenterAndNotifyStateChange(presentation_info);
+ if (presentation_info->IsEmpty())
+ one_ua_presentations_.erase(it++);
+ else
+ ++it;
+ } else {
+ ++it;
+ }
+ }
+}
+
+OneUAPresentationRouter::OneUAPresentationRouter() {}
+
+void OneUAPresentationRouter::RemovePresenterAndNotifyStateChange(
+ OneUAPresentationInfo* presentation_info) {
+ presentation_info->presenter_frame_id = RenderFrameHostId();
+ presentation_info->session_callback.Reset();
+
+ auto& route = presentation_info->route;
+ if (route.presenter) {
+ route.presenter.reset();
+ auto& controller = route.controller;
+ if (controller && !controller->state_change_callback.is_null()) {
+ controller->state_change_callback.Run(
+ controller->session,
+ content::PRESENTATION_SESSION_STATE_DISCONNECTED);
+ }
+ }
+}
+
+void OneUAPresentationRouter::RemoveControllerAndNotifyStateChange(
+ OneUAPresentationInfo* presentation_info) {
+ auto& route = presentation_info->route;
+ route.controller.reset();
+
+ auto& presenter = route.presenter;
+ if (presenter && !presenter->state_change_callback.is_null()) {
+ presenter->state_change_callback.Run(
+ presenter->session, content::PRESENTATION_SESSION_STATE_DISCONNECTED);
+ }
+}
+
+OneUAPresentationRouter::OneUAPresentationInfo*
+OneUAPresentationRouter::GetOrCreateOneUAPresentationInfo(
+ const std::string& presentation_id) {
+ OneUAPresentationInfo* info = nullptr;
+ auto presentation_info_it = one_ua_presentations_.find(presentation_id);
+ if (presentation_info_it == one_ua_presentations_.end()) {
+ info = new OneUAPresentationInfo;
+ one_ua_presentations_.insert(presentation_id, make_scoped_ptr(info));
+ } else {
+ info = presentation_info_it->second;
+ }
+ DCHECK(info);
+ return info;
+}
+
+OneUAPresentationRouter::OneUAPresentationInfo*
+OneUAPresentationRouter::GetOneUAPresentationInfo(
+ const std::string& presentation_id) const {
+ OneUAPresentationInfo* info = nullptr;
+ auto presentation_info_it = one_ua_presentations_.find(presentation_id);
+ return presentation_info_it == one_ua_presentations_.end()
+ ? nullptr
+ : presentation_info_it->second;
+}
+
+OneUAPresentationRouter::OneUAPresentationSession::OneUAPresentationSession(
+ const RenderFrameHostId& controller_frame_id,
+ const content::PresentationSessionInfo& session)
+ : controller_frame_id(controller_frame_id), session(session) {}
+
+OneUAPresentationRouter::OneUAPresentationSession::~OneUAPresentationSession() {
+}
+
+OneUAPresentationRouter::OneUAPresentationRoute::OneUAPresentationRoute() {}
+
+OneUAPresentationRouter::OneUAPresentationRoute::~OneUAPresentationRoute() {}
+
+OneUAPresentationRouter::OneUAPresentationInfo::OneUAPresentationInfo() {}
+
+OneUAPresentationRouter::OneUAPresentationInfo::~OneUAPresentationInfo() {}
+
+bool OneUAPresentationRouter::OneUAPresentationInfo::IsEmpty() const {
+ return !route.presenter && !route.controller;
+}
+
+} // namespace media_router

Powered by Google App Engine
This is Rietveld 408576698