OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef CHROME_BROWSER_MEDIA_ROUTER_OFFSCREEN_PRESENTATION_MANAGER_H_ | 5 #ifndef CHROME_BROWSER_MEDIA_ROUTER_OFFSCREEN_PRESENTATION_MANAGER_H_ |
6 #define CHROME_BROWSER_MEDIA_ROUTER_OFFSCREEN_PRESENTATION_MANAGER_H_ | 6 #define CHROME_BROWSER_MEDIA_ROUTER_OFFSCREEN_PRESENTATION_MANAGER_H_ |
7 | 7 |
8 #include <map> | 8 #include <map> |
9 #include <memory> | 9 #include <memory> |
10 #include <string> | 10 #include <string> |
11 #include <unordered_map> | 11 #include <unordered_map> |
12 | 12 |
13 #include "base/macros.h" | 13 #include "base/macros.h" |
14 #include "base/threading/thread_checker.h" | 14 #include "base/threading/thread_checker.h" |
15 #include "chrome/browser/media/router/render_frame_host_id.h" | 15 #include "chrome/browser/media/router/render_frame_host_id.h" |
16 #include "components/keyed_service/core/keyed_service.h" | 16 #include "components/keyed_service/core/keyed_service.h" |
17 #include "content/public/browser/presentation_service_delegate.h" | 17 #include "content/public/browser/presentation_service_delegate.h" |
18 | 18 |
19 class GURL; | 19 class GURL; |
20 | 20 |
21 // TODO(zhaobin): move these back to | |
22 // content/public/browser/presentation_service_delegate.h when they are actually | |
23 // used in content. | |
24 namespace content { | |
25 // TODO(zhaobin): A class stub for blink::mojom::PresentationConnectionPtr. | |
26 // presentation.mojom is under security review. Change this to | |
27 // blink::mojom::PresentationConnectionPtr once that is done. | |
28 class PresentationConnectionPtr {}; | |
29 | |
30 using ReceiverConnectionAvailableCallback = | |
31 base::Callback<void(const content::PresentationSessionInfo&, | |
32 PresentationConnectionPtr)>; | |
33 } // namespace content | |
34 | |
35 namespace media_router { | 21 namespace media_router { |
36 // Manages all offscreen presentations started in the associated Profile and | 22 // Manages all offscreen presentations started in the associated Profile and |
37 // facilitates communication between the controllers and the receiver of an | 23 // facilitates communication between the controllers and the receiver of an |
38 // offscreen presentation. | 24 // offscreen presentation. |
39 // | 25 // |
40 // Design doc: | 26 // Design doc: |
41 // https://docs.google.com/document/d/1XM3jhMJTQyhEC5PDAAJFNIaKh6UUEihqZDz_ztEe4
Co/edit#heading=h.hadpx5oi0gml | 27 // https://docs.google.com/document/d/1XM3jhMJTQyhEC5PDAAJFNIaKh6UUEihqZDz_ztEe4
Co/edit#heading=h.hadpx5oi0gml |
42 // | 28 // |
43 // Example usage: | 29 // Example usage: |
44 // | 30 // |
45 // Receiver is created to host the offscreen presentation and registers itself | 31 // Receiver is created to host the offscreen presentation and registers itself |
46 // so that controller frames can connect to it: | 32 // so that controller frames can connect to it: |
47 // | 33 // |
48 // OffscreenPresentationManager* manager = | 34 // OffscreenPresentationManager* manager = |
49 // OffscreenPresentationManagerFactory::GetOrCreateForBrowserContext( | 35 // OffscreenPresentationManagerFactory::GetOrCreateForBrowserContext( |
50 // web_contents_->GetBrowserContext()); | 36 // web_contents_->GetBrowserContext()); |
51 // manager->OnOffscreenPresentationReceiverCreated(presentation_id, | 37 // manager->OnOffscreenPresentationReceiverCreated(presentation_id, |
52 // base::Bind(&PresentationServiceImpl::OnReceiverConnectionAvailable)); | 38 // base::Bind(&PresentationServiceImpl::OnReceiverConnectionAvailable)); |
53 // | 39 // |
54 // Controller frame establishes connection with the receiver side, resulting | 40 // Controlling frame establishes connection with the receiver side, resulting |
55 // in a connection with the two endpoints being the controller | 41 // in a connection with the two endpoints being the controller |
56 // PresentationConnectionPtr and receiver PresentationConnectionPtr. | 42 // PresentationConnectionPtr and receiver PresentationConnectionPtr. |
57 // Note calling this will trigger receiver frame's | 43 // Note calling this will trigger receiver frame's |
58 // PresentationServiceImpl::OnReceiverConnectionAvailable. | 44 // PresentationServiceImpl::OnReceiverConnectionAvailable. |
59 // | 45 // |
60 // manager->RegisterOffscreenPresentationController( | 46 // manager->RegisterOffscreenPresentationController( |
61 // presentation_id, controller_frame_id, controller_ptr); | 47 // presentation_id, controller_frame_id, controller_connection_ptr, |
| 48 // receiver_connection_request); |
62 // | 49 // |
63 // Invoked on receiver's PresentationServiceImpl when controller connection is | 50 // Invoked on receiver's PresentationServiceImpl when controller connection is |
64 // established. | 51 // established. |
65 // | 52 // |
66 // |presentation_receiver_client_|: blink::mojom::PresentationServiceClienPtr | 53 // |presentation_receiver_client_|: blink::mojom::PresentationServiceClienPtr |
67 // for the presentation receiver. | 54 // for the presentation receiver. |
68 // |PresentationConnectionPtr|: blink::mojom::PresentationConnectionPtr for | 55 // |controller_connection_ptr|: blink::mojom::PresentationConnectionPtr for |
69 // blink::PresentationConnection object in render process. | 56 // blink::PresentationConnection object in controlling frame's render process. |
| 57 // |receiver_connection_request|: Mojo InterfaceRequest to be bind to |
| 58 // blink::PresentationConnection object in receiver frame's render process. |
70 // void PresentationServiceImpl::OnReceiverConnectionAvailable( | 59 // void PresentationServiceImpl::OnReceiverConnectionAvailable( |
71 // const content::PresentationSessionInfo& session, | 60 // const content::PresentationSessionInfo& session, |
72 // PresentationConnectionPtr&& controller) { | 61 // PresentationConnectionPtr controller_connection_ptr, |
| 62 // PresentationConnectionRequest receiver_connection_request) { |
73 // presentation_receiver_client_->OnReceiverConnectionAvailable( | 63 // presentation_receiver_client_->OnReceiverConnectionAvailable( |
74 // blink::mojom::PresentationSessionInfo::From(session_info), | 64 // blink::mojom::PresentationSessionInfo::From(session_info), |
75 // std::move(controller)); | 65 // std::move(controller_connection_ptr), |
| 66 // std::move(receiver_connection_request)); |
76 // } | 67 // } |
77 // | 68 // |
78 // Send message from controller/receiver to receiver/controller: | 69 // Send message from controlling/receiver frame to receiver/controlling frame: |
79 // | 70 // |
80 // |target_connection_|: member variable of | 71 // |target_connection_|: member variable of |
81 // blink::mojom::PresentationConnectionPtr type, | 72 // blink::mojom::PresentationConnectionPtr type, |
82 // refering to remote PresentationConnectionProxy | 73 // refering to remote PresentationConnectionProxy |
83 // object on receiver/controlling frame. | 74 // object on receiver/controlling frame. |
84 // |message|: Text message to be sent. | 75 // |message|: Text message to be sent. |
85 // PresentationConnctionPtr::SendString( | 76 // PresentationConnctionPtr::SendString( |
86 // const blink::WebString& message) { | 77 // const blink::WebString& message) { |
87 // target_connection_->OnSessionMessageReceived(std::move(session_message)); | 78 // target_connection_->OnSessionMessageReceived(std::move(session_message)); |
88 // } | 79 // } |
89 // | 80 // |
90 // A controller or receiver leaves the offscreen presentation (e.g., | 81 // A controller or receiver leaves the offscreen presentation (e.g., due to |
91 // due to navigation) by unregistering themselves from | 82 // navigation) by unregistering themselves from OffscreenPresentation object. |
92 // OffscreenPresentation object. | |
93 // | 83 // |
94 // When the receiver is no longer associated with an offscreen presentation, it | 84 // When the receiver is no longer associated with an offscreen presentation, it |
95 // shall unregister itself with OffscreenPresentationManager. Unregistration | 85 // shall unregister itself with OffscreenPresentationManager. Unregistration |
96 // will prevent additional controllers from establishing a connection with the | 86 // will prevent additional controllers from establishing a connection with the |
97 // receiver: | 87 // receiver: |
98 // | 88 // |
99 // In receiver's PSImpl::Reset() { | 89 // In receiver's PSImpl::Reset() { |
100 // offscreen_presentation_manager-> | 90 // offscreen_presentation_manager-> |
101 // OnOffscreenPresentationReceiverTerminated(presentation_id); | 91 // OnOffscreenPresentationReceiverTerminated(presentation_id); |
102 // } | 92 // } |
103 // | 93 // |
104 // This class is not thread safe. All functions must be invoked on the UI | 94 // This class is not thread safe. All functions must be invoked on the UI |
105 // thread. All callbacks passed into this class will also be invoked on UI | 95 // thread. All callbacks passed into this class will also be invoked on UI |
106 // thread. | 96 // thread. |
107 class OffscreenPresentationManager : public KeyedService { | 97 class OffscreenPresentationManager : public KeyedService { |
108 public: | 98 public: |
109 ~OffscreenPresentationManager() override; | 99 ~OffscreenPresentationManager() override; |
110 | 100 |
111 // Registers controller PresentationConnectionPtr to presentation | 101 // Registers controller PresentationConnectionPtr to presentation with |
112 // with |presentation_id|, |render_frame_id|. | 102 // |presentation_id| and |render_frame_id|. |
113 // Creates a new presentation if no presentation with |presentation_id| | 103 // Creates a new presentation if no presentation with |presentation_id| |
114 // exists. | 104 // exists. |
115 // |controller|: Not owned by this class. Ownership is transferred to the | 105 // |controller_connection_ptr|, |receiver_connection_request|: Not owned by |
116 // presentation receiver via |receiver_callback| passed below. | 106 // this class. Ownership is transferred to presentation receiver via |
117 void RegisterOffscreenPresentationController( | 107 // |receiver_callback| passed below. |
| 108 virtual void RegisterOffscreenPresentationController( |
118 const std::string& presentation_id, | 109 const std::string& presentation_id, |
119 const GURL& presentation_url, | 110 const GURL& presentation_url, |
120 const RenderFrameHostId& render_frame_id, | 111 const RenderFrameHostId& render_frame_id, |
121 content::PresentationConnectionPtr controller); | 112 content::PresentationConnectionPtr controller_connection_ptr, |
| 113 content::PresentationConnectionRequest receiver_connection_request); |
122 | 114 |
123 // Unregisters controller PresentationConnectionPtr to presentation with | 115 // Unregisters controller PresentationConnectionPtr to presentation with |
124 // |presentation_id|, |render_frame_id|. It does nothing if there is no | 116 // |presentation_id|, |render_frame_id|. It does nothing if there is no |
125 // controller that matches the provided arguments. It removes presentation | 117 // controller that matches the provided arguments. It removes presentation |
126 // that matches the arguments if the presentation has no receiver_callback and | 118 // that matches the arguments if the presentation has no |receiver_callback| |
127 // any other pending controller. | 119 // and any other pending controller. |
128 void UnregisterOffscreenPresentationController( | 120 virtual void UnregisterOffscreenPresentationController( |
129 const std::string& presentation_id, | 121 const std::string& presentation_id, |
130 const RenderFrameHostId& render_frame_id); | 122 const RenderFrameHostId& render_frame_id); |
131 | 123 |
132 // Registers ReceiverConnectionAvailableCallback to presentation | 124 // Registers |receiver_callback| to presentation with |presentation_id| and |
133 // with |presentation_id|. | 125 // |presentation_url|. |
134 void OnOffscreenPresentationReceiverCreated( | 126 virtual void OnOffscreenPresentationReceiverCreated( |
135 const std::string& presentation_id, | 127 const std::string& presentation_id, |
136 const GURL& presentation_url, | 128 const GURL& presentation_url, |
137 const content::ReceiverConnectionAvailableCallback& receiver_callback); | 129 const content::ReceiverConnectionAvailableCallback& receiver_callback); |
138 | 130 |
139 // Unregisters the ReceiverConnectionAvailableCallback associated with | 131 // Unregisters ReceiverConnectionAvailableCallback associated with |
140 // |presentation_id|. | 132 // |presentation_id|. |
141 void OnOffscreenPresentationReceiverTerminated( | 133 virtual void OnOffscreenPresentationReceiverTerminated( |
142 const std::string& presentation_id); | 134 const std::string& presentation_id); |
143 | 135 |
144 private: | 136 private: |
145 // Represents an offscreen presentation registered with | 137 // Represents an offscreen presentation registered with |
146 // OffscreenPresentationManager. | 138 // OffscreenPresentationManager. Contains callback to the receiver to inform |
147 // Contains callback to the receiver to inform it of new connections | 139 // it of new connections established from a controller. Contains set of |
148 // established from a controller. | 140 // controllers registered to OffscreenPresentationManager before corresponding |
149 // Contains set of controllers registered to OffscreenPresentationManager | 141 // receiver. |
150 // before corresponding receiver. | |
151 class OffscreenPresentation { | 142 class OffscreenPresentation { |
152 public: | 143 public: |
153 OffscreenPresentation(const std::string& presentation_id, | 144 OffscreenPresentation(const std::string& presentation_id, |
154 const GURL& presentation_url); | 145 const GURL& presentation_url); |
155 ~OffscreenPresentation(); | 146 ~OffscreenPresentation(); |
156 | 147 |
157 // Register |controller| with |render_frame_id|. If |receiver_callback_| has | 148 // Register controller with |render_frame_id|. If |receiver_callback_| has |
158 // been set, invoke |receiver_callback_| with |controller| as parameter, | 149 // been set, invoke |receiver_callback_| with |controller_connection_ptr| |
159 // else store |controller| in |pending_controllers_| map. | 150 // and |receiver_connection_request| as parameter, else creates a |
160 void RegisterController(const RenderFrameHostId& render_frame_id, | 151 // ControllerConnection object with |controller_connection_ptr| and |
161 content::PresentationConnectionPtr controller); | 152 // |receiver_connection_request|, and store it in |pending_controllers_| |
| 153 // map. |
| 154 void RegisterController( |
| 155 const RenderFrameHostId& render_frame_id, |
| 156 content::PresentationConnectionPtr controller_connection_ptr, |
| 157 content::PresentationConnectionRequest receiver_connection_request); |
162 | 158 |
163 // Unregister controller with |render_frame_id|. Do nothing if there is no | 159 // Unregister controller with |render_frame_id|. Do nothing if there is no |
164 // pending controller with |render_frame_id|. | 160 // pending controller with |render_frame_id|. |
165 void UnregisterController(const RenderFrameHostId& render_frame_id); | 161 void UnregisterController(const RenderFrameHostId& render_frame_id); |
166 | 162 |
167 // Register |receiver_callback| to current offscreen_presentation object. | 163 // Register |receiver_callback| to current offscreen_presentation object. |
168 // For each controller in |pending_controllers_| map, invoke | 164 // For each controller in |pending_controllers_| map, invoke |
169 // |receiver_callback| with controller as parameter. Clear | 165 // |receiver_callback| with controller as parameter. Clear |
170 // |pending_controllers_| map afterwards. | 166 // |pending_controllers_| map afterwards. |
171 void RegisterReceiver( | 167 void RegisterReceiver( |
172 const content::ReceiverConnectionAvailableCallback& receiver_callback); | 168 const content::ReceiverConnectionAvailableCallback& receiver_callback); |
173 | 169 |
174 private: | 170 private: |
175 friend class OffscreenPresentationManagerTest; | 171 friend class OffscreenPresentationManagerTest; |
176 friend class OffscreenPresentationManager; | 172 friend class OffscreenPresentationManager; |
177 | 173 |
178 // Returns false if receiver_callback_ is null and there are no pending | 174 // Returns false if receiver_callback_ is null and there are no pending |
179 // controllers. | 175 // controllers. |
180 bool IsValid() const; | 176 bool IsValid() const; |
181 | 177 |
182 const std::string presentation_id_; | 178 const std::string presentation_id_; |
183 const GURL presentation_url_; | 179 const GURL presentation_url_; |
184 | 180 |
185 // Callback to invoke whenever a receiver connection is available. | 181 // Callback to invoke whenever a receiver connection is available. |
186 content::ReceiverConnectionAvailableCallback receiver_callback_; | 182 content::ReceiverConnectionAvailableCallback receiver_callback_; |
187 | 183 |
188 // Contains Mojo pointers to controller PresentationConnections registered | 184 // Stores controller information. |
189 // via |RegisterController()| before |receiver_callback_| is set. | 185 // |controller_connection_ptr|: Mojo::InterfacePtr to |
| 186 // blink::PresentationConnection object in controlling frame; |
| 187 // |receiver_connection_request|: Mojo::InterfaceRequest to be bind to |
| 188 // blink::PresentationConnection object in receiver frame. |
| 189 struct ControllerConnection { |
| 190 public: |
| 191 ControllerConnection( |
| 192 content::PresentationConnectionPtr controller_connection_ptr, |
| 193 content::PresentationConnectionRequest receiver_connection_request); |
| 194 ~ControllerConnection(); |
| 195 |
| 196 content::PresentationConnectionPtr controller_connection_ptr; |
| 197 content::PresentationConnectionRequest receiver_connection_request; |
| 198 }; |
| 199 |
| 200 // Contains ControllerConnection objects registered via |
| 201 // |RegisterController()| before |receiver_callback_| is set. |
190 std::unordered_map<RenderFrameHostId, | 202 std::unordered_map<RenderFrameHostId, |
191 content::PresentationConnectionPtr, | 203 std::unique_ptr<ControllerConnection>, |
192 RenderFrameHostIdHasher> | 204 RenderFrameHostIdHasher> |
193 pending_controllers_; | 205 pending_controllers_; |
194 | 206 |
195 DISALLOW_COPY_AND_ASSIGN(OffscreenPresentation); | 207 DISALLOW_COPY_AND_ASSIGN(OffscreenPresentation); |
196 }; | 208 }; |
197 | 209 |
198 private: | 210 private: |
199 friend class OffscreenPresentationManagerFactory; | 211 friend class OffscreenPresentationManagerFactory; |
200 friend class OffscreenPresentationManagerTest; | 212 friend class OffscreenPresentationManagerTest; |
| 213 friend class MockOffscreenPresentationManager; |
| 214 FRIEND_TEST_ALL_PREFIXES(PresentationServiceDelegateImplTest, |
| 215 ConnectToOffscreenPresentation); |
201 | 216 |
202 // Used by OffscreenPresentationManagerFactory::GetOrCreateForBrowserContext. | 217 // Used by OffscreenPresentationManagerFactory::GetOrCreateForBrowserContext. |
203 OffscreenPresentationManager(); | 218 OffscreenPresentationManager(); |
204 | 219 |
205 using OffscreenPresentationMap = | 220 using OffscreenPresentationMap = |
206 std::map<std::string, std::unique_ptr<OffscreenPresentation>>; | 221 std::map<std::string, std::unique_ptr<OffscreenPresentation>>; |
207 | 222 |
208 // Creates an offscreen presentation with |presentation_id| and | 223 // Creates an offscreen presentation with |presentation_id| and |
209 // |presentation_url|. | 224 // |presentation_url|. |
210 OffscreenPresentation* GetOrCreateOffscreenPresentation( | 225 OffscreenPresentation* GetOrCreateOffscreenPresentation( |
211 const std::string& presentation_id, | 226 const std::string& presentation_id, |
212 const GURL& presentation_url); | 227 const GURL& presentation_url); |
213 | 228 |
214 // Maps from presentation ID to OffscreenPresentation. | 229 // Maps from presentation ID to OffscreenPresentation. |
215 OffscreenPresentationMap offscreen_presentations_; | 230 OffscreenPresentationMap offscreen_presentations_; |
216 | 231 |
217 base::ThreadChecker thread_checker_; | 232 base::ThreadChecker thread_checker_; |
218 | 233 |
219 DISALLOW_COPY_AND_ASSIGN(OffscreenPresentationManager); | 234 DISALLOW_COPY_AND_ASSIGN(OffscreenPresentationManager); |
220 }; | 235 }; |
221 | 236 |
222 } // namespace media_router | 237 } // namespace media_router |
223 | 238 |
224 #endif // CHROME_BROWSER_MEDIA_ROUTER_OFFSCREEN_PRESENTATION_MANAGER_H_ | 239 #endif // CHROME_BROWSER_MEDIA_ROUTER_OFFSCREEN_PRESENTATION_MANAGER_H_ |
OLD | NEW |