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

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

Powered by Google App Engine
This is Rietveld 408576698