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

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

Issue 2735493002: MediaRouter: Cache MediaRoutesObserver queries to prevent ext wake-ups (Closed)
Patch Set: nits Created 3 years, 9 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
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 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 #include "chrome/browser/media/router/mojo/media_router_mojo_impl.h" 5 #include "chrome/browser/media/router/mojo/media_router_mojo_impl.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <utility> 9 #include <utility>
10 10
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 const std::vector<url::Origin>& origins) { 178 const std::vector<url::Origin>& origins) {
179 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 179 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
180 DVLOG_WITH_INSTANCE(1) << "OnSinksReceived"; 180 DVLOG_WITH_INSTANCE(1) << "OnSinksReceived";
181 auto it = sinks_queries_.find(media_source); 181 auto it = sinks_queries_.find(media_source);
182 if (it == sinks_queries_.end()) { 182 if (it == sinks_queries_.end()) {
183 DVLOG_WITH_INSTANCE(1) << "Received sink list without MediaSinksQuery."; 183 DVLOG_WITH_INSTANCE(1) << "Received sink list without MediaSinksQuery.";
184 return; 184 return;
185 } 185 }
186 186
187 auto* sinks_query = it->second.get(); 187 auto* sinks_query = it->second.get();
188 sinks_query->has_cached_result = true; 188 sinks_query->cached_sink_list = sinks;
189 sinks_query->origins = origins; 189 sinks_query->origins = origins;
190 sinks_query->cached_sink_list = sinks;
191 190
192 if (!sinks_query->observers.might_have_observers()) { 191 if (sinks_query->observers.might_have_observers()) {
192 for (auto& observer : sinks_query->observers) {
193 observer.OnSinksUpdated(*sinks_query->cached_sink_list,
194 sinks_query->origins);
195 }
196 } else {
193 DVLOG_WITH_INSTANCE(1) 197 DVLOG_WITH_INSTANCE(1)
194 << "Received sink list without any active observers: " << media_source; 198 << "Received sink list without any active observers: " << media_source;
195 } else {
196 for (auto& observer : sinks_query->observers) {
197 observer.OnSinksUpdated(sinks_query->cached_sink_list,
198 sinks_query->origins);
199 }
200 } 199 }
201 } 200 }
202 201
203 void MediaRouterMojoImpl::OnRoutesUpdated( 202 void MediaRouterMojoImpl::OnRoutesUpdated(
204 const std::vector<MediaRoute>& routes, 203 const std::vector<MediaRoute>& routes,
205 const std::string& media_source, 204 const std::string& media_source,
206 const std::vector<std::string>& joinable_route_ids) { 205 const std::vector<std::string>& joinable_route_ids) {
207 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 206 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
208 207
209 DVLOG_WITH_INSTANCE(1) << "OnRoutesUpdated"; 208 DVLOG_WITH_INSTANCE(1) << "OnRoutesUpdated";
210 auto it = routes_queries_.find(media_source); 209 auto it = routes_queries_.find(media_source);
211 if (it == routes_queries_.end() || 210 if (it == routes_queries_.end() ||
212 !(it->second->observers.might_have_observers())) { 211 !(it->second->observers.might_have_observers())) {
213 DVLOG_WITH_INSTANCE(1) 212 DVLOG_WITH_INSTANCE(1)
214 << "Received route list without any active observers: " << media_source; 213 << "Received route list without any active observers: " << media_source;
215 return; 214 return;
216 } 215 }
217 216
218 for (auto& observer : it->second->observers) 217 auto* routes_query = it->second.get();
219 observer.OnRoutesUpdated(routes, joinable_route_ids); 218 routes_query->cached_route_list = routes;
219 routes_query->joinable_route_ids = joinable_route_ids;
220
221 if (routes_query->observers.might_have_observers()) {
222 for (auto& observer : routes_query->observers)
223 observer.OnRoutesUpdated(routes, joinable_route_ids);
224 } else {
225 DVLOG_WITH_INSTANCE(1)
226 << "Received routes update without any active observers: "
227 << media_source;
228 }
220 } 229 }
221 230
222 void MediaRouterMojoImpl::RouteResponseReceived( 231 void MediaRouterMojoImpl::RouteResponseReceived(
223 const std::string& presentation_id, 232 const std::string& presentation_id,
224 bool is_incognito, 233 bool is_incognito,
225 const std::vector<MediaRouteResponseCallback>& callbacks, 234 const std::vector<MediaRouteResponseCallback>& callbacks,
226 bool is_join, 235 bool is_join,
227 const base::Optional<MediaRoute>& media_route, 236 const base::Optional<MediaRoute>& media_route,
228 const base::Optional<std::string>& error_text, 237 const base::Optional<std::string>& error_text,
229 RouteRequestResult::ResultCode result_code) { 238 RouteRequestResult::ResultCode result_code) {
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
386 } 395 }
387 396
388 bool MediaRouterMojoImpl::RegisterMediaSinksObserver( 397 bool MediaRouterMojoImpl::RegisterMediaSinksObserver(
389 MediaSinksObserver* observer) { 398 MediaSinksObserver* observer) {
390 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 399 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
391 400
392 // Create an observer list for the media source and add |observer| 401 // Create an observer list for the media source and add |observer|
393 // to it. Fail if |observer| is already registered. 402 // to it. Fail if |observer| is already registered.
394 const std::string& source_id = observer->source().id(); 403 const std::string& source_id = observer->source().id();
395 std::unique_ptr<MediaSinksQuery>& sinks_query = sinks_queries_[source_id]; 404 std::unique_ptr<MediaSinksQuery>& sinks_query = sinks_queries_[source_id];
396 bool new_query = false; 405 bool is_new_query = false;
397 if (!sinks_query) { 406 if (!sinks_query) {
398 new_query = true; 407 is_new_query = true;
399 sinks_query = base::MakeUnique<MediaSinksQuery>(); 408 sinks_query = base::MakeUnique<MediaSinksQuery>();
400 } else { 409 } else {
401 DCHECK(!sinks_query->observers.HasObserver(observer)); 410 DCHECK(!sinks_query->observers.HasObserver(observer));
402 } 411 }
403 412
404 // If sink availability is UNAVAILABLE, then there is no need to call MRPM. 413 // If sink availability is UNAVAILABLE, then there is no need to call MRPM.
405 // |observer| can be immediately notified with an empty list. 414 // |observer| can be immediately notified with an empty list.
406 sinks_query->observers.AddObserver(observer); 415 sinks_query->observers.AddObserver(observer);
407 if (availability_ == mojom::MediaRouter::SinkAvailability::UNAVAILABLE) { 416 if (availability_ == mojom::MediaRouter::SinkAvailability::UNAVAILABLE) {
408 observer->OnSinksUpdated(std::vector<MediaSink>(), 417 observer->OnSinksUpdated(std::vector<MediaSink>(),
409 std::vector<url::Origin>()); 418 std::vector<url::Origin>());
410 } else { 419 } else {
411 // Need to call MRPM to start observing sinks if the query is new. 420 // Need to call MRPM to start observing sinks if the query is new.
412 if (new_query) { 421 if (is_new_query) {
413 SetWakeReason(MediaRouteProviderWakeReason::START_OBSERVING_MEDIA_SINKS); 422 SetWakeReason(MediaRouteProviderWakeReason::START_OBSERVING_MEDIA_SINKS);
414 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoStartObservingMediaSinks, 423 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoStartObservingMediaSinks,
415 base::Unretained(this), source_id)); 424 base::Unretained(this), source_id));
416 } else if (sinks_query->has_cached_result) { 425 } else if (sinks_query->cached_sink_list) {
417 observer->OnSinksUpdated(sinks_query->cached_sink_list, 426 observer->OnSinksUpdated(*sinks_query->cached_sink_list,
418 sinks_query->origins); 427 sinks_query->origins);
419 } 428 }
420 } 429 }
421 return true; 430 return true;
422 } 431 }
423 432
424 void MediaRouterMojoImpl::UnregisterMediaSinksObserver( 433 void MediaRouterMojoImpl::UnregisterMediaSinksObserver(
425 MediaSinksObserver* observer) { 434 MediaSinksObserver* observer) {
426 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 435 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
427 436
(...skipping 24 matching lines...) Expand all
452 sinks_queries_.erase(source_id); 461 sinks_queries_.erase(source_id);
453 } 462 }
454 } 463 }
455 } 464 }
456 465
457 void MediaRouterMojoImpl::RegisterMediaRoutesObserver( 466 void MediaRouterMojoImpl::RegisterMediaRoutesObserver(
458 MediaRoutesObserver* observer) { 467 MediaRoutesObserver* observer) {
459 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 468 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
460 const MediaSource::Id source_id = observer->source_id(); 469 const MediaSource::Id source_id = observer->source_id();
461 auto& routes_query = routes_queries_[source_id]; 470 auto& routes_query = routes_queries_[source_id];
471 bool is_new_query = false;
462 if (!routes_query) { 472 if (!routes_query) {
473 is_new_query = true;
463 routes_query = base::MakeUnique<MediaRoutesQuery>(); 474 routes_query = base::MakeUnique<MediaRoutesQuery>();
464 } else { 475 } else {
465 DCHECK(!routes_query->observers.HasObserver(observer)); 476 DCHECK(!routes_query->observers.HasObserver(observer));
466 } 477 }
467 478
468 routes_query->observers.AddObserver(observer); 479 routes_query->observers.AddObserver(observer);
469 SetWakeReason(MediaRouteProviderWakeReason::START_OBSERVING_MEDIA_ROUTES); 480 if (is_new_query) {
470 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoStartObservingMediaRoutes, 481 SetWakeReason(MediaRouteProviderWakeReason::START_OBSERVING_MEDIA_ROUTES);
471 base::Unretained(this), source_id)); 482 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoStartObservingMediaRoutes,
483 base::Unretained(this), source_id));
484 // The MRPM will call MediaRouterMojoImpl::OnRoutesUpdated() soon, if there
485 // are any existing routes the new observer should be aware of.
486 } else if (routes_query->cached_route_list) {
487 // Return to the event loop before notifying of a cached route list because
488 // MediaRoutesObserver is calling this method from its constructor, and that
489 // must complete before invoking its virtual OnRoutesUpdated() method.
490 content::BrowserThread::PostTask(
491 content::BrowserThread::UI, FROM_HERE,
492 base::Bind(&MediaRouterMojoImpl::NotifyOfExistingRoutesIfRegistered,
493 weak_factory_.GetWeakPtr(), source_id, observer));
494 }
495 }
496
497 void MediaRouterMojoImpl::NotifyOfExistingRoutesIfRegistered(
498 const MediaSource::Id& source_id,
499 MediaRoutesObserver* observer) const {
500 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
501
502 // Check that the route query still exists with a cached result, and that the
503 // observer is still registered. Otherwise, there is nothing to report to the
504 // observer.
505 const auto it = routes_queries_.find(source_id);
506 if (it == routes_queries_.end() || !it->second->cached_route_list ||
507 !it->second->observers.HasObserver(observer)) {
508 return;
509 }
510
511 observer->OnRoutesUpdated(*it->second->cached_route_list,
512 it->second->joinable_route_ids);
472 } 513 }
473 514
474 void MediaRouterMojoImpl::UnregisterMediaRoutesObserver( 515 void MediaRouterMojoImpl::UnregisterMediaRoutesObserver(
475 MediaRoutesObserver* observer) { 516 MediaRoutesObserver* observer) {
476 const MediaSource::Id source_id = observer->source_id(); 517 const MediaSource::Id source_id = observer->source_id();
477 auto it = routes_queries_.find(source_id); 518 auto it = routes_queries_.find(source_id);
478 if (it == routes_queries_.end() || 519 if (it == routes_queries_.end() ||
479 !it->second->observers.HasObserver(observer)) { 520 !it->second->observers.HasObserver(observer)) {
480 return; 521 return;
481 } 522 }
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
678 SinkAvailability availability) { 719 SinkAvailability availability) {
679 if (availability_ == availability) 720 if (availability_ == availability)
680 return; 721 return;
681 722
682 availability_ = availability; 723 availability_ = availability;
683 if (availability_ == mojom::MediaRouter::SinkAvailability::UNAVAILABLE) { 724 if (availability_ == mojom::MediaRouter::SinkAvailability::UNAVAILABLE) {
684 // Sinks are no longer available. MRPM has already removed all sink queries. 725 // Sinks are no longer available. MRPM has already removed all sink queries.
685 for (auto& source_and_query : sinks_queries_) { 726 for (auto& source_and_query : sinks_queries_) {
686 const auto& query = source_and_query.second; 727 const auto& query = source_and_query.second;
687 query->is_active = false; 728 query->is_active = false;
688 query->has_cached_result = false; 729 query->cached_sink_list = base::nullopt;
689 query->cached_sink_list.clear();
690 query->origins.clear(); 730 query->origins.clear();
691 } 731 }
692 } else { 732 } else {
693 // Sinks are now available. Tell MRPM to start all sink queries again. 733 // Sinks are now available. Tell MRPM to start all sink queries again.
694 for (const auto& source_and_query : sinks_queries_) { 734 for (const auto& source_and_query : sinks_queries_) {
695 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoStartObservingMediaSinks, 735 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoStartObservingMediaSinks,
696 base::Unretained(this), source_and_query.first)); 736 base::Unretained(this), source_and_query.first));
697 } 737 }
698 } 738 }
699 } 739 }
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
929 base::Unretained(this), source_id)); 969 base::Unretained(this), source_id));
930 } 970 }
931 971
932 void MediaRouterMojoImpl::DoUpdateMediaSinks( 972 void MediaRouterMojoImpl::DoUpdateMediaSinks(
933 const MediaSource::Id& source_id) { 973 const MediaSource::Id& source_id) {
934 DVLOG_WITH_INSTANCE(1) << "DoUpdateMediaSinks" << source_id; 974 DVLOG_WITH_INSTANCE(1) << "DoUpdateMediaSinks" << source_id;
935 media_route_provider_->UpdateMediaSinks(source_id); 975 media_route_provider_->UpdateMediaSinks(source_id);
936 } 976 }
937 977
938 } // namespace media_router 978 } // namespace media_router
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698