1// Copyright (c) 2012 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/chromeos/cros/network_library_impl_stub.h"
6
7#include "base/bind.h"
8#include "base/command_line.h"
9#include "base/stl_util.h"
10#include "chrome/browser/chromeos/cros/native_network_constants.h"
11#include "chromeos/chromeos_switches.h"
12#include "content/public/browser/browser_thread.h"
13#include "third_party/cros_system_api/dbus/service_constants.h"
14
15using content::BrowserThread;
16
17namespace {
18
19bool IsEthernetEnabled() {
20  return !CommandLine::ForCurrentProcess()->HasSwitch(
21      chromeos::switches::kDisableStubEthernet);
22}
23
24bool IsInteractive() {
25  return CommandLine::ForCurrentProcess()->HasSwitch(
26      chromeos::switches::kEnableStubInteractive);
27}
28
29}  // namespace
30
31namespace chromeos {
32
33NetworkLibraryImplStub::NetworkLibraryImplStub()
34    : ip_address_("1.1.1.1"),
35      hardware_address_("01:23:45:67:89:ab"),
36      pin_(""),
37      pin_required_(false),
38      pin_entered_(false),
39      network_priority_order_(0),
40      weak_pointer_factory_(this) {
41}
42
43NetworkLibraryImplStub::~NetworkLibraryImplStub() {
44  disabled_wifi_networks_.clear();
45  disabled_cellular_networks_.clear();
46  disabled_wimax_networks_.clear();
47  STLDeleteValues(&service_configurations_);
48}
49
50void NetworkLibraryImplStub::Init() {
51  is_locked_ = false;
52
53  // Enable only Cellular initially
54  int devices = (1 << TYPE_WIFI) | (1 << TYPE_CELLULAR) | (1 << TYPE_WIMAX);
55  if (IsEthernetEnabled())
56    devices |= 1 << TYPE_ETHERNET;
57  available_devices_ = devices;
58  uninitialized_devices_ = (1 << TYPE_CELLULAR);
59  enabled_devices_ = (available_devices_ & (1 << TYPE_ETHERNET));
60
61  if (IsInteractive()) {
62    const int kWifiInitDelaySeconds = 5;
63    const int kCellularInitDelaySeconds = 10;
64    const int kCellularActivateDelaySeconds = 15;
65    BrowserThread::PostDelayedTask(
66        BrowserThread::UI, FROM_HERE,
67        base::Bind(&NetworkLibraryImplStub::CompleteWifiInit,
68                   weak_pointer_factory_.GetWeakPtr()),
69        base::TimeDelta::FromSeconds(kWifiInitDelaySeconds));
70    BrowserThread::PostDelayedTask(
71        BrowserThread::UI, FROM_HERE,
72        base::Bind(&NetworkLibraryImplStub::CompleteCellularInit,
73                   weak_pointer_factory_.GetWeakPtr()),
74        base::TimeDelta::FromSeconds(kCellularInitDelaySeconds));
75    BrowserThread::PostDelayedTask(
76        BrowserThread::UI, FROM_HERE,
77        base::Bind(&NetworkLibraryImplStub::CompleteCellularActivate,
78                   weak_pointer_factory_.GetWeakPtr()),
79        base::TimeDelta::FromSeconds(kCellularActivateDelaySeconds));
80  } else {
81    CompleteWifiInit();
82    CompleteCellularInit();
83  }
84}
85
86bool NetworkLibraryImplStub::IsCros() const {
87  return false;
88}
89
90////////////////////////////////////////////////////////////////////////////
91// NetworkLibraryImplStub private methods.
92
93void NetworkLibraryImplStub::CompleteWifiInit() {
94  VLOG(1) << "CompleteWifiInit()";
95
96  uninitialized_devices_ &= ~(1 << TYPE_WIFI);
97  enabled_devices_ |= (available_devices_ & (1 << TYPE_WIFI));
98
99  // Profiles
100  AddProfile("default", PROFILE_SHARED);
101  AddProfile("user", PROFILE_USER);
102
103  // Networks
104  // If these change, the expectations in network_library_unittest and
105  // network_menu_icon_unittest need to be changed also.
106
107  if (IsEthernetEnabled()) {
108    Network* ethernet = new EthernetNetwork("eth1");
109    ethernet->set_name("Fake Ethernet");
110    ethernet->set_connected();
111    AddStubNetwork(ethernet, PROFILE_SHARED);
112    ethernet->set_is_active(ethernet->connected());
113  }
114
115  WifiNetwork* wifi1 = new WifiNetwork("wifi1");
116  wifi1->set_name("Fake WiFi1");
117  wifi1->set_strength(100);
118  wifi1->set_connected();
119  wifi1->set_encryption(SECURITY_NONE);
120  AddStubNetwork(wifi1, PROFILE_SHARED);
121
122  WifiNetwork* wifi2 = new WifiNetwork("wifi2");
123  wifi2->set_name("Fake WiFi2");
124  wifi2->set_strength(70);
125  wifi2->set_encryption(SECURITY_NONE);
126  AddStubNetwork(wifi2, PROFILE_SHARED);
127
128  WifiNetwork* wifi3 = new WifiNetwork("wifi3");
129  wifi3->set_name("Fake WiFi3 Encrypted with a long name");
130  wifi3->set_strength(60);
131  wifi3->set_encryption(SECURITY_WEP);
132  wifi3->set_passphrase_required(true);
133  AddStubNetwork(wifi3, PROFILE_USER);
134
135  CertificatePattern pattern;
136  IssuerSubjectPattern issuer;
137  issuer.set_organization("Google, Inc.");
138  pattern.set_issuer(issuer);
139  std::vector<std::string> enrollment_uris;
140  enrollment_uris.push_back("http://youtu.be/dQw4w9WgXcQ");
141  enrollment_uris.push_back("chrome-extension://abc/keygen-cert.html");
142  pattern.set_enrollment_uri_list(enrollment_uris);
143
144  WifiNetwork* wifi_cert_pattern = new WifiNetwork("wifi_cert_pattern");
145  wifi_cert_pattern->set_name("Fake WiFi CertPattern 802.1x");
146  wifi_cert_pattern->set_strength(50);
147  wifi_cert_pattern->set_connectable(false);
148  wifi_cert_pattern->set_encryption(SECURITY_8021X);
149  wifi_cert_pattern->SetEAPMethod(EAP_METHOD_TLS);
150  wifi_cert_pattern->SetEAPUseSystemCAs(true);
151  wifi_cert_pattern->SetEAPIdentity("user@example.com");
152  wifi_cert_pattern->SetEAPPhase2Auth(EAP_PHASE_2_AUTH_AUTO);
153  wifi_cert_pattern->set_client_cert_type(CLIENT_CERT_TYPE_PATTERN);
154  wifi_cert_pattern->set_client_cert_pattern(pattern);
155  wifi_cert_pattern->set_eap_save_credentials(true);
156
157  AddStubNetwork(wifi_cert_pattern, PROFILE_USER);
158
159  WifiNetwork* wifi4 = new WifiNetwork("wifi4");
160  wifi4->set_name("Fake WiFi4 802.1x");
161  wifi4->set_strength(50);
162  wifi4->set_connectable(false);
163  wifi4->set_encryption(SECURITY_8021X);
164  wifi4->SetEAPMethod(EAP_METHOD_PEAP);
165  wifi4->SetEAPIdentity("nobody@google.com");
166  wifi4->SetEAPPassphrase("password");
167  AddStubNetwork(wifi4, PROFILE_NONE);
168
169  WifiNetwork* wifi5 = new WifiNetwork("wifi5");
170  wifi5->set_name("Fake WiFi5 UTF-8 SSID ");
171  wifi5->SetSsid("Fake WiFi5 UTF-8 SSID \u3042\u3044\u3046");
172  wifi5->set_strength(25);
173  AddStubNetwork(wifi5, PROFILE_NONE);
174
175  WifiNetwork* wifi6 = new WifiNetwork("wifi6");
176  wifi6->set_name("Fake WiFi6 latin-1 SSID ");
177  wifi6->SetSsid("Fake WiFi6 latin-1 SSID \xc0\xcb\xcc\xd6\xfb");
178  wifi6->set_strength(20);
179  AddStubNetwork(wifi6, PROFILE_NONE);
180
181  WifiNetwork* wifi7 = new WifiNetwork("wifi7");
182  wifi7->set_name("Fake Wifi7 (policy-managed)");
183  wifi7->set_strength(100);
184  wifi7->set_connectable(false);
185  wifi7->set_passphrase_required(true);
186  wifi7->set_encryption(SECURITY_8021X);
187  wifi7->SetEAPMethod(EAP_METHOD_PEAP);
188  wifi7->SetEAPIdentity("enterprise@example.com");
189  wifi7->SetEAPPassphrase("password");
190  NetworkUIData wifi7_ui_data;
191  wifi7_ui_data.set_onc_source(onc::ONC_SOURCE_DEVICE_POLICY);
192  wifi7->set_ui_data(wifi7_ui_data);
193  AddStubNetwork(wifi7, PROFILE_USER);
194
195  VirtualNetwork* vpn1 = new VirtualNetwork("vpn1");
196  vpn1->set_name("Fake VPN1");
197  vpn1->set_server_hostname("vpn1server.fake.com");
198  vpn1->set_provider_type(PROVIDER_TYPE_L2TP_IPSEC_PSK);
199  vpn1->set_username("VPN User 1");
200  AddStubNetwork(vpn1, PROFILE_USER);
201
202  VirtualNetwork* vpn2 = new VirtualNetwork("vpn2");
203  vpn2->set_name("Fake VPN2");
204  vpn2->set_server_hostname("vpn2server.fake.com");
205  vpn2->set_provider_type(PROVIDER_TYPE_L2TP_IPSEC_USER_CERT);
206  vpn2->set_username("VPN User 2");
207  AddStubNetwork(vpn2, PROFILE_USER);
208
209  VirtualNetwork* vpn3 = new VirtualNetwork("vpn3");
210  vpn3->set_name("Fake VPN3");
211  vpn3->set_server_hostname("vpn3server.fake.com");
212  vpn3->set_provider_type(PROVIDER_TYPE_OPEN_VPN);
213  AddStubNetwork(vpn3, PROFILE_USER);
214
215  VirtualNetwork* vpn4 = new VirtualNetwork("vpn4");
216  vpn4->set_name("Fake VPN4 (policy-managed)");
217  vpn4->set_server_hostname("vpn4server.fake.com");
218  vpn4->set_provider_type(PROVIDER_TYPE_OPEN_VPN);
219  NetworkUIData vpn4_ui_data;
220  vpn4_ui_data.set_onc_source(onc::ONC_SOURCE_DEVICE_POLICY);
221  vpn4->set_ui_data(vpn4_ui_data);
222  AddStubNetwork(vpn4, PROFILE_USER);
223
224  VirtualNetwork* vpn_cert_pattern = new VirtualNetwork("vpn_cert_pattern");
225  vpn_cert_pattern->set_name("Fake VPN CertPattern");
226  vpn_cert_pattern->set_server_hostname("vpn4server.fake.com");
227  vpn_cert_pattern->set_provider_type(PROVIDER_TYPE_OPEN_VPN);
228  vpn_cert_pattern->set_client_cert_type(CLIENT_CERT_TYPE_PATTERN);
229  vpn_cert_pattern->set_client_cert_pattern(pattern);
230
231  AddStubNetwork(vpn_cert_pattern, PROFILE_USER);
232
233  wifi_scanning_ = false;
234
235  // Ensure our active network is connected and vice versa, otherwise our
236  // autotest browser_tests sometimes conclude the device is offline.
237  CHECK(active_network()->connected())
238      << "Active: " << active_network()->name();
239  CHECK(connected_network()->is_active());
240
241  std::string test_blob(
242        "{"
243        "  \"NetworkConfigurations\": ["
244        "    {"
245        "      \"GUID\": \"guid\","
246        "      \"Type\": \"VPN\","
247        "      \"Name\": \"VPNtest\","
248        "      \"VPN\": {"
249        "        \"Host\": \"172.22.12.98\","
250        "        \"Type\": \"L2TP-IPsec\","
251        "        \"IPsec\": {"
252        "          \"AuthenticationType\": \"PSK\","
253        "          \"IKEVersion\": 2,"
254        "          \"PSK\": \"chromeos\","
255        "        },"
256        "        \"L2TP\": {"
257        "          \"Username\": \"vpntest\","
258        "        }"
259        "      }"
260        "    }"
261        "  ],"
262        "  \"Certificates\": []"
263        "}");
264//  LoadOncNetworks(test_blob, "", onc::ONC_SOURCE_USER_IMPORT, NULL);
265
266  SignalNetworkManagerObservers();
267}
268
269void NetworkLibraryImplStub::CompleteCellularInit() {
270  VLOG(1) << "CompleteCellularInit()";
271
272  uninitialized_devices_ &= ~(1 << TYPE_CELLULAR);
273  uninitialized_devices_ &= ~(1 << TYPE_WIMAX);
274  enabled_devices_ |= (available_devices_ & (1 << TYPE_CELLULAR));
275  enabled_devices_ |= (available_devices_ & (1 << TYPE_WIMAX));
276
277  base::ListValue supported_carriers;
278  supported_carriers.Append(new StringValue("Generic CDMA Carrier 1"));
279  supported_carriers.Append(new StringValue("Generic UMTS"));
280  supported_carriers.Append(new StringValue("Generic CDMA Carrier 2"));
281  supported_carriers.Append(new StringValue("Generic CDMA Carrier 3"));
282
283  NetworkDevice* cellular = new NetworkDevice("cellular");
284  cellular->type_ = TYPE_CELLULAR;
285  cellular->set_technology_family(TECHNOLOGY_FAMILY_CDMA);
286  cellular->set_carrier("Generic CDMA Carrier 2");
287  cellular->imsi_ = "123456789012345";
288  cellular->set_supported_carriers(supported_carriers);
289  device_map_["cellular"] = cellular;
290
291  CellularApn apn;
292  apn.apn = "apn";
293  apn.network_id = "network_id";
294  apn.username = "username";
295  apn.password = "password";
296  apn.name = "name";
297  apn.localized_name = "localized_name";
298  apn.language = "language";
299
300  CellularApnList apn_list;
301  apn_list.push_back(apn);
302
303  NetworkDevice* cellular_gsm = new NetworkDevice("cellular_gsm");
304  cellular_gsm->type_ = TYPE_CELLULAR;
305  cellular_gsm->set_technology_family(TECHNOLOGY_FAMILY_GSM);
306  cellular_gsm->imsi_ = "123456789012345";
307  cellular_gsm->set_sim_pin_required(SIM_PIN_REQUIRED);
308  cellular_gsm->set_provider_apn_list(apn_list);
309  cellular_gsm->set_supported_carriers(supported_carriers);
310  device_map_["cellular_gsm"] = cellular_gsm;
311
312  CellularNetwork* cellular1 = new CellularNetwork("cellular1");
313  cellular1->set_name("Fake Cellular 1");
314  cellular1->set_device_path(cellular->device_path());
315  cellular1->set_strength(100);
316  cellular1->set_connected();
317  cellular1->set_activation_state(ACTIVATION_STATE_ACTIVATED);
318  cellular1->set_payment_url(std::string("http://www.google.com"));
319  cellular1->set_usage_url(std::string("http://www.google.com"));
320  cellular1->set_network_technology(NETWORK_TECHNOLOGY_EVDO);
321  AddStubNetwork(cellular1, PROFILE_NONE);
322
323  CellularNetwork* cellular2 = new CellularNetwork("cellular2");
324  cellular2->set_name("Fake Cellular 2");
325  cellular2->set_device_path(cellular->device_path());
326  cellular2->set_strength(50);
327  cellular2->set_activation_state(ACTIVATION_STATE_ACTIVATING);
328  cellular2->set_network_technology(NETWORK_TECHNOLOGY_UMTS);
329  cellular2->set_roaming_state(ROAMING_STATE_ROAMING);
330  cellular2->set_payment_url(std::string("http://www.google.com"));
331  cellular2->set_usage_url(std::string("http://www.google.com"));
332  AddStubNetwork(cellular2, PROFILE_NONE);
333
334  CellularNetwork* cellular3 = new CellularNetwork("cellular3");
335  cellular3->set_name("Fake Cellular 3 (policy-managed)");
336  cellular3->set_device_path(cellular->device_path());
337  cellular3->set_activation_state(ACTIVATION_STATE_ACTIVATED);
338  cellular3->set_network_technology(NETWORK_TECHNOLOGY_EVDO);
339  NetworkUIData cellular3_ui_data;
340  cellular3_ui_data.set_onc_source(onc::ONC_SOURCE_USER_POLICY);
341  cellular3->set_ui_data(cellular3_ui_data);
342  AddStubNetwork(cellular3, PROFILE_NONE);
343
344  CellularNetwork* cellular4 = new CellularNetwork("cellular4");
345  cellular4->set_name("Fake Cellular 4 (policy-managed)");
346  cellular4->set_device_path(cellular_gsm->device_path());
347  cellular4->set_activation_state(ACTIVATION_STATE_ACTIVATED);
348  cellular4->set_network_technology(NETWORK_TECHNOLOGY_GSM);
349  NetworkUIData cellular4_ui_data;
350  cellular4_ui_data.set_onc_source(onc::ONC_SOURCE_USER_POLICY);
351  cellular4->set_ui_data(cellular4_ui_data);
352  AddStubNetwork(cellular4, PROFILE_NONE);
353
354  WimaxNetwork* wimax1 = new WimaxNetwork("wimax1");
355  wimax1->set_name("Fake WiMAX Protected");
356  wimax1->set_strength(75);
357  wimax1->set_connectable(true);
358  wimax1->set_eap_identity("WiMAX User 1");
359  wimax1->set_passphrase_required(true);
360  AddStubNetwork(wimax1, PROFILE_NONE);
361
362  WimaxNetwork* wimax2 = new WimaxNetwork("wimax2");
363  wimax2->set_name("Fake WiMAX Open");
364  wimax2->set_strength(50);
365  wimax2->set_connected();
366  wimax2->set_passphrase_required(false);
367  AddStubNetwork(wimax2, PROFILE_NONE);
368
369  SignalNetworkManagerObservers();
370}
371
372void NetworkLibraryImplStub::CompleteCellularActivate() {
373  VLOG(1) << "CompleteCellularActivate()";
374  CellularNetwork* cellular2 = FindCellularNetworkByPath("cellular2");
375  cellular2->set_activation_state(ACTIVATION_STATE_ACTIVATED);
376  SignalNetworkManagerObservers();
377}
378
379void NetworkLibraryImplStub::AddStubNetwork(
380    Network* network, NetworkProfileType profile_type) {
381  // Currently we don't prioritize networks in Shill so don't do so in the stub.
382  // network->priority_order_ = network_priority_order_++;
383  network->CalculateUniqueId();
384  if (!network->unique_id().empty())
385    network_unique_id_map_[network->unique_id()] = network;
386  AddNetwork(network);
387  UpdateActiveNetwork(network);
388  SetProfileType(network, profile_type);
389  AddStubRememberedNetwork(network);
390}
391
392// Add a remembered network to the appropriate profile if specified.
393void NetworkLibraryImplStub::AddStubRememberedNetwork(Network* network) {
394  if (network->profile_type() == PROFILE_NONE)
395    return;
396
397  Network* remembered = FindRememberedFromNetwork(network);
398  if (remembered) {
399    // This network is already in the rememebred list. Check to see if the
400    // type has changed.
401    if (remembered->profile_type() == network->profile_type())
402      return;  // Same type, nothing to do.
403    // Delete the existing remembered network from the previous profile.
404    DeleteRememberedNetwork(remembered->service_path());
405    remembered = NULL;
406  }
407
408  NetworkProfile* profile = GetProfileForType(network->profile_type());
409  if (profile) {
410    profile->services.insert(network->service_path());
411  } else {
412    LOG(ERROR) << "No profile type: " << network->profile_type();
413    return;
414  }
415
416  if (network->type() == TYPE_WIFI) {
417    WifiNetwork* remembered_wifi = new WifiNetwork(network->service_path());
418    remembered_wifi->set_encryption(remembered_wifi->encryption());
419    NetworkUIData wifi_ui_data;
420    wifi_ui_data.set_onc_source(network->ui_data().onc_source());
421    remembered_wifi->set_ui_data(wifi_ui_data);
422    remembered = remembered_wifi;
423  } else if (network->type() == TYPE_VPN) {
424    VirtualNetwork* remembered_vpn =
425        new VirtualNetwork(network->service_path());
426    remembered_vpn->set_server_hostname("vpnserver.fake.com");
427    remembered_vpn->set_provider_type(PROVIDER_TYPE_L2TP_IPSEC_USER_CERT);
428    NetworkUIData vpn_ui_data;
429    vpn_ui_data.set_onc_source(network->ui_data().onc_source());
430    remembered_vpn->set_ui_data(vpn_ui_data);
431    remembered = remembered_vpn;
432  }
433  if (remembered) {
434    remembered->set_name(network->name());
435    remembered->set_unique_id(network->unique_id());
436    // ValidateAndAddRememberedNetwork will insert the network into the right
437    // remembered_*_networks_ list and the remembered_network_map_.
438    if (!ValidateAndAddRememberedNetwork(remembered))
439      NOTREACHED();
440    remembered->set_profile_path(profile->path);
441    remembered->set_profile_type(profile->type);
442  }
443}
444
445void NetworkLibraryImplStub::ConnectToNetwork(Network* network) {
446  std::string passphrase;
447  if (network->type() == TYPE_WIFI) {
448    WifiNetwork* wifi = static_cast<WifiNetwork*>(network);
449    if (wifi->passphrase_required())
450      passphrase = wifi->passphrase();
451  } else if (network->type() == TYPE_WIMAX) {
452    WimaxNetwork* wimax = static_cast<WimaxNetwork*>(network);
453    if (wimax->passphrase_required())
454      passphrase = wimax->eap_passphrase();
455  }
456  if (!passphrase.empty()) {
457    if (passphrase.find("bad") == 0) {
458      NetworkConnectCompleted(network, CONNECT_BAD_PASSPHRASE);
459      return;
460    } else if (passphrase.find("error") == 0) {
461      NetworkConnectCompleted(network, CONNECT_FAILED);
462      return;
463    }
464  }
465
466  // Disconnect ethernet when connecting to a new network (for UI testing).
467  if (IsEthernetEnabled() && network->type() != TYPE_VPN) {
468    ethernet_->set_is_active(false);
469    ethernet_->set_disconnected();
470  }
471
472  // Set connected state.
473  network->set_connected();
474  network->set_user_connect_state(USER_CONNECT_CONNECTED);
475
476  // Make the connected network the highest priority network.
477  // Set all other networks of the same type to disconnected + inactive;
478  int old_priority_order = network->priority_order_;
479  network->priority_order_ = 0;
480  for (NetworkMap::iterator iter = network_map_.begin();
481       iter != network_map_.end(); ++iter) {
482    Network* other = iter->second;
483    if (other == network)
484      continue;
485    if (other->priority_order_ < old_priority_order)
486      other->priority_order_++;
487    if (other->type() == network->type()) {
488      other->set_is_active(false);
489      other->set_disconnected();
490    }
491  }
492
493  // Remember connected network.
494  if (network->profile_type() == PROFILE_NONE) {
495    NetworkProfileType profile_type = PROFILE_USER;
496    if (network->type() == TYPE_WIFI) {
497      WifiNetwork* wifi = static_cast<WifiNetwork*>(network);
498      if (!wifi->encrypted())
499        profile_type = PROFILE_SHARED;
500    }
501    SetProfileType(network, profile_type);
502  }
503  AddStubRememberedNetwork(network);
504
505  // Call Completed and signal observers.
506  NetworkConnectCompleted(network, CONNECT_SUCCESS);
507}
508
509void NetworkLibraryImplStub::ScanCompleted() {
510  wifi_scanning_ = false;
511  SignalNetworkManagerObservers();
512}
513
514//////////////////////////////////////////////////////////////////////////////
515// NetworkLibraryImplBase implementation.
516
517void NetworkLibraryImplStub::MonitorNetworkStart(
518    const std::string& service_path) {}
519
520void NetworkLibraryImplStub::MonitorNetworkStop(
521    const std::string& service_path) {}
522
523void NetworkLibraryImplStub::MonitorNetworkDeviceStart(
524    const std::string& device_path) {}
525
526void NetworkLibraryImplStub::MonitorNetworkDeviceStop(
527    const std::string& device_path) {}
528
529void NetworkLibraryImplStub::CallConfigureService(
530    const std::string& identifier,
531    const DictionaryValue* info) {
532  DictionaryValue*& config_entry = service_configurations_[identifier];
533  delete config_entry;
534  config_entry = info->DeepCopy();
535}
536
537void NetworkLibraryImplStub::CallConnectToNetwork(Network* network) {
538  // Immediately set the network to active to mimic shill's behavior.
539  SetActiveNetwork(network->type(), network->service_path());
540  // If a delay has been set (i.e. we are interactive), delay the call to
541  // ConnectToNetwork (but signal observers since we changed connecting state).
542  if (IsInteractive()) {
543    const int kConnectDelayMs = 4 * 1000;
544    BrowserThread::PostDelayedTask(
545        BrowserThread::UI, FROM_HERE,
546        base::Bind(&NetworkLibraryImplStub::ConnectToNetwork,
547                   weak_pointer_factory_.GetWeakPtr(), network),
548        base::TimeDelta::FromMilliseconds(kConnectDelayMs));
549    SignalNetworkManagerObservers();
550    NotifyNetworkChanged(network);
551  } else {
552    ConnectToNetwork(network);
553  }
554}
555
556void NetworkLibraryImplStub::CallRequestWifiNetworkAndConnect(
557    const std::string& ssid, ConnectionSecurity security) {
558  WifiNetwork* wifi = new WifiNetwork(ssid);
559  wifi->set_name(ssid);
560  wifi->set_encryption(security);
561  AddNetwork(wifi);
562  ConnectToWifiNetworkUsingConnectData(wifi);
563  SignalNetworkManagerObservers();
564}
565
566void NetworkLibraryImplStub::CallRequestVirtualNetworkAndConnect(
567    const std::string& service_name,
568    const std::string& server_hostname,
569    ProviderType provider_type) {
570  VirtualNetwork* vpn = new VirtualNetwork(service_name);
571  vpn->set_name(service_name);
572  vpn->set_server_hostname(server_hostname);
573  vpn->set_provider_type(provider_type);
574  AddNetwork(vpn);
575  ConnectToVirtualNetworkUsingConnectData(vpn);
576  SignalNetworkManagerObservers();
577}
578
579void NetworkLibraryImplStub::CallDeleteRememberedNetwork(
580    const std::string& profile_path,
581    const std::string& service_path) {}
582
583void NetworkLibraryImplStub::CallEnableNetworkDeviceType(
584    ConnectionType device, bool enable) {
585  if (enable) {
586    if (device == TYPE_WIFI && !wifi_enabled()) {
587      wifi_networks_.swap(disabled_wifi_networks_);
588      disabled_wifi_networks_.clear();
589      RequestNetworkScan();
590    } else if (device == TYPE_WIMAX && !wimax_enabled()) {
591      wimax_networks_.swap(disabled_wimax_networks_);
592      disabled_wimax_networks_.clear();
593    } else if (device == TYPE_CELLULAR && !cellular_enabled()) {
594      cellular_networks_.swap(disabled_cellular_networks_);
595      disabled_cellular_networks_.clear();
596    }
597    enabled_devices_ |= (1 << device);
598  } else {
599    if (device == TYPE_WIFI && wifi_enabled()) {
600      wifi_networks_.swap(disabled_wifi_networks_);
601      wifi_networks_.clear();
602      if (active_wifi_)
603        DisconnectFromNetwork(active_wifi_);
604    } else if (device == TYPE_WIMAX && wimax_enabled()) {
605        wimax_networks_.swap(disabled_wimax_networks_);
606        wimax_networks_.clear();
607        if (active_wimax_)
608          DisconnectFromNetwork(active_wimax_);
609    } else if (device == TYPE_CELLULAR && cellular_enabled()) {
610      cellular_networks_.swap(disabled_cellular_networks_);
611      cellular_networks_.clear();
612      if (active_cellular_)
613        DisconnectFromNetwork(active_cellular_);
614    }
615    enabled_devices_ &= ~(1 << device);
616  }
617  SignalNetworkManagerObservers();
618}
619
620void NetworkLibraryImplStub::CallRemoveNetwork(const Network* network) {}
621
622/////////////////////////////////////////////////////////////////////////////
623// NetworkLibrary implementation.
624
625void NetworkLibraryImplStub::ChangePin(const std::string& old_pin,
626                                       const std::string& new_pin) {
627  sim_operation_ = SIM_OPERATION_CHANGE_PIN;
628  if (!pin_required_ || old_pin == pin_) {
629    pin_ = new_pin;
630    NotifyPinOperationCompleted(PIN_ERROR_NONE);
631  } else {
632    NotifyPinOperationCompleted(PIN_ERROR_INCORRECT_CODE);
633  }
634}
635
636void NetworkLibraryImplStub::ChangeRequirePin(bool require_pin,
637                                              const std::string& pin) {
638  sim_operation_ = SIM_OPERATION_CHANGE_REQUIRE_PIN;
639  if (!pin_required_ || pin == pin_) {
640    pin_required_ = require_pin;
641    NotifyPinOperationCompleted(PIN_ERROR_NONE);
642  } else {
643    NotifyPinOperationCompleted(PIN_ERROR_INCORRECT_CODE);
644  }
645}
646
647void NetworkLibraryImplStub::EnterPin(const std::string& pin) {
648  sim_operation_ = SIM_OPERATION_ENTER_PIN;
649  if (!pin_required_ || pin == pin_) {
650    pin_entered_ = true;
651    NotifyPinOperationCompleted(PIN_ERROR_NONE);
652  } else {
653    NotifyPinOperationCompleted(PIN_ERROR_INCORRECT_CODE);
654  }
655}
656
657void NetworkLibraryImplStub::UnblockPin(const std::string& puk,
658                                        const std::string& new_pin) {
659  sim_operation_ = SIM_OPERATION_UNBLOCK_PIN;
660  // TODO(stevenjb): something?
661  NotifyPinOperationCompleted(PIN_ERROR_NONE);
662}
663
664void NetworkLibraryImplStub::RequestCellularScan() {}
665
666void NetworkLibraryImplStub::RequestCellularRegister(
667    const std::string& network_id) {}
668
669void NetworkLibraryImplStub::SetCellularDataRoamingAllowed(bool new_value) {}
670
671void NetworkLibraryImplStub::SetCarrier(
672    const std::string& carrier,
673    const NetworkOperationCallback& completed) {
674  // Call the completed callback with a 10s delay if we're interactive.
675  int delay_ms = IsInteractive() ? 10000 : 100;
676  BrowserThread::PostDelayedTask(
677      BrowserThread::UI,
678      FROM_HERE,
679      base::Bind(completed, "", NETWORK_METHOD_ERROR_NONE,""),
680      base::TimeDelta::FromMilliseconds(delay_ms));
681}
682
683bool NetworkLibraryImplStub::IsCellularAlwaysInRoaming() {
684  return false;
685}
686
687void NetworkLibraryImplStub::RequestNetworkScan() {
688  // This is triggered by user interaction, so set a network connect delay.
689  int scan_delay_ms = IsInteractive() ? 2 * 1000 : 100;
690  wifi_scanning_ = true;
691  BrowserThread::PostDelayedTask(
692      BrowserThread::UI, FROM_HERE,
693      base::Bind(&NetworkLibraryImplStub::ScanCompleted,
694                 weak_pointer_factory_.GetWeakPtr()),
695      base::TimeDelta::FromMilliseconds(scan_delay_ms));
696}
697
698void NetworkLibraryImplStub::DisconnectFromNetwork(const Network* network) {
699  // Update the network state here since no network manager in stub impl.
700  Network* modify_network = const_cast<Network*>(network);
701  modify_network->set_is_active(false);
702  modify_network->set_disconnected();
703  if (network == active_wifi_)
704    active_wifi_ = NULL;
705  else if (network == active_cellular_)
706    active_cellular_ = NULL;
707  else if (network == active_virtual_)
708    active_virtual_ = NULL;
709  SignalNetworkManagerObservers();
710  NotifyNetworkChanged(network);
711}
712
713void NetworkLibraryImplStub::GetIPConfigs(
714    const std::string& device_path,
715    HardwareAddressFormat format,
716    const NetworkGetIPConfigsCallback& callback) {
717  callback.Run(ip_configs_, hardware_address_);
718}
719
720void NetworkLibraryImplStub::SetIPParameters(const std::string& service_path,
721                                             const std::string& address,
722                                             const std::string& netmask,
723                                             const std::string& gateway,
724                                             const std::string& name_servers,
725                                             int dhcp_usage_mask) {
726  VLOG(1) << "Setting IP parameters:"
727      << "\n  address: " << address
728      << (dhcp_usage_mask & USE_DHCP_ADDRESS ?
729          " (ignored)" : " (in use)")
730      << "\n  netmask: " << netmask
731      << (dhcp_usage_mask & USE_DHCP_NETMASK ?
732          " (ignored)" : " (in use)")
733      << "\n  gateway: " << gateway
734      << (dhcp_usage_mask & USE_DHCP_GATEWAY ?
735          " (ignored)" : " (in use)")
736      << "\n  name_servers: " << name_servers
737      << (dhcp_usage_mask & USE_DHCP_NAME_SERVERS ?
738          " (ignored)" : " (in use)");
739
740    Network* network = FindNetworkByPath(service_path);
741    if (network)
742      ip_configs_.push_back(NetworkIPConfig(network->device_path(),
743                                            IPCONFIG_TYPE_IPV4,
744                                            address,
745                                            netmask,
746                                            gateway,
747                                            name_servers));
748}
749
750void NetworkLibraryImplStub::RequestNetworkServiceProperties(
751    const std::string& service_path,
752    const NetworkServicePropertiesCallback& callback) {
753  BrowserThread::PostDelayedTask(
754      BrowserThread::UI,
755      FROM_HERE,
756      base::Bind(&NetworkLibraryImplStub::SendNetworkServiceProperties,
757                 weak_pointer_factory_.GetWeakPtr(),
758                 service_path, callback),
759      base::TimeDelta::FromMilliseconds(100));
760}
761
762void NetworkLibraryImplStub::SendNetworkServiceProperties(
763    const std::string& service_path,
764    const NetworkServicePropertiesCallback& callback) {
765  scoped_ptr<base::DictionaryValue> dictionary(new base::DictionaryValue());
766  Network* network = FindNetworkByPath(service_path);
767  if (network) {
768    // Populate a few common properties.
769    dictionary->SetString(flimflam::kTypeProperty,
770                          ConnectionTypeToString(network->type()));
771    dictionary->SetString(flimflam::kNameProperty, network->name());
772    dictionary->SetString(flimflam::kGuidProperty, network->unique_id());
773    dictionary->SetString(flimflam::kStateProperty,
774                          ConnectionStateToString(network->state()));
775  }
776  callback.Run(service_path, dictionary.get());
777}
778
779const std::map<std::string, base::DictionaryValue*>&
780NetworkLibraryImplStub::GetConfigurations() {
781  return service_configurations_;
782}
783
784}  // namespace chromeos
785