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

Side by Side 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, 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef CHROME_BROWSER_MEDIA_ROUTER_OFFSCREEN_PRESENTATION_MANAGER_H_
6 #define CHROME_BROWSER_MEDIA_ROUTER_OFFSCREEN_PRESENTATION_MANAGER_H_
7
8 #include <map>
9 #include <string>
10 #include <vector>
11
12 #include "base/containers/scoped_ptr_map.h"
13 #include "base/macros.h"
14 #include "chrome/browser/media/router/render_frame_host_helper.h"
15 #include "components/keyed_service/core/keyed_service.h"
16 #include "content/public/browser/presentation_service_delegate.h"
17
18 namespace media_router {
19
20 // 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
21 // (AKA the receiver tab) and the frames that start/connect and control the
22 // presentation (AKA the controller frames). Coordinates the (un)registration
23 // of receiver tabs and controller frames in the context of an offscreen
24 // presentation to enable the exchange of messages and notification of state
25 // change to/from the other side.
26 //
27 // Example usage:
28 //
29 // 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
30 // itself so that controller frames can connect to it:
31 //
32 // OffscreenPresentationManager* manager =
33 // OffscreenPresentationManagerFactory::GetOrCreateForBrowserContext(
34 // context);
35 // manager->RegisterOffscreenPresentationReceiver(presentation_id,
36 // &base::Bind(&OnSessionAvailable));
37 // ...
38 // 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
39 // scoped_ptr<OffscreenPresentationSession> receiver_session) {
40 // [Calls methods in |receiver_session| to send/receive messages, etc.]
41 // }
42 //
43 // Controller frame establishes connection with the receiver side, resulting
44 // in a connection with the two endpoints being the controller session
45 // (given to controller frame) and the receiver session (given to receiver tab).
46 // Note calling this will trigger |OnSessionAvailable| on the receiver side.
47 //
48 // 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
49 // manager->CreateOffscreenPresentationConnection(
50 // session_info, controller_frame_id);
51 // [Calls methods in |controller_session| to send/receive messages, etc.]
52 //
53 // A controller or receiver session leaves the offscreen presentation (e.g.,
54 // due to navigation) by destroying the OffscreenPresentationSession object
55 // returned by this class.
56 //
57 // Receiver tab is no longer associated with an offscreen presentation.
58 // This will prevent additional controllers from establishing a connection with
59 // the receiver tab:
60 //
61 // 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
62 //
mark a. foltz 2015/10/01 18:39:12 Threading constraints need to be discussed somewhe
imcheng 2015/10/06 00:59:14 Done.
63 class OffscreenPresentationManager : public KeyedService {
64 private:
65 // Forward declarations for OffscreenPresentationSession.
66 class OffscreenPresentationConnection;
67 class OffscreenPresentation;
68
69 public:
70 // RAII representation of either the controller or receiver endpoint of an
71 // offscreen presentation connection. Roughly corresponds to a
72 // PresentationSession
73 // object created as a result of PresentationRequest.start/reconnect (for
74 // controller) or navigator.presentation.receiver APIs (for receiver).
75 // Two instances, one representing the controller and other representing the
76 // receiver, are created and returned by OffscreenPresentationManager when
77 // |CreateOffscreenPresentationConnection| is called.
78 // The controller or receiver session may disconnect itself by destroying the
79 // instance.
80 // 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
81 // created it.
82 class OffscreenPresentationSession {
83 public:
84 ~OffscreenPresentationSession();
85
86 // Sends |message| to the other endpoint of the connection.
87 // |callback| will be invoked with whether the message was sent.
88 void SendMessage(scoped_ptr<content::PresentationSessionMessage> message,
89 const content::SendMessageCallback& callback);
90 // Listens for messages from the other endpoint of the connection.
91 // |callback| will be invoked with messages whenever there are messages.
92 void ListenForMessages(
93 const content::PresentationSessionMessageCallback& callback);
94 void ListenForStateChanges(
95 content::PresentationSessionStateListener* listener);
96
97 private:
98 friend class OffscreenPresentation;
99 friend class OffscreenPresentationConnection;
100
101 OffscreenPresentationSession(bool is_controller,
102 OffscreenPresentationConnection* connection);
103 void OnSessionStateChanged(content::PresentationSessionState state);
104 void OnMessageReceived(scoped_ptr<content::PresentationSessionMessage>);
105
106 const bool is_controller_;
107 OffscreenPresentationConnection* const connection_;
108 content::PresentationSessionMessageCallback messages_callback_;
109 content::PresentationSessionStateListener* state_change_listener_;
110
111 DISALLOW_COPY_AND_ASSIGN(OffscreenPresentationSession);
112 };
113
114 ~OffscreenPresentationManager() override;
115
116 using ReceiverSessionAvailableCallback =
117 base::Callback<void(scoped_ptr<OffscreenPresentationSession>)>;
118
119 // Registers an offscreen presentation given by |presentation_id|.
120 // Enables controller frames to call |CreateOffscreenPresentationConnection|
121 // with the same presentation ID to establish a connection with the receiver
122 // side of the presentation.
123 // Whenever a connection is established, |receiver_available_callback| will be
124 // invoked with a OffscreenPresentationSession that represents the receiver
125 // side of the resulting connection.
126 void RegisterOffscreenPresentationReceiver(
127 const std::string& presentation_id,
128 const ReceiverSessionAvailableCallback& receiver_available_callback);
129
130 // Unregisters a previously registered offscreen presentation. After this
131 // call, controller frames will no longer be able to establish connections
132 // 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
133 void UnregisterOffscreenPresentationReceiver(
134 const std::string& presentation_id);
135
136 // Creates a connection to the receiver side of an offscreen presentation
137 // given by |presentation_id| registered with this instance, with the frame
138 // |controller_frame_id| as the controller side of the connection.
139 // Returns nullptr if the offscreen presentation is not already registered.
140 // Returns a OffscreenPresentationSession object representing the controller
141 // side of the resulting connection. In addition,
142 // |receiver_available_callback_| will be invoked with a
143 // OffscreenPresentationSession object representing the receiver side of the
144 // connection.
145 scoped_ptr<OffscreenPresentationSession>
146 CreateOffscreenPresentationConnection(
mark a. foltz 2015/10/01 18:39:12 Nit: Might name this ConnectToOffscreenPresentatio
imcheng 2015/10/06 00:59:14 Done.
147 const std::string& presentation_id,
148 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
149
150 private:
151 friend class OffscreenPresentationManagerFactory;
152
153 // Represents a connection between a controller session and a receiver session
154 // of an offscreen presentation and coordinates the exchange of information
155 // between them.
156 // Note that each offscreen presentation may contain multiple connections.
157 class OffscreenPresentationConnection {
158 public:
159 ~OffscreenPresentationConnection();
160 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.
161 void SendMessage(bool is_controller,
mark a. foltz 2015/10/01 18:39:13 SendMessageToController() SendMessageToReceiver()
imcheng 2015/10/06 00:59:14 Done.
162 scoped_ptr<content::PresentationSessionMessage> message,
163 const content::SendMessageCallback& callback);
164
165 private:
166 friend class OffscreenPresentation;
167 OffscreenPresentationConnection(
168 const RenderFrameHostId& controller_frame_id,
169 OffscreenPresentation* presentation);
170 void Init(OffscreenPresentationSession* controller,
171 OffscreenPresentationSession* receiver);
172
173 const RenderFrameHostId controller_frame_id_;
174 OffscreenPresentation* const presentation_;
175
176 // 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
177 OffscreenPresentationSession* controller_;
178 OffscreenPresentationSession* receiver_;
179
180 DISALLOW_COPY_AND_ASSIGN(OffscreenPresentationConnection);
181 };
182
183 // Represents an offscreen presentation registered with
184 // OffscreenPresentationManager.
185 // Maintains set of connections to the presentation.
186 // 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.
187 // established from a controller.
188 class OffscreenPresentation {
189 public:
190 OffscreenPresentation(
191 const std::string& presentation_id,
192 const ReceiverSessionAvailableCallback& receiver_available_callback,
193 OffscreenPresentationManager* manager);
194 ~OffscreenPresentation();
195
196 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
197 const RenderFrameHostId& controller_frame_id);
198 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.
199
200 bool IsReceiverGone() const {
201 return receiver_available_callback_.is_null();
202 }
203
204 private:
205 friend class OffscreenPresentationConnection;
206
207 void RemoveConnection(const RenderFrameHostId& controller_frame_id);
208 void MaybeSelfDestruct();
209
210 const std::string presentation_id_;
211 ReceiverSessionAvailableCallback receiver_available_callback_;
212 base::ScopedPtrMap<RenderFrameHostId,
213 scoped_ptr<OffscreenPresentationConnection>>
214 connections_;
215 OffscreenPresentationManager* const manager_;
216
217 DISALLOW_COPY_AND_ASSIGN(OffscreenPresentation);
218 };
219
220 // Used by OffscreenPresentationManagerFactory::GetOrCreateForBrowserContext.
221 OffscreenPresentationManager();
222
223 void RemovePresentation(const std::string& presentation_id);
224
225 // Maps from presentation ID to OffscreenPresentation.
226 base::ScopedPtrMap<std::string, scoped_ptr<OffscreenPresentation>>
227 offscreen_presentations_;
228
229 DISALLOW_COPY_AND_ASSIGN(OffscreenPresentationManager);
230 };
231
232 } // namespace media_router
233
234 #endif // CHROME_BROWSER_MEDIA_ROUTER_OFFSCREEN_PRESENTATION_MANAGER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698