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

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

Issue 1314413005: [Presentation API] 1-UA presentation support + presenter APIs. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 4 years, 6 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/offscreen_presentation_manager.cc
diff --git a/chrome/browser/media/router/offscreen_presentation_manager.cc b/chrome/browser/media/router/offscreen_presentation_manager.cc
new file mode 100644
index 0000000000000000000000000000000000000000..7522618779f055a65cbd98e379868d1d5dfe4d55
--- /dev/null
+++ b/chrome/browser/media/router/offscreen_presentation_manager.cc
@@ -0,0 +1,238 @@
+// 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/offscreen_presentation_manager.h"
+
+#include "base/memory/ptr_util.h"
+#include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/web_contents.h"
+
+namespace media_router {
+
+// OffscreenPresentationConnection implementation.
+// ////////////////////////////////
+
+OffscreenPresentationManager::OffscreenPresentationConnection::
+ OffscreenPresentationConnection(
+ OffscreenPresentationManager::OffscreenPresentationSession* session)
+ : session_(session) {
+ DCHECK(session_);
+}
+
+OffscreenPresentationManager::OffscreenPresentationConnection::
+ ~OffscreenPresentationConnection() {
+ if (session_) {
+ content::PresentationConnectionStateChangeInfo remove_reason(
+ content::PRESENTATION_CONNECTION_STATE_CLOSED);
+ remove_reason.close_reason =
+ content::PRESENTATION_CONNECTION_CLOSE_REASON_WENT_AWAY;
+ session_->RemoveConnection(this, remove_reason);
+ }
+}
+
+void OffscreenPresentationManager::OffscreenPresentationConnection::SendMessage(
+ std::unique_ptr<content::PresentationSessionMessage> message,
+ const content::SendMessageCallback& callback) {
+ if (!session_) {
+ callback.Run(false);
+ return;
+ }
+
+ session_->SendMessageFrom(this, std::move(message), callback);
+}
+
+void OffscreenPresentationManager::OffscreenPresentationConnection::
+ ListenForMessages(
+ const content::PresentationSessionMessageCallback& callback) {
+ DCHECK(messages_callback_.is_null());
+ DCHECK(!callback.is_null());
+ messages_callback_ = callback;
+}
+
+void OffscreenPresentationManager::OffscreenPresentationConnection::
+ ListenForStateChange(
+ const content::PresentationConnectionStateChangedCallback& callback) {
+ DCHECK(state_change_callback_.is_null());
+ DCHECK(!state_change_callback_.is_null());
+ state_change_callback_ = callback;
+}
+
+void OffscreenPresentationManager::OffscreenPresentationConnection::
+ RemoveFromPresentation(
+ const content::PresentationConnectionStateChangeInfo& remove_reason) {
+ if (session_) {
+ session_->RemoveConnection(this, remove_reason);
+ session_ = nullptr;
+ }
+}
+
+void OffscreenPresentationManager::OffscreenPresentationConnection::
+ OnConnectionStateChanged(
+ const content::PresentationConnectionStateChangeInfo& info) {
+ if (!state_change_callback_.is_null())
+ state_change_callback_.Run(info);
+
+ if (info.state == content::PRESENTATION_CONNECTION_STATE_CLOSED ||
+ info.state == content::PRESENTATION_CONNECTION_STATE_TERMINATED) {
+ session_ = nullptr;
+ }
+}
+
+void OffscreenPresentationManager::OffscreenPresentationConnection::
+ OnMessageReceived(
+ std::unique_ptr<content::PresentationSessionMessage> message) {
+ if (messages_callback_.is_null())
+ return;
+
+ // TODO(imcheng): Implement message queueing/batching.
+ ScopedVector<content::PresentationSessionMessage> messages;
+ messages.push_back(std::move(message));
+ messages_callback_.Run(messages, true);
+}
+
+// OffscreenPresentationManager implementation. ////////////////////////////////
+
+OffscreenPresentationManager::~OffscreenPresentationManager() {}
+
+void OffscreenPresentationManager::RegisterOffscreenPresentationReceiver(
+ const std::string& presentation_id,
+ const ReceiverConnectionAvailableCallback& receiver_available_callback) {
+ DCHECK(!ContainsKey(offscreen_presentations_, presentation_id));
+
+ offscreen_presentations_.insert(
+ std::make_pair(presentation_id,
+ base::WrapUnique(new OffscreenPresentation(
+ presentation_id, receiver_available_callback, this))));
+}
+
+void OffscreenPresentationManager::UnregisterOffscreenPresentationReceiver(
+ const std::string& presentation_id) {
+ DCHECK(ContainsKey(offscreen_presentations_, presentation_id));
+ offscreen_presentations_.erase(presentation_id);
+}
+
+std::unique_ptr<OffscreenPresentationManager::OffscreenPresentationConnection>
+OffscreenPresentationManager::ConnectToOffscreenPresentation(
+ const std::string& presentation_id,
+ const RenderFrameHostId& controller_frame_id) {
+ auto it = offscreen_presentations_.find(presentation_id);
+ if (it == offscreen_presentations_.end())
+ return std::unique_ptr<OffscreenPresentationConnection>();
+
+ return it->second->AddSession(controller_frame_id);
+}
+
+OffscreenPresentationManager::OffscreenPresentationManager() {}
+
+// OffscreenPresentationSession implementation. /////////////////////////////
+
+OffscreenPresentationManager::OffscreenPresentationSession::
+ OffscreenPresentationSession(const RenderFrameHostId& controller_frame_id,
+ OffscreenPresentation* presentation)
+ : controller_frame_id_(controller_frame_id),
+ presentation_(presentation),
+ controller_(nullptr),
+ receiver_(nullptr) {
+ DCHECK(presentation_);
+}
+
+void OffscreenPresentationManager::OffscreenPresentationSession::Init(
+ OffscreenPresentationManager::OffscreenPresentationConnection* controller,
+ OffscreenPresentationManager::OffscreenPresentationConnection* receiver) {
+ DCHECK(!controller_);
+ DCHECK(!receiver_);
+ DCHECK(controller);
+ DCHECK(receiver);
+ controller_ = controller;
+ receiver_ = receiver;
+}
+
+OffscreenPresentationManager::OffscreenPresentationSession::
+ ~OffscreenPresentationSession() {
+ DCHECK(!controller_ || !receiver_);
+}
+
+void OffscreenPresentationManager::OffscreenPresentationSession::
+ RemoveConnection(
+ OffscreenPresentationConnection* connection,
+ const content::PresentationConnectionStateChangeInfo& remove_reason) {
+ DCHECK(connection);
+ OffscreenPresentationConnection* other_connection = nullptr;
+ if (connection == controller_) {
+ controller_ = nullptr;
+ other_connection = receiver_;
+ } else {
+ DCHECK(connection == receiver_);
+ receiver_ = nullptr;
+ other_connection = controller_;
+ }
+
+ DCHECK(other_connection);
+ other_connection->OnConnectionStateChanged(remove_reason);
+ presentation_->RemoveSession(controller_frame_id_);
+ // |this| is deleted beyond this point.
+}
+
+void OffscreenPresentationManager::OffscreenPresentationSession::
+ SendMessageFrom(
+ OffscreenPresentationConnection* connection,
+ std::unique_ptr<content::PresentationSessionMessage> message,
+ const content::SendMessageCallback& callback) {
+ OffscreenPresentationConnection* other_connection =
+ connection == controller_ ? receiver_ : controller_;
+ DCHECK(other_connection);
+
+ other_connection->OnMessageReceived(std::move(message));
+ callback.Run(true);
+}
+
+// OffscreenPresentation implementation. ///////////////////////////////////////
+
+OffscreenPresentationManager::OffscreenPresentation::OffscreenPresentation(
+ const std::string& presentation_id,
+ const ReceiverConnectionAvailableCallback& receiver_available_callback,
+ OffscreenPresentationManager* manager)
+ : presentation_id_(presentation_id),
+ receiver_available_callback_(receiver_available_callback),
+ manager_(manager) {
+ DCHECK(!receiver_available_callback_.is_null());
+ DCHECK(manager_);
+}
+
+OffscreenPresentationManager::OffscreenPresentation::~OffscreenPresentation() {
+ // The receiver must have destroyed all connections before unregistration.
+ DCHECK(sessions_.empty());
+}
+
+std::unique_ptr<OffscreenPresentationManager::OffscreenPresentationConnection>
+OffscreenPresentationManager::OffscreenPresentation::AddSession(
+ const RenderFrameHostId& controller_frame_id) {
+ if (ContainsKey(sessions_, controller_frame_id)) {
+ DLOG(ERROR) << "Frame " << controller_frame_id.first << ", "
+ << controller_frame_id.second << " already registered as a "
+ << "controller for presentation " << presentation_id_;
+ return std::unique_ptr<OffscreenPresentationConnection>();
+ }
+
+ std::unique_ptr<OffscreenPresentationSession> session(
+ new OffscreenPresentationSession(controller_frame_id, this));
+ std::unique_ptr<OffscreenPresentationConnection> controller_connection(
+ new OffscreenPresentationConnection(session.get()));
+ std::unique_ptr<OffscreenPresentationConnection> receiver_connection(
+ new OffscreenPresentationConnection(session.get()));
+
+ session->Init(controller_connection.get(), receiver_connection.get());
+ sessions_.insert(std::make_pair(controller_frame_id, std::move(session)));
+ receiver_available_callback_.Run(std::move(receiver_connection));
+ return controller_connection;
+}
+
+void OffscreenPresentationManager::OffscreenPresentation::RemoveSession(
+ const RenderFrameHostId& controller_frame_id) {
+ DCHECK(ContainsKey(sessions_, controller_frame_id));
+ sessions_.erase(controller_frame_id);
+}
+
+} // namespace media_router

Powered by Google App Engine
This is Rietveld 408576698