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

Side by Side Diff: chrome/browser/net/discovery_network_monitor.cc

Issue 2750453002: Add DiscoveryNetworkMonitor implementation (Closed)
Patch Set: Created 3 years, 9 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 (c) 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 "chrome/browser/net/discovery_network_monitor.h"
6
7 #include <iostream>
8
9 #include "base/lazy_instance.h"
10 #include "base/logging.h"
11 #include "chrome/browser/net/discovery_network_list.h"
12 #include "content/public/browser/browser_thread.h"
13 #include "net/base/network_interfaces.h"
14
15 namespace {
16
17 using content::BrowserThread;
18
19 std::vector<NetworkInfo> GetNetworkInfo() {
20 DCHECK_CURRENTLY_ON(BrowserThread::IO);
21
22 net::NetworkInterfaceList interface_list;
23 if (!net::GetNetworkList(&interface_list,
24 net::INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES)) {
25 DVLOG(2) << "net::GetNetworkList failed after a network change event";
26 return std::vector<NetworkInfo>();
27 }
28
29 std::vector<NetworkInfo> network_info_list;
30 for (const auto& interface : interface_list) {
31 if (interface.type != net::NetworkChangeNotifier::CONNECTION_ETHERNET &&
32 interface.type != net::NetworkChangeNotifier::CONNECTION_WIFI) {
33 continue;
34 }
35 network_info_list.push_back(
36 NetworkInfo{interface.interface_index, interface.type, interface.name,
37 std::string(""), interface.address});
38 }
39
40 auto network_ids = GetDiscoveryNetworkIdList();
41 for (const auto& network_id : network_ids) {
42 auto matching_info_it =
43 std::find_if(begin(network_info_list), end(network_info_list),
44 [&network_id](const NetworkInfo& network_info) {
45 return network_info.name == network_id.interface_name;
46 });
47 if (matching_info_it != end(network_info_list)) {
48 matching_info_it->network_id = network_id.network_id;
imcheng 2017/03/14 22:45:35 So it looks like we are combining information from
btolsch 2017/04/03 10:16:35 Although this is possible on linux, as best as I c
49 }
50 }
51 return network_info_list;
imcheng 2017/03/14 22:45:35 Do we know if the networks in the returned list ar
btolsch 2017/04/03 10:16:35 Yes, it looks like net::GetNetworkList only return
52 }
53
54 base::LazyInstance<DiscoveryNetworkMonitor>::Leaky g_discovery_monitor;
55
56 } // namespace
57 NetworkInfo::NetworkInfo() {}
58
59 NetworkInfo::NetworkInfo(
60 uint32_t index,
61 net::NetworkChangeNotifier::ConnectionType connection_type,
62 std::string name,
63 std::string network_id,
64 net::IPAddress ip_address)
65 : index(index),
66 connection_type(connection_type),
67 name(name),
68 network_id(network_id),
69 ip_address(ip_address) {}
70
71 NetworkInfo::NetworkInfo(const NetworkInfo&) = default;
72
73 NetworkInfo& NetworkInfo::operator=(const NetworkInfo&) = default;
74
75 DiscoveryNetworkMonitor::DiscoveryNetworkMonitor()
76 : observers_(new base::ObserverListThreadSafe<Observer>(
77 base::ObserverListThreadSafe<
78 Observer>::NotificationType::NOTIFY_EXISTING_ONLY)) {
79 net::NetworkChangeNotifier::AddNetworkChangeObserver(this);
80 }
81
82 DiscoveryNetworkMonitor::~DiscoveryNetworkMonitor() {
83 net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this);
84 }
85
86 DiscoveryNetworkMonitor* DiscoveryNetworkMonitor::GetInstance() {
87 DiscoveryNetworkMonitor* monitor = g_discovery_monitor.Pointer();
88 if (!monitor->network_info_strategy_) {
89 monitor->network_info_strategy_ = base::Bind(&GetNetworkInfo);
90 }
91 return monitor;
92 }
93
94 DiscoveryNetworkMonitor* DiscoveryNetworkMonitor::GetInstanceForTest(
95 NetworkInfoStrategy strategy) {
96 DiscoveryNetworkMonitor* monitor = g_discovery_monitor.Pointer();
97 monitor->network_info_strategy_ = std::move(strategy);
98 return monitor;
99 }
100
101 void DiscoveryNetworkMonitor::RebindNetworkChangeObserverForTest() {
102 net::NetworkChangeNotifier::AddNetworkChangeObserver(this);
103 }
104
105 void DiscoveryNetworkMonitor::AddObserver(Observer* const observer) {
106 observers_->AddObserver(observer);
107 }
108
109 void DiscoveryNetworkMonitor::RemoveObserver(Observer* const observer) {
110 observers_->RemoveObserver(observer);
111 }
112
113 void DiscoveryNetworkMonitor::ForceNetworkInfoRefresh(
114 NetworkRefreshCompleteCallback callback) {
115 DCHECK_CURRENTLY_ON(BrowserThread::UI);
116
117 BrowserThread::PostTask(
118 BrowserThread::IO, FROM_HERE,
119 base::Bind(&DiscoveryNetworkMonitor::UpdateNetworkInfoWithCallback,
120 base::Unretained(this), callback));
121 }
122
123 void DiscoveryNetworkMonitor::OnNetworkChanged(
124 net::NetworkChangeNotifier::ConnectionType) {
125 DCHECK_CURRENTLY_ON(BrowserThread::UI);
126
127 BrowserThread::PostTask(
128 BrowserThread::IO, FROM_HERE,
129 base::Bind(&DiscoveryNetworkMonitor::UpdateNetworkInfoWithObservers,
130 base::Unretained(this)));
131 }
132
133 std::string DiscoveryNetworkMonitor::ComputeNetworkId(
134 const std::vector<NetworkInfo>& network_info_list) {
135 DCHECK_CURRENTLY_ON(BrowserThread::IO);
136
137 if (network_info_list.size() == 0) {
138 return std::string("disconnected");
mark a. foltz 2017/03/18 19:58:21 Can these special network id constants be defined
btolsch 2017/04/03 10:16:36 Done.
139 }
140 std::string network_ids;
141 for (const auto& network_info : network_info_list) {
142 network_ids += network_info.network_id;
143 }
144 if (network_ids.size() == 0) {
145 return std::string("unknown");
146 }
147 int folded_ids = 0;
148 unsigned long size = network_ids.size();
149 for (unsigned long i = 0; i < size; ++i) {
150 folded_ids ^= network_ids[i] << (8 * (i % 2));
mark a. foltz 2017/03/18 19:58:21 What is this computing? Maybe you can just comput
btolsch 2017/04/03 10:16:35 Done.
151 }
152
153 std::string network_id = "#_____";
154 network_id[5] = '0' + (folded_ids % 10);
155 folded_ids /= 10;
156 network_id[4] = '0' + (folded_ids % 10);
157 folded_ids /= 10;
158 network_id[3] = '0' + (folded_ids % 10);
159 folded_ids /= 10;
160 network_id[2] = '0' + (folded_ids % 10);
161 folded_ids /= 10;
162 network_id[1] = '0' + (folded_ids % 10);
163
164 return network_id;
imcheng 2017/03/14 22:45:35 Is the purpose of this to mimic the Cast MRP logic
btolsch 2017/04/03 10:16:35 The order shouldn't matter. I added a sort to the
165 }
166
167 void DiscoveryNetworkMonitor::UpdateNetworkInfo() {
mark a. foltz 2017/03/18 19:58:21 Will this get called when WiFi SSIDs change?
btolsch 2017/04/03 10:16:35 I guess that depends on whether NetworkChangeNotif
168 DCHECK_CURRENTLY_ON(BrowserThread::IO);
169
170 auto network_info_list = network_info_strategy_.Run();
171 auto network_id = ComputeNetworkId(network_info_list);
172
173 base::AutoLock auto_lock(network_info_lock_);
174 networks_.swap(network_info_list);
175 network_id_.swap(network_id);
176 }
177
178 void DiscoveryNetworkMonitor::UpdateNetworkInfoWithObservers() {
179 DCHECK_CURRENTLY_ON(BrowserThread::IO);
180
181 UpdateNetworkInfo();
182
183 observers_->Notify(FROM_HERE, &Observer::OnNetworksChanged,
mark a. foltz 2017/03/18 19:58:21 Do you only want to do this if the network list /
btolsch 2017/04/03 10:16:35 Yes. Done.
184 base::ConstRef(*this));
185 }
186
187 void DiscoveryNetworkMonitor::UpdateNetworkInfoWithCallback(
mark a. foltz 2017/03/18 19:58:21 Maybe UpdateNetworkInfo() could always update obse
btolsch 2017/04/03 10:16:35 Done.
188 NetworkRefreshCompleteCallback callback) {
189 DCHECK_CURRENTLY_ON(BrowserThread::IO);
190
191 UpdateNetworkInfo();
192
193 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback);
194 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698