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

Side by Side Diff: chromeos/components/tether/host_scan_cache.cc

Issue 2852693004: [CrOS Tether] Create HostScanCache, which caches scan results and inserts them into the network sta… (Closed)
Patch Set: stevenjb@ comments. Created 3 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 2017 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 "chromeos/components/tether/host_scan_cache.h"
6
7 #include <algorithm>
8
9 #include "base/bind.h"
10 #include "base/memory/ptr_util.h"
11 #include "chromeos/components/tether/active_host.h"
12 #include "chromeos/components/tether/device_id_tether_network_guid_map.h"
13 #include "chromeos/components/tether/tether_host_response_recorder.h"
14 #include "chromeos/network/network_state_handler.h"
15 #include "components/proximity_auth/logging/logging.h"
16
17 namespace chromeos {
18
19 namespace tether {
20
21 HostScanCache::TimerFactoryImpl::TimerFactoryImpl() {}
22
23 HostScanCache::TimerFactoryImpl::~TimerFactoryImpl() {}
24
25 std::unique_ptr<base::Timer>
26 HostScanCache::TimerFactoryImpl::CreateOneShotTimer() {
27 return base::MakeUnique<base::OneShotTimer>();
28 }
29
30 HostScanCache::HostScanCache(
31 NetworkStateHandler* network_state_handler,
32 ActiveHost* active_host,
33 TetherHostResponseRecorder* tether_host_response_recorder,
34 DeviceIdTetherNetworkGuidMap* device_id_tether_network_guid_map)
35 : HostScanCache(base::MakeUnique<TimerFactoryImpl>(),
36 network_state_handler,
37 active_host,
38 tether_host_response_recorder,
39 device_id_tether_network_guid_map) {}
40
41 HostScanCache::HostScanCache(
42 std::unique_ptr<TimerFactory> timer_factory,
43 NetworkStateHandler* network_state_handler,
44 ActiveHost* active_host,
45 TetherHostResponseRecorder* tether_host_response_recorder,
46 DeviceIdTetherNetworkGuidMap* device_id_tether_network_guid_map)
47 : timer_factory_(std::move(timer_factory)),
48 network_state_handler_(network_state_handler),
49 active_host_(active_host),
50 tether_host_response_recorder_(tether_host_response_recorder),
51 device_id_tether_network_guid_map_(device_id_tether_network_guid_map),
52 weak_ptr_factory_(this) {
53 tether_host_response_recorder_->AddObserver(this);
54 }
55
56 HostScanCache::~HostScanCache() {
57 tether_host_response_recorder_->RemoveObserver(this);
58 }
59
60 void HostScanCache::SetHostScanResult(const std::string& tether_network_guid,
61 const std::string& device_name,
62 const std::string& carrier,
63 int battery_percentage,
64 int signal_strength) {
65 DCHECK(!tether_network_guid.empty());
66
67 auto found_iter = tether_guid_to_timer_map_.find(tether_network_guid);
68
69 if (found_iter == tether_guid_to_timer_map_.end()) {
70 // Add the Tether network to NetworkStateHandler and create an associated
71 // Timer.
72 network_state_handler_->AddTetherNetworkState(
73 tether_network_guid, device_name, carrier, battery_percentage,
74 signal_strength, HasConnectedToHost(tether_network_guid));
75 tether_guid_to_timer_map_.emplace(tether_network_guid,
76 timer_factory_->CreateOneShotTimer());
77
78 PA_LOG(INFO) << "Added scan result for Tether network with GUID "
79 << tether_network_guid << ". Device name: " << device_name
80 << ", carrier: " << carrier
81 << ", battery percentage: " << battery_percentage
82 << ", signal strength: " << signal_strength;
83 } else {
84 // Update the existing network and stop the associated Timer.
85 network_state_handler_->UpdateTetherNetworkProperties(
86 tether_network_guid, carrier, battery_percentage, signal_strength);
87 found_iter->second->Stop();
88
89 PA_LOG(INFO) << "Updated scan result for Tether network with GUID "
90 << tether_network_guid << ". New carrier: " << carrier << ", "
91 << "new battery percentage: " << battery_percentage << ", "
92 << "new signal strength: " << signal_strength;
93 }
94
95 StartTimer(tether_network_guid);
96 }
97
98 bool HostScanCache::RemoveHostScanResult(
99 const std::string& tether_network_guid) {
100 DCHECK(!tether_network_guid.empty());
101
102 auto it = tether_guid_to_timer_map_.find(tether_network_guid);
103 if (it == tether_guid_to_timer_map_.end()) {
104 PA_LOG(ERROR) << "Attempted to remove a host scan result which does not "
105 << "exist in the cache. GUID: " << tether_network_guid;
106 return false;
107 }
108
109 if (active_host_->GetTetherNetworkGuid() == tether_network_guid) {
110 PA_LOG(ERROR) << "RemoveHostScanResult() called for Tether network with "
111 << "GUID " << tether_network_guid << ", but the "
112 << "corresponding device is the active host. Not removing "
113 << "this scan result from the cache.";
114 return false;
115 }
116
117 tether_guid_to_timer_map_.erase(it);
118 return network_state_handler_->RemoveTetherNetworkState(tether_network_guid);
119 }
120
121 void HostScanCache::ClearCacheExceptForActiveHost() {
122 // Create a list of all Tether network GUIDs serving as keys to
123 // |tether_guid_to_timer_map_|.
124 std::vector<std::string> tether_network_guids;
125 tether_network_guids.reserve(tether_guid_to_timer_map_.size());
126 for (auto& it : tether_guid_to_timer_map_)
127 tether_network_guids.push_back(it.first);
128
129 std::string active_host_tether_guid = active_host_->GetTetherNetworkGuid();
130 if (active_host_tether_guid.empty()) {
stevenjb 2017/05/01 22:13:01 No, I meant, isn't this logic backwards? If active
Kyle Horimoto 2017/05/02 00:02:18 You're right! Done.
131 PA_LOG(INFO) << "Clearing " << (tether_guid_to_timer_map_.size() - 1) << " "
132 << "of the " << tether_guid_to_timer_map_.size() << " "
133 << "entries from the cache. Not removing the entry "
134 << "corresponding to the Tether network with GUID "
135 << active_host_tether_guid << " because it represents the "
136 << "active host.";
137 } else {
138 PA_LOG(INFO) << "Clearing all " << tether_guid_to_timer_map_.size() << " "
139 << "entries from the cache.";
140 }
141
142 // Iterate through the keys, removing all scan results not corresponding to
143 // the active host. Iteration is done via a list of pre-computed keys instead
144 // if iterating through the map because RemoteHostScanResult() will remove
145 // key/value pairs from the map, which would invalidate the map iterator.
146 for (auto& tether_network_guid : tether_network_guids) {
147 if (active_host_->GetTetherNetworkGuid() == tether_network_guid) {
148 // Do not remove the active host from the cache.
149 continue;
150 }
151
152 RemoveHostScanResult(tether_network_guid);
153 }
154 }
155
156 void HostScanCache::OnPreviouslyConnectedHostIdsChanged() {
157 for (auto& map_entry : tether_guid_to_timer_map_) {
158 const std::string& tether_network_guid = map_entry.first;
159 if (!HasConnectedToHost(tether_network_guid))
160 continue;
161
162 // If a the current device has connected to the Tether network with GUID
163 // |tether_network_guid|, alert |network_state_handler_|. Note that this
164 // function is a no-op if it is called on a network which already has its
165 // HasConnectedToHost property set to true.
166 bool update_successful =
167 network_state_handler_->SetTetherNetworkHasConnectedToHost(
168 tether_network_guid);
169
170 if (update_successful) {
171 PA_LOG(INFO) << "Successfully set the HasConnectedToHost property of "
172 << "the Tether network with GUID " << tether_network_guid
173 << " to true.";
174 }
175 }
176 }
177
178 bool HostScanCache::HasConnectedToHost(const std::string& tether_network_guid) {
179 std::string device_id =
180 device_id_tether_network_guid_map_->GetDeviceIdForTetherNetworkGuid(
181 tether_network_guid);
182 std::vector<std::string> connected_device_ids =
183 tether_host_response_recorder_->GetPreviouslyConnectedHostIds();
184 return std::find(connected_device_ids.begin(), connected_device_ids.end(),
185 device_id) != connected_device_ids.end();
186 }
187
188 void HostScanCache::StartTimer(const std::string& tether_network_guid) {
189 auto found_iter = tether_guid_to_timer_map_.find(tether_network_guid);
190 DCHECK(found_iter != tether_guid_to_timer_map_.end());
191 DCHECK(!found_iter->second->IsRunning());
192
193 PA_LOG(INFO) << "Starting host scan cache timer for Tether network with GUID "
194 << tether_network_guid << ". Will fire in "
195 << kNumMinutesBeforeCacheEntryExpires << " minutes.";
196
197 found_iter->second->Start(
198 FROM_HERE,
199 base::TimeDelta::FromMinutes(kNumMinutesBeforeCacheEntryExpires),
200 base::Bind(&HostScanCache::OnTimerFired, weak_ptr_factory_.GetWeakPtr(),
201 tether_network_guid));
202 }
203
204 void HostScanCache::OnTimerFired(const std::string& tether_network_guid) {
205 if (active_host_->GetTetherNetworkGuid() == tether_network_guid) {
206 // Log as a warning. This situation should be uncommon in practice since
207 // KeepAliveScheduler should schedule a new keep-alive status update every
208 // 4 minutes.
209 PA_LOG(WARNING) << "Timer fired for Tether network GUID "
210 << tether_network_guid << ", but the corresponding device "
211 << "is the active host. Restarting timer.";
212
213 // If the Timer which fired corresponds to the active host, do not remove
214 // the cache entry. The active host must always remain in the cache so that
215 // the UI can reflect that it is the connecting/connected network. In this
216 // case, just restart the timer.
217 StartTimer(tether_network_guid);
218 return;
219 }
220
221 PA_LOG(INFO) << "Timer fired for Tether network GUID " << tether_network_guid
222 << ". Removing stale scan result.";
223 RemoveHostScanResult(tether_network_guid);
224 }
225
226 } // namespace tether
227
228 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698