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

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

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.h
diff --git a/chrome/browser/media/router/offscreen_presentation_manager.h b/chrome/browser/media/router/offscreen_presentation_manager.h
new file mode 100644
index 0000000000000000000000000000000000000000..b6aa9b6b85d7b65b785ee6acdd82918b31ce3bd0
--- /dev/null
+++ b/chrome/browser/media/router/offscreen_presentation_manager.h
@@ -0,0 +1,234 @@
+// 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.
+
+#ifndef CHROME_BROWSER_MEDIA_ROUTER_OFFSCREEN_PRESENTATION_MANAGER_H_
+#define CHROME_BROWSER_MEDIA_ROUTER_OFFSCREEN_PRESENTATION_MANAGER_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "base/containers/scoped_ptr_map.h"
+#include "base/macros.h"
+#include "chrome/browser/media/router/render_frame_host_helper.h"
+#include "components/keyed_service/core/keyed_service.h"
+#include "content/public/browser/presentation_service_delegate.h"
+
+namespace media_router {
+
+// Acts as an intermediary between the tab that hosts an offscreen presentation
mark a. foltz 2015/10/01 18:39:12 Nit: there's no "tab" per se just a WebContents co
imcheng 2015/10/06 00:59:14 Ok, I will replace "tab" with "WebContents". Rega
+// (AKA the receiver tab) and the frames that start/connect and control the
+// presentation (AKA the controller frames). Coordinates the (un)registration
+// of receiver tabs and controller frames in the context of an offscreen
+// presentation to enable the exchange of messages and notification of state
+// change to/from the other side.
+//
+// Example usage:
+//
+// Receiver tab is created to host the offscreen presentation and registers
mark a. foltz 2015/10/01 18:39:13 It's not clear how the receiver WebContents is use
imcheng 2015/10/06 00:59:14 Actually, the receiver side of OPM is not necessar
+// itself so that controller frames can connect to it:
+//
+// OffscreenPresentationManager* manager =
+// OffscreenPresentationManagerFactory::GetOrCreateForBrowserContext(
+// context);
+// manager->RegisterOffscreenPresentationReceiver(presentation_id,
+// &base::Bind(&OnSessionAvailable));
+// ...
+// void OnSessionAvailable(
mark a. foltz 2015/10/01 18:39:12 Can this be called more than once as additional co
imcheng 2015/10/06 00:59:14 Yes. In fact this provides a pretty straightforwar
+// scoped_ptr<OffscreenPresentationSession> receiver_session) {
+// [Calls methods in |receiver_session| to send/receive messages, etc.]
+// }
+//
+// Controller frame establishes connection with the receiver side, resulting
+// in a connection with the two endpoints being the controller session
+// (given to controller frame) and the receiver session (given to receiver tab).
+// Note calling this will trigger |OnSessionAvailable| on the receiver side.
+//
+// scoped_ptr<OffscreenPresentationSession> controller_session =
mark a. foltz 2015/10/01 18:39:12 The comments should make it clear that the OPS is
imcheng 2015/10/06 00:59:14 For symmetry, Controllers also use OffscrenPresent
+// manager->CreateOffscreenPresentationConnection(
+// session_info, controller_frame_id);
+// [Calls methods in |controller_session| to send/receive messages, etc.]
+//
+// A controller or receiver session leaves the offscreen presentation (e.g.,
+// due to navigation) by destroying the OffscreenPresentationSession object
+// returned by this class.
+//
+// Receiver tab is no longer associated with an offscreen presentation.
+// This will prevent additional controllers from establishing a connection with
+// the receiver tab:
+//
+// manager->UnregisterOffscreenPresentationReceiver(presentation_id);
mark a. foltz 2015/10/01 18:39:13 This would be called in response to PresentationSe
imcheng 2015/10/06 00:59:14 Correct. Right now this is called on ~ReceiverPres
+//
mark a. foltz 2015/10/01 18:39:12 Threading constraints need to be discussed somewhe
imcheng 2015/10/06 00:59:14 Done.
+class OffscreenPresentationManager : public KeyedService {
+ private:
+ // Forward declarations for OffscreenPresentationSession.
+ class OffscreenPresentationConnection;
+ class OffscreenPresentation;
+
+ public:
+ // RAII representation of either the controller or receiver endpoint of an
+ // offscreen presentation connection. Roughly corresponds to a
+ // PresentationSession
+ // object created as a result of PresentationRequest.start/reconnect (for
+ // controller) or navigator.presentation.receiver APIs (for receiver).
+ // Two instances, one representing the controller and other representing the
+ // receiver, are created and returned by OffscreenPresentationManager when
+ // |CreateOffscreenPresentationConnection| is called.
+ // The controller or receiver session may disconnect itself by destroying the
+ // instance.
+ // Instances must not outlive the OffscreenPresentationManager instance that
mark a. foltz 2015/10/01 18:39:12 Does the manager keep track of the live sessions/p
imcheng 2015/10/06 00:59:14 Since it is a KeyedService, it will live for as lo
+ // created it.
+ class OffscreenPresentationSession {
+ public:
+ ~OffscreenPresentationSession();
+
+ // Sends |message| to the other endpoint of the connection.
+ // |callback| will be invoked with whether the message was sent.
+ void SendMessage(scoped_ptr<content::PresentationSessionMessage> message,
+ const content::SendMessageCallback& callback);
+ // Listens for messages from the other endpoint of the connection.
+ // |callback| will be invoked with messages whenever there are messages.
+ void ListenForMessages(
+ const content::PresentationSessionMessageCallback& callback);
+ void ListenForStateChanges(
+ content::PresentationSessionStateListener* listener);
+
+ private:
+ friend class OffscreenPresentation;
+ friend class OffscreenPresentationConnection;
+
+ OffscreenPresentationSession(bool is_controller,
+ OffscreenPresentationConnection* connection);
+ void OnSessionStateChanged(content::PresentationSessionState state);
+ void OnMessageReceived(scoped_ptr<content::PresentationSessionMessage>);
+
+ const bool is_controller_;
+ OffscreenPresentationConnection* const connection_;
+ content::PresentationSessionMessageCallback messages_callback_;
+ content::PresentationSessionStateListener* state_change_listener_;
+
+ DISALLOW_COPY_AND_ASSIGN(OffscreenPresentationSession);
+ };
+
+ ~OffscreenPresentationManager() override;
+
+ using ReceiverSessionAvailableCallback =
+ base::Callback<void(scoped_ptr<OffscreenPresentationSession>)>;
+
+ // Registers an offscreen presentation given by |presentation_id|.
+ // Enables controller frames to call |CreateOffscreenPresentationConnection|
+ // with the same presentation ID to establish a connection with the receiver
+ // side of the presentation.
+ // Whenever a connection is established, |receiver_available_callback| will be
+ // invoked with a OffscreenPresentationSession that represents the receiver
+ // side of the resulting connection.
+ void RegisterOffscreenPresentationReceiver(
+ const std::string& presentation_id,
+ const ReceiverSessionAvailableCallback& receiver_available_callback);
+
+ // Unregisters a previously registered offscreen presentation. After this
+ // call, controller frames will no longer be able to establish connections
+ // to the presentation.
mark a. foltz 2015/10/01 18:39:12 What happens to pending callbacks passed into Regi
imcheng 2015/10/06 00:59:14 The callback will be removed from this class. I wi
+ void UnregisterOffscreenPresentationReceiver(
+ const std::string& presentation_id);
+
+ // Creates a connection to the receiver side of an offscreen presentation
+ // given by |presentation_id| registered with this instance, with the frame
+ // |controller_frame_id| as the controller side of the connection.
+ // Returns nullptr if the offscreen presentation is not already registered.
+ // Returns a OffscreenPresentationSession object representing the controller
+ // side of the resulting connection. In addition,
+ // |receiver_available_callback_| will be invoked with a
+ // OffscreenPresentationSession object representing the receiver side of the
+ // connection.
+ scoped_ptr<OffscreenPresentationSession>
+ CreateOffscreenPresentationConnection(
mark a. foltz 2015/10/01 18:39:12 Nit: Might name this ConnectToOffscreenPresentatio
imcheng 2015/10/06 00:59:14 Done.
+ const std::string& presentation_id,
+ const RenderFrameHostId& controller_frame_id);
mark a. foltz 2015/10/01 18:39:13 It seems a little asymmetrical for the controller
imcheng 2015/10/06 00:59:14 Yes, this is also how presentation.receiver API wo
+
+ private:
+ friend class OffscreenPresentationManagerFactory;
+
+ // Represents a connection between a controller session and a receiver session
+ // of an offscreen presentation and coordinates the exchange of information
+ // between them.
+ // Note that each offscreen presentation may contain multiple connections.
+ class OffscreenPresentationConnection {
+ public:
+ ~OffscreenPresentationConnection();
+ void RemoveSession(bool is_controller);
mark a. foltz 2015/10/01 18:39:12 What does is_controller mean? Does this mean the
imcheng 2015/10/06 00:59:14 Done.
+ void SendMessage(bool is_controller,
mark a. foltz 2015/10/01 18:39:13 SendMessageToController() SendMessageToReceiver()
imcheng 2015/10/06 00:59:14 Done.
+ scoped_ptr<content::PresentationSessionMessage> message,
+ const content::SendMessageCallback& callback);
+
+ private:
+ friend class OffscreenPresentation;
+ OffscreenPresentationConnection(
+ const RenderFrameHostId& controller_frame_id,
+ OffscreenPresentation* presentation);
+ void Init(OffscreenPresentationSession* controller,
+ OffscreenPresentationSession* receiver);
+
+ const RenderFrameHostId controller_frame_id_;
+ OffscreenPresentation* const presentation_;
+
+ // Not owned by this class.
mark a. foltz 2015/10/01 18:39:13 Destruction of either would seem to require that t
imcheng 2015/10/06 00:59:14 Currently, this will be destroyed once both sessio
+ OffscreenPresentationSession* controller_;
+ OffscreenPresentationSession* receiver_;
+
+ DISALLOW_COPY_AND_ASSIGN(OffscreenPresentationConnection);
+ };
+
+ // Represents an offscreen presentation registered with
+ // OffscreenPresentationManager.
+ // Maintains set of connections to the presentation.
+ // Contains callback to the receiver to inform it of new connections
mark a. foltz 2015/10/01 18:39:13 Called only once, or once per connected controller
imcheng 2015/10/06 00:59:14 Once per connected controller.
+ // established from a controller.
+ class OffscreenPresentation {
+ public:
+ OffscreenPresentation(
+ const std::string& presentation_id,
+ const ReceiverSessionAvailableCallback& receiver_available_callback,
+ OffscreenPresentationManager* manager);
+ ~OffscreenPresentation();
+
+ scoped_ptr<OffscreenPresentationSession> AddConnectionAndNotifyReceiver(
mark a. foltz 2015/10/01 18:39:12 Is this called when a new controller connects? May
imcheng 2015/10/06 00:59:14 I want to keep name as AddConnection() so there's
+ const RenderFrameHostId& controller_frame_id);
+ void OnReceiverDetached();
mark a. foltz 2015/10/01 18:39:12 What is a "detached" receiver? Do you mean contro
imcheng 2015/10/06 00:59:14 No, this is called when the receiver unregisters.
+
+ bool IsReceiverGone() const {
+ return receiver_available_callback_.is_null();
+ }
+
+ private:
+ friend class OffscreenPresentationConnection;
+
+ void RemoveConnection(const RenderFrameHostId& controller_frame_id);
+ void MaybeSelfDestruct();
+
+ const std::string presentation_id_;
+ ReceiverSessionAvailableCallback receiver_available_callback_;
+ base::ScopedPtrMap<RenderFrameHostId,
+ scoped_ptr<OffscreenPresentationConnection>>
+ connections_;
+ OffscreenPresentationManager* const manager_;
+
+ DISALLOW_COPY_AND_ASSIGN(OffscreenPresentation);
+ };
+
+ // Used by OffscreenPresentationManagerFactory::GetOrCreateForBrowserContext.
+ OffscreenPresentationManager();
+
+ void RemovePresentation(const std::string& presentation_id);
+
+ // Maps from presentation ID to OffscreenPresentation.
+ base::ScopedPtrMap<std::string, scoped_ptr<OffscreenPresentation>>
+ offscreen_presentations_;
+
+ DISALLOW_COPY_AND_ASSIGN(OffscreenPresentationManager);
+};
+
+} // namespace media_router
+
+#endif // CHROME_BROWSER_MEDIA_ROUTER_OFFSCREEN_PRESENTATION_MANAGER_H_

Powered by Google App Engine
This is Rietveld 408576698