OLD | NEW |
---|---|
(Empty) | |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome/browser/ui/webui/media_router/query_result_manager.h" | |
6 | |
7 #include "base/stl_util.h" | |
8 #include "chrome/browser/media/router/media_router.h" | |
9 | |
10 namespace media_router { | |
11 | |
12 QueryResultManager::QueryResultManager(MediaRouter* router) : router_(router) { | |
13 DCHECK(router_); | |
14 } | |
15 | |
16 QueryResultManager::~QueryResultManager() { | |
17 DCHECK(thread_checker_.CalledOnValidThread()); | |
18 } | |
19 | |
20 void QueryResultManager::AddObserver(Observer* observer) { | |
21 DCHECK(thread_checker_.CalledOnValidThread()); | |
22 DCHECK(observer); | |
23 observers_.AddObserver(observer); | |
24 } | |
25 | |
26 void QueryResultManager::RemoveObserver(Observer* observer) { | |
27 DCHECK(thread_checker_.CalledOnValidThread()); | |
28 DCHECK(observer); | |
29 observers_.RemoveObserver(observer); | |
30 } | |
31 | |
32 void QueryResultManager::StartSinksQuery(MediaCastMode cast_mode, | |
33 const MediaSource& source) { | |
34 DCHECK(thread_checker_.CalledOnValidThread()); | |
35 DCHECK(!source.Empty()); | |
36 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.
| |
37 LOG(WARNING) << "StartSinksQuery called with empty source for " | |
38 << cast_mode; | |
39 return; | |
40 } | |
41 | |
42 SetSourceForCastMode(cast_mode, source); | |
43 RemoveObserverForCastMode(cast_mode); | |
44 UpdateWithSinksQueryResult(cast_mode, std::vector<MediaSink>()); | |
45 | |
46 linked_ptr<CastModeMediaSinksObserver> observer( | |
47 new CastModeMediaSinksObserver(cast_mode, source, router_, this)); | |
48 auto result = sinks_observers_.insert(std::make_pair(cast_mode, observer)); | |
49 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.
| |
50 NotifyOnResultsUpdated(); | |
51 } | |
52 | |
53 void QueryResultManager::StopSinksQuery(MediaCastMode cast_mode) { | |
54 DCHECK(thread_checker_.CalledOnValidThread()); | |
55 RemoveObserverForCastMode(cast_mode); | |
56 SetSourceForCastMode(cast_mode, MediaSource()); | |
57 UpdateWithSinksQueryResult(cast_mode, std::vector<MediaSink>()); | |
58 NotifyOnResultsUpdated(); | |
59 } | |
60 | |
61 void QueryResultManager::SetSourceForCastMode( | |
62 MediaCastMode cast_mode, const MediaSource& source) { | |
63 DCHECK(thread_checker_.CalledOnValidThread()); | |
64 cast_mode_sources_[cast_mode] = source; | |
65 } | |
66 | |
67 void QueryResultManager::RemoveObserverForCastMode(MediaCastMode cast_mode) { | |
68 auto observers_it = sinks_observers_.find(cast_mode); | |
69 if (observers_it != sinks_observers_.end()) | |
70 sinks_observers_.erase(observers_it); | |
71 } | |
72 | |
73 bool QueryResultManager::IsValid(const MediaSinkWithCastModes& entry) const { | |
74 return !entry.cast_modes.empty(); | |
75 } | |
76 | |
77 void QueryResultManager::UpdateWithSinksQueryResult( | |
78 MediaCastMode cast_mode, | |
79 const std::vector<MediaSink>& result) { | |
80 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.
| |
81 for (const MediaSink& sink : result) { | |
82 result_sink_ids.insert(sink.id()); | |
83 } | |
84 | |
85 // (1) Iterate through current sink set, remove cast mode from those that | |
86 // do not appear in latest result. | |
87 for (auto it = all_sinks_.begin(); it != all_sinks_.end(); /*no-op*/) { | |
88 if (!ContainsKey(result_sink_ids, it->first)) { | |
89 it->second.cast_modes.erase(cast_mode); | |
90 } | |
91 if (!IsValid(it->second)) { | |
92 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
| |
93 } else { | |
94 ++it; | |
95 } | |
96 } | |
97 | |
98 // (2) Add / update sinks with latest result. | |
99 for (const MediaSink& sink : result) { | |
100 auto all_sinks_it = all_sinks_.find(sink.id()); | |
101 if (all_sinks_it == all_sinks_.end()) { | |
102 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.
| |
103 std::make_pair(sink.id(), MediaSinkWithCastModes(sink))).first; | |
104 } | |
105 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.
| |
106 all_sinks_it->second.cast_modes.insert(cast_mode); | |
107 } | |
108 } | |
109 | |
110 void QueryResultManager::GetSupportedCastModes(CastModeSet* cast_modes) const { | |
111 DCHECK(cast_modes); | |
112 cast_modes->clear(); | |
113 for (const auto& observer_pair : sinks_observers_) { | |
114 cast_modes->insert(observer_pair.first); | |
115 } | |
116 } | |
117 | |
118 MediaSource QueryResultManager::GetSourceForCastMode( | |
119 MediaCastMode cast_mode) const { | |
120 DCHECK(thread_checker_.CalledOnValidThread()); | |
121 auto source_it = cast_mode_sources_.find(cast_mode); | |
122 if (source_it == cast_mode_sources_.end()) | |
123 return MediaSource(); | |
124 return source_it->second; | |
125 } | |
126 | |
127 void QueryResultManager::NotifyOnResultsUpdated() { | |
128 std::vector<MediaSinkWithCastModes> sinks; | |
129 for (const auto& sink_pair : all_sinks_) { | |
130 sinks.push_back(sink_pair.second); | |
131 } | |
132 FOR_EACH_OBSERVER(QueryResultManager::Observer, observers_, | |
133 OnResultsUpdated(sinks)); | |
134 } | |
135 | |
136 QueryResultManager::CastModeMediaSinksObserver::CastModeMediaSinksObserver( | |
137 MediaCastMode cast_mode, | |
138 const MediaSource& source, | |
139 MediaRouter* router, | |
140 QueryResultManager* result_manager) | |
141 : MediaSinksObserver(router, source), | |
142 cast_mode_(cast_mode), | |
143 result_manager_(result_manager) { | |
144 DCHECK(result_manager); | |
145 } | |
146 | |
147 QueryResultManager::CastModeMediaSinksObserver::~CastModeMediaSinksObserver() { | |
148 } | |
149 | |
150 void QueryResultManager::CastModeMediaSinksObserver::OnSinksReceived( | |
151 const std::vector<MediaSink>& result) { | |
152 latest_sink_ids_.clear(); | |
153 for (const MediaSink& sink : result) { | |
154 latest_sink_ids_.push_back(sink.id()); | |
155 } | |
156 result_manager_->UpdateWithSinksQueryResult(cast_mode_, result); | |
157 result_manager_->NotifyOnResultsUpdated(); | |
158 } | |
159 | |
160 | |
161 void QueryResultManager::CastModeMediaSinksObserver::GetLatestSinkIds( | |
162 std::vector<MediaSinkId>* sink_ids) const { | |
163 DCHECK(sink_ids); | |
164 *sink_ids = latest_sink_ids_; | |
165 } | |
166 | |
167 } // namespace media_router | |
OLD | NEW |