Chromium Code Reviews| Index: chrome/browser/ui/webui/media_router/query_result_manager.cc |
| diff --git a/chrome/browser/ui/webui/media_router/query_result_manager.cc b/chrome/browser/ui/webui/media_router/query_result_manager.cc |
| index 132bd925c77bc8112298f6a1e27164516fffcd38..7e0159da0430ed2d00c65028e3df60cce3fd3b61 100644 |
| --- a/chrome/browser/ui/webui/media_router/query_result_manager.cc |
| +++ b/chrome/browser/ui/webui/media_router/query_result_manager.cc |
| @@ -4,6 +4,8 @@ |
| #include "chrome/browser/ui/webui/media_router/query_result_manager.h" |
| +#include <utility> |
| + |
| #include "base/containers/hash_tables.h" |
| #include "base/stl_util.h" |
| #include "chrome/browser/media/router/media_router.h" |
| @@ -13,7 +15,7 @@ |
| namespace media_router { |
| // MediaSinkObserver that propagates results back to |result_manager|. |
| -// An instance of this class is associated with each registered MediaCastMode. |
| +// An instance of this class is associated with each registered MediaSource. |
| class QueryResultManager::CastModeMediaSinksObserver |
| : public MediaSinksObserver { |
| public: |
| @@ -24,6 +26,7 @@ class QueryResultManager::CastModeMediaSinksObserver |
| QueryResultManager* result_manager) |
| : MediaSinksObserver(router, source, origin), |
| cast_mode_(cast_mode), |
| + source_(source), |
| result_manager_(result_manager) { |
| DCHECK(result_manager); |
| } |
| @@ -36,7 +39,7 @@ class QueryResultManager::CastModeMediaSinksObserver |
| for (const MediaSink& sink : result) { |
| latest_sink_ids_.push_back(sink.id()); |
| } |
| - result_manager_->UpdateWithSinksQueryResult(cast_mode_, result); |
| + result_manager_->UpdateWithSinksQueryResult(cast_mode_, source_, result); |
| result_manager_->NotifyOnResultsUpdated(); |
| } |
| @@ -50,6 +53,7 @@ class QueryResultManager::CastModeMediaSinksObserver |
| private: |
| const MediaCastMode cast_mode_; |
| + const MediaSource source_; |
| std::vector<MediaSink::Id> latest_sink_ids_; |
| QueryResultManager* const result_manager_; |
| }; |
| @@ -74,106 +78,145 @@ void QueryResultManager::RemoveObserver(Observer* observer) { |
| observers_.RemoveObserver(observer); |
| } |
| -void QueryResultManager::StartSinksQuery(MediaCastMode cast_mode, |
| - const MediaSource& source, |
| - const GURL& origin) { |
| +void QueryResultManager::StartSinksQuery( |
| + MediaCastMode cast_mode, |
| + const std::vector<MediaSource>& sources, |
| + const GURL& origin) { |
| DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| - if (source.Empty()) { |
| + if (sources.empty()) { |
| LOG(WARNING) << "StartSinksQuery called with empty source for " |
| << cast_mode; |
| return; |
| } |
| - SetSourceForCastMode(cast_mode, source); |
| - RemoveObserverForCastMode(cast_mode); |
| - UpdateWithSinksQueryResult(cast_mode, std::vector<MediaSink>()); |
| - |
| - std::unique_ptr<CastModeMediaSinksObserver> observer( |
| - new CastModeMediaSinksObserver(cast_mode, source, origin, router_, this)); |
| - observer->Init(); |
| - auto result = |
| - sinks_observers_.insert(std::make_pair(cast_mode, std::move(observer))); |
| - DCHECK(result.second); |
| + RemoveOldSourcesForCastMode(cast_mode, sources); |
| + RegisterNewObserversForCastMode(cast_mode, sources, origin); |
| + SetSourcesForCastMode(cast_mode, sources); |
| NotifyOnResultsUpdated(); |
| } |
| void QueryResultManager::StopSinksQuery(MediaCastMode cast_mode) { |
| DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| - RemoveObserverForCastMode(cast_mode); |
| - SetSourceForCastMode(cast_mode, MediaSource()); |
| - UpdateWithSinksQueryResult(cast_mode, std::vector<MediaSink>()); |
| + RemoveOldSourcesForCastMode(cast_mode, std::vector<MediaSource>()); |
| + cast_mode_sources_.erase(cast_mode); |
| NotifyOnResultsUpdated(); |
| } |
| -void QueryResultManager::SetSourceForCastMode( |
| - MediaCastMode cast_mode, const MediaSource& source) { |
| +CastModeSet QueryResultManager::GetSupportedCastModes() const { |
| + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| + CastModeSet modes; |
| + for (const auto& observer_pair : cast_mode_sources_) |
| + modes.insert(observer_pair.first); |
| + return modes; |
| +} |
| + |
| +MediaSource QueryResultManager::GetSourceForCastModeAndSink( |
| + MediaCastMode cast_mode, MediaSink::Id sink_id) const { |
| DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| - cast_mode_sources_[cast_mode] = source; |
| + for (const auto& sink_pair : all_sinks_) { |
| + if (sink_pair.first.id() == sink_id) { |
|
mark a. foltz
2016/08/31 05:18:55
You could create a MediaSink(sink_id) and lookup w
takumif
2016/09/01 21:09:26
Creating a dummy sink with fake description and ic
|
| + return GetHighestPrioritySourceForCastModeAndSink( |
| + cast_mode, sink_pair.first); |
| + } |
| + } |
| + return MediaSource(); |
| +} |
| + |
| +std::vector<MediaSource> QueryResultManager::GetSourcesForCastMode( |
| + MediaCastMode cast_mode) const { |
| + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| + return cast_mode_sources_.find(cast_mode) == cast_mode_sources_.end() ? |
|
mark a. foltz
2016/08/31 05:18:55
base::ContainsKey here and elsewhere to test map m
takumif
2016/09/01 21:09:26
Done.
|
| + std::vector<MediaSource>() : cast_mode_sources_.at(cast_mode); |
| } |
| -void QueryResultManager::RemoveObserverForCastMode(MediaCastMode cast_mode) { |
| - auto observers_it = sinks_observers_.find(cast_mode); |
| - if (observers_it != sinks_observers_.end()) |
| - sinks_observers_.erase(observers_it); |
| +void QueryResultManager::SetSourcesForCastMode( |
| + MediaCastMode cast_mode, const std::vector<MediaSource>& sources) { |
| + cast_mode_sources_[cast_mode] = sources; |
|
mark a. foltz
2016/08/31 05:18:55
Nit:
- What does it mean if |sources| is empty?
takumif
2016/09/01 21:09:26
Removed.
|
| } |
| -bool QueryResultManager::IsValid(const MediaSinkWithCastModes& entry) const { |
| - return !entry.cast_modes.empty(); |
| +void QueryResultManager::RemoveOldSourcesForCastMode( |
| + MediaCastMode cast_mode, const std::vector<MediaSource>& new_sources) { |
| + const std::vector<MediaSource> old_sources = |
|
mark a. foltz
2016/08/31 05:18:55
Slight preference for just an early return if ther
takumif
2016/09/01 21:09:26
Done.
|
| + cast_mode_sources_.find(cast_mode) == cast_mode_sources_.end() ? |
| + std::vector<MediaSource>() : cast_mode_sources_.at(cast_mode); |
| + |
| + for (const MediaSource& source : old_sources) { |
| + if (std::find(new_sources.begin(), new_sources.end(), source) == |
| + new_sources.end()) { |
| + sinks_observers_.erase(source); |
| + UpdateWithSinksQueryResult(cast_mode, source, std::vector<MediaSink>()); |
| + } |
| + } |
| +} |
| + |
| +void QueryResultManager::RegisterNewObserversForCastMode( |
| + MediaCastMode cast_mode, |
| + const std::vector<MediaSource>& sources, |
| + const GURL& origin) { |
| + for (const MediaSource& source : sources) { |
| + if (sinks_observers_.find(source) == sinks_observers_.end()) { |
| + std::unique_ptr<CastModeMediaSinksObserver> observer( |
| + new CastModeMediaSinksObserver( |
| + cast_mode, source, origin, router_, this)); |
| + observer->Init(); |
| + sinks_observers_[source] = std::move(observer); |
| + } |
| + } |
| } |
| void QueryResultManager::UpdateWithSinksQueryResult( |
| MediaCastMode cast_mode, |
| - const std::vector<MediaSink>& result) { |
| + MediaSource source, |
| + const std::vector<MediaSink>& result_sinks) { |
| base::hash_set<MediaSink::Id> result_sink_ids; |
| - for (const MediaSink& sink : result) |
| + for (const MediaSink& sink : result_sinks) |
| result_sink_ids.insert(sink.id()); |
| // (1) Iterate through current sink set, remove cast mode from those that |
| // do not appear in latest result. |
| for (auto it = all_sinks_.begin(); it != all_sinks_.end(); /*no-op*/) { |
| - if (!base::ContainsKey(result_sink_ids, it->first)) { |
| - it->second.cast_modes.erase(cast_mode); |
| - } |
| - if (!IsValid(it->second)) { |
| + const MediaSink& sink = it->first; |
| + if (!base::ContainsKey(result_sink_ids, sink.id())) |
| + all_sinks_[sink].RemoveSource(source, cast_mode); |
| + if (all_sinks_[sink].IsEmpty()) |
| all_sinks_.erase(it++); |
| - } else { |
| + else |
| ++it; |
| - } |
| } |
| + if (source.Empty()) |
| + return; |
| + |
| // (2) Add / update sinks with latest result. |
| - for (const MediaSink& sink : result) { |
| - auto result = |
| - all_sinks_.insert(std::make_pair(sink.id(), |
| - MediaSinkWithCastModes(sink))); |
| - if (!result.second) |
| - result.first->second.sink = sink; |
| - result.first->second.cast_modes.insert(cast_mode); |
| - } |
| + for (const MediaSink& sink : result_sinks) |
| + all_sinks_[sink].AddSource(source, cast_mode); |
| } |
| -CastModeSet QueryResultManager::GetSupportedCastModes() const { |
| - CastModeSet modes; |
| - for (const auto& observer_pair : sinks_observers_) |
| - modes.insert(observer_pair.first); |
| - return modes; |
| -} |
| +MediaSource QueryResultManager::GetHighestPrioritySourceForCastModeAndSink( |
| + MediaCastMode cast_mode, const MediaSink& sink) const { |
| + if (cast_mode_sources_.find(cast_mode) == cast_mode_sources_.end()) |
|
mark a. foltz
2016/08/31 05:18:55
Store the result from find() and use it below
takumif
2016/09/01 21:09:26
I used base::ContainsKey here instead.
|
| + return MediaSource(); |
|
mark a. foltz
2016/08/31 05:18:55
What does it mean to return an empty source here?
takumif
2016/09/01 21:09:25
I got rid of empty sources (and the default ctor)
|
| -MediaSource QueryResultManager::GetSourceForCastMode( |
| - MediaCastMode cast_mode) const { |
| - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| - auto source_it = cast_mode_sources_.find(cast_mode); |
| - return source_it == cast_mode_sources_.end() ? |
| - MediaSource() : source_it->second; |
| + for (const MediaSource source : cast_mode_sources_.at(cast_mode)) { |
| + if (all_sinks_.at(sink).HasSource(source, cast_mode)) |
| + return source; |
| + } |
| + return MediaSource(); |
|
mark a. foltz
2016/08/31 05:18:55
Ditto
|
| } |
| void QueryResultManager::NotifyOnResultsUpdated() { |
| std::vector<MediaSinkWithCastModes> sinks; |
| - for (const auto& sink_pair : all_sinks_) { |
| - sinks.push_back(sink_pair.second); |
| - } |
| + for (const auto& sink_pair : all_sinks_) |
| + sinks.push_back(GetMediaSinkWithCastModes(sink_pair.first)); |
| FOR_EACH_OBSERVER(QueryResultManager::Observer, observers_, |
| OnResultsUpdated(sinks)); |
| } |
| +MediaSinkWithCastModes QueryResultManager::GetMediaSinkWithCastModes( |
| + const MediaSink& sink) { |
| + MediaSinkWithCastModes sink_with_cast_modes(sink); |
| + sink_with_cast_modes.cast_modes = all_sinks_[sink].GetCastModes(); |
| + return sink_with_cast_modes; |
| +} |
| + |
| } // namespace media_router |