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

Side by Side Diff: chrome/browser/media/router/one_ua_presentation_router.cc

Issue 1314413005: [Presentation API] 1-UA presentation support + presenter APIs. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: 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 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 #include "chrome/browser/media/router/one_ua_presentation_router.h"
6
7 using content::PresentationSessionInfo;
8 using content::PresenterSessionAvailableCallback;
9
10 namespace media_router {
11
12 OneUAPresentationRouter::~OneUAPresentationRouter() {}
13
14 void OneUAPresentationRouter::RegisterPresenter(
15 const std::string& presentation_id,
16 const RenderFrameHostId& presenter_frame_id) {
17 DCHECK(!ContainsKey(presenter_frames_, presenter_frame_id));
18 presenter_frames_[presenter_frame_id] = presentation_id;
19
20 auto* presentation_info = GetOrCreateOneUAPresentationInfo(presentation_id);
21 presentation_info->presenter_frame_id = presenter_frame_id;
22 // We wait until the controller side has registered before setting up the
23 // route.
24 }
25
26 void OneUAPresentationRouter::UnregisterPresenter(
27 const RenderFrameHostId& presenter_frame_id) {
28 DCHECK(ContainsKey(presenter_frames_, presenter_frame_id));
29 auto it = presenter_frames_.find(presenter_frame_id);
30 std::string presentation_id = it->second;
31 presenter_frames_.erase(it);
32
33 auto* presentation_info = GetOneUAPresentationInfo(presentation_id);
34 DCHECK(presentation_info);
35 DCHECK(presenter_frame_id == presentation_info->presenter_frame_id);
36 RemovePresenterAndNotifyStateChange(presentation_info);
37 if (presentation_info->IsEmpty())
38 one_ua_presentations_.erase(presentation_id);
39 }
40
41 void OneUAPresentationRouter::RegisterController(
42 const content::PresentationSessionInfo& session,
43 const RenderFrameHostId& controller_frame_id) {
44 const std::string& presentation_id = session.presentation_id;
45 auto* presentation_info = GetOrCreateOneUAPresentationInfo(presentation_id);
46
47 auto& route = presentation_info->route;
48
49 // Check that this (presentation, controller) is not already registered.
50 DCHECK(!route.controller);
51 DCHECK(!route.presenter);
52
53 route.controller.reset(
54 new OneUAPresentationSession(controller_frame_id, session));
55 content::PresentationSessionInfo presenter_session(std::string(),
56 presentation_id);
57 route.presenter.reset(
58 new OneUAPresentationSession(controller_frame_id, presenter_session));
59
60 // Resolve pending getSession() request.
61 // Note: session objects for presenters do not contain presentation URLs.
62 if (!presentation_info->session_callback.is_null()) {
63 presentation_info->session_callback.Run(presenter_session);
64 presentation_info->session_callback.Reset();
65 }
66 }
67
68 void OneUAPresentationRouter::UnregisterController(
69 const std::string& presentation_id,
70 const RenderFrameHostId& controller_frame_id) {
71 auto* presentation_info = GetOneUAPresentationInfo(presentation_id);
72 DCHECK(presentation_info);
73 DCHECK(controller_frame_id ==
74 presentation_info->route.controller->controller_frame_id);
75 RemoveControllerAndNotifyStateChange(presentation_info);
76
77 if (presentation_info->IsEmpty())
78 one_ua_presentations_.erase(presentation_id);
79 }
80
81 bool OneUAPresentationRouter::IsPresenter(
82 const RenderFrameHostId& frame_id) const {
83 return ContainsKey(presenter_frames_, frame_id);
84 }
85
86 bool OneUAPresentationRouter::IsController(
87 const std::string& presentation_id,
88 const RenderFrameHostId& frame_id) const {
89 auto* presentation_info = GetOneUAPresentationInfo(presentation_id);
90 if (!presentation_info)
91 return false;
92
93 const auto& route = presentation_info->route;
94 if (!route.controller)
95 return false;
96 return frame_id == route.controller->controller_frame_id;
97 }
98
99 void OneUAPresentationRouter::GetSinglePresenterSession(
100 const RenderFrameHostId& presenter_frame_id,
101 const PresenterSessionAvailableCallback& callback) {
102 DCHECK(!callback.is_null());
103 DCHECK(IsPresenter(presenter_frame_id));
104
105 const std::string& presentation_id = presenter_frames_[presenter_frame_id];
106 auto* presentation_info = GetOneUAPresentationInfo(presentation_id);
107 DCHECK(presentation_info);
108 DCHECK(presenter_frame_id == presentation_info->presenter_frame_id);
109
110 // Resolve with the first route.
111 const auto& route = presentation_info->route;
112 if (route.presenter) {
113 callback.Run(route.presenter->session);
114 return;
115 } else {
116 presentation_info->session_callback = callback;
117 }
118 }
119
120 std::vector<content::PresentationSessionInfo>
121 OneUAPresentationRouter::GetPresenterSessions(
122 const RenderFrameHostId& presenter_frame_id) const {
123 DCHECK(IsPresenter(presenter_frame_id));
124
125 auto it = presenter_frames_.find(presenter_frame_id);
126 DCHECK(it != presenter_frames_.end());
127 const std::string& presentation_id = it->second;
128 auto* presentation_info = GetOneUAPresentationInfo(presentation_id);
129 DCHECK(presentation_info);
130
131 std::vector<content::PresentationSessionInfo> sessions;
132 // TODO(imcheng): Support multiple controllers.
133 if (presentation_info->route.presenter)
134 sessions.push_back(presentation_info->route.presenter->session);
135 return sessions;
136 }
137
138 void OneUAPresentationRouter::SendMessage(
139 const PresentationSessionInfo& session,
140 scoped_ptr<content::PresentationSessionMessage> message,
141 const content::SendMessageCallback& callback) {
142 const std::string& presentation_id = session.presentation_id;
143 auto* presentation_info = GetOneUAPresentationInfo(presentation_id);
144 if (!presentation_info) {
145 LOG(ERROR) << "SendMessage: Unknown 1UA presentation " << presentation_id;
146 callback.Run(false);
147 return;
148 }
149
150 bool from_presenter = session.presentation_url.empty();
151 auto& route = presentation_info->route;
152 // From presenter to controller.
153 if (from_presenter) {
154 auto* controller = route.controller.get();
155 if (controller && !controller->message_callback.is_null()) {
156 ScopedVector<content::PresentationSessionMessage> messages;
157 messages.push_back(message.release());
158 controller->message_callback.Run(messages.Pass(), true);
159 }
160 } else {
161 auto* presenter = route.presenter.get();
162 // From controller to presenter.
163 if (presenter && !presenter->message_callback.is_null()) {
164 ScopedVector<content::PresentationSessionMessage> messages;
165 messages.push_back(message.release());
166 presenter->message_callback.Run(messages.Pass(), true);
167 }
168 }
169
170 callback.Run(true);
171 }
172
173 void OneUAPresentationRouter::ListenForMessages(
174 const PresentationSessionInfo& session,
175 const content::PresentationSessionMessageCallback& callback) {
176 const std::string& presentation_id = session.presentation_id;
177 auto* presentation_info = GetOneUAPresentationInfo(presentation_id);
178 if (!presentation_info) {
179 LOG(ERROR) << "ListenForMessages: Unknown 1UA presentation "
180 << presentation_id;
181 return;
182 }
183
184 bool from_presenter = session.presentation_url.empty();
185 auto& route = presentation_info->route;
186 if (from_presenter) {
187 auto* presenter = route.presenter.get();
188 if (!presenter) {
189 LOG(ERROR) << "ListenForMessages: presenter frame not found for "
190 << presentation_id;
191 return;
192 }
193 DVLOG_IF(2, !presenter->message_callback.is_null())
194 << "Overwriting presenter frame message callback for "
195 << presentation_id;
196 presenter->message_callback = callback;
197 } else {
198 auto* controller = route.controller.get();
199 if (!controller) {
200 LOG(ERROR) << "ListenForMessages: controller frame not found for "
201 << presentation_id;
202 return;
203 }
204 DVLOG_IF(2, !controller->message_callback.is_null())
205 << "Overwriting controller frame message callback for "
206 << presentation_id;
207 controller->message_callback = callback;
208 }
209 }
210
211 void OneUAPresentationRouter::ListenForStateChanges(
212 const PresentationSessionInfo& session,
213 const content::SessionStateChangedCallback& callback) {
214 const std::string& presentation_id = session.presentation_id;
215 auto* presentation_info = GetOneUAPresentationInfo(presentation_id);
216 if (!presentation_info) {
217 LOG(ERROR) << "ListenForMessages: Unknown 1UA presentation "
218 << presentation_id;
219 return;
220 }
221
222 bool from_presenter = session.presentation_url.empty();
223 auto& route = presentation_info->route;
224 if (from_presenter) {
225 auto* presenter = route.presenter.get();
226 if (!presenter) {
227 LOG(ERROR) << "ListenForMessages: presenter frame not found for "
228 << presentation_id;
229 return;
230 }
231 DVLOG_IF(2, !presenter->state_change_callback.is_null())
232 << "Overwriting presenter frame state change callback for "
233 << presentation_id;
234 presenter->state_change_callback = callback;
235 } else {
236 auto* controller = route.controller.get();
237 if (!controller) {
238 LOG(ERROR) << "ListenForMessages: controller frame not found for "
239 << presentation_id;
240 return;
241 }
242 DVLOG_IF(2, !controller->state_change_callback.is_null())
243 << "Overwriting controller frame state change callback for "
244 << presentation_id;
245 controller->state_change_callback = callback;
246 }
247 }
248
249 void OneUAPresentationRouter::Reset(const RenderFrameHostId& frame_id) {
250 if (IsPresenter(frame_id))
251 UnregisterPresenter(frame_id);
252
253 for (auto it = one_ua_presentations_.begin();
254 it != one_ua_presentations_.end();
255 /* no-op */) {
256 auto* presentation_info = it->second;
257 auto* controller = presentation_info->route.controller.get();
258 if (controller && controller->controller_frame_id == frame_id) {
259 RemovePresenterAndNotifyStateChange(presentation_info);
260 if (presentation_info->IsEmpty())
261 one_ua_presentations_.erase(it++);
262 else
263 ++it;
264 } else {
265 ++it;
266 }
267 }
268 }
269
270 OneUAPresentationRouter::OneUAPresentationRouter() {}
271
272 void OneUAPresentationRouter::RemovePresenterAndNotifyStateChange(
273 OneUAPresentationInfo* presentation_info) {
274 presentation_info->presenter_frame_id = RenderFrameHostId();
275 presentation_info->session_callback.Reset();
276
277 auto& route = presentation_info->route;
278 if (route.presenter) {
279 route.presenter.reset();
280 auto& controller = route.controller;
281 if (controller && !controller->state_change_callback.is_null()) {
282 controller->state_change_callback.Run(
283 controller->session,
284 content::PRESENTATION_SESSION_STATE_DISCONNECTED);
285 }
286 }
287 }
288
289 void OneUAPresentationRouter::RemoveControllerAndNotifyStateChange(
290 OneUAPresentationInfo* presentation_info) {
291 auto& route = presentation_info->route;
292 route.controller.reset();
293
294 auto& presenter = route.presenter;
295 if (presenter && !presenter->state_change_callback.is_null()) {
296 presenter->state_change_callback.Run(
297 presenter->session, content::PRESENTATION_SESSION_STATE_DISCONNECTED);
298 }
299 }
300
301 OneUAPresentationRouter::OneUAPresentationInfo*
302 OneUAPresentationRouter::GetOrCreateOneUAPresentationInfo(
303 const std::string& presentation_id) {
304 OneUAPresentationInfo* info = nullptr;
305 auto presentation_info_it = one_ua_presentations_.find(presentation_id);
306 if (presentation_info_it == one_ua_presentations_.end()) {
307 info = new OneUAPresentationInfo;
308 one_ua_presentations_.insert(presentation_id, make_scoped_ptr(info));
309 } else {
310 info = presentation_info_it->second;
311 }
312 DCHECK(info);
313 return info;
314 }
315
316 OneUAPresentationRouter::OneUAPresentationInfo*
317 OneUAPresentationRouter::GetOneUAPresentationInfo(
318 const std::string& presentation_id) const {
319 OneUAPresentationInfo* info = nullptr;
320 auto presentation_info_it = one_ua_presentations_.find(presentation_id);
321 return presentation_info_it == one_ua_presentations_.end()
322 ? nullptr
323 : presentation_info_it->second;
324 }
325
326 OneUAPresentationRouter::OneUAPresentationSession::OneUAPresentationSession(
327 const RenderFrameHostId& controller_frame_id,
328 const content::PresentationSessionInfo& session)
329 : controller_frame_id(controller_frame_id), session(session) {}
330
331 OneUAPresentationRouter::OneUAPresentationSession::~OneUAPresentationSession() {
332 }
333
334 OneUAPresentationRouter::OneUAPresentationRoute::OneUAPresentationRoute() {}
335
336 OneUAPresentationRouter::OneUAPresentationRoute::~OneUAPresentationRoute() {}
337
338 OneUAPresentationRouter::OneUAPresentationInfo::OneUAPresentationInfo() {}
339
340 OneUAPresentationRouter::OneUAPresentationInfo::~OneUAPresentationInfo() {}
341
342 bool OneUAPresentationRouter::OneUAPresentationInfo::IsEmpty() const {
343 return !route.presenter && !route.controller;
344 }
345
346 } // namespace media_router
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698