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

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: Rebase again to pick up Yuri's cl Created 5 years, 2 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..3c8f383936ff87ecc6cd48811a63348fe62cead2
--- /dev/null
+++ b/chrome/browser/media/router/offscreen_presentation_manager.h
@@ -0,0 +1,242 @@
+// 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 party that hosts an offscreen
+// presentation (AKA the receiver) and the frames that start/connect and
miu 2015/10/07 21:51:46 nit: s/frames/render frames/ for clarity
imcheng 2015/10/10 04:39:43 Done.
+// control the presentation (AKA the controller frames). Coordinates the
+// (un)registration of receivers 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 is created to host the offscreen presentation and
+// registers itself so that controller frames can connect to it:
+//
+// OffscreenPresentationManager* manager =
+// OffscreenPresentationManagerFactory::GetOrCreateForBrowserContext(
+// context);
+// manager->RegisterOffscreenPresentationReceiver(presentation_id,
+// &base::Bind(&OnSessionAvailable));
miu 2015/10/07 21:51:46 Delete the first ampersand.
imcheng 2015/10/10 04:39:43 Done.
+// ...
+// void OnSessionAvailable(
+// 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).
+// Note calling this will trigger |OnSessionAvailable| on the receiver side.
+//
+// scoped_ptr<OffscreenPresentationSession> controller_session =
+// manager->CreateOffscreenPresentationConnection(
+// presentation_id, 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 is no longer associated with an offscreen presentation.
+// Receiver unregisters with OffscreenPresentationManager. Note that all
+// sessions must be destroyed before unregistration.
miu 2015/10/07 21:51:46 formatting: More text fits on this line. Also, ma
imcheng 2015/10/10 04:39:43 Done.
+// This will prevent additional controllers from establishing a connection with
+// the receiver:
+//
+// receiver_sessions.clear();
+// manager->UnregisterOffscreenPresentationReceiver(presentation_id);
+//
+// This class is not thread safe. All functions must be invoked on the UI
+// thread. All callbacks passed into this class will also be invoked on UI
+// thread.
+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
+ // 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* 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. The ReceiverSessionAvailableCallback previously
+ // registered will be removed and will no longer be invoked.
+ // NOTE: before this call can be made, all OffscreenPresentationSession
miu 2015/10/07 21:51:46 This "note" comment makes me wonder: Could you enf
imcheng 2015/10/10 04:39:43 That could work. I separate the two calls because
+ // owned by the receiver must be destroyed first.
+ 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
miu 2015/10/07 21:51:46 nit: To clarify, might I suggest this last sentenc
imcheng 2015/10/10 04:39:43 Thanks. I made some modification to your suggestio
+ // OffscreenPresentationSession object representing the receiver side of the
+ // connection.
+ scoped_ptr<OffscreenPresentationSession> ConnectToOffscreenPresentation(
+ const std::string& presentation_id,
+ const RenderFrameHostId& controller_frame_id);
+
+ 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 RemoveControllerSession();
+ void RemoveReceiverSession();
+ void SendMessageToController(
+ scoped_ptr<content::PresentationSessionMessage> message,
+ const content::SendMessageCallback& callback);
+ void SendMessageToReceiver(
+ 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);
+ void RemoveSession(OffscreenPresentationSession* session);
+ void SendMessage(OffscreenPresentationSession* session,
+ scoped_ptr<content::PresentationSessionMessage> message,
+ const content::SendMessageCallback& callback);
+
+ const RenderFrameHostId controller_frame_id_;
+ OffscreenPresentation* const presentation_;
+
+ // Not owned by this class.
+ 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
+ // established from a controller.
+ class OffscreenPresentation {
+ public:
+ OffscreenPresentation(
+ const std::string& presentation_id,
+ const ReceiverSessionAvailableCallback& receiver_available_callback,
+ OffscreenPresentationManager* manager);
+ ~OffscreenPresentation();
+
+ scoped_ptr<OffscreenPresentationSession> AddConnection(
+ const RenderFrameHostId& controller_frame_id);
+
+ private:
+ friend class OffscreenPresentationConnection;
+
+ void RemoveConnection(const RenderFrameHostId& controller_frame_id);
+
+ 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();
+
+ // 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