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

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

Issue 1132903002: [MediaRouter] Add implementation of PresentationServiceDelegate (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 7 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 2014 The Chromium Authors. All rights reserved.
mark a. foltz 2015/05/11 07:36:21 Copyright
haibinlu 2015/05/13 01:40:19 Done.
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/presentation_service_delegate_impl.h"
6
7 #include <string>
8
9 #include "base/guid.h"
10 #include "base/strings/string_util.h"
11 #include "base/strings/stringprintf.h"
12 #include "chrome/browser/media/router/create_session_request.h"
13 #include "chrome/browser/media/router/media_route.h"
14 #include "chrome/browser/media/router/media_router.h"
15 #include "chrome/browser/media/router/media_router_impl.h"
mark a. foltz 2015/05/11 07:36:21 Why does this class need to know about the MR impl
haibinlu 2015/05/13 01:40:19 removed.
16 #include "chrome/browser/media/router/media_router_impl_factory.h"
17 #include "chrome/browser/media/router/media_sink.h"
18 #include "chrome/browser/media/router/media_source_helper.h"
19 #include "chrome/browser/media/router/presentation_helper.h"
20 #include "chrome/browser/media/router/presentation_media_sinks_observer.h"
21 #include "chrome/browser/sessions/session_tab_helper.h"
22 #include "chrome/browser/ui/webui/media_router/media_router_dialog_controller.h"
23 #include "content/public/browser/presentation_screen_availability_listener.h"
24 #include "content/public/browser/presentation_session.h"
25 #include "content/public/browser/render_frame_host.h"
26 #include "content/public/browser/render_process_host.h"
27
28 DEFINE_WEB_CONTENTS_USER_DATA_KEY(
29 media_router::PresentationServiceDelegateImpl);
30
31 using content::RenderFrameHost;
32
33 namespace media_router {
34
35 PresentationServiceDelegateImpl::PresentationServiceDelegateImpl(
36 content::WebContents* web_contents)
37 : num_observers_(0u),
38 web_contents_(web_contents),
39 router_(MediaRouterImplFactory::GetMediaRouterForBrowserContext(
40 web_contents_->GetBrowserContext())),
41 weak_factory_(this) {
42 DCHECK(router_);
43 }
44
45 PresentationServiceDelegateImpl::~PresentationServiceDelegateImpl() {
46 DCHECK(observers_.empty());
47 DCHECK_EQ(0u, num_observers_);
48
49 for (const auto& delegate_observer_entry : delegate_observers_)
50 delegate_observer_entry.second->OnDelegateDestroyed();
51 }
52
53 void PresentationServiceDelegateImpl::AddObserver(
54 int render_process_id,
55 int render_frame_id,
56 content::PresentationServiceDelegate::Observer* observer) {
57 DCHECK(observer);
58
59 RenderFrameHostId rfh_id(render_process_id, render_frame_id);
60 DCHECK(!ContainsKey(delegate_observers_, rfh_id));
61
62 delegate_observers_[rfh_id] = observer;
63 }
64
65 void PresentationServiceDelegateImpl::RemoveObserver(int render_process_id,
66 int render_frame_id) {
67 delegate_observers_.erase(
68 RenderFrameHostId(render_process_id, render_frame_id));
69 }
70
71 MediaSource PresentationServiceDelegateImpl::GetMediaSourceFromListener(
72 content::PresentationScreenAvailabilityListener* listener) {
73 // If the default presentation URL is empty then fall back to 1-UA mode,
74 // i.e. offscreeen tab rendering.
75 std::string presentation_url(listener->GetPresentationUrl());
76 return presentation_url.empty()
77 ? ForTabMediaSource(SessionTabHelper::IdForTab(web_contents_))
78 : ForPresentationUrl(presentation_url);
79 }
80
81 bool PresentationServiceDelegateImpl::AddScreenAvailabilityListener(
82 int render_process_id,
83 int routing_id,
84 content::PresentationScreenAvailabilityListener* listener) {
85 DCHECK(listener);
86
87 if (num_observers_ >= kMaxNumSources) {
88 return false;
89 }
90
91 RenderFrameHostId rfh_id(render_process_id, routing_id);
92 MediaSource source(GetMediaSourceFromListener(listener));
93 auto& observers_for_frame = observers_[rfh_id];
94 // Already exists.
95 if (ContainsKey(observers_for_frame, source.id()))
96 return false;
97
98 linked_ptr<PresentationMediaSinksObserver> observer(
99 new PresentationMediaSinksObserver(router_, listener, source));
100 observers_for_frame.insert(std::make_pair(source.id(), observer));
101 num_observers_++;
102 return true;
103 }
104
105 void PresentationServiceDelegateImpl::RemoveScreenAvailabilityListener(
106 int render_process_id,
107 int routing_id,
108 content::PresentationScreenAvailabilityListener* listener) {
109 DCHECK(listener);
110
111 RenderFrameHostId rfh_id(render_process_id, routing_id);
112 MediaSource source(GetMediaSourceFromListener(listener));
113 auto it = observers_.find(rfh_id);
114 if (it != observers_.end()) {
115 auto& observers_by_id = it->second;
116 auto observer_it = observers_by_id.find(source.id());
117 if (observer_it != observers_by_id.end()) {
118 observers_by_id.erase(observer_it);
119 num_observers_--;
120
121 if (observers_by_id.empty())
122 observers_.erase(it);
123 }
124 }
125 }
126
127 void PresentationServiceDelegateImpl::Reset(int render_process_id,
128 int routing_id) {
129 RenderFrameHostId rfh_id(render_process_id, routing_id);
130 UnregisterAllObserversFromFrame(rfh_id);
131 default_presentation_infos_.erase(rfh_id);
132 if (IsMainFrame(rfh_id))
133 UpdateDefaultMediaSourceAndNotifyObservers(MediaSource(), std::string());
134 }
135
136 void PresentationServiceDelegateImpl::SetDefaultPresentationUrl(
137 int render_process_id,
138 int render_frame_id,
139 const std::string& default_presentation_url,
140 const std::string& default_presentation_id) {
141 RenderFrameHostId rfh_id(render_process_id, render_frame_id);
142 if (default_presentation_url.empty() && default_presentation_id.empty()) {
143 default_presentation_infos_.erase(rfh_id);
144 } else {
145 default_presentation_infos_[rfh_id].reset(
146 new content::PresentationSessionInfo(default_presentation_url,
147 default_presentation_id));
148 }
149
150 if (IsMainFrame(rfh_id)) {
151 // This is the main frame, that means tab-level default presentation
152 // might have been updated.
153 MediaSource new_default_source;
154 if (!default_presentation_url.empty())
155 new_default_source = ForPresentationUrl(default_presentation_url);
156 std::string new_default_source_host(GetSourceHostForFrame(rfh_id));
157 UpdateDefaultMediaSourceAndNotifyObservers(new_default_source,
158 new_default_source_host);
159 }
160 }
161
162 bool PresentationServiceDelegateImpl::IsMainFrame(
163 RenderFrameHostId rfh_id) const {
164 RenderFrameHost* main_frame = web_contents_->GetMainFrame();
165 return main_frame && GetRenderFrameHostId(main_frame) == rfh_id;
166 }
167
168 void PresentationServiceDelegateImpl::
169 UpdateDefaultMediaSourceAndNotifyObservers(
170 const MediaSource& new_default_source,
171 const std::string& new_default_source_host) {
172 if (!new_default_source.Equals(default_source_) ||
173 new_default_source_host != default_source_host_) {
174 default_source_ = new_default_source;
175 default_source_host_ = new_default_source_host;
176 FOR_EACH_OBSERVER(
177 DefaultMediaSourceObserver, default_media_source_observers_,
178 OnDefaultMediaSourceChanged(default_source_, default_source_host_));
179 }
180 }
181
182 std::string PresentationServiceDelegateImpl::GetOrGeneratePresentationId(
183 RenderFrameHostId rfh_id,
184 const std::string& presentation_id) const {
185 if (!presentation_id.empty())
186 return presentation_id;
187
188 auto it = default_presentation_infos_.find(rfh_id);
189 if (it != default_presentation_infos_.end()) {
190 const std::string& default_presentation_id = it->second->presentation_id;
191 if (!default_presentation_id.empty())
192 return default_presentation_id;
193 }
194
195 return base::GenerateGUID();
196 }
197
198 void PresentationServiceDelegateImpl::StartSession(
199 int render_process_id,
200 int render_frame_id,
201 const std::string& presentation_url,
202 const std::string& presentation_id,
203 const PresentationSessionSuccessCallback& success_cb,
204 const PresentationSessionErrorCallback& error_cb) {
205 if (presentation_url.empty() || !IsValidPresentationUrl(presentation_url)) {
206 error_cb.Run(content::PresentationError(content::PRESENTATION_ERROR_UNKNOWN,
207 "Invalid presentation arguments."));
208 return;
209 }
210
211 RenderFrameHostId rfh_id(render_process_id, render_frame_id);
212 scoped_ptr<CreateSessionRequest> context(new CreateSessionRequest(
213 presentation_url, GetOrGeneratePresentationId(rfh_id, presentation_id),
214 GURL(GetSourceHostForFrame(rfh_id)), success_cb, error_cb));
215
216 // NOTE: Currently this request is ignored if a dialog is already open, e.g.
217 // via browser action. In practice, this should rarely happen, but log
218 // an error message in case it does.
219 MediaRouterDialogController* controller =
220 MediaRouterDialogController::GetInstance();
221 DCHECK(controller);
222 bool created = controller->ShowMediaRouterDialogForPresentation(
223 web_contents_, context.Pass());
224 if (!created) {
225 LOG(ERROR) << "Media router dialog already exists. Ignoring StartSession.";
226 error_cb.Run(content::PresentationError(content::PRESENTATION_ERROR_UNKNOWN,
227 "Unable to create dialog."));
228 return;
229 }
230 }
231
232 void PresentationServiceDelegateImpl::JoinSession(
233 int render_process_id,
234 int render_frame_id,
235 const std::string& presentation_url,
236 const std::string& presentation_id,
237 const PresentationSessionSuccessCallback& success_cb,
238 const PresentationSessionErrorCallback& error_cb) {
239 NOTIMPLEMENTED();
240 }
241
242 void PresentationServiceDelegateImpl::ListenForSessionMessages(
243 int render_process_id,
244 int render_frame_id,
245 const PresentationSessionMessageCallback& message_cb) {
246 NOTIMPLEMENTED();
247 }
248
249 void PresentationServiceDelegateImpl::OnRouteCreated(const MediaRoute& route) {
250 const MediaSource& source = route.media_source();
251 DCHECK(!source.Empty());
252 if (default_source_.Equals(source)) {
253 RenderFrameHost* main_frame = web_contents_->GetMainFrame();
254 if (main_frame) {
255 RenderFrameHostId rfh_id(GetRenderFrameHostId(main_frame));
256 auto it = delegate_observers_.find(rfh_id);
257 if (it != delegate_observers_.end()) {
258 // TODO(imcheng): Pass in valid default presentation ID once it is
259 // available from MediaRoute URN.
260 it->second->OnDefaultPresentationStarted(
261 content::PresentationSessionInfo(GetPresentationUrl(source),
262 std::string()));
263 }
264 }
265 }
266 }
267
268 MediaSource PresentationServiceDelegateImpl::GetDefaultMediaSource() const {
269 return default_source_;
270 }
271
272 std::string PresentationServiceDelegateImpl::GetSourceHostForFrame(
273 RenderFrameHostId rfh_id) const {
274 RenderFrameHost* rfh = RenderFrameHost::FromID(rfh_id.first, rfh_id.second);
275 DCHECK(rfh);
276 std::string host = rfh->GetLastCommittedURL().host();
277 if (StartsWithASCII(host, "www.", false))
278 host = host.substr(4);
279 return host;
280 }
281
282 void PresentationServiceDelegateImpl::UnregisterAllObserversFromFrame(
283 RenderFrameHostId rfh_id) {
284 auto it = observers_.find(rfh_id);
285 if (it != observers_.end()) {
286 auto& observers_by_id = it->second;
287 num_observers_ -= observers_by_id.size();
288 observers_.erase(it);
289 }
290 }
291
292 void PresentationServiceDelegateImpl::AddDefaultMediaSourceObserver(
293 DefaultMediaSourceObserver* observer) {
294 default_media_source_observers_.AddObserver(observer);
295 }
296
297 void PresentationServiceDelegateImpl::RemoveDefaultMediaSourceObserver(
298 DefaultMediaSourceObserver* observer) {
299 default_media_source_observers_.RemoveObserver(observer);
300 }
301
302 void PresentationServiceDelegateImpl::SetMediaRouterForTest(
303 MediaRouter* router) {
304 router_ = router;
305 }
306
307 // static
308 PresentationServiceDelegateImpl::RenderFrameHostId
309 PresentationServiceDelegateImpl::GetRenderFrameHostId(RenderFrameHost* rfh) {
310 int render_process_id = rfh->GetProcess()->GetID();
311 int routing_id = rfh->GetRoutingID();
312 return RenderFrameHostId(render_process_id, routing_id);
313 }
314
315 base::WeakPtr<PresentationServiceDelegateImpl>
316 PresentationServiceDelegateImpl::GetWeakPtr() {
317 return weak_factory_.GetWeakPtr();
318 }
319
320 } // namespace media_router
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698