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

Unified Diff: chrome/browser/ui/webui/media_router/query_result_manager.cc

Issue 1131913003: Adds QueryResultManager support class for Media Router Dialog WebUI (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix copyrights. 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 side-by-side diff with in-line comments
Download patch
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
new file mode 100644
index 0000000000000000000000000000000000000000..7441b36c3213d1b63ab2499ad829b6a356135bbd
--- /dev/null
+++ b/chrome/browser/ui/webui/media_router/query_result_manager.cc
@@ -0,0 +1,167 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/webui/media_router/query_result_manager.h"
+
+#include "base/stl_util.h"
+#include "chrome/browser/media/router/media_router.h"
+
+namespace media_router {
+
+QueryResultManager::QueryResultManager(MediaRouter* router) : router_(router) {
+ DCHECK(router_);
+}
+
+QueryResultManager::~QueryResultManager() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+}
+
+void QueryResultManager::AddObserver(Observer* observer) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(observer);
+ observers_.AddObserver(observer);
+}
+
+void QueryResultManager::RemoveObserver(Observer* observer) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(observer);
+ observers_.RemoveObserver(observer);
+}
+
+void QueryResultManager::StartSinksQuery(MediaCastMode cast_mode,
+ const MediaSource& source) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(!source.Empty());
+ if (source.Empty()) {
Bernhard Bauer 2015/05/08 08:34:33 If you have a DCHECK for the inverse condition rig
mark a. foltz 2015/05/12 06:23:14 Yeah, this is a bug but not a terminal condition.
+ LOG(WARNING) << "StartSinksQuery called with empty source for "
+ << cast_mode;
+ return;
+ }
+
+ SetSourceForCastMode(cast_mode, source);
+ RemoveObserverForCastMode(cast_mode);
+ UpdateWithSinksQueryResult(cast_mode, std::vector<MediaSink>());
+
+ linked_ptr<CastModeMediaSinksObserver> observer(
+ new CastModeMediaSinksObserver(cast_mode, source, router_, this));
+ auto result = sinks_observers_.insert(std::make_pair(cast_mode, observer));
+ CHECK(result.second);
Bernhard Bauer 2015/05/08 08:34:33 Unless there is a specific reason (like avoiding s
mark a. foltz 2015/05/12 06:23:14 Done.
+ NotifyOnResultsUpdated();
+}
+
+void QueryResultManager::StopSinksQuery(MediaCastMode cast_mode) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ RemoveObserverForCastMode(cast_mode);
+ SetSourceForCastMode(cast_mode, MediaSource());
+ UpdateWithSinksQueryResult(cast_mode, std::vector<MediaSink>());
+ NotifyOnResultsUpdated();
+}
+
+void QueryResultManager::SetSourceForCastMode(
+ MediaCastMode cast_mode, const MediaSource& source) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ cast_mode_sources_[cast_mode] = source;
+}
+
+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);
+}
+
+bool QueryResultManager::IsValid(const MediaSinkWithCastModes& entry) const {
+ return !entry.cast_modes.empty();
+}
+
+void QueryResultManager::UpdateWithSinksQueryResult(
+ MediaCastMode cast_mode,
+ const std::vector<MediaSink>& result) {
+ base::hash_set<MediaSinkId> result_sink_ids;
Bernhard Bauer 2015/05/08 08:34:33 You could call the constructor with result.begin()
mark a. foltz 2015/05/12 06:23:14 We are inserting sink.id() not just the sinks.
Bernhard Bauer 2015/05/12 09:34:33 Oh, right.
+ for (const MediaSink& sink : result) {
+ 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 (!ContainsKey(result_sink_ids, it->first)) {
+ it->second.cast_modes.erase(cast_mode);
+ }
+ if (!IsValid(it->second)) {
+ all_sinks_.erase(it++);
Bernhard Bauer 2015/05/08 08:34:33 Whoa... is deleting elements from a hash set while
mark a. foltz 2015/05/12 06:23:14 This is deleting from the all_sinks_ std::map, not
Bernhard Bauer 2015/05/12 09:34:33 Oh, you're right, you iterate over the map. That's
+ } else {
+ ++it;
+ }
+ }
+
+ // (2) Add / update sinks with latest result.
+ for (const MediaSink& sink : result) {
+ auto all_sinks_it = all_sinks_.find(sink.id());
+ if (all_sinks_it == all_sinks_.end()) {
+ all_sinks_it = all_sinks_.insert(
Bernhard Bauer 2015/05/08 08:34:33 insert() will actually already do pretty much what
mark a. foltz 2015/05/12 06:23:14 Done.
+ std::make_pair(sink.id(), MediaSinkWithCastModes(sink))).first;
+ }
+ all_sinks_it->second.sink = sink;
Bernhard Bauer 2015/05/08 08:34:33 Is this necessary if you have just inserted a new
mark a. foltz 2015/05/12 06:23:14 Done.
+ all_sinks_it->second.cast_modes.insert(cast_mode);
+ }
+}
+
+void QueryResultManager::GetSupportedCastModes(CastModeSet* cast_modes) const {
+ DCHECK(cast_modes);
+ cast_modes->clear();
+ for (const auto& observer_pair : sinks_observers_) {
+ cast_modes->insert(observer_pair.first);
+ }
+}
+
+MediaSource QueryResultManager::GetSourceForCastMode(
+ MediaCastMode cast_mode) const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ auto source_it = cast_mode_sources_.find(cast_mode);
+ if (source_it == cast_mode_sources_.end())
+ return MediaSource();
+ return source_it->second;
+}
+
+void QueryResultManager::NotifyOnResultsUpdated() {
+ std::vector<MediaSinkWithCastModes> sinks;
+ for (const auto& sink_pair : all_sinks_) {
+ sinks.push_back(sink_pair.second);
+ }
+ FOR_EACH_OBSERVER(QueryResultManager::Observer, observers_,
+ OnResultsUpdated(sinks));
+}
+
+QueryResultManager::CastModeMediaSinksObserver::CastModeMediaSinksObserver(
+ MediaCastMode cast_mode,
+ const MediaSource& source,
+ MediaRouter* router,
+ QueryResultManager* result_manager)
+ : MediaSinksObserver(router, source),
+ cast_mode_(cast_mode),
+ result_manager_(result_manager) {
+ DCHECK(result_manager);
+}
+
+QueryResultManager::CastModeMediaSinksObserver::~CastModeMediaSinksObserver() {
+}
+
+void QueryResultManager::CastModeMediaSinksObserver::OnSinksReceived(
+ const std::vector<MediaSink>& result) {
+ latest_sink_ids_.clear();
+ for (const MediaSink& sink : result) {
+ latest_sink_ids_.push_back(sink.id());
+ }
+ result_manager_->UpdateWithSinksQueryResult(cast_mode_, result);
+ result_manager_->NotifyOnResultsUpdated();
+}
+
+
+void QueryResultManager::CastModeMediaSinksObserver::GetLatestSinkIds(
+ std::vector<MediaSinkId>* sink_ids) const {
+ DCHECK(sink_ids);
+ *sink_ids = latest_sink_ids_;
+}
+
+} // namespace media_router

Powered by Google App Engine
This is Rietveld 408576698