1 // Copyright 2013 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 "components/wifi/wifi_service.h"
6
7 #include "base/bind.h"
8 #include "base/json/json_reader.h"
9 #include "base/message_loop/message_loop.h"
10 #include "components/onc/onc_constants.h"
11
12 namespace wifi {
13
14 // Fake implementation of WiFiService used to satisfy expectations of
15 // networkingPrivateApi browser test.
16 class FakeWiFiService : public WiFiService {
17 public:
FakeWiFiService()18 FakeWiFiService() {
19 // Populate data expected by unit test.
20 {
21 WiFiService::NetworkProperties network_properties;
22 network_properties.connection_state = onc::connection_state::kConnected;
23 network_properties.guid = "stub_ethernet";
24 network_properties.name = "eth0";
25 network_properties.type = onc::network_type::kEthernet;
26 network_properties.json_extra =
27 " {"
28 " \"Authentication\": \"None\""
29 " }";
30 networks_.push_back(network_properties);
31 }
32 {
33 WiFiService::NetworkProperties network_properties;
34 network_properties.connection_state = onc::connection_state::kConnected;
35 network_properties.guid = "stub_wifi1";
36 network_properties.name = "wifi1";
37 network_properties.type = onc::network_type::kWiFi;
38 network_properties.frequency = 0;
39 network_properties.ssid = "stub_wifi1";
40 network_properties.security = onc::wifi::kWEP_PSK;
41 network_properties.signal_strength = 0;
42 networks_.push_back(network_properties);
43 }
44 {
45 WiFiService::NetworkProperties network_properties;
46 network_properties.connection_state = onc::connection_state::kConnected;
47 network_properties.guid = "stub_vpn1";
48 network_properties.name = "vpn1";
49 network_properties.type = onc::network_type::kVPN;
50 networks_.push_back(network_properties);
51 }
52 {
53 WiFiService::NetworkProperties network_properties;
54 network_properties.connection_state =
55 onc::connection_state::kNotConnected;
56 network_properties.guid = "stub_wifi2";
57 network_properties.name = "wifi2_PSK";
58 network_properties.type = onc::network_type::kWiFi;
59 network_properties.frequency = 5000;
60 network_properties.frequency_list.push_back(2400);
61 network_properties.frequency_list.push_back(5000);
62 network_properties.ssid = "wifi2_PSK";
63 network_properties.security = onc::wifi::kWPA_PSK;
64 network_properties.signal_strength = 80;
65 networks_.push_back(network_properties);
66 }
67 {
68 WiFiService::NetworkProperties network_properties;
69 network_properties.connection_state =
70 onc::connection_state::kNotConnected;
71 network_properties.guid = "stub_cellular1";
72 network_properties.name = "cellular1";
73 network_properties.type = onc::network_type::kCellular;
74 network_properties.json_extra =
75 " {"
76 " \"ActivateOverNonCellularNetwork\": false,"
77 " \"ActivationState\": \"not-activated\","
78 " \"NetworkTechnology\": \"GSM\","
79 " \"RoamingState\": \"home\""
80 " }";
81 networks_.push_back(network_properties);
82 }
83 }
84
Initialize(scoped_refptr<base::SequencedTaskRunner> task_runner)85 virtual void Initialize(
86 scoped_refptr<base::SequencedTaskRunner> task_runner) OVERRIDE {}
87
UnInitialize()88 virtual void UnInitialize() OVERRIDE {}
89
GetProperties(const std::string & network_guid,DictionaryValue * properties,std::string * error)90 virtual void GetProperties(const std::string& network_guid,
91 DictionaryValue* properties,
92 std::string* error) OVERRIDE {
93 NetworkList::iterator network_properties = FindNetwork(network_guid);
94 if (network_properties != networks_.end()) {
95 properties->Swap(network_properties->ToValue(false).get());
96 } else {
97 *error = "Error.DBusFailed";
98 }
99 }
100
GetManagedProperties(const std::string & network_guid,DictionaryValue * managed_properties,std::string * error)101 virtual void GetManagedProperties(const std::string& network_guid,
102 DictionaryValue* managed_properties,
103 std::string* error) OVERRIDE {
104 const std::string network_properties =
105 "{"
106 " \"ConnectionState\": {"
107 " \"Active\": \"NotConnected\","
108 " \"Effective\": \"Unmanaged\""
109 " },"
110 " \"GUID\": \"stub_wifi2\","
111 " \"Name\": {"
112 " \"Active\": \"wifi2_PSK\","
113 " \"Effective\": \"UserPolicy\","
114 " \"UserPolicy\": \"My WiFi Network\""
115 " },"
116 " \"Type\": {"
117 " \"Active\": \"WiFi\","
118 " \"Effective\": \"UserPolicy\","
119 " \"UserPolicy\": \"WiFi\""
120 " },"
121 " \"WiFi\": {"
122 " \"AutoConnect\": {"
123 " \"Active\": false,"
124 " \"UserEditable\": true"
125 " },"
126 " \"Frequency\" : {"
127 " \"Active\": 5000,"
128 " \"Effective\": \"Unmanaged\""
129 " },"
130 " \"FrequencyList\" : {"
131 " \"Active\": [2400, 5000],"
132 " \"Effective\": \"Unmanaged\""
133 " },"
134 " \"Passphrase\": {"
135 " \"Effective\": \"UserSetting\","
136 " \"UserEditable\": true,"
137 " \"UserSetting\": \"FAKE_CREDENTIAL_VPaJDV9x\""
138 " },"
139 " \"SSID\": {"
140 " \"Active\": \"wifi2_PSK\","
141 " \"Effective\": \"UserPolicy\","
142 " \"UserPolicy\": \"wifi2_PSK\""
143 " },"
144 " \"Security\": {"
145 " \"Active\": \"WPA-PSK\","
146 " \"Effective\": \"UserPolicy\","
147 " \"UserPolicy\": \"WPA-PSK\""
148 " },"
149 " \"SignalStrength\": {"
150 " \"Active\": 80,"
151 " \"Effective\": \"Unmanaged\""
152 " }"
153 " }"
154 "}";
155 scoped_ptr<DictionaryValue> properties_value(
156 reinterpret_cast<DictionaryValue*>(
157 base::JSONReader::Read(network_properties)));
158 managed_properties->MergeDictionary(properties_value.get());
159 }
160
GetState(const std::string & network_guid,DictionaryValue * properties,std::string * error)161 virtual void GetState(const std::string& network_guid,
162 DictionaryValue* properties,
163 std::string* error) OVERRIDE {
164 NetworkList::iterator network_properties = FindNetwork(network_guid);
165 if (network_properties == networks_.end()) {
166 *error = "Error.InvalidParameter";
167 return;
168 }
169
170 const std::string network_state =
171 "{"
172 " \"ConnectionState\": \"NotConnected\","
173 " \"GUID\": \"stub_wifi2\","
174 " \"Name\": \"wifi2_PSK\","
175 " \"Type\": \"WiFi\","
176 " \"WiFi\": {"
177 " \"Security\": \"WPA-PSK\","
178 " \"SignalStrength\": 80"
179 " }"
180 "}";
181 scoped_ptr<DictionaryValue> properties_value(
182 reinterpret_cast<DictionaryValue*>(
183 base::JSONReader::Read(network_state)));
184 properties->MergeDictionary(properties_value.get());
185 }
186
SetProperties(const std::string & network_guid,scoped_ptr<base::DictionaryValue> properties,std::string * error)187 virtual void SetProperties(const std::string& network_guid,
188 scoped_ptr<base::DictionaryValue> properties,
189 std::string* error) OVERRIDE {
190 NetworkList::iterator network_properties = FindNetwork(network_guid);
191 if (network_properties == networks_.end() ||
192 !network_properties->UpdateFromValue(*properties)) {
193 *error = "Error.DBusFailed";
194 }
195 }
196
CreateNetwork(bool shared,scoped_ptr<base::DictionaryValue> properties,std::string * network_guid,std::string * error)197 virtual void CreateNetwork(bool shared,
198 scoped_ptr<base::DictionaryValue> properties,
199 std::string* network_guid,
200 std::string* error) OVERRIDE {
201 WiFiService::NetworkProperties network_properties;
202 if (network_properties.UpdateFromValue(*properties)) {
203 network_properties.guid = network_properties.ssid;
204 networks_.push_back(network_properties);
205 *network_guid = network_properties.guid;
206 } else {
207 *error = "Error.DBusFailed";
208 }
209 }
210
GetVisibleNetworks(const std::string & network_type,ListValue * network_list)211 virtual void GetVisibleNetworks(const std::string& network_type,
212 ListValue* network_list) OVERRIDE {
213 for (WiFiService::NetworkList::const_iterator it = networks_.begin();
214 it != networks_.end();
215 ++it) {
216 if (network_type.empty() ||
217 network_type == onc::network_type::kAllTypes ||
218 it->type == network_type) {
219 scoped_ptr<DictionaryValue> network(it->ToValue(true));
220 network_list->Append(network.release());
221 }
222 }
223 }
224
RequestNetworkScan()225 virtual void RequestNetworkScan() OVERRIDE {
226 NotifyNetworkListChanged(networks_);
227 }
228
StartConnect(const std::string & network_guid,std::string * error)229 virtual void StartConnect(const std::string& network_guid,
230 std::string* error) OVERRIDE {
231 NetworkList::iterator network_properties = FindNetwork(network_guid);
232 if (network_properties != networks_.end()) {
233 DisconnectAllNetworksOfType(network_properties->type);
234 network_properties->connection_state = onc::connection_state::kConnected;
235 SortNetworks();
236 NotifyNetworkListChanged(networks_);
237 NotifyNetworkChanged(network_guid);
238 } else {
239 *error = "configure-failed";
240 }
241 }
242
StartDisconnect(const std::string & network_guid,std::string * error)243 virtual void StartDisconnect(const std::string& network_guid,
244 std::string* error) OVERRIDE {
245 NetworkList::iterator network_properties = FindNetwork(network_guid);
246 if (network_properties != networks_.end()) {
247 network_properties->connection_state =
248 onc::connection_state::kNotConnected;
249 SortNetworks();
250 NotifyNetworkListChanged(networks_);
251 NotifyNetworkChanged(network_guid);
252 } else {
253 *error = "not-found";
254 }
255 }
256
SetEventObservers(scoped_refptr<base::MessageLoopProxy> message_loop_proxy,const NetworkGuidListCallback & networks_changed_observer,const NetworkGuidListCallback & network_list_changed_observer)257 virtual void SetEventObservers(
258 scoped_refptr<base::MessageLoopProxy> message_loop_proxy,
259 const NetworkGuidListCallback& networks_changed_observer,
260 const NetworkGuidListCallback& network_list_changed_observer) OVERRIDE {
261 message_loop_proxy_.swap(message_loop_proxy);
262 networks_changed_observer_ = networks_changed_observer;
263 network_list_changed_observer_ = network_list_changed_observer;
264 }
265
266 private:
FindNetwork(const std::string & network_guid)267 NetworkList::iterator FindNetwork(const std::string& network_guid) {
268 for (NetworkList::iterator it = networks_.begin(); it != networks_.end();
269 ++it) {
270 if (it->guid == network_guid)
271 return it;
272 }
273 return networks_.end();
274 }
275
DisconnectAllNetworksOfType(const std::string & type)276 void DisconnectAllNetworksOfType(const std::string& type) {
277 for (NetworkList::iterator it = networks_.begin(); it != networks_.end();
278 ++it) {
279 if (it->type == type)
280 it->connection_state = onc::connection_state::kNotConnected;
281 }
282 }
283
SortNetworks()284 void SortNetworks() {
285 // Sort networks, so connected/connecting is up front, then by type:
286 // Ethernet, WiFi, Cellular, VPN
287 networks_.sort(WiFiService::NetworkProperties::OrderByType);
288 }
289
NotifyNetworkListChanged(const NetworkList & networks)290 void NotifyNetworkListChanged(const NetworkList& networks) {
291 WiFiService::NetworkGuidList current_networks;
292 for (WiFiService::NetworkList::const_iterator it = networks.begin();
293 it != networks.end();
294 ++it) {
295 current_networks.push_back(it->guid);
296 }
297
298 message_loop_proxy_->PostTask(
299 FROM_HERE,
300 base::Bind(network_list_changed_observer_, current_networks));
301 }
302
NotifyNetworkChanged(const std::string & network_guid)303 void NotifyNetworkChanged(const std::string& network_guid) {
304 WiFiService::NetworkGuidList changed_networks(1, network_guid);
305 message_loop_proxy_->PostTask(
306 FROM_HERE,
307 base::Bind(networks_changed_observer_, changed_networks));
308 }
309
310 NetworkList networks_;
311 scoped_refptr<base::MessageLoopProxy> message_loop_proxy_;
312 NetworkGuidListCallback networks_changed_observer_;
313 NetworkGuidListCallback network_list_changed_observer_;
314 };
315
CreateForTest()316 WiFiService* WiFiService::CreateForTest() { return new FakeWiFiService(); }
317
318 } // namespace wifi
319