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/fake_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
12namespace wifi {
13
14FakeWiFiService::FakeWiFiService() {
15  // Populate data expected by unit test.
16  {
17    NetworkProperties network_properties;
18    network_properties.connection_state = onc::connection_state::kConnected;
19    network_properties.guid = "stub_wifi1_guid";
20    network_properties.name = "wifi1";
21    network_properties.type = onc::network_type::kWiFi;
22    network_properties.frequency = 0;
23    network_properties.ssid = "wifi1";
24    network_properties.security = onc::wifi::kWEP_PSK;
25    network_properties.signal_strength = 40;
26    network_properties.json_extra =
27      "{"
28      "  \"MacAddress\": \"00:11:22:AA:BB:CC\","
29      "  \"IPConfigs\": [{"
30      "     \"Gateway\": \"0.0.0.1\","
31      "     \"IPAddress\": \"0.0.0.0\","
32      "     \"RoutingPrefix\": 0,"
33      "     \"Type\": \"IPv4\""
34      "  }],"
35      "  \"WiFi\": {"
36      "    \"Frequency\": 2400,"
37      "    \"FrequencyList\": [2400]"
38      "  }"
39      "}";
40    networks_.push_back(network_properties);
41  }
42  {
43    NetworkProperties network_properties;
44    network_properties.connection_state = onc::connection_state::kNotConnected;
45    network_properties.guid = "stub_wifi2_guid";
46    network_properties.name = "wifi2_PSK";
47    network_properties.type = onc::network_type::kWiFi;
48    network_properties.frequency = 5000;
49    network_properties.frequency_set.insert(2400);
50    network_properties.frequency_set.insert(5000);
51    network_properties.ssid = "wifi2_PSK";
52    network_properties.security = onc::wifi::kWPA_PSK;
53    network_properties.signal_strength = 80;
54    networks_.push_back(network_properties);
55  }
56}
57
58FakeWiFiService::~FakeWiFiService() {
59}
60
61void FakeWiFiService::Initialize(
62    scoped_refptr<base::SequencedTaskRunner> task_runner) {
63}
64
65void FakeWiFiService::UnInitialize() {
66}
67
68void FakeWiFiService::GetProperties(const std::string& network_guid,
69                                    base::DictionaryValue* properties,
70                                    std::string* error) {
71  NetworkList::iterator network_properties = FindNetwork(network_guid);
72  if (network_properties == networks_.end()) {
73    *error = "Error.InvalidNetworkGuid";
74    return;
75  }
76  properties->Swap(network_properties->ToValue(false).get());
77}
78
79void FakeWiFiService::GetManagedProperties(
80    const std::string& network_guid,
81    base::DictionaryValue* managed_properties,
82    std::string* error) {
83  // Not implemented
84  *error = kErrorWiFiService;
85}
86
87void FakeWiFiService::GetState(const std::string& network_guid,
88                               base::DictionaryValue* properties,
89                               std::string* error) {
90  NetworkList::iterator network_properties = FindNetwork(network_guid);
91  if (network_properties == networks_.end()) {
92    *error = "Error.InvalidNetworkGuid";
93    return;
94  }
95  properties->Swap(network_properties->ToValue(true).get());
96}
97
98void FakeWiFiService::SetProperties(
99    const std::string& network_guid,
100    scoped_ptr<base::DictionaryValue> properties,
101    std::string* error) {
102  NetworkList::iterator network_properties = FindNetwork(network_guid);
103  if (network_properties == networks_.end() ||
104      !network_properties->UpdateFromValue(*properties)) {
105    *error = "Error.DBusFailed";
106  }
107}
108
109void FakeWiFiService::CreateNetwork(
110    bool shared,
111    scoped_ptr<base::DictionaryValue> properties,
112    std::string* network_guid,
113    std::string* error) {
114  NetworkProperties network_properties;
115  if (network_properties.UpdateFromValue(*properties)) {
116    network_properties.guid = network_properties.ssid;
117    networks_.push_back(network_properties);
118    *network_guid = network_properties.guid;
119  } else {
120    *error = "Error.DBusFailed";
121  }
122}
123
124void FakeWiFiService::GetVisibleNetworks(const std::string& network_type,
125                                         base::ListValue* network_list,
126                                         bool include_details) {
127  for (NetworkList::const_iterator it = networks_.begin();
128       it != networks_.end();
129       ++it) {
130    if (network_type.empty() || network_type == onc::network_type::kAllTypes ||
131        it->type == network_type) {
132      scoped_ptr<base::DictionaryValue> network(it->ToValue(!include_details));
133      network_list->Append(network.release());
134    }
135  }
136}
137
138void FakeWiFiService::RequestNetworkScan() {
139  NotifyNetworkListChanged(networks_);
140}
141
142void FakeWiFiService::StartConnect(const std::string& network_guid,
143                                   std::string* error) {
144  NetworkList::iterator network_properties = FindNetwork(network_guid);
145  if (network_properties == networks_.end()) {
146    *error = "Error.InvalidNetworkGuid";
147    return;
148  }
149  DisconnectAllNetworksOfType(network_properties->type);
150  network_properties->connection_state = onc::connection_state::kConnected;
151  SortNetworks();
152  NotifyNetworkListChanged(networks_);
153  NotifyNetworkChanged(network_guid);
154}
155
156void FakeWiFiService::StartDisconnect(const std::string& network_guid,
157                                      std::string* error) {
158  NetworkList::iterator network_properties = FindNetwork(network_guid);
159  if (network_properties == networks_.end()) {
160    *error = "Error.InvalidNetworkGuid";
161    return;
162  }
163  network_properties->connection_state = onc::connection_state::kNotConnected;
164  SortNetworks();
165  NotifyNetworkListChanged(networks_);
166  NotifyNetworkChanged(network_guid);
167}
168
169void FakeWiFiService::GetKeyFromSystem(const std::string& network_guid,
170                                       std::string* key_data,
171                                       std::string* error) {
172  *error = "not-found";
173}
174
175void FakeWiFiService::SetEventObservers(
176    scoped_refptr<base::MessageLoopProxy> message_loop_proxy,
177    const NetworkGuidListCallback& networks_changed_observer,
178    const NetworkGuidListCallback& network_list_changed_observer) {
179  message_loop_proxy_.swap(message_loop_proxy);
180  networks_changed_observer_ = networks_changed_observer;
181  network_list_changed_observer_ = network_list_changed_observer;
182}
183
184void FakeWiFiService::RequestConnectedNetworkUpdate() {
185}
186
187NetworkList::iterator FakeWiFiService::FindNetwork(
188    const std::string& network_guid) {
189  for (NetworkList::iterator it = networks_.begin(); it != networks_.end();
190       ++it) {
191    if (it->guid == network_guid)
192      return it;
193  }
194  return networks_.end();
195}
196
197void FakeWiFiService::DisconnectAllNetworksOfType(const std::string& type) {
198  for (NetworkList::iterator it = networks_.begin(); it != networks_.end();
199       ++it) {
200    if (it->type == type)
201      it->connection_state = onc::connection_state::kNotConnected;
202  }
203}
204
205void FakeWiFiService::SortNetworks() {
206  // Sort networks, so connected/connecting is up front, then by type:
207  // Ethernet, WiFi, Cellular, VPN
208  networks_.sort(NetworkProperties::OrderByType);
209}
210
211void FakeWiFiService::NotifyNetworkListChanged(const NetworkList& networks) {
212  WiFiService::NetworkGuidList current_networks;
213  for (NetworkList::const_iterator it = networks.begin(); it != networks.end();
214       ++it) {
215    current_networks.push_back(it->guid);
216  }
217
218  message_loop_proxy_->PostTask(
219      FROM_HERE, base::Bind(network_list_changed_observer_, current_networks));
220}
221
222void FakeWiFiService::NotifyNetworkChanged(const std::string& network_guid) {
223  WiFiService::NetworkGuidList changed_networks(1, network_guid);
224  message_loop_proxy_->PostTask(
225      FROM_HERE, base::Bind(networks_changed_observer_, changed_networks));
226}
227
228}  // namespace wifi
229