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

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

Issue 1055403006: Upstreaming review for Media Router Mojo interface. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Incorporate latest changes to MR API. 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.
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/media_router_mojo_impl.h"
6
7 #include <map>
8
9 #include "base/bind.h"
10 #include "base/guid.h"
11 #include "base/logging.h"
12 #include "base/observer_list.h"
13 #include "chrome/browser/media/router/media_router_impl.h"
14 #include "chrome/browser/media/router/media_router_impl_factory.h"
15 #include "chrome/browser/media/router/media_router_mojo_impl_factory.h"
16 #include "chrome/browser/media/router/media_router_type_converters.h"
17 #include "chrome/browser/media/router/media_routes_observer.h"
18 #include "chrome/browser/media/router/media_sinks_observer.h"
19 #include "extensions/browser/process_manager.h"
20
21 #define DVLOG_WITH_INSTANCE(level) \
22 DVLOG(level) << "MR #" << instance_id_ << ": "
23
24 namespace media_router {
25 namespace {
26
27 void CreateRouteFinished(const MediaSinkId& sink_id,
28 const MediaRouteResponseCallback& callback,
29 interfaces::MediaRoutePtr media_route,
30 const mojo::String& error_text) {
31 if (media_route.is_null()) {
32 // An error occurred.
33 DCHECK(!error_text.is_null());
34 callback.Run(nullptr, (!error_text.get().empty() ? error_text.get()
35 : "Unknown error."));
36 return;
37 }
38 callback.Run(make_scoped_ptr(new MediaRoute(media_route.To<MediaRoute>())),
39 "");
40 }
41
42 void EventPageWakeComplete(bool success) {
43 if (!success)
44 LOG(ERROR) << "An error encountered while waking the event page.";
45 }
46
47 } // namespace
48
49 MediaRouterMojoImpl::MediaRouterMojoImpl()
50 : event_page_tracker_(nullptr), instance_id_(base::GenerateGUID()) {
51 }
52
53 MediaRouterMojoImpl::MediaRouterMojoImpl(
54 const std::string& mrpm_extension_id,
55 extensions::EventPageTracker* event_page_tracker_for_test)
56 : MediaRouterMojoImpl() {
57 DCHECK(!mrpm_extension_id.empty());
58 DCHECK(event_page_tracker_for_test);
59 mrpm_extension_id_ = mrpm_extension_id;
60 event_page_tracker_ = event_page_tracker_for_test;
61 }
62
63 MediaRouterMojoImpl::~MediaRouterMojoImpl() {
64 DCHECK(thread_checker_.CalledOnValidThread());
65 }
66
67 // static
68 void MediaRouterMojoImpl::BindToRequest(
69 const std::string& extension_id,
70 content::BrowserContext* context,
71 mojo::InterfaceRequest<interfaces::MediaRouterObserver> request) {
72 MediaRouterMojoImpl* impl =
73 MediaRouterMojoImplFactory::GetApiForBrowserContext(context);
74 DCHECK(impl);
75 impl->Bind(request.Pass());
76 impl->MonitorExtension(extension_id, context);
77 }
78
79 void MediaRouterMojoImpl::Bind(
80 mojo::InterfaceRequest<interfaces::MediaRouterObserver> request) {
81 DCHECK(thread_checker_.CalledOnValidThread());
82 binding_.reset(
83 new mojo::Binding<interfaces::MediaRouterObserver>(this, request.Pass()));
84 binding_->set_error_handler(this);
85 }
86
87 void MediaRouterMojoImpl::OnConnectionError() {
88 DCHECK(thread_checker_.CalledOnValidThread());
89 mrpm_.reset();
90 binding_.reset();
91 }
92
93 void MediaRouterMojoImpl::ProvideMediaRouter(
94 interfaces::MediaRouterPtr mrpm,
95 const interfaces::MediaRouterObserver::ProvideMediaRouterCallback&
96 callback) {
97 DCHECK(thread_checker_.CalledOnValidThread());
98 mrpm_ = mrpm.Pass();
99 mrpm_.set_error_handler(this);
100 callback.Run(instance_id_);
101 ExecutePendingRequests();
102 }
103
104 void MediaRouterMojoImpl::OnMessage(const mojo::String& route_id,
105 const mojo::String& message) {
106 DCHECK(thread_checker_.CalledOnValidThread());
107 NOTIMPLEMENTED();
108 }
109
110 void MediaRouterMojoImpl::OnIssue(const interfaces::IssuePtr issue) {
111 DCHECK(thread_checker_.CalledOnValidThread());
112 NOTIMPLEMENTED();
113 }
114
115 void MediaRouterMojoImpl::OnSinksReceived(
116 const mojo::String& media_source,
117 mojo::Array<interfaces::MediaSinkPtr> sinks) {
118 DCHECK(thread_checker_.CalledOnValidThread());
119 DVLOG_WITH_INSTANCE(1) << "OnSinksReceived";
120 std::vector<MediaSink> sinks_converted;
121 sinks_converted.reserve(sinks.size());
122
123 for (size_t i = 0; i < sinks.size(); ++i) {
124 sinks_converted.push_back(sinks[i].To<MediaSink>());
125 }
126
127 auto it = sinks_observers_.find(media_source);
128 if (it == sinks_observers_.end()) {
129 DVLOG_WITH_INSTANCE(1)
130 << "Received sink list without any active observers: " << media_source;
131 } else {
132 FOR_EACH_OBSERVER(MediaSinksObserver, *it->second,
133 OnSinksReceived(sinks_converted));
134 }
135 }
136
137 void MediaRouterMojoImpl::OnRoutesUpdated(
138 mojo::Array<interfaces::MediaRoutePtr> routes) {
139 DCHECK(thread_checker_.CalledOnValidThread());
140 DVLOG_WITH_INSTANCE(1) << "OnRoutesUpdated";
141
142 std::vector<MediaRoute> routes_converted;
143 routes_converted.reserve(routes.size());
144
145 for (size_t i = 0; i < routes.size(); ++i) {
146 routes_converted.push_back(routes[i].To<MediaRoute>());
147 }
148
149 FOR_EACH_OBSERVER(MediaRoutesObserver, routes_observers_,
150 OnRoutesUpdated(routes_converted));
151 }
152
153 // ----------------------------------------------------------------------------
154 // MediaRouter methods.
155
156 void MediaRouterMojoImpl::CreateRoute(
157 const MediaSourceId& source_id,
158 const MediaSinkId& sink_id,
159 const MediaRouteResponseCallback& callback) {
160 DCHECK(thread_checker_.CalledOnValidThread());
161 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoCreateRoute,
162 base::Unretained(this), source_id, sink_id, callback));
163 }
164
165 void MediaRouterMojoImpl::CloseRoute(const MediaRouteId& route_id) {
166 DCHECK(thread_checker_.CalledOnValidThread());
167 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoCloseRoute,
168 base::Unretained(this), route_id));
169 }
170
171 void MediaRouterMojoImpl::PostMessage(const MediaRouteId& route_id,
172 const std::string& message) {
173 DCHECK(thread_checker_.CalledOnValidThread());
174 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoPostMessage,
175 base::Unretained(this), route_id, message));
176 }
177
178 void MediaRouterMojoImpl::ClearIssue(const Issue::IssueId& issue_id) {
179 DCHECK(thread_checker_.CalledOnValidThread());
180 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoClearIssue,
181 base::Unretained(this), issue_id));
182 }
183
184 bool MediaRouterMojoImpl::RegisterMediaSinksObserver(
185 MediaSinksObserver* observer) {
186 DCHECK(thread_checker_.CalledOnValidThread());
187
188 // Lazily create an observer list for the media source and add |observer|
189 // to it.
190 const std::string& source_id = observer->source().id();
191 linked_ptr<ObserverList<MediaSinksObserver>> observer_list =
192 sinks_observers_[source_id];
193 if (!observer_list.get()) {
194 observer_list = make_linked_ptr(new ObserverList<MediaSinksObserver>);
195 sinks_observers_[source_id] = observer_list;
196 } else {
197 if (observer_list->HasObserver(observer)) {
198 DLOG(FATAL) << "Redundant RegisterMediaSinksObserver call detected.";
199 return true;
200 }
201 }
202
203 // Turn on sink observation if this is the first time we've started observing
204 // sinks for the media source.
205 if (!observer_list->might_have_observers()) {
206 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoStartObservingMediaSinks,
207 base::Unretained(this), source_id));
208 }
209 observer_list->AddObserver(observer);
210
211 return true;
212 }
213
214 void MediaRouterMojoImpl::UnregisterMediaSinksObserver(
215 MediaSinksObserver* observer) {
216 DCHECK(thread_checker_.CalledOnValidThread());
217
218 const std::string& source_id = observer->source().id();
219 const auto observer_list_it = sinks_observers_.find(source_id);
220 if (observer_list_it == sinks_observers_.end() ||
221 !observer_list_it->second->HasObserver(observer)) {
222 return;
223 }
224 observer_list_it->second->RemoveObserver(observer);
225
226 // If we are removing the final observer for the source, then stop
227 // observing sinks.
228 if (!observer_list_it->second->might_have_observers()) {
229 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoStopObservingMediaSinks,
230 base::Unretained(this), source_id));
231 sinks_observers_.erase(observer_list_it);
232 }
233 }
234
235 bool MediaRouterMojoImpl::RegisterMediaRoutesObserver(
236 MediaRoutesObserver* observer) {
237 DCHECK(thread_checker_.CalledOnValidThread());
238 if (!routes_observers_.HasObserver(observer)) {
239 DLOG(FATAL) << "Redundant RegisterMediaRoutesObserver() call detected.";
240 return true;
241 }
242
243 // TODO(kmarshall): add result caching and max limits.
244 if (!routes_observers_.might_have_observers()) {
245 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoStartObservingMediaRoutes,
246 base::Unretained(this)));
247 }
248 routes_observers_.AddObserver(observer);
249 return true;
250 }
251
252 void MediaRouterMojoImpl::UnregisterMediaRoutesObserver(
253 MediaRoutesObserver* observer) {
254 if (!routes_observers_.HasObserver(observer)) {
255 return;
256 }
257 routes_observers_.RemoveObserver(observer);
258 if (!routes_observers_.might_have_observers()) {
259 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoStopObservingMediaRoutes,
260 base::Unretained(this)));
261 }
262 }
263
264 void MediaRouterMojoImpl::AddIssuesObserver(IssuesObserver* observer) {
265 NOTIMPLEMENTED(); // TODO(kmarshall): To be landed in a separate CL.
266 }
267
268 void MediaRouterMojoImpl::RemoveIssuesObserver(IssuesObserver* observer) {
269 NOTIMPLEMENTED();
270 }
271
272 void MediaRouterMojoImpl::DoCreateRoute(
273 const MediaSourceId& source_id,
274 const MediaSinkId& sink_id,
275 const MediaRouteResponseCallback& callback) {
276 DCHECK(thread_checker_.CalledOnValidThread());
277 DCHECK(mrpm_);
278 DVLOG_WITH_INSTANCE(1) << "CreateRoute " << source_id << "=>" << sink_id;
279 mrpm_->CreateRoute(source_id, sink_id,
280 base::Bind(&CreateRouteFinished, sink_id, callback));
281 }
282
283 void MediaRouterMojoImpl::DoCloseRoute(const MediaRouteId& route_id) {
284 DCHECK(thread_checker_.CalledOnValidThread());
285 DCHECK(mrpm_);
286 DVLOG_WITH_INSTANCE(1) << "CloseRoute " << route_id;
287 mrpm_->CloseRoute(route_id);
288 }
289
290 void MediaRouterMojoImpl::DoPostMessage(const MediaRouteId& route_id,
291 const std::string& message) {
292 DCHECK(thread_checker_.CalledOnValidThread());
293 DCHECK(mrpm_);
294 DVLOG_WITH_INSTANCE(1) << "PostMessage " << route_id;
295 mrpm_->PostMessage(route_id, message);
296 }
297
298 void MediaRouterMojoImpl::DoClearIssue(const Issue::IssueId& issue_id) {
299 DCHECK(thread_checker_.CalledOnValidThread());
300 DCHECK(mrpm_);
301 DVLOG_WITH_INSTANCE(1) << "ClearIssue " << issue_id;
302 mrpm_->ClearIssue(issue_id);
303 }
304
305 void MediaRouterMojoImpl::DoStartObservingMediaSinks(
306 const std::string& source_id) {
307 DCHECK(thread_checker_.CalledOnValidThread());
308 DCHECK(mrpm_);
309 DVLOG_WITH_INSTANCE(1) << "StartObservingMediaSinks: " << source_id;
310 mrpm_->StartObservingMediaSinks(source_id);
311 }
312
313 void MediaRouterMojoImpl::DoStopObservingMediaSinks(
314 const std::string& source_id) {
315 DCHECK(thread_checker_.CalledOnValidThread());
316 DCHECK(mrpm_);
317 DVLOG_WITH_INSTANCE(1) << "StopObservingMediaSinks: " << source_id;
318 mrpm_->StopObservingMediaSinks(source_id);
319 }
320
321 void MediaRouterMojoImpl::DoStartObservingMediaRoutes() {
322 DCHECK(thread_checker_.CalledOnValidThread());
323 DCHECK(mrpm_);
324 DVLOG_WITH_INSTANCE(1) << "StartObservingMediaRoutes";
325 mrpm_->StartObservingMediaRoutes();
326 }
327
328 void MediaRouterMojoImpl::DoStopObservingMediaRoutes() {
329 DCHECK(thread_checker_.CalledOnValidThread());
330 DCHECK(mrpm_);
331 DVLOG_WITH_INSTANCE(1) << "StopObservingMediaRoutes";
332 mrpm_->StopObservingMediaRoutes();
333 }
334
335 void MediaRouterMojoImpl::EnqueueTask(const base::Closure& closure) {
336 DVLOG_WITH_INSTANCE(2) << "EnqueueTask (size=" << pending_requests_.size()
337 << ")";
338 pending_requests_.push_back(closure);
339 }
340
341 void MediaRouterMojoImpl::MonitorExtension(const std::string& extension_id,
342 content::BrowserContext* context) {
343 DCHECK(thread_checker_.CalledOnValidThread());
344 DCHECK(!extension_id.empty());
345 DCHECK(context);
346 mrpm_extension_id_ = extension_id;
347 event_page_tracker_ = extensions::ProcessManager::Get(context);
348 }
349
350 void MediaRouterMojoImpl::RunOrDefer(const base::Closure& request_cb) {
351 DCHECK(event_page_tracker_);
352 if (event_page_tracker_->IsEventPageSuspended(mrpm_extension_id_)) {
353 DVLOG(1) << "Waking event page.";
354 pending_requests_.push_back(request_cb);
355 if (!event_page_tracker_->WakeEventPage(
356 mrpm_extension_id_, base::Bind(&EventPageWakeComplete))) {
357 LOG(ERROR) << "An error encountered while waking the event page.";
358 }
359 mrpm_.reset();
360 } else if (!mrpm_) {
361 DVLOG(1) << "Extension is awake, awaiting MRPM connection.";
362 pending_requests_.push_back(request_cb);
363 } else {
364 request_cb.Run();
365 }
366 }
367
368 void MediaRouterMojoImpl::ExecutePendingRequests() {
369 DCHECK(thread_checker_.CalledOnValidThread());
370 DCHECK(mrpm_);
371 DCHECK(event_page_tracker_);
372 if (event_page_tracker_->IsEventPageSuspended(mrpm_extension_id_)) {
373 DVLOG_WITH_INSTANCE(1)
374 << "ExecutePendingRequests was called while extension is suspended.";
375 return;
376 }
377
378 for (const auto& next_request : pending_requests_) {
379 next_request.Run();
380 }
381 pending_requests_.clear();
382 }
383
384 } // namespace media_router
OLDNEW
« no previous file with comments | « chrome/browser/media/router/media_router_mojo_impl.h ('k') | chrome/browser/media/router/media_router_mojo_impl_factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698