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: 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 85 virtual void Initialize( 86 scoped_refptr<base::SequencedTaskRunner> task_runner) OVERRIDE {} 87 88 virtual void UnInitialize() OVERRIDE {} 89 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 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 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 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 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 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 225 virtual void RequestNetworkScan() OVERRIDE { 226 NotifyNetworkListChanged(networks_); 227 } 228 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 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 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: 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 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 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 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 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 316 WiFiService* WiFiService::CreateForTest() { return new FakeWiFiService(); } 317 318 } // namespace wifi 319