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

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: Addressed Yuri's comments; rework of the OffscreenPresentationManager interface 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/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..f4ce74e1ac413a26709c347db90c997224d6ad09
--- /dev/null
+++ b/chrome/browser/media/router/offscreen_presentation_manager.cc
@@ -0,0 +1,228 @@
+// 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 "content/public/browser/presentation_session_state_listener.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 {
+
+OffscreenPresentationManager::OffscreenPresentationSession::
+ OffscreenPresentationSession(
+ bool is_controller,
+ OffscreenPresentationManager::OffscreenPresentationConnection*
+ connection)
+ : is_controller_(is_controller),
+ state_change_listener_(nullptr),
+ connection_(connection) {
+ DCHECK(connection_);
+}
+
+OffscreenPresentationManager::OffscreenPresentationSession::
+ ~OffscreenPresentationSession() {
+ connection_->RemoveSession(is_controller_);
+}
+
+void OffscreenPresentationManager::OffscreenPresentationSession::SendMessage(
+ scoped_ptr<content::PresentationSessionMessage> message,
+ const content::SendMessageCallback& callback) {
+ connection_->SendMessage(is_controller_, message.Pass(), callback);
+}
+
+void OffscreenPresentationManager::OffscreenPresentationSession::
+ ListenForMessages(
+ const content::PresentationSessionMessageCallback& callback) {
+ messages_callback_ = callback;
+}
+
+void OffscreenPresentationManager::OffscreenPresentationSession::
+ ListenForStateChanges(content::PresentationSessionStateListener* listener) {
+ state_change_listener_ = listener;
+}
+
+void OffscreenPresentationManager::OffscreenPresentationSession::
+ OnSessionStateChanged(content::PresentationSessionState state) {
+ if (state_change_listener_)
+ state_change_listener_->OnSessionStateChanged(state);
+}
+
+void OffscreenPresentationManager::OffscreenPresentationSession::
+ OnMessageReceived(scoped_ptr<content::PresentationSessionMessage> message) {
mark a. foltz 2015/10/01 18:39:12 IIUC the PresentationService gets batches of messa
imcheng 2015/10/06 00:59:14 Yes. I added a TODO here. I want to make sure it w
+ if (!messages_callback_.is_null()) {
+ ScopedVector<content::PresentationSessionMessage> messages;
+ messages.push_back(message.release());
+ messages_callback_.Run(messages.Pass(), true);
+ }
+}
+
+OffscreenPresentationManager::~OffscreenPresentationManager() {}
+
+void OffscreenPresentationManager::RegisterOffscreenPresentationReceiver(
+ const std::string& presentation_id,
+ const ReceiverSessionAvailableCallback& receiver_available_callback) {
+ DCHECK(!ContainsKey(offscreen_presentations_, presentation_id));
mark a. foltz 2015/10/01 18:39:12 Well this will be a no-op in release builds. Mayb
imcheng 2015/10/06 00:59:13 insert() will also be no-op if there is already an
+
+ offscreen_presentations_.insert(
+ presentation_id,
+ make_scoped_ptr(new OffscreenPresentation(
+ presentation_id, receiver_available_callback, this)));
+}
+
+void OffscreenPresentationManager::UnregisterOffscreenPresentationReceiver(
+ const std::string& presentation_id) {
+ auto it = offscreen_presentations_.find(presentation_id);
+ DCHECK(it != offscreen_presentations_.end());
mark a. foltz 2015/10/01 18:39:12 Similar comment here - it would be better to DLOG
imcheng 2015/10/06 00:59:13 We are always deleting the OffscreenPresentation h
+ it->second->OnReceiverDetached();
+}
+
+scoped_ptr<OffscreenPresentationManager::OffscreenPresentationSession>
+OffscreenPresentationManager::CreateOffscreenPresentationConnection(
+ const std::string& presentation_id,
+ const RenderFrameHostId& controller_frame_id) {
+ auto it = offscreen_presentations_.find(presentation_id);
+ if (it == offscreen_presentations_.end())
+ return scoped_ptr<
+ OffscreenPresentationManager::OffscreenPresentationSession>();
+
+ return it->second->AddConnectionAndNotifyReceiver(controller_frame_id);
+}
+
+OffscreenPresentationManager::OffscreenPresentationManager() {}
+
+void OffscreenPresentationManager::RemovePresentation(
mark a. foltz 2015/10/01 18:39:12 This must only be called on presentations that are
imcheng 2015/10/06 00:59:14 This function is removed. But that is correct - I
+ const std::string& presentation_id) {
+ offscreen_presentations_.erase(presentation_id);
+}
+
+OffscreenPresentationManager::OffscreenPresentationConnection::
+ OffscreenPresentationConnection(
+ const RenderFrameHostId& controller_frame_id,
+ OffscreenPresentation* presentation)
+ : presentation_(presentation),
+ controller_frame_id_(controller_frame_id),
+ controller_(nullptr),
mark a. foltz 2015/10/01 18:39:12 This class would be simpler by accepting a non-nul
imcheng 2015/10/06 00:59:13 The issue is that OffscreenPresentationConnection
+ receiver_(nullptr) {
+ DCHECK(presentation_);
+}
+
+void OffscreenPresentationManager::OffscreenPresentationConnection::Init(
+ OffscreenPresentationManager::OffscreenPresentationSession* controller,
+ OffscreenPresentationManager::OffscreenPresentationSession* receiver) {
+ DCHECK(!controller_);
+ DCHECK(!receiver_);
+ DCHECK(controller);
+ DCHECK(receiver);
+ controller_ = controller;
+ receiver_ = receiver;
+}
+
+OffscreenPresentationManager::OffscreenPresentationConnection::
+ ~OffscreenPresentationConnection() {
+ DCHECK(!controller_);
+ DCHECK(!receiver_);
+}
+
+void OffscreenPresentationManager::OffscreenPresentationConnection::
+ RemoveSession(bool is_controller) {
+ OffscreenPresentationManager::OffscreenPresentationSession* other_session =
+ nullptr;
+ if (is_controller) {
mark a. foltz 2015/10/01 18:39:12 This would seem simpler as: if (is_controller &&
imcheng 2015/10/06 00:59:14 Ack
+ DCHECK(controller_);
+ controller_ = nullptr;
+ other_session = receiver_;
+ } else {
+ DCHECK(receiver_);
+ receiver_ = nullptr;
+ other_session = controller_;
+ }
+
+ if (other_session) {
+ other_session->OnSessionStateChanged(
+ content::PRESENTATION_SESSION_STATE_DISCONNECTED);
+ } else {
+ presentation_->RemoveConnection(controller_frame_id_);
+ // |this| is deleted beyond this point.
+ }
+}
+
+void OffscreenPresentationManager::OffscreenPresentationConnection::SendMessage(
+ bool is_controller,
+ scoped_ptr<content::PresentationSessionMessage> message,
+ const content::SendMessageCallback& callback) {
+ OffscreenPresentationManager::OffscreenPresentationSession* other_session =
mark a. foltz 2015/10/01 18:39:12 Help me understand - the connection will always ha
imcheng 2015/10/06 00:59:13 Went with your other comment in the .h - SendMessa
+ is_controller ? receiver_ : controller_;
+ if (!other_session) {
+ callback.Run(false);
+ return;
+ } else {
+ other_session->OnMessageReceived(message.Pass());
+ callback.Run(true);
+ }
+}
+
+OffscreenPresentationManager::OffscreenPresentation::OffscreenPresentation(
+ const std::string& presentation_id,
+ const ReceiverSessionAvailableCallback& 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() {}
+
+void OffscreenPresentationManager::OffscreenPresentation::OnReceiverDetached() {
+ receiver_available_callback_.Reset();
+ MaybeSelfDestruct();
+}
+
+scoped_ptr<OffscreenPresentationManager::OffscreenPresentationSession>
+OffscreenPresentationManager::OffscreenPresentation::
+ AddConnectionAndNotifyReceiver(
+ const RenderFrameHostId& controller_frame_id) {
+ DCHECK(!ContainsKey(connections_, controller_frame_id));
+
+ if (IsReceiverGone()) {
+ return scoped_ptr<
+ OffscreenPresentationManager::OffscreenPresentationSession>();
+ }
+
+ scoped_ptr<OffscreenPresentationConnection> connection(
+ new OffscreenPresentationManager::OffscreenPresentationConnection(
+ controller_frame_id, this));
mark a. foltz 2015/10/01 18:39:12 ISTM the connection should create and own the rece
imcheng 2015/10/06 00:59:14 Per comment above, I could new these Session objec
+ scoped_ptr<OffscreenPresentationManager::OffscreenPresentationSession>
+ controller_session(
+ new OffscreenPresentationManager::OffscreenPresentationSession(
+ true, connection.get()));
+ scoped_ptr<OffscreenPresentationManager::OffscreenPresentationSession>
+ receiver_session(
+ new OffscreenPresentationManager::OffscreenPresentationSession(
+ false, connection.get()));
+
+ connection->Init(controller_session.get(), receiver_session.get());
+ connections_.insert(controller_frame_id, connection.Pass());
+ receiver_available_callback_.Run(receiver_session.Pass());
+ return controller_session.Pass();
+}
+
+void OffscreenPresentationManager::OffscreenPresentation::RemoveConnection(
mark a. foltz 2015/10/01 18:39:12 What guarantees that the two sessions are in the d
imcheng 2015/10/06 00:59:13 In the new patchset, this is only called from Offs
+ const RenderFrameHostId& controller_frame_id) {
+ DCHECK(ContainsKey(connections_, controller_frame_id));
+
+ connections_.erase(controller_frame_id);
+ MaybeSelfDestruct();
+}
+
+void OffscreenPresentationManager::OffscreenPresentation::MaybeSelfDestruct() {
+ if (IsReceiverGone() && connections_.empty())
+ manager_->RemovePresentation(presentation_id_);
+ // |this| will be deleted beyond this point.
+}
+
+} // namespace media_router

Powered by Google App Engine
This is Rietveld 408576698