• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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.h"
6 
7 #include <algorithm>
8 #include <map>
9 
10 #include "base/i18n/icu_encoding_detection.h"
11 #include "base/i18n/icu_string_conversions.h"
12 #include "base/i18n/time_formatting.h"
13 #include "base/metrics/histogram.h"
14 #include "base/stl_util-inl.h"
15 #include "base/string_number_conversions.h"
16 #include "base/string_util.h"
17 #include "base/stringprintf.h"
18 #include "base/utf_string_conversions.h"
19 #include "base/utf_string_conversion_utils.h"
20 #include "base/values.h"
21 #include "chrome/browser/chromeos/cros/cros_library.h"
22 #include "chrome/browser/chromeos/login/user_manager.h"
23 #include "chrome/browser/chromeos/network_login_observer.h"
24 #include "chrome/browser/chromeos/user_cros_settings_provider.h"
25 #include "chrome/common/time_format.h"
26 #include "content/browser/browser_thread.h"
27 #include "grit/generated_resources.h"
28 #include "ui/base/l10n/l10n_util.h"
29 
30 ////////////////////////////////////////////////////////////////////////////////
31 // Implementation notes.
32 // NetworkLibraryImpl manages a series of classes that describe network devices
33 // and services:
34 //
35 // NetworkDevice: e.g. ethernet, wifi modem, cellular modem
36 //  device_map_: canonical map<path,NetworkDevice*> for devices
37 //
38 // Network: a network service ("network").
39 //  network_map_: canonical map<path,Network*> for all visible networks.
40 //  EthernetNetwork
41 //   ethernet_: EthernetNetwork* to the active ethernet network in network_map_.
42 //  WirelessNetwork: a Wifi or Cellular Network.
43 //  WifiNetwork
44 //   active_wifi_: WifiNetwork* to the active wifi network in network_map_.
45 //   wifi_networks_: ordered vector of WifiNetwork* entries in network_map_,
46 //       in descending order of importance.
47 //  CellularNetwork
48 //   active_cellular_: Cellular version of wifi_.
49 //   cellular_networks_: Cellular version of wifi_.
50 // network_unique_id_map_: map<unique_id,Network*> for visible networks.
51 // remembered_network_map_: a canonical map<path,Network*> for all networks
52 //     remembered in the active Profile ("favorites").
53 // remembered_wifi_networks_: ordered vector of WifiNetwork* entries in
54 //     remembered_network_map_, in descending order of preference.
55 //
56 // network_manager_monitor_: a handle to the libcros network Manager handler.
57 // NetworkManagerStatusChanged: This handles all messages from the Manager.
58 //   Messages are parsed here and the appropriate updates are then requested.
59 //
60 // UpdateNetworkServiceList: This is the primary Manager handler. It handles
61 //  the "Services" message which list all visible networks. The handler
62 //  rebuilds the network lists without destroying existing Network structures,
63 //  then requests neccessary updates to be fetched asynchronously from
64 //  libcros (RequestNetworkServiceInfo).
65 //
66 // TODO(stevenjb): Document cellular data plan handlers.
67 //
68 // AddNetworkObserver: Adds an observer for a specific network.
69 // NetworkObserverList: A monitor and list of observers of a network.
70 // network_monitor_: a handle to the libcros network Service handler.
71 // UpdateNetworkStatus: This handles changes to a monitored service, typically
72 //     changes to transient states like Strength. (Note: also updates State).
73 //
74 // AddNetworkDeviceObserver: Adds an observer for a specific device.
75 //                           Will be called on any device property change.
76 // NetworkDeviceObserverList: A monitor and list of observers of a device.
77 // UpdateNetworkDeviceStatus: Handles changes to a monitored device, like
78 //     SIM lock state and updates device state.
79 //
80 // All *Pin(...) methods use internal callback that would update cellular
81 //    device state once async call is completed and notify all device observers.
82 //
83 ////////////////////////////////////////////////////////////////////////////////
84 
85 namespace chromeos {
86 
87 // Local constants.
88 namespace {
89 
90 // Only send network change notifications to observers once every 50ms.
91 const int kNetworkNotifyDelayMs = 50;
92 
93 // How long we should remember that cellular plan payment was received.
94 const int kRecentPlanPaymentHours = 6;
95 
96 // Default value of the SIM unlock retries count. It is updated to the real
97 // retries count once cellular device with SIM card is initialized.
98 // If cellular device doesn't have SIM card, then retries are never used.
99 const int kDefaultSimUnlockRetriesCount = 999;
100 
101 // Format of the Carrier ID: <carrier name> (<carrier country>).
102 const char* kCarrierIdFormat = "%s (%s)";
103 
104 // Type of a pending SIM operation.
105 enum SimOperationType {
106   SIM_OPERATION_NONE               = 0,
107   SIM_OPERATION_CHANGE_PIN         = 1,
108   SIM_OPERATION_CHANGE_REQUIRE_PIN = 2,
109   SIM_OPERATION_ENTER_PIN          = 3,
110   SIM_OPERATION_UNBLOCK_PIN        = 4,
111 };
112 
113 // D-Bus interface string constants.
114 
115 // Flimflam property names.
116 const char* kSecurityProperty = "Security";
117 const char* kPassphraseProperty = "Passphrase";
118 const char* kIdentityProperty = "Identity";
119 const char* kCertPathProperty = "CertPath";
120 const char* kPassphraseRequiredProperty = "PassphraseRequired";
121 const char* kSaveCredentialsProperty = "SaveCredentials";
122 const char* kProfilesProperty = "Profiles";
123 const char* kServicesProperty = "Services";
124 const char* kServiceWatchListProperty = "ServiceWatchList";
125 const char* kAvailableTechnologiesProperty = "AvailableTechnologies";
126 const char* kEnabledTechnologiesProperty = "EnabledTechnologies";
127 const char* kConnectedTechnologiesProperty = "ConnectedTechnologies";
128 const char* kDefaultTechnologyProperty = "DefaultTechnology";
129 const char* kOfflineModeProperty = "OfflineMode";
130 const char* kSignalStrengthProperty = "Strength";
131 const char* kNameProperty = "Name";
132 const char* kStateProperty = "State";
133 const char* kConnectivityStateProperty = "ConnectivityState";
134 const char* kTypeProperty = "Type";
135 const char* kDeviceProperty = "Device";
136 const char* kActivationStateProperty = "Cellular.ActivationState";
137 const char* kNetworkTechnologyProperty = "Cellular.NetworkTechnology";
138 const char* kRoamingStateProperty = "Cellular.RoamingState";
139 const char* kOperatorNameProperty = "Cellular.OperatorName";
140 const char* kOperatorCodeProperty = "Cellular.OperatorCode";
141 const char* kServingOperatorProperty = "Cellular.ServingOperator";
142 const char* kPaymentURLProperty = "Cellular.OlpUrl";
143 const char* kUsageURLProperty = "Cellular.UsageUrl";
144 const char* kCellularApnProperty = "Cellular.APN";
145 const char* kCellularLastGoodApnProperty = "Cellular.LastGoodAPN";
146 const char* kWifiHexSsid = "WiFi.HexSSID";
147 const char* kWifiFrequency = "WiFi.Frequency";
148 const char* kWifiHiddenSsid = "WiFi.HiddenSSID";
149 const char* kWifiPhyMode = "WiFi.PhyMode";
150 const char* kFavoriteProperty = "Favorite";
151 const char* kConnectableProperty = "Connectable";
152 const char* kAutoConnectProperty = "AutoConnect";
153 const char* kIsActiveProperty = "IsActive";
154 const char* kModeProperty = "Mode";
155 const char* kErrorProperty = "Error";
156 const char* kActiveProfileProperty = "ActiveProfile";
157 const char* kEntriesProperty = "Entries";
158 const char* kDevicesProperty = "Devices";
159 const char* kProviderProperty = "Provider";
160 const char* kHostProperty = "Host";
161 
162 // Flimflam property names for SIMLock status.
163 const char* kSIMLockStatusProperty = "Cellular.SIMLockStatus";
164 const char* kSIMLockTypeProperty = "LockType";
165 const char* kSIMLockRetriesLeftProperty = "RetriesLeft";
166 
167 // Flimflam property names for Cellular.FoundNetworks.
168 const char* kLongNameProperty = "long_name";
169 const char* kStatusProperty = "status";
170 const char* kShortNameProperty = "short_name";
171 const char* kTechnologyProperty = "technology";
172 
173 // Flimflam SIMLock status types.
174 const char* kSIMLockPin = "sim-pin";
175 const char* kSIMLockPuk = "sim-puk";
176 
177 // APN info property names.
178 const char* kApnProperty = "apn";
179 const char* kNetworkIdProperty = "network_id";
180 const char* kUsernameProperty = "username";
181 const char* kPasswordProperty = "password";
182 
183 // Operator info property names.
184 const char* kOperatorNameKey = "name";
185 const char* kOperatorCodeKey = "code";
186 const char* kOperatorCountryKey = "country";
187 
188 // Flimflam device info property names.
189 const char* kScanningProperty = "Scanning";
190 const char* kCarrierProperty = "Cellular.Carrier";
191 const char* kCellularAllowRoamingProperty = "Cellular.AllowRoaming";
192 const char* kHomeProviderProperty = "Cellular.HomeProvider";
193 const char* kMeidProperty = "Cellular.MEID";
194 const char* kImeiProperty = "Cellular.IMEI";
195 const char* kImsiProperty = "Cellular.IMSI";
196 const char* kEsnProperty = "Cellular.ESN";
197 const char* kMdnProperty = "Cellular.MDN";
198 const char* kMinProperty = "Cellular.MIN";
199 const char* kModelIDProperty = "Cellular.ModelID";
200 const char* kManufacturerProperty = "Cellular.Manufacturer";
201 const char* kFirmwareRevisionProperty = "Cellular.FirmwareRevision";
202 const char* kHardwareRevisionProperty = "Cellular.HardwareRevision";
203 const char* kPoweredProperty = "Powered";
204 const char* kPRLVersionProperty = "Cellular.PRLVersion"; // (INT16)
205 const char* kSelectedNetworkProperty = "Cellular.SelectedNetwork";
206 const char* kSupportNetworkScanProperty = "Cellular.SupportNetworkScan";
207 const char* kFoundNetworksProperty = "Cellular.FoundNetworks";
208 
209 // Flimflam type options.
210 const char* kTypeEthernet = "ethernet";
211 const char* kTypeWifi = "wifi";
212 const char* kTypeWimax = "wimax";
213 const char* kTypeBluetooth = "bluetooth";
214 const char* kTypeCellular = "cellular";
215 const char* kTypeVPN = "vpn";
216 
217 // Flimflam mode options.
218 const char* kModeManaged = "managed";
219 const char* kModeAdhoc = "adhoc";
220 
221 // Flimflam security options.
222 const char* kSecurityWpa = "wpa";
223 const char* kSecurityWep = "wep";
224 const char* kSecurityRsn = "rsn";
225 const char* kSecurity8021x = "802_1x";
226 const char* kSecurityPsk = "psk";
227 const char* kSecurityNone = "none";
228 
229 // Flimflam L2TPIPsec property names.
230 const char* kL2TPIPSecCACertProperty = "L2TPIPsec.CACert";
231 const char* kL2TPIPSecCertProperty = "L2TPIPsec.Cert";
232 const char* kL2TPIPSecKeyProperty = "L2TPIPsec.Key";
233 const char* kL2TPIPSecPSKProperty = "L2TPIPsec.PSK";
234 const char* kL2TPIPSecUserProperty = "L2TPIPsec.User";
235 const char* kL2TPIPSecPasswordProperty = "L2TPIPsec.Password";
236 
237 // Flimflam EAP property names.
238 // See src/third_party/flimflam/doc/service-api.txt.
239 const char* kEapIdentityProperty = "EAP.Identity";
240 const char* kEapMethodProperty = "EAP.EAP";
241 const char* kEapPhase2AuthProperty = "EAP.InnerEAP";
242 const char* kEapAnonymousIdentityProperty = "EAP.AnonymousIdentity";
243 const char* kEapClientCertProperty = "EAP.ClientCert";  // path
244 const char* kEapCertIDProperty = "EAP.CertID";  // PKCS#11 ID
245 const char* kEapClientCertNssProperty = "EAP.ClientCertNSS";  // NSS nickname
246 const char* kEapPrivateKeyProperty = "EAP.PrivateKey";
247 const char* kEapPrivateKeyPasswordProperty = "EAP.PrivateKeyPassword";
248 const char* kEapKeyIDProperty = "EAP.KeyID";
249 const char* kEapCaCertProperty = "EAP.CACert";  // server CA cert path
250 const char* kEapCaCertIDProperty = "EAP.CACertID";  // server CA PKCS#11 ID
251 const char* kEapCaCertNssProperty = "EAP.CACertNSS";  // server CA NSS nickname
252 const char* kEapUseSystemCAsProperty = "EAP.UseSystemCAs";
253 const char* kEapPinProperty = "EAP.PIN";
254 const char* kEapPasswordProperty = "EAP.Password";
255 const char* kEapKeyMgmtProperty = "EAP.KeyMgmt";
256 
257 // Flimflam EAP method options.
258 const std::string& kEapMethodPEAP = "PEAP";
259 const std::string& kEapMethodTLS = "TLS";
260 const std::string& kEapMethodTTLS = "TTLS";
261 const std::string& kEapMethodLEAP = "LEAP";
262 
263 // Flimflam EAP phase 2 auth options.
264 const std::string& kEapPhase2AuthPEAPMD5 = "auth=MD5";
265 const std::string& kEapPhase2AuthPEAPMSCHAPV2 = "auth=MSCHAPV2";
266 const std::string& kEapPhase2AuthTTLSMD5 = "autheap=MD5";
267 const std::string& kEapPhase2AuthTTLSMSCHAPV2 = "autheap=MSCHAPV2";
268 const std::string& kEapPhase2AuthTTLSMSCHAP = "autheap=MSCHAP";
269 const std::string& kEapPhase2AuthTTLSPAP = "autheap=PAP";
270 const std::string& kEapPhase2AuthTTLSCHAP = "autheap=CHAP";
271 
272 // Flimflam VPN provider types.
273 const char* kProviderL2tpIpsec = "l2tpipsec";
274 const char* kProviderOpenVpn = "openvpn";
275 
276 
277 // Flimflam state options.
278 const char* kStateIdle = "idle";
279 const char* kStateCarrier = "carrier";
280 const char* kStateAssociation = "association";
281 const char* kStateConfiguration = "configuration";
282 const char* kStateReady = "ready";
283 const char* kStateDisconnect = "disconnect";
284 const char* kStateFailure = "failure";
285 const char* kStateActivationFailure = "activation-failure";
286 
287 // Flimflam connectivity state options.
288 const char* kConnStateUnrestricted = "unrestricted";
289 const char* kConnStateRestricted = "restricted";
290 const char* kConnStateNone = "none";
291 
292 // Flimflam network technology options.
293 const char* kNetworkTechnology1Xrtt = "1xRTT";
294 const char* kNetworkTechnologyEvdo = "EVDO";
295 const char* kNetworkTechnologyGprs = "GPRS";
296 const char* kNetworkTechnologyEdge = "EDGE";
297 const char* kNetworkTechnologyUmts = "UMTS";
298 const char* kNetworkTechnologyHspa = "HSPA";
299 const char* kNetworkTechnologyHspaPlus = "HSPA+";
300 const char* kNetworkTechnologyLte = "LTE";
301 const char* kNetworkTechnologyLteAdvanced = "LTE Advanced";
302 
303 // Flimflam roaming state options
304 const char* kRoamingStateHome = "home";
305 const char* kRoamingStateRoaming = "roaming";
306 const char* kRoamingStateUnknown = "unknown";
307 
308 // Flimflam activation state options
309 const char* kActivationStateActivated = "activated";
310 const char* kActivationStateActivating = "activating";
311 const char* kActivationStateNotActivated = "not-activated";
312 const char* kActivationStatePartiallyActivated = "partially-activated";
313 const char* kActivationStateUnknown = "unknown";
314 
315 // Flimflam error options.
316 const char* kErrorOutOfRange = "out-of-range";
317 const char* kErrorPinMissing = "pin-missing";
318 const char* kErrorDhcpFailed = "dhcp-failed";
319 const char* kErrorConnectFailed = "connect-failed";
320 const char* kErrorBadPassphrase = "bad-passphrase";
321 const char* kErrorBadWEPKey = "bad-wepkey";
322 const char* kErrorActivationFailed = "activation-failed";
323 const char* kErrorNeedEvdo = "need-evdo";
324 const char* kErrorNeedHomeNetwork = "need-home-network";
325 const char* kErrorOtaspFailed = "otasp-failed";
326 const char* kErrorAaaFailed = "aaa-failed";
327 
328 // Flimflam error messages.
329 const char* kErrorPassphraseRequiredMsg = "Passphrase required";
330 const char* kErrorIncorrectPinMsg = "org.chromium.flimflam.Error.IncorrectPin";
331 const char* kErrorPinBlockedMsg = "org.chromium.flimflam.Error.PinBlocked";
332 const char* kErrorPinRequiredMsg = "org.chromium.flimflam.Error.PinRequired";
333 
334 const char* kUnknownString = "UNKNOWN";
335 
336 ////////////////////////////////////////////////////////////////////////////
337 
ConnectionTypeToString(ConnectionType type)338 static const char* ConnectionTypeToString(ConnectionType type) {
339   switch (type) {
340     case TYPE_UNKNOWN:
341       break;
342     case TYPE_ETHERNET:
343       return kTypeEthernet;
344     case TYPE_WIFI:
345       return kTypeWifi;
346     case TYPE_WIMAX:
347       return kTypeWimax;
348     case TYPE_BLUETOOTH:
349       return kTypeBluetooth;
350     case TYPE_CELLULAR:
351       return kTypeCellular;
352     case TYPE_VPN:
353       return kTypeVPN;
354   }
355   LOG(ERROR) << "ConnectionTypeToString called with unknown type: " << type;
356   return kUnknownString;
357 }
358 
359 // TODO(stevenjb/njw): Deprecate in favor of setting EAP properties.
SecurityToString(ConnectionSecurity security)360 static const char* SecurityToString(ConnectionSecurity security) {
361   switch (security) {
362     case SECURITY_NONE:
363       return kSecurityNone;
364     case SECURITY_WEP:
365       return kSecurityWep;
366     case SECURITY_WPA:
367       return kSecurityWpa;
368     case SECURITY_RSN:
369       return kSecurityRsn;
370     case SECURITY_8021X:
371       return kSecurity8021x;
372     case SECURITY_PSK:
373       return kSecurityPsk;
374     case SECURITY_UNKNOWN:
375       break;
376   }
377   LOG(ERROR) << "SecurityToString called with unknown type: " << security;
378   return kUnknownString;
379 }
380 
ProviderTypeToString(VirtualNetwork::ProviderType type)381 static const char* ProviderTypeToString(VirtualNetwork::ProviderType type) {
382   switch (type) {
383     case VirtualNetwork::PROVIDER_TYPE_L2TP_IPSEC_PSK:
384     case VirtualNetwork::PROVIDER_TYPE_L2TP_IPSEC_USER_CERT:
385       return kProviderL2tpIpsec;
386     case VirtualNetwork::PROVIDER_TYPE_OPEN_VPN:
387       return kProviderOpenVpn;
388     case VirtualNetwork::PROVIDER_TYPE_MAX:
389       break;
390   }
391   LOG(ERROR) << "ProviderTypeToString called with unknown type: " << type;
392   return kUnknownString;
393 }
394 
395 ////////////////////////////////////////////////////////////////////////////
396 
397 // Helper class to cache maps of strings to enums.
398 template <typename Type>
399 class StringToEnum {
400  public:
401   struct Pair {
402     const char* key;
403     const Type value;
404   };
405 
StringToEnum(const Pair * list,size_t num_entries,Type unknown)406   explicit StringToEnum(const Pair* list, size_t num_entries, Type unknown)
407       : unknown_value_(unknown) {
408     for (size_t i = 0; i < num_entries; ++i, ++list)
409       enum_map_[list->key] = list->value;
410   }
411 
Get(const std::string & type) const412   Type Get(const std::string& type) const {
413     EnumMapConstIter iter = enum_map_.find(type);
414     if (iter != enum_map_.end())
415       return iter->second;
416     return unknown_value_;
417   }
418 
419  private:
420   typedef typename std::map<std::string, Type> EnumMap;
421   typedef typename std::map<std::string, Type>::const_iterator EnumMapConstIter;
422   EnumMap enum_map_;
423   Type unknown_value_;
424   DISALLOW_COPY_AND_ASSIGN(StringToEnum);
425 };
426 
427 ////////////////////////////////////////////////////////////////////////////
428 
429 enum PropertyIndex {
430   PROPERTY_INDEX_ACTIVATION_STATE,
431   PROPERTY_INDEX_ACTIVE_PROFILE,
432   PROPERTY_INDEX_AUTO_CONNECT,
433   PROPERTY_INDEX_AVAILABLE_TECHNOLOGIES,
434   PROPERTY_INDEX_CARRIER,
435   PROPERTY_INDEX_CELLULAR_ALLOW_ROAMING,
436   PROPERTY_INDEX_CELLULAR_APN,
437   PROPERTY_INDEX_CELLULAR_LAST_GOOD_APN,
438   PROPERTY_INDEX_CERT_PATH,
439   PROPERTY_INDEX_CONNECTABLE,
440   PROPERTY_INDEX_CONNECTED_TECHNOLOGIES,
441   PROPERTY_INDEX_CONNECTIVITY_STATE,
442   PROPERTY_INDEX_DEFAULT_TECHNOLOGY,
443   PROPERTY_INDEX_DEVICE,
444   PROPERTY_INDEX_DEVICES,
445   PROPERTY_INDEX_EAP_IDENTITY,
446   PROPERTY_INDEX_EAP_METHOD,
447   PROPERTY_INDEX_EAP_PHASE_2_AUTH,
448   PROPERTY_INDEX_EAP_ANONYMOUS_IDENTITY,
449   PROPERTY_INDEX_EAP_CLIENT_CERT,
450   PROPERTY_INDEX_EAP_CERT_ID,
451   PROPERTY_INDEX_EAP_CLIENT_CERT_NSS,
452   PROPERTY_INDEX_EAP_PRIVATE_KEY,
453   PROPERTY_INDEX_EAP_PRIVATE_KEY_PASSWORD,
454   PROPERTY_INDEX_EAP_KEY_ID,
455   PROPERTY_INDEX_EAP_CA_CERT,
456   PROPERTY_INDEX_EAP_CA_CERT_ID,
457   PROPERTY_INDEX_EAP_CA_CERT_NSS,
458   PROPERTY_INDEX_EAP_USE_SYSTEM_CAS,
459   PROPERTY_INDEX_EAP_PIN,
460   PROPERTY_INDEX_EAP_PASSWORD,
461   PROPERTY_INDEX_EAP_KEY_MGMT,
462   PROPERTY_INDEX_ENABLED_TECHNOLOGIES,
463   PROPERTY_INDEX_ERROR,
464   PROPERTY_INDEX_ESN,
465   PROPERTY_INDEX_FAVORITE,
466   PROPERTY_INDEX_FIRMWARE_REVISION,
467   PROPERTY_INDEX_FOUND_NETWORKS,
468   PROPERTY_INDEX_HARDWARE_REVISION,
469   PROPERTY_INDEX_HOME_PROVIDER,
470   PROPERTY_INDEX_HOST,
471   PROPERTY_INDEX_IDENTITY,
472   PROPERTY_INDEX_IMEI,
473   PROPERTY_INDEX_IMSI,
474   PROPERTY_INDEX_IS_ACTIVE,
475   PROPERTY_INDEX_L2TPIPSEC_CA_CERT,
476   PROPERTY_INDEX_L2TPIPSEC_CERT,
477   PROPERTY_INDEX_L2TPIPSEC_KEY,
478   PROPERTY_INDEX_L2TPIPSEC_PASSWORD,
479   PROPERTY_INDEX_L2TPIPSEC_PSK,
480   PROPERTY_INDEX_L2TPIPSEC_USER,
481   PROPERTY_INDEX_MANUFACTURER,
482   PROPERTY_INDEX_MDN,
483   PROPERTY_INDEX_MEID,
484   PROPERTY_INDEX_MIN,
485   PROPERTY_INDEX_MODE,
486   PROPERTY_INDEX_MODEL_ID,
487   PROPERTY_INDEX_NAME,
488   PROPERTY_INDEX_NETWORK_TECHNOLOGY,
489   PROPERTY_INDEX_OFFLINE_MODE,
490   PROPERTY_INDEX_OPERATOR_CODE,
491   PROPERTY_INDEX_OPERATOR_NAME,
492   PROPERTY_INDEX_PASSPHRASE,
493   PROPERTY_INDEX_PASSPHRASE_REQUIRED,
494   PROPERTY_INDEX_PAYMENT_URL,
495   PROPERTY_INDEX_POWERED,
496   PROPERTY_INDEX_PRL_VERSION,
497   PROPERTY_INDEX_PROFILES,
498   PROPERTY_INDEX_PROVIDER,
499   PROPERTY_INDEX_ROAMING_STATE,
500   PROPERTY_INDEX_SAVE_CREDENTIALS,
501   PROPERTY_INDEX_SCANNING,
502   PROPERTY_INDEX_SECURITY,
503   PROPERTY_INDEX_SELECTED_NETWORK,
504   PROPERTY_INDEX_SERVICES,
505   PROPERTY_INDEX_SERVICE_WATCH_LIST,
506   PROPERTY_INDEX_SERVING_OPERATOR,
507   PROPERTY_INDEX_SIGNAL_STRENGTH,
508   PROPERTY_INDEX_SIM_LOCK,
509   PROPERTY_INDEX_STATE,
510   PROPERTY_INDEX_SUPPORT_NETWORK_SCAN,
511   PROPERTY_INDEX_TYPE,
512   PROPERTY_INDEX_UNKNOWN,
513   PROPERTY_INDEX_USAGE_URL,
514   PROPERTY_INDEX_WIFI_FREQUENCY,
515   PROPERTY_INDEX_WIFI_HEX_SSID,
516   PROPERTY_INDEX_WIFI_HIDDEN_SSID,
517   PROPERTY_INDEX_WIFI_PHY_MODE,
518 };
519 
520 StringToEnum<PropertyIndex>::Pair property_index_table[] = {
521   { kActivationStateProperty, PROPERTY_INDEX_ACTIVATION_STATE },
522   { kActiveProfileProperty, PROPERTY_INDEX_ACTIVE_PROFILE },
523   { kAutoConnectProperty, PROPERTY_INDEX_AUTO_CONNECT },
524   { kAvailableTechnologiesProperty, PROPERTY_INDEX_AVAILABLE_TECHNOLOGIES },
525   { kCellularAllowRoamingProperty, PROPERTY_INDEX_CELLULAR_ALLOW_ROAMING },
526   { kCellularApnProperty, PROPERTY_INDEX_CELLULAR_APN },
527   { kCellularLastGoodApnProperty, PROPERTY_INDEX_CELLULAR_LAST_GOOD_APN },
528   { kCarrierProperty, PROPERTY_INDEX_CARRIER },
529   { kCertPathProperty, PROPERTY_INDEX_CERT_PATH },
530   { kConnectableProperty, PROPERTY_INDEX_CONNECTABLE },
531   { kConnectedTechnologiesProperty, PROPERTY_INDEX_CONNECTED_TECHNOLOGIES },
532   { kConnectivityStateProperty, PROPERTY_INDEX_CONNECTIVITY_STATE },
533   { kDefaultTechnologyProperty, PROPERTY_INDEX_DEFAULT_TECHNOLOGY },
534   { kDeviceProperty, PROPERTY_INDEX_DEVICE },
535   { kDevicesProperty, PROPERTY_INDEX_DEVICES },
536   { kEapIdentityProperty, PROPERTY_INDEX_EAP_IDENTITY },
537   { kEapMethodProperty, PROPERTY_INDEX_EAP_METHOD },
538   { kEapPhase2AuthProperty, PROPERTY_INDEX_EAP_PHASE_2_AUTH },
539   { kEapAnonymousIdentityProperty, PROPERTY_INDEX_EAP_ANONYMOUS_IDENTITY },
540   { kEapClientCertProperty, PROPERTY_INDEX_EAP_CLIENT_CERT },
541   { kEapCertIDProperty, PROPERTY_INDEX_EAP_CERT_ID },
542   { kEapClientCertNssProperty, PROPERTY_INDEX_EAP_CLIENT_CERT_NSS },
543   { kEapPrivateKeyProperty, PROPERTY_INDEX_EAP_PRIVATE_KEY },
544   { kEapPrivateKeyPasswordProperty, PROPERTY_INDEX_EAP_PRIVATE_KEY_PASSWORD },
545   { kEapKeyIDProperty, PROPERTY_INDEX_EAP_KEY_ID },
546   { kEapCaCertProperty, PROPERTY_INDEX_EAP_CA_CERT },
547   { kEapCaCertIDProperty, PROPERTY_INDEX_EAP_CA_CERT_ID },
548   { kEapCaCertNssProperty, PROPERTY_INDEX_EAP_CA_CERT_NSS },
549   { kEapUseSystemCAsProperty, PROPERTY_INDEX_EAP_USE_SYSTEM_CAS },
550   { kEapPinProperty, PROPERTY_INDEX_EAP_PIN },
551   { kEapPasswordProperty, PROPERTY_INDEX_EAP_PASSWORD },
552   { kEapKeyMgmtProperty, PROPERTY_INDEX_EAP_KEY_MGMT },
553   { kEnabledTechnologiesProperty, PROPERTY_INDEX_ENABLED_TECHNOLOGIES },
554   { kErrorProperty, PROPERTY_INDEX_ERROR },
555   { kEsnProperty, PROPERTY_INDEX_ESN },
556   { kFavoriteProperty, PROPERTY_INDEX_FAVORITE },
557   { kFirmwareRevisionProperty, PROPERTY_INDEX_FIRMWARE_REVISION },
558   { kFoundNetworksProperty, PROPERTY_INDEX_FOUND_NETWORKS },
559   { kHardwareRevisionProperty, PROPERTY_INDEX_HARDWARE_REVISION },
560   { kHomeProviderProperty, PROPERTY_INDEX_HOME_PROVIDER },
561   { kHostProperty, PROPERTY_INDEX_HOST },
562   { kIdentityProperty, PROPERTY_INDEX_IDENTITY },
563   { kImeiProperty, PROPERTY_INDEX_IMEI },
564   { kImsiProperty, PROPERTY_INDEX_IMSI },
565   { kIsActiveProperty, PROPERTY_INDEX_IS_ACTIVE },
566   { kL2TPIPSecCACertProperty, PROPERTY_INDEX_L2TPIPSEC_CA_CERT },
567   { kL2TPIPSecCertProperty, PROPERTY_INDEX_L2TPIPSEC_CERT },
568   { kL2TPIPSecKeyProperty, PROPERTY_INDEX_L2TPIPSEC_KEY },
569   { kL2TPIPSecPasswordProperty, PROPERTY_INDEX_L2TPIPSEC_PASSWORD },
570   { kL2TPIPSecPSKProperty, PROPERTY_INDEX_L2TPIPSEC_PSK },
571   { kL2TPIPSecUserProperty, PROPERTY_INDEX_L2TPIPSEC_USER },
572   { kManufacturerProperty, PROPERTY_INDEX_MANUFACTURER },
573   { kMdnProperty, PROPERTY_INDEX_MDN },
574   { kMeidProperty, PROPERTY_INDEX_MEID },
575   { kMinProperty, PROPERTY_INDEX_MIN },
576   { kModeProperty, PROPERTY_INDEX_MODE },
577   { kModelIDProperty, PROPERTY_INDEX_MODEL_ID },
578   { kNameProperty, PROPERTY_INDEX_NAME },
579   { kNetworkTechnologyProperty, PROPERTY_INDEX_NETWORK_TECHNOLOGY },
580   { kOfflineModeProperty, PROPERTY_INDEX_OFFLINE_MODE },
581   { kOperatorCodeProperty, PROPERTY_INDEX_OPERATOR_CODE },
582   { kOperatorNameProperty, PROPERTY_INDEX_OPERATOR_NAME },
583   { kPRLVersionProperty, PROPERTY_INDEX_PRL_VERSION },
584   { kPassphraseProperty, PROPERTY_INDEX_PASSPHRASE },
585   { kPassphraseRequiredProperty, PROPERTY_INDEX_PASSPHRASE_REQUIRED },
586   { kPaymentURLProperty, PROPERTY_INDEX_PAYMENT_URL },
587   { kPoweredProperty, PROPERTY_INDEX_POWERED },
588   { kProfilesProperty, PROPERTY_INDEX_PROFILES },
589   { kProviderProperty, PROPERTY_INDEX_PROVIDER },
590   { kRoamingStateProperty, PROPERTY_INDEX_ROAMING_STATE },
591   { kSaveCredentialsProperty, PROPERTY_INDEX_SAVE_CREDENTIALS },
592   { kScanningProperty, PROPERTY_INDEX_SCANNING },
593   { kSecurityProperty, PROPERTY_INDEX_SECURITY },
594   { kSelectedNetworkProperty, PROPERTY_INDEX_SELECTED_NETWORK },
595   { kServiceWatchListProperty, PROPERTY_INDEX_SERVICE_WATCH_LIST },
596   { kServicesProperty, PROPERTY_INDEX_SERVICES },
597   { kServingOperatorProperty, PROPERTY_INDEX_SERVING_OPERATOR },
598   { kSignalStrengthProperty, PROPERTY_INDEX_SIGNAL_STRENGTH },
599   { kSIMLockStatusProperty, PROPERTY_INDEX_SIM_LOCK },
600   { kStateProperty, PROPERTY_INDEX_STATE },
601   { kSupportNetworkScanProperty, PROPERTY_INDEX_SUPPORT_NETWORK_SCAN },
602   { kTypeProperty, PROPERTY_INDEX_TYPE },
603   { kUsageURLProperty, PROPERTY_INDEX_USAGE_URL },
604   { kWifiFrequency, PROPERTY_INDEX_WIFI_FREQUENCY },
605   { kWifiHexSsid, PROPERTY_INDEX_WIFI_HEX_SSID },
606   { kWifiHiddenSsid, PROPERTY_INDEX_WIFI_HIDDEN_SSID },
607   { kWifiPhyMode, PROPERTY_INDEX_WIFI_PHY_MODE },
608 };
609 
property_index_parser()610 StringToEnum<PropertyIndex>& property_index_parser() {
611   static StringToEnum<PropertyIndex> parser(property_index_table,
612                                             arraysize(property_index_table),
613                                             PROPERTY_INDEX_UNKNOWN);
614   return parser;
615 }
616 
617 ////////////////////////////////////////////////////////////////////////////
618 // Parse strings from libcros.
619 
620 // Network.
ParseType(const std::string & type)621 static ConnectionType ParseType(const std::string& type) {
622   static StringToEnum<ConnectionType>::Pair table[] = {
623     { kTypeEthernet, TYPE_ETHERNET },
624     { kTypeWifi, TYPE_WIFI },
625     { kTypeWimax, TYPE_WIMAX },
626     { kTypeBluetooth, TYPE_BLUETOOTH },
627     { kTypeCellular, TYPE_CELLULAR },
628     { kTypeVPN, TYPE_VPN },
629   };
630   static StringToEnum<ConnectionType> parser(
631       table, arraysize(table), TYPE_UNKNOWN);
632   return parser.Get(type);
633 }
634 
ParseTypeFromDictionary(const DictionaryValue * info)635 ConnectionType ParseTypeFromDictionary(const DictionaryValue* info) {
636   std::string type_string;
637   info->GetString(kTypeProperty, &type_string);
638   return ParseType(type_string);
639 }
640 
ParseMode(const std::string & mode)641 static ConnectionMode ParseMode(const std::string& mode) {
642   static StringToEnum<ConnectionMode>::Pair table[] = {
643     { kModeManaged, MODE_MANAGED },
644     { kModeAdhoc, MODE_ADHOC },
645   };
646   static StringToEnum<ConnectionMode> parser(
647       table, arraysize(table), MODE_UNKNOWN);
648   return parser.Get(mode);
649 }
650 
ParseState(const std::string & state)651 static ConnectionState ParseState(const std::string& state) {
652   static StringToEnum<ConnectionState>::Pair table[] = {
653     { kStateIdle, STATE_IDLE },
654     { kStateCarrier, STATE_CARRIER },
655     { kStateAssociation, STATE_ASSOCIATION },
656     { kStateConfiguration, STATE_CONFIGURATION },
657     { kStateReady, STATE_READY },
658     { kStateDisconnect, STATE_DISCONNECT },
659     { kStateFailure, STATE_FAILURE },
660     { kStateActivationFailure, STATE_ACTIVATION_FAILURE },
661   };
662   static StringToEnum<ConnectionState> parser(
663       table, arraysize(table), STATE_UNKNOWN);
664   return parser.Get(state);
665 }
666 
ParseError(const std::string & error)667 static ConnectionError ParseError(const std::string& error) {
668   static StringToEnum<ConnectionError>::Pair table[] = {
669     { kErrorOutOfRange, ERROR_OUT_OF_RANGE },
670     { kErrorPinMissing, ERROR_PIN_MISSING },
671     { kErrorDhcpFailed, ERROR_DHCP_FAILED },
672     { kErrorConnectFailed, ERROR_CONNECT_FAILED },
673     { kErrorBadPassphrase, ERROR_BAD_PASSPHRASE },
674     { kErrorBadWEPKey, ERROR_BAD_WEPKEY },
675     { kErrorActivationFailed, ERROR_ACTIVATION_FAILED },
676     { kErrorNeedEvdo, ERROR_NEED_EVDO },
677     { kErrorNeedHomeNetwork, ERROR_NEED_HOME_NETWORK },
678     { kErrorOtaspFailed, ERROR_OTASP_FAILED },
679     { kErrorAaaFailed, ERROR_AAA_FAILED },
680   };
681   static StringToEnum<ConnectionError> parser(
682       table, arraysize(table), ERROR_NO_ERROR);
683   return parser.Get(error);
684 }
685 
686 // VirtualNetwork
ParseProviderType(const std::string & mode)687 static VirtualNetwork::ProviderType ParseProviderType(const std::string& mode) {
688   static StringToEnum<VirtualNetwork::ProviderType>::Pair table[] = {
689     { kProviderL2tpIpsec, VirtualNetwork::PROVIDER_TYPE_L2TP_IPSEC_PSK },
690     { kProviderOpenVpn, VirtualNetwork::PROVIDER_TYPE_OPEN_VPN },
691   };
692   static StringToEnum<VirtualNetwork::ProviderType> parser(
693       table, arraysize(table), VirtualNetwork::PROVIDER_TYPE_MAX);
694   return parser.Get(mode);
695 }
696 
697 // CellularNetwork.
ParseActivationState(const std::string & state)698 static ActivationState ParseActivationState(const std::string& state) {
699   static StringToEnum<ActivationState>::Pair table[] = {
700     { kActivationStateActivated, ACTIVATION_STATE_ACTIVATED },
701     { kActivationStateActivating, ACTIVATION_STATE_ACTIVATING },
702     { kActivationStateNotActivated, ACTIVATION_STATE_NOT_ACTIVATED },
703     { kActivationStatePartiallyActivated, ACTIVATION_STATE_PARTIALLY_ACTIVATED},
704     { kActivationStateUnknown, ACTIVATION_STATE_UNKNOWN},
705   };
706   static StringToEnum<ActivationState> parser(
707       table, arraysize(table), ACTIVATION_STATE_UNKNOWN);
708   return parser.Get(state);
709 }
710 
ParseConnectivityState(const std::string & state)711 static ConnectivityState ParseConnectivityState(const std::string& state) {
712   static StringToEnum<ConnectivityState>::Pair table[] = {
713     { kConnStateUnrestricted, CONN_STATE_UNRESTRICTED },
714     { kConnStateRestricted, CONN_STATE_RESTRICTED },
715     { kConnStateNone, CONN_STATE_NONE },
716   };
717   static StringToEnum<ConnectivityState> parser(
718       table, arraysize(table), CONN_STATE_UNKNOWN);
719   return parser.Get(state);
720 }
721 
ParseNetworkTechnology(const std::string & technology)722 static NetworkTechnology ParseNetworkTechnology(const std::string& technology) {
723   static StringToEnum<NetworkTechnology>::Pair table[] = {
724     { kNetworkTechnology1Xrtt, NETWORK_TECHNOLOGY_1XRTT },
725     { kNetworkTechnologyEvdo, NETWORK_TECHNOLOGY_EVDO },
726     { kNetworkTechnologyGprs, NETWORK_TECHNOLOGY_GPRS },
727     { kNetworkTechnologyEdge, NETWORK_TECHNOLOGY_EDGE },
728     { kNetworkTechnologyUmts, NETWORK_TECHNOLOGY_UMTS },
729     { kNetworkTechnologyHspa, NETWORK_TECHNOLOGY_HSPA },
730     { kNetworkTechnologyHspaPlus, NETWORK_TECHNOLOGY_HSPA_PLUS },
731     { kNetworkTechnologyLte, NETWORK_TECHNOLOGY_LTE },
732     { kNetworkTechnologyLteAdvanced, NETWORK_TECHNOLOGY_LTE_ADVANCED },
733   };
734   static StringToEnum<NetworkTechnology> parser(
735       table, arraysize(table), NETWORK_TECHNOLOGY_UNKNOWN);
736   return parser.Get(technology);
737 }
738 
ParseSimLockState(const std::string & state)739 static SIMLockState ParseSimLockState(const std::string& state) {
740   static StringToEnum<SIMLockState>::Pair table[] = {
741     { "", SIM_UNLOCKED },
742     { kSIMLockPin, SIM_LOCKED_PIN },
743     { kSIMLockPuk, SIM_LOCKED_PUK },
744   };
745   static StringToEnum<SIMLockState> parser(
746       table, arraysize(table), SIM_UNKNOWN);
747   SIMLockState parsed_state = parser.Get(state);
748   DCHECK(parsed_state != SIM_UNKNOWN) << "Unknown SIMLock state encountered";
749   return parsed_state;
750 }
751 
ParseSimLockStateFromDictionary(const DictionaryValue * info,SIMLockState * out_state,int * out_retries)752 static bool ParseSimLockStateFromDictionary(const DictionaryValue* info,
753                                             SIMLockState* out_state,
754                                             int* out_retries) {
755   std::string state_string;
756   if (!info->GetString(kSIMLockTypeProperty, &state_string) ||
757       !info->GetInteger(kSIMLockRetriesLeftProperty, out_retries)) {
758     LOG(ERROR) << "Error parsing SIMLock state";
759     return false;
760   }
761   *out_state = ParseSimLockState(state_string);
762   return true;
763 }
764 
ParseFoundNetworksFromList(const ListValue * list,CellularNetworkList * found_networks_)765 static bool ParseFoundNetworksFromList(const ListValue* list,
766                                        CellularNetworkList* found_networks_) {
767   found_networks_->clear();
768   found_networks_->reserve(list->GetSize());
769   for (ListValue::const_iterator it = list->begin(); it != list->end(); ++it) {
770     if ((*it)->IsType(Value::TYPE_DICTIONARY)) {
771       found_networks_->resize(found_networks_->size() + 1);
772       DictionaryValue* dict = static_cast<const DictionaryValue*>(*it);
773       dict->GetStringWithoutPathExpansion(
774           kStatusProperty, &found_networks_->back().status);
775       dict->GetStringWithoutPathExpansion(
776           kNetworkIdProperty, &found_networks_->back().network_id);
777       dict->GetStringWithoutPathExpansion(
778           kShortNameProperty, &found_networks_->back().short_name);
779       dict->GetStringWithoutPathExpansion(
780           kLongNameProperty, &found_networks_->back().long_name);
781       dict->GetStringWithoutPathExpansion(
782           kTechnologyProperty, &found_networks_->back().technology);
783     } else {
784       return false;
785     }
786   }
787   return true;
788 }
789 
ParseRoamingState(const std::string & roaming_state)790 static NetworkRoamingState ParseRoamingState(const std::string& roaming_state) {
791   static StringToEnum<NetworkRoamingState>::Pair table[] = {
792     { kRoamingStateHome, ROAMING_STATE_HOME },
793     { kRoamingStateRoaming, ROAMING_STATE_ROAMING },
794     { kRoamingStateUnknown, ROAMING_STATE_UNKNOWN },
795   };
796   static StringToEnum<NetworkRoamingState> parser(
797       table, arraysize(table), ROAMING_STATE_UNKNOWN);
798   return parser.Get(roaming_state);
799 }
800 
801 // WifiNetwork
ParseSecurity(const std::string & security)802 static ConnectionSecurity ParseSecurity(const std::string& security) {
803   static StringToEnum<ConnectionSecurity>::Pair table[] = {
804     { kSecurityNone, SECURITY_NONE },
805     { kSecurityWep, SECURITY_WEP },
806     { kSecurityWpa, SECURITY_WPA },
807     { kSecurityRsn, SECURITY_RSN },
808     { kSecurityPsk, SECURITY_PSK },
809     { kSecurity8021x, SECURITY_8021X },
810   };
811   static StringToEnum<ConnectionSecurity> parser(
812       table, arraysize(table), SECURITY_UNKNOWN);
813   return parser.Get(security);
814 }
815 
ParseEAPMethod(const std::string & method)816 static EAPMethod ParseEAPMethod(const std::string& method) {
817   static StringToEnum<EAPMethod>::Pair table[] = {
818     { kEapMethodPEAP.c_str(), EAP_METHOD_PEAP },
819     { kEapMethodTLS.c_str(), EAP_METHOD_TLS },
820     { kEapMethodTTLS.c_str(), EAP_METHOD_TTLS },
821     { kEapMethodLEAP.c_str(), EAP_METHOD_LEAP },
822   };
823   static StringToEnum<EAPMethod> parser(
824       table, arraysize(table), EAP_METHOD_UNKNOWN);
825   return parser.Get(method);
826 }
827 
ParseEAPPhase2Auth(const std::string & auth)828 static EAPPhase2Auth ParseEAPPhase2Auth(const std::string& auth) {
829   static StringToEnum<EAPPhase2Auth>::Pair table[] = {
830     { kEapPhase2AuthPEAPMD5.c_str(), EAP_PHASE_2_AUTH_MD5 },
831     { kEapPhase2AuthPEAPMSCHAPV2.c_str(), EAP_PHASE_2_AUTH_MSCHAPV2 },
832     { kEapPhase2AuthTTLSMD5.c_str(), EAP_PHASE_2_AUTH_MD5 },
833     { kEapPhase2AuthTTLSMSCHAPV2.c_str(), EAP_PHASE_2_AUTH_MSCHAPV2 },
834     { kEapPhase2AuthTTLSMSCHAP.c_str(), EAP_PHASE_2_AUTH_MSCHAP },
835     { kEapPhase2AuthTTLSPAP.c_str(), EAP_PHASE_2_AUTH_PAP },
836     { kEapPhase2AuthTTLSCHAP.c_str(), EAP_PHASE_2_AUTH_CHAP },
837   };
838   static StringToEnum<EAPPhase2Auth> parser(
839       table, arraysize(table), EAP_PHASE_2_AUTH_AUTO);
840   return parser.Get(auth);
841 }
842 
843 ////////////////////////////////////////////////////////////////////////////////
844 // Misc.
845 
846 // Safe string constructor since we can't rely on non NULL pointers
847 // for string values from libcros.
SafeString(const char * s)848 static std::string SafeString(const char* s) {
849   return s ? std::string(s) : std::string();
850 }
851 
852 // Erase the memory used by a string, then clear it.
WipeString(std::string * str)853 static void WipeString(std::string* str) {
854   str->assign(str->size(), '\0');
855   str->clear();
856 }
857 
EnsureCrosLoaded()858 static bool EnsureCrosLoaded() {
859   if (!CrosLibrary::Get()->EnsureLoaded()) {
860     return false;
861   } else {
862     if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
863       LOG(ERROR) << "chromeos_library calls made from non UI thread!";
864       NOTREACHED();
865     }
866     return true;
867   }
868 }
869 
ValidateUTF8(const std::string & str,std::string * output)870 static void ValidateUTF8(const std::string& str, std::string* output) {
871   output->clear();
872 
873   for (int32 index = 0; index < static_cast<int32>(str.size()); ++index) {
874     uint32 code_point_out;
875     bool is_unicode_char = base::ReadUnicodeCharacter(str.c_str(), str.size(),
876                                                       &index, &code_point_out);
877     if (is_unicode_char && (code_point_out >= 0x20))
878       base::WriteUnicodeCharacter(code_point_out, output);
879     else
880       // Puts REPLACEMENT CHARACTER (U+FFFD) if character is not readable UTF-8
881       base::WriteUnicodeCharacter(0xFFFD, output);
882   }
883 }
884 
885 }  // namespace
886 
887 ////////////////////////////////////////////////////////////////////////////////
888 // NetworkDevice
889 
NetworkDevice(const std::string & device_path)890 NetworkDevice::NetworkDevice(const std::string& device_path)
891     : device_path_(device_path),
892       type_(TYPE_UNKNOWN),
893       scanning_(false),
894       sim_lock_state_(SIM_UNKNOWN),
895       sim_retries_left_(kDefaultSimUnlockRetriesCount),
896       sim_pin_required_(SIM_PIN_REQUIRE_UNKNOWN),
897       PRL_version_(0),
898       data_roaming_allowed_(false),
899       support_network_scan_(false) {
900 }
901 
ParseValue(int index,const Value * value)902 bool NetworkDevice::ParseValue(int index, const Value* value) {
903   switch (index) {
904     case PROPERTY_INDEX_TYPE: {
905       std::string type_string;
906       if (value->GetAsString(&type_string)) {
907         type_ = ParseType(type_string);
908         return true;
909       }
910       break;
911     }
912     case PROPERTY_INDEX_NAME:
913       return value->GetAsString(&name_);
914     case PROPERTY_INDEX_CARRIER:
915       return value->GetAsString(&carrier_);
916     case PROPERTY_INDEX_SCANNING:
917       return value->GetAsBoolean(&scanning_);
918     case PROPERTY_INDEX_CELLULAR_ALLOW_ROAMING:
919       return value->GetAsBoolean(&data_roaming_allowed_);
920     case PROPERTY_INDEX_FOUND_NETWORKS:
921       if (value->IsType(Value::TYPE_LIST)) {
922         return ParseFoundNetworksFromList(
923             static_cast<const ListValue*>(value),
924             &found_cellular_networks_);
925       }
926       break;
927     case PROPERTY_INDEX_HOME_PROVIDER: {
928       if (value->IsType(Value::TYPE_DICTIONARY)) {
929         const DictionaryValue *dict =
930             static_cast<const DictionaryValue*>(value);
931         home_provider_code_.clear();
932         home_provider_country_.clear();
933         home_provider_name_.clear();
934         dict->GetStringWithoutPathExpansion(kOperatorCodeKey,
935                                             &home_provider_code_);
936         dict->GetStringWithoutPathExpansion(kOperatorCountryKey,
937                                             &home_provider_country_);
938         dict->GetStringWithoutPathExpansion(kOperatorNameKey,
939                                             &home_provider_name_);
940         if (!home_provider_name_.empty() && !home_provider_country_.empty()) {
941           home_provider_id_ = base::StringPrintf(
942               kCarrierIdFormat,
943               home_provider_name_.c_str(),
944               home_provider_country_.c_str());
945         } else {
946           home_provider_id_ = home_provider_code_;
947           LOG(WARNING) << "Carrier ID not defined, using code instead: "
948                        << home_provider_id_;
949         }
950         return true;
951       }
952       break;
953     }
954     case PROPERTY_INDEX_MEID:
955       return value->GetAsString(&MEID_);
956     case PROPERTY_INDEX_IMEI:
957       return value->GetAsString(&IMEI_);
958     case PROPERTY_INDEX_IMSI:
959       return value->GetAsString(&IMSI_);
960     case PROPERTY_INDEX_ESN:
961       return value->GetAsString(&ESN_);
962     case PROPERTY_INDEX_MDN:
963       return value->GetAsString(&MDN_);
964     case PROPERTY_INDEX_MIN:
965       return value->GetAsString(&MIN_);
966     case PROPERTY_INDEX_MODEL_ID:
967       return value->GetAsString(&model_id_);
968     case PROPERTY_INDEX_MANUFACTURER:
969       return value->GetAsString(&manufacturer_);
970     case PROPERTY_INDEX_SIM_LOCK:
971       if (value->IsType(Value::TYPE_DICTIONARY)) {
972         bool result = ParseSimLockStateFromDictionary(
973             static_cast<const DictionaryValue*>(value),
974             &sim_lock_state_,
975             &sim_retries_left_);
976         // Initialize PinRequired value only once.
977         // See SIMPinRequire enum comments.
978         if (sim_pin_required_ == SIM_PIN_REQUIRE_UNKNOWN) {
979           if (sim_lock_state_ == SIM_UNLOCKED) {
980             sim_pin_required_ = SIM_PIN_NOT_REQUIRED;
981           } else if (sim_lock_state_ == SIM_LOCKED_PIN ||
982                      sim_lock_state_ == SIM_LOCKED_PUK) {
983             sim_pin_required_ = SIM_PIN_REQUIRED;
984           }
985         }
986         return result;
987       }
988       break;
989     case PROPERTY_INDEX_FIRMWARE_REVISION:
990       return value->GetAsString(&firmware_revision_);
991     case PROPERTY_INDEX_HARDWARE_REVISION:
992       return value->GetAsString(&hardware_revision_);
993     case PROPERTY_INDEX_POWERED:
994       // we don't care about the value, just the fact that it changed
995       return true;
996     case PROPERTY_INDEX_PRL_VERSION:
997       return value->GetAsInteger(&PRL_version_);
998     case PROPERTY_INDEX_SELECTED_NETWORK:
999       return value->GetAsString(&selected_cellular_network_);
1000     case PROPERTY_INDEX_SUPPORT_NETWORK_SCAN:
1001       return value->GetAsBoolean(&support_network_scan_);
1002     default:
1003       break;
1004   }
1005   return false;
1006 }
1007 
ParseInfo(const DictionaryValue * info)1008 void NetworkDevice::ParseInfo(const DictionaryValue* info) {
1009   for (DictionaryValue::key_iterator iter = info->begin_keys();
1010        iter != info->end_keys(); ++iter) {
1011     const std::string& key = *iter;
1012     Value* value;
1013     bool res = info->GetWithoutPathExpansion(key, &value);
1014     DCHECK(res);
1015     if (res) {
1016       int index = property_index_parser().Get(key);
1017       if (!ParseValue(index, value))
1018         VLOG(1) << "NetworkDevice: Unhandled key: " << key;
1019     }
1020   }
1021 }
1022 
1023 ////////////////////////////////////////////////////////////////////////////////
1024 // Network
1025 
SetName(const std::string & name)1026 void Network::SetName(const std::string& name) {
1027   std::string name_utf8;
1028   ValidateUTF8(name, &name_utf8);
1029   set_name(name_utf8);
1030 }
1031 
ParseValue(int index,const Value * value)1032 bool Network::ParseValue(int index, const Value* value) {
1033   switch (index) {
1034     case PROPERTY_INDEX_TYPE: {
1035       std::string type_string;
1036       if (value->GetAsString(&type_string)) {
1037         ConnectionType type = ParseType(type_string);
1038         LOG_IF(ERROR, type != type_)
1039             << "Network with mismatched type: " << service_path_
1040             << " " << type << " != " << type_;
1041         return true;
1042       }
1043       break;
1044     }
1045     case PROPERTY_INDEX_DEVICE:
1046       return value->GetAsString(&device_path_);
1047     case PROPERTY_INDEX_NAME: {
1048       std::string name;
1049       if (value->GetAsString(&name)) {
1050         SetName(name);
1051         return true;
1052       }
1053       break;
1054     }
1055     case PROPERTY_INDEX_STATE: {
1056       std::string state_string;
1057       if (value->GetAsString(&state_string)) {
1058         ConnectionState prev_state = state_;
1059         state_ = ParseState(state_string);
1060         if (state_ != prev_state) {
1061           // State changed, so refresh IP address.
1062           // Note: blocking DBus call. TODO(stevenjb): refactor this.
1063           InitIPAddress();
1064         }
1065         return true;
1066       }
1067       break;
1068     }
1069     case PROPERTY_INDEX_MODE: {
1070       std::string mode_string;
1071       if (value->GetAsString(&mode_string)) {
1072         mode_ = ParseMode(mode_string);
1073         return true;
1074       }
1075       break;
1076     }
1077     case PROPERTY_INDEX_ERROR: {
1078       std::string error_string;
1079       if (value->GetAsString(&error_string)) {
1080         error_ = ParseError(error_string);
1081         return true;
1082       }
1083       break;
1084     }
1085     case PROPERTY_INDEX_CONNECTABLE:
1086       return value->GetAsBoolean(&connectable_);
1087     case PROPERTY_INDEX_IS_ACTIVE:
1088       return value->GetAsBoolean(&is_active_);
1089     case PROPERTY_INDEX_FAVORITE:
1090       return value->GetAsBoolean(&favorite_);
1091     case PROPERTY_INDEX_AUTO_CONNECT:
1092       return value->GetAsBoolean(&auto_connect_);
1093     case PROPERTY_INDEX_CONNECTIVITY_STATE: {
1094       std::string connectivity_state_string;
1095       if (value->GetAsString(&connectivity_state_string)) {
1096         connectivity_state_ = ParseConnectivityState(connectivity_state_string);
1097         return true;
1098       }
1099       break;
1100     }
1101     default:
1102       break;
1103   }
1104   return false;
1105 }
1106 
ParseInfo(const DictionaryValue * info)1107 void Network::ParseInfo(const DictionaryValue* info) {
1108   for (DictionaryValue::key_iterator iter = info->begin_keys();
1109        iter != info->end_keys(); ++iter) {
1110     const std::string& key = *iter;
1111     Value* value;
1112     bool res = info->GetWithoutPathExpansion(key, &value);
1113     DCHECK(res);
1114     if (res) {
1115       int index = property_index_parser().Get(key);
1116       if (!ParseValue(index, value))  // virtual.
1117         VLOG(1) << "Network: " << name()
1118                 << " Type: " << ConnectionTypeToString(type())
1119                 << " Unhandled key: " << key;
1120     }
1121   }
1122 }
1123 
SetValueProperty(const char * prop,Value * val)1124 void Network::SetValueProperty(const char* prop, Value* val) {
1125   DCHECK(prop);
1126   DCHECK(val);
1127   if (!EnsureCrosLoaded())
1128     return;
1129   SetNetworkServiceProperty(service_path_.c_str(), prop, val);
1130 }
1131 
ClearProperty(const char * prop)1132 void Network::ClearProperty(const char* prop) {
1133   DCHECK(prop);
1134   if (!EnsureCrosLoaded())
1135     return;
1136   ClearNetworkServiceProperty(service_path_.c_str(), prop);
1137 }
1138 
SetStringProperty(const char * prop,const std::string & str,std::string * dest)1139 void Network::SetStringProperty(
1140     const char* prop, const std::string& str, std::string* dest) {
1141   if (dest)
1142     *dest = str;
1143   scoped_ptr<Value> value(Value::CreateStringValue(str));
1144   SetValueProperty(prop, value.get());
1145 }
1146 
SetOrClearStringProperty(const char * prop,const std::string & str,std::string * dest)1147 void Network::SetOrClearStringProperty(const char* prop,
1148                                        const std::string& str,
1149                                        std::string* dest) {
1150   if (str.empty()) {
1151     ClearProperty(prop);
1152     if (dest)
1153       dest->clear();
1154   } else {
1155     SetStringProperty(prop, str, dest);
1156   }
1157 }
1158 
SetBooleanProperty(const char * prop,bool b,bool * dest)1159 void Network::SetBooleanProperty(const char* prop, bool b, bool* dest) {
1160   if (dest)
1161     *dest = b;
1162   scoped_ptr<Value> value(Value::CreateBooleanValue(b));
1163   SetValueProperty(prop, value.get());
1164 }
1165 
SetIntegerProperty(const char * prop,int i,int * dest)1166 void Network::SetIntegerProperty(const char* prop, int i, int* dest) {
1167   if (dest)
1168     *dest = i;
1169   scoped_ptr<Value> value(Value::CreateIntegerValue(i));
1170   SetValueProperty(prop, value.get());
1171 }
1172 
SetAutoConnect(bool auto_connect)1173 void Network::SetAutoConnect(bool auto_connect) {
1174   SetBooleanProperty(kAutoConnectProperty, auto_connect, &auto_connect_);
1175 }
1176 
GetStateString() const1177 std::string Network::GetStateString() const {
1178   switch (state_) {
1179     case STATE_UNKNOWN:
1180       return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_STATE_UNKNOWN);
1181     case STATE_IDLE:
1182       return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_STATE_IDLE);
1183     case STATE_CARRIER:
1184       return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_STATE_CARRIER);
1185     case STATE_ASSOCIATION:
1186       return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_STATE_ASSOCIATION);
1187     case STATE_CONFIGURATION:
1188       return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_STATE_CONFIGURATION);
1189     case STATE_READY:
1190       return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_STATE_READY);
1191     case STATE_DISCONNECT:
1192       return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_STATE_DISCONNECT);
1193     case STATE_FAILURE:
1194       return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_STATE_FAILURE);
1195     case STATE_ACTIVATION_FAILURE:
1196       return l10n_util::GetStringUTF8(
1197           IDS_CHROMEOS_NETWORK_STATE_ACTIVATION_FAILURE);
1198   }
1199   return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_STATE_UNRECOGNIZED);
1200 }
1201 
GetErrorString() const1202 std::string Network::GetErrorString() const {
1203   switch (error_) {
1204     case ERROR_NO_ERROR:
1205       // TODO(nkostylev): Introduce new error message "None" instead.
1206       return std::string();
1207     case ERROR_OUT_OF_RANGE:
1208       return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_ERROR_OUT_OF_RANGE);
1209     case ERROR_PIN_MISSING:
1210       return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_ERROR_PIN_MISSING);
1211     case ERROR_DHCP_FAILED:
1212       return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_ERROR_DHCP_FAILED);
1213     case ERROR_CONNECT_FAILED:
1214       return l10n_util::GetStringUTF8(
1215           IDS_CHROMEOS_NETWORK_ERROR_CONNECT_FAILED);
1216     case ERROR_BAD_PASSPHRASE:
1217       return l10n_util::GetStringUTF8(
1218           IDS_CHROMEOS_NETWORK_ERROR_BAD_PASSPHRASE);
1219     case ERROR_BAD_WEPKEY:
1220       return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_ERROR_BAD_WEPKEY);
1221     case ERROR_ACTIVATION_FAILED:
1222       return l10n_util::GetStringUTF8(
1223           IDS_CHROMEOS_NETWORK_ERROR_ACTIVATION_FAILED);
1224     case ERROR_NEED_EVDO:
1225       return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_ERROR_NEED_EVDO);
1226     case ERROR_NEED_HOME_NETWORK:
1227       return l10n_util::GetStringUTF8(
1228           IDS_CHROMEOS_NETWORK_ERROR_NEED_HOME_NETWORK);
1229     case ERROR_OTASP_FAILED:
1230       return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_ERROR_OTASP_FAILED);
1231     case ERROR_AAA_FAILED:
1232       return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_ERROR_AAA_FAILED);
1233   }
1234   return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_STATE_UNRECOGNIZED);
1235 }
1236 
InitIPAddress()1237 void Network::InitIPAddress() {
1238   ip_address_.clear();
1239   // If connected, get ip config.
1240   if (EnsureCrosLoaded() && connected() && !device_path_.empty()) {
1241     IPConfigStatus* ipconfig_status = ListIPConfigs(device_path_.c_str());
1242     if (ipconfig_status) {
1243       for (int i = 0; i < ipconfig_status->size; i++) {
1244         IPConfig ipconfig = ipconfig_status->ips[i];
1245         if (strlen(ipconfig.address) > 0) {
1246           ip_address_ = ipconfig.address;
1247           break;
1248         }
1249       }
1250       FreeIPConfigStatus(ipconfig_status);
1251     }
1252   }
1253 }
1254 
1255 ////////////////////////////////////////////////////////////////////////////////
1256 // VirtualNetwork
1257 
ParseProviderValue(int index,const Value * value)1258 bool VirtualNetwork::ParseProviderValue(int index, const Value* value) {
1259   switch (index) {
1260     case PROPERTY_INDEX_HOST:
1261       return value->GetAsString(&server_hostname_);
1262     case PROPERTY_INDEX_NAME:
1263       // Note: shadows Network::name_ property.
1264       return value->GetAsString(&name_);
1265     case PROPERTY_INDEX_TYPE: {
1266       std::string provider_type_string;
1267       if (value->GetAsString(&provider_type_string)) {
1268         provider_type_ = ParseProviderType(provider_type_string);
1269         return true;
1270       }
1271       break;
1272     }
1273     default:
1274       break;
1275   }
1276   return false;
1277 }
1278 
ParseValue(int index,const Value * value)1279 bool VirtualNetwork::ParseValue(int index, const Value* value) {
1280   switch (index) {
1281     case PROPERTY_INDEX_PROVIDER: {
1282       DCHECK_EQ(value->GetType(), Value::TYPE_DICTIONARY);
1283       const DictionaryValue* dict = static_cast<const DictionaryValue*>(value);
1284       for (DictionaryValue::key_iterator iter = dict->begin_keys();
1285            iter != dict->end_keys(); ++iter) {
1286         const std::string& key = *iter;
1287         Value* v;
1288         bool res = dict->GetWithoutPathExpansion(key, &v);
1289         DCHECK(res);
1290         if (res) {
1291           int index = property_index_parser().Get(key);
1292           if (!ParseProviderValue(index, v))
1293             VLOG(1) << name() << ": Provider unhandled key: " << key
1294                     << " Type: " << v->GetType();
1295         }
1296       }
1297       return true;
1298     }
1299     case PROPERTY_INDEX_L2TPIPSEC_CA_CERT:
1300       return value->GetAsString(&ca_cert_);
1301     case PROPERTY_INDEX_L2TPIPSEC_PSK:
1302       return value->GetAsString(&psk_passphrase_);
1303     case PROPERTY_INDEX_L2TPIPSEC_CERT:
1304       return value->GetAsString(&user_cert_);
1305     case PROPERTY_INDEX_L2TPIPSEC_KEY:
1306       return value->GetAsString(&user_cert_key_);
1307     case PROPERTY_INDEX_L2TPIPSEC_USER:
1308       return value->GetAsString(&username_);
1309     case PROPERTY_INDEX_L2TPIPSEC_PASSWORD:
1310       return value->GetAsString(&user_passphrase_);
1311     default:
1312       return Network::ParseValue(index, value);
1313       break;
1314   }
1315   return false;
1316 }
1317 
ParseInfo(const DictionaryValue * info)1318 void VirtualNetwork::ParseInfo(const DictionaryValue* info) {
1319   Network::ParseInfo(info);
1320   VLOG(1) << "VPN: " << name()
1321           << " Type: " << ProviderTypeToString(provider_type());
1322   if (provider_type_ == PROVIDER_TYPE_L2TP_IPSEC_PSK) {
1323     if (!user_cert_.empty())
1324       provider_type_ = PROVIDER_TYPE_L2TP_IPSEC_USER_CERT;
1325   }
1326 }
1327 
NeedMoreInfoToConnect() const1328 bool VirtualNetwork::NeedMoreInfoToConnect() const {
1329   if (server_hostname_.empty() || username_.empty() || user_passphrase_.empty())
1330     return true;
1331   switch (provider_type_) {
1332     case PROVIDER_TYPE_L2TP_IPSEC_PSK:
1333       if (psk_passphrase_.empty())
1334         return true;
1335       break;
1336     case PROVIDER_TYPE_L2TP_IPSEC_USER_CERT:
1337     case PROVIDER_TYPE_OPEN_VPN:
1338       if (user_cert_.empty())
1339         return true;
1340       break;
1341     case PROVIDER_TYPE_MAX:
1342       break;
1343   }
1344   return false;
1345 }
1346 
SetCACert(const std::string & ca_cert)1347 void VirtualNetwork::SetCACert(const std::string& ca_cert) {
1348   SetStringProperty(kL2TPIPSecCACertProperty, ca_cert, &ca_cert_);
1349 }
1350 
SetPSKPassphrase(const std::string & psk_passphrase)1351 void VirtualNetwork::SetPSKPassphrase(const std::string& psk_passphrase) {
1352   SetStringProperty(kL2TPIPSecPSKProperty, psk_passphrase,
1353                            &psk_passphrase_);
1354 }
1355 
SetUserCert(const std::string & user_cert)1356 void VirtualNetwork::SetUserCert(const std::string& user_cert) {
1357   SetStringProperty(kL2TPIPSecCertProperty, user_cert, &user_cert_);
1358 }
1359 
SetUserCertKey(const std::string & key)1360 void VirtualNetwork::SetUserCertKey(const std::string& key) {
1361   SetStringProperty(kL2TPIPSecKeyProperty, key, &user_cert_key_);
1362 }
1363 
SetUsername(const std::string & username)1364 void VirtualNetwork::SetUsername(const std::string& username) {
1365   SetStringProperty(kL2TPIPSecUserProperty, username, &username_);
1366 }
1367 
SetUserPassphrase(const std::string & user_passphrase)1368 void VirtualNetwork::SetUserPassphrase(const std::string& user_passphrase) {
1369   SetStringProperty(kL2TPIPSecPasswordProperty, user_passphrase,
1370                     &user_passphrase_);
1371 }
1372 
GetProviderTypeString() const1373 std::string VirtualNetwork::GetProviderTypeString() const {
1374   switch (this->provider_type_) {
1375     case PROVIDER_TYPE_L2TP_IPSEC_PSK:
1376       return l10n_util::GetStringUTF8(
1377           IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_L2TP_IPSEC_PSK);
1378       break;
1379     case PROVIDER_TYPE_L2TP_IPSEC_USER_CERT:
1380       return l10n_util::GetStringUTF8(
1381           IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_L2TP_IPSEC_USER_CERT);
1382       break;
1383     case PROVIDER_TYPE_OPEN_VPN:
1384       return l10n_util::GetStringUTF8(
1385           IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_OPEN_VPN);
1386       break;
1387     default:
1388       return l10n_util::GetStringUTF8(
1389           IDS_CHROMEOS_NETWORK_ERROR_UNKNOWN);
1390       break;
1391   }
1392 }
1393 
1394 ////////////////////////////////////////////////////////////////////////////////
1395 // WirelessNetwork
1396 
ParseValue(int index,const Value * value)1397 bool WirelessNetwork::ParseValue(int index, const Value* value) {
1398   switch (index) {
1399     case PROPERTY_INDEX_SIGNAL_STRENGTH:
1400       return value->GetAsInteger(&strength_);
1401     default:
1402       return Network::ParseValue(index, value);
1403       break;
1404   }
1405   return false;
1406 }
1407 
1408 ////////////////////////////////////////////////////////////////////////////////
1409 // CellularDataPlan
1410 
GetPlanDesciption() const1411 string16 CellularDataPlan::GetPlanDesciption() const {
1412   switch (plan_type) {
1413     case chromeos::CELLULAR_DATA_PLAN_UNLIMITED: {
1414       return l10n_util::GetStringFUTF16(
1415           IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PURCHASE_UNLIMITED_DATA,
1416           base::TimeFormatFriendlyDate(plan_start_time));
1417       break;
1418     }
1419     case chromeos::CELLULAR_DATA_PLAN_METERED_PAID: {
1420       return l10n_util::GetStringFUTF16(
1421                 IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PURCHASE_DATA,
1422                 FormatBytes(plan_data_bytes,
1423                             GetByteDisplayUnits(plan_data_bytes),
1424                             true),
1425                 base::TimeFormatFriendlyDate(plan_start_time));
1426     }
1427     case chromeos::CELLULAR_DATA_PLAN_METERED_BASE: {
1428       return l10n_util::GetStringFUTF16(
1429                 IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_RECEIVED_FREE_DATA,
1430                 FormatBytes(plan_data_bytes,
1431                             GetByteDisplayUnits(plan_data_bytes),
1432                             true),
1433                 base::TimeFormatFriendlyDate(plan_start_time));
1434     default:
1435       break;
1436     }
1437   }
1438   return string16();
1439 }
1440 
GetRemainingWarning() const1441 string16 CellularDataPlan::GetRemainingWarning() const {
1442   if (plan_type == chromeos::CELLULAR_DATA_PLAN_UNLIMITED) {
1443     // Time based plan. Show nearing expiration and data expiration.
1444     if (remaining_time().InSeconds() <= chromeos::kCellularDataVeryLowSecs) {
1445       return GetPlanExpiration();
1446     }
1447   } else if (plan_type == chromeos::CELLULAR_DATA_PLAN_METERED_PAID ||
1448              plan_type == chromeos::CELLULAR_DATA_PLAN_METERED_BASE) {
1449     // Metered plan. Show low data and out of data.
1450     if (remaining_data() <= chromeos::kCellularDataVeryLowBytes) {
1451       int64 remaining_mbytes = remaining_data() / (1024 * 1024);
1452       return l10n_util::GetStringFUTF16(
1453           IDS_NETWORK_DATA_REMAINING_MESSAGE,
1454           UTF8ToUTF16(base::Int64ToString(remaining_mbytes)));
1455     }
1456   }
1457   return string16();
1458 }
1459 
GetDataRemainingDesciption() const1460 string16 CellularDataPlan::GetDataRemainingDesciption() const {
1461   int64 remaining_bytes = remaining_data();
1462   switch (plan_type) {
1463     case chromeos::CELLULAR_DATA_PLAN_UNLIMITED: {
1464       return l10n_util::GetStringUTF16(
1465           IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_UNLIMITED);
1466     }
1467     case chromeos::CELLULAR_DATA_PLAN_METERED_PAID: {
1468       return FormatBytes(remaining_bytes,
1469           GetByteDisplayUnits(remaining_bytes),
1470           true);
1471     }
1472     case chromeos::CELLULAR_DATA_PLAN_METERED_BASE: {
1473       return FormatBytes(remaining_bytes,
1474           GetByteDisplayUnits(remaining_bytes),
1475           true);
1476     }
1477     default:
1478       break;
1479   }
1480   return string16();
1481 }
1482 
GetUsageInfo() const1483 string16 CellularDataPlan::GetUsageInfo() const {
1484   if (plan_type == chromeos::CELLULAR_DATA_PLAN_UNLIMITED) {
1485     // Time based plan. Show nearing expiration and data expiration.
1486     return GetPlanExpiration();
1487   } else if (plan_type == chromeos::CELLULAR_DATA_PLAN_METERED_PAID ||
1488              plan_type == chromeos::CELLULAR_DATA_PLAN_METERED_BASE) {
1489     // Metered plan. Show low data and out of data.
1490     int64 remaining_bytes = remaining_data();
1491     if (remaining_bytes == 0) {
1492       return l10n_util::GetStringUTF16(
1493           IDS_NETWORK_DATA_NONE_AVAILABLE_MESSAGE);
1494     } else if (remaining_bytes < 1024 * 1024) {
1495       return l10n_util::GetStringUTF16(
1496           IDS_NETWORK_DATA_LESS_THAN_ONE_MB_AVAILABLE_MESSAGE);
1497     } else {
1498       int64 remaining_mb = remaining_bytes / (1024 * 1024);
1499       return l10n_util::GetStringFUTF16(
1500           IDS_NETWORK_DATA_MB_AVAILABLE_MESSAGE,
1501           UTF8ToUTF16(base::Int64ToString(remaining_mb)));
1502     }
1503   }
1504   return string16();
1505 }
1506 
GetUniqueIdentifier() const1507 std::string CellularDataPlan::GetUniqueIdentifier() const {
1508   // A cellular plan is uniquely described by the union of name, type,
1509   // start time, end time, and max bytes.
1510   // So we just return a union of all these variables.
1511   return plan_name + "|" +
1512       base::Int64ToString(plan_type) + "|" +
1513       base::Int64ToString(plan_start_time.ToInternalValue()) + "|" +
1514       base::Int64ToString(plan_end_time.ToInternalValue()) + "|" +
1515       base::Int64ToString(plan_data_bytes);
1516 }
1517 
remaining_time() const1518 base::TimeDelta CellularDataPlan::remaining_time() const {
1519   base::TimeDelta time = plan_end_time - base::Time::Now();
1520   return time.InMicroseconds() < 0 ? base::TimeDelta() : time;
1521 }
1522 
remaining_minutes() const1523 int64 CellularDataPlan::remaining_minutes() const {
1524   return remaining_time().InMinutes();
1525 }
1526 
remaining_data() const1527 int64 CellularDataPlan::remaining_data() const {
1528   int64 data = plan_data_bytes - data_bytes_used;
1529   return data < 0 ? 0 : data;
1530 }
1531 
GetPlanExpiration() const1532 string16 CellularDataPlan::GetPlanExpiration() const {
1533   return TimeFormat::TimeRemaining(remaining_time());
1534 }
1535 
1536 ////////////////////////////////////////////////////////////////////////////////
1537 // CellularNetwork::Apn
1538 
Set(const DictionaryValue & dict)1539 void CellularNetwork::Apn::Set(const DictionaryValue& dict) {
1540   if (!dict.GetStringWithoutPathExpansion(kApnProperty, &apn))
1541     apn.clear();
1542   if (!dict.GetStringWithoutPathExpansion(kNetworkIdProperty, &network_id))
1543     network_id.clear();
1544   if (!dict.GetStringWithoutPathExpansion(kUsernameProperty, &username))
1545     username.clear();
1546   if (!dict.GetStringWithoutPathExpansion(kPasswordProperty, &password))
1547     password.clear();
1548 }
1549 
1550 ////////////////////////////////////////////////////////////////////////////////
1551 // CellularNetwork
1552 
~CellularNetwork()1553 CellularNetwork::~CellularNetwork() {
1554 }
1555 
ParseValue(int index,const Value * value)1556 bool CellularNetwork::ParseValue(int index, const Value* value) {
1557   switch (index) {
1558     case PROPERTY_INDEX_ACTIVATION_STATE: {
1559       std::string activation_state_string;
1560       if (value->GetAsString(&activation_state_string)) {
1561         ActivationState prev_state = activation_state_;
1562         activation_state_ = ParseActivationState(activation_state_string);
1563         if (activation_state_ != prev_state)
1564           RefreshDataPlansIfNeeded();
1565         return true;
1566       }
1567       break;
1568     }
1569     case PROPERTY_INDEX_CELLULAR_APN: {
1570       if (value->IsType(Value::TYPE_DICTIONARY)) {
1571         apn_.Set(*static_cast<const DictionaryValue*>(value));
1572         return true;
1573       }
1574       break;
1575     }
1576     case PROPERTY_INDEX_CELLULAR_LAST_GOOD_APN: {
1577       if (value->IsType(Value::TYPE_DICTIONARY)) {
1578         last_good_apn_.Set(*static_cast<const DictionaryValue*>(value));
1579         return true;
1580       }
1581       break;
1582     }
1583     case PROPERTY_INDEX_NETWORK_TECHNOLOGY: {
1584       std::string network_technology_string;
1585       if (value->GetAsString(&network_technology_string)) {
1586         network_technology_ = ParseNetworkTechnology(network_technology_string);
1587         return true;
1588       }
1589       break;
1590     }
1591     case PROPERTY_INDEX_ROAMING_STATE: {
1592       std::string roaming_state_string;
1593       if (value->GetAsString(&roaming_state_string)) {
1594         roaming_state_ = ParseRoamingState(roaming_state_string);
1595         return true;
1596       }
1597       break;
1598     }
1599     case PROPERTY_INDEX_OPERATOR_NAME:
1600       return value->GetAsString(&operator_name_);
1601     case PROPERTY_INDEX_OPERATOR_CODE:
1602       return value->GetAsString(&operator_code_);
1603     case PROPERTY_INDEX_SERVING_OPERATOR: {
1604       if (value->IsType(Value::TYPE_DICTIONARY)) {
1605         const DictionaryValue *dict =
1606             static_cast<const DictionaryValue*>(value);
1607         operator_code_.clear();
1608         operator_country_.clear();
1609         operator_name_.clear();
1610         dict->GetStringWithoutPathExpansion(kOperatorNameKey,
1611                                             &operator_name_);
1612         dict->GetStringWithoutPathExpansion(kOperatorCodeKey,
1613                                             &operator_code_);
1614         dict->GetStringWithoutPathExpansion(kOperatorCountryKey,
1615                                             &operator_country_);
1616         return true;
1617       }
1618       break;
1619     }
1620     case PROPERTY_INDEX_PAYMENT_URL:
1621       return value->GetAsString(&payment_url_);
1622     case PROPERTY_INDEX_USAGE_URL:
1623       return value->GetAsString(&usage_url_);
1624     case PROPERTY_INDEX_STATE: {
1625       // Save previous state before calling WirelessNetwork::ParseValue.
1626       ConnectionState prev_state = state_;
1627       if (WirelessNetwork::ParseValue(index, value)) {
1628         if (state_ != prev_state)
1629           RefreshDataPlansIfNeeded();
1630         return true;
1631       }
1632       break;
1633     }
1634     case PROPERTY_INDEX_CONNECTIVITY_STATE: {
1635       // Save previous state before calling WirelessNetwork::ParseValue.
1636       ConnectivityState prev_state = connectivity_state_;
1637       if (WirelessNetwork::ParseValue(index, value)) {
1638         if (connectivity_state_ != prev_state)
1639           RefreshDataPlansIfNeeded();
1640         return true;
1641       }
1642       break;
1643     }
1644     default:
1645       return WirelessNetwork::ParseValue(index, value);
1646   }
1647   return false;
1648 }
1649 
StartActivation() const1650 bool CellularNetwork::StartActivation() const {
1651   if (!EnsureCrosLoaded())
1652     return false;
1653   return ActivateCellularModem(service_path().c_str(), NULL);
1654 }
1655 
RefreshDataPlansIfNeeded() const1656 void CellularNetwork::RefreshDataPlansIfNeeded() const {
1657   if (!EnsureCrosLoaded())
1658     return;
1659   if (connected() && activated())
1660     RequestCellularDataPlanUpdate(service_path().c_str());
1661 }
1662 
SetApn(const Apn & apn)1663 void CellularNetwork::SetApn(const Apn& apn) {
1664   if (!EnsureCrosLoaded())
1665     return;
1666 
1667   if (!apn.apn.empty()) {
1668     DictionaryValue value;
1669     value.SetString(kApnProperty, apn.apn);
1670     value.SetString(kNetworkIdProperty, apn.network_id);
1671     value.SetString(kUsernameProperty, apn.username);
1672     value.SetString(kPasswordProperty, apn.password);
1673     SetValueProperty(kCellularApnProperty, &value);
1674   } else {
1675     ClearProperty(kCellularApnProperty);
1676   }
1677 }
1678 
SupportsDataPlan() const1679 bool CellularNetwork::SupportsDataPlan() const {
1680   // TODO(nkostylev): Are there cases when only one of this is defined?
1681   return !usage_url().empty() || !payment_url().empty();
1682 }
1683 
GetNetworkTechnologyString() const1684 std::string CellularNetwork::GetNetworkTechnologyString() const {
1685   // No need to localize these cellular technology abbreviations.
1686   switch (network_technology_) {
1687     case NETWORK_TECHNOLOGY_1XRTT:
1688       return "1xRTT";
1689       break;
1690     case NETWORK_TECHNOLOGY_EVDO:
1691       return "EVDO";
1692       break;
1693     case NETWORK_TECHNOLOGY_GPRS:
1694       return "GPRS";
1695       break;
1696     case NETWORK_TECHNOLOGY_EDGE:
1697       return "EDGE";
1698       break;
1699     case NETWORK_TECHNOLOGY_UMTS:
1700       return "UMTS";
1701       break;
1702     case NETWORK_TECHNOLOGY_HSPA:
1703       return "HSPA";
1704       break;
1705     case NETWORK_TECHNOLOGY_HSPA_PLUS:
1706       return "HSPA Plus";
1707       break;
1708     case NETWORK_TECHNOLOGY_LTE:
1709       return "LTE";
1710       break;
1711     case NETWORK_TECHNOLOGY_LTE_ADVANCED:
1712       return "LTE Advanced";
1713       break;
1714     default:
1715       return l10n_util::GetStringUTF8(
1716           IDS_CHROMEOS_NETWORK_CELLULAR_TECHNOLOGY_UNKNOWN);
1717       break;
1718   }
1719 }
1720 
GetConnectivityStateString() const1721 std::string CellularNetwork::GetConnectivityStateString() const {
1722   // These strings do not appear in the UI, so no need to localize them
1723   switch (connectivity_state_) {
1724     case CONN_STATE_UNRESTRICTED:
1725       return "unrestricted";
1726       break;
1727     case CONN_STATE_RESTRICTED:
1728       return "restricted";
1729       break;
1730     case CONN_STATE_NONE:
1731       return "none";
1732       break;
1733     case CONN_STATE_UNKNOWN:
1734     default:
1735       return "unknown";
1736   }
1737 }
1738 
ActivationStateToString(ActivationState activation_state)1739 std::string CellularNetwork::ActivationStateToString(
1740     ActivationState activation_state) {
1741   switch (activation_state) {
1742     case ACTIVATION_STATE_ACTIVATED:
1743       return l10n_util::GetStringUTF8(
1744           IDS_CHROMEOS_NETWORK_ACTIVATION_STATE_ACTIVATED);
1745       break;
1746     case ACTIVATION_STATE_ACTIVATING:
1747       return l10n_util::GetStringUTF8(
1748           IDS_CHROMEOS_NETWORK_ACTIVATION_STATE_ACTIVATING);
1749       break;
1750     case ACTIVATION_STATE_NOT_ACTIVATED:
1751       return l10n_util::GetStringUTF8(
1752           IDS_CHROMEOS_NETWORK_ACTIVATION_STATE_NOT_ACTIVATED);
1753       break;
1754     case ACTIVATION_STATE_PARTIALLY_ACTIVATED:
1755       return l10n_util::GetStringUTF8(
1756           IDS_CHROMEOS_NETWORK_ACTIVATION_STATE_PARTIALLY_ACTIVATED);
1757       break;
1758     default:
1759       return l10n_util::GetStringUTF8(
1760           IDS_CHROMEOS_NETWORK_ACTIVATION_STATE_UNKNOWN);
1761       break;
1762   }
1763 }
1764 
GetActivationStateString() const1765 std::string CellularNetwork::GetActivationStateString() const {
1766   return ActivationStateToString(this->activation_state_);
1767 }
1768 
GetRoamingStateString() const1769 std::string CellularNetwork::GetRoamingStateString() const {
1770   switch (this->roaming_state_) {
1771     case ROAMING_STATE_HOME:
1772       return l10n_util::GetStringUTF8(
1773           IDS_CHROMEOS_NETWORK_ROAMING_STATE_HOME);
1774       break;
1775     case ROAMING_STATE_ROAMING:
1776       return l10n_util::GetStringUTF8(
1777           IDS_CHROMEOS_NETWORK_ROAMING_STATE_ROAMING);
1778       break;
1779     default:
1780       return l10n_util::GetStringUTF8(
1781           IDS_CHROMEOS_NETWORK_ROAMING_STATE_UNKNOWN);
1782       break;
1783   }
1784 }
1785 
1786 ////////////////////////////////////////////////////////////////////////////////
1787 // WifiNetwork
1788 
1789 // Called from ParseNetwork after calling ParseInfo.
CalculateUniqueId()1790 void WifiNetwork::CalculateUniqueId() {
1791   ConnectionSecurity encryption = encryption_;
1792   // Flimflam treats wpa and rsn as psk internally, so convert those types
1793   // to psk for unique naming.
1794   if (encryption == SECURITY_WPA || encryption == SECURITY_RSN)
1795     encryption = SECURITY_PSK;
1796   std::string security = std::string(SecurityToString(encryption));
1797   unique_id_ = security + "|" + name_;
1798 }
1799 
SetSsid(const std::string & ssid)1800 bool WifiNetwork::SetSsid(const std::string& ssid) {
1801   // Detects encoding and convert to UTF-8.
1802   std::string ssid_utf8;
1803   if (!IsStringUTF8(ssid)) {
1804     std::string encoding;
1805     if (base::DetectEncoding(ssid, &encoding)) {
1806       if (!base::ConvertToUtf8AndNormalize(ssid, encoding, &ssid_utf8)) {
1807         ssid_utf8.clear();
1808       }
1809     }
1810   }
1811 
1812   if (ssid_utf8.empty())
1813     SetName(ssid);
1814   else
1815     SetName(ssid_utf8);
1816 
1817   return true;
1818 }
1819 
SetHexSsid(const std::string & ssid_hex)1820 bool WifiNetwork::SetHexSsid(const std::string& ssid_hex) {
1821   // Converts ascii hex dump (eg. "49656c6c6f") to string (eg. "Hello").
1822   std::vector<uint8> ssid_raw;
1823   if (!base::HexStringToBytes(ssid_hex, &ssid_raw)) {
1824     LOG(ERROR) << "Iligal hex char is found in WiFi.HexSSID.";
1825     ssid_raw.clear();
1826     return false;
1827   }
1828 
1829   return SetSsid(std::string(ssid_raw.begin(), ssid_raw.end()));
1830 }
1831 
ParseValue(int index,const Value * value)1832 bool WifiNetwork::ParseValue(int index, const Value* value) {
1833   switch (index) {
1834     case PROPERTY_INDEX_WIFI_HEX_SSID: {
1835       std::string ssid_hex;
1836       if (!value->GetAsString(&ssid_hex))
1837         return false;
1838 
1839       SetHexSsid(ssid_hex);
1840       return true;
1841     }
1842     case PROPERTY_INDEX_NAME: {
1843       // Does not change network name when it was already set by WiFi.HexSSID.
1844       if (!name().empty())
1845         return true;
1846       else
1847         return WirelessNetwork::ParseValue(index, value);
1848     }
1849     case PROPERTY_INDEX_SECURITY: {
1850       std::string security_string;
1851       if (value->GetAsString(&security_string)) {
1852         encryption_ = ParseSecurity(security_string);
1853         return true;
1854       }
1855       break;
1856     }
1857     case PROPERTY_INDEX_PASSPHRASE: {
1858       std::string passphrase;
1859       if (value->GetAsString(&passphrase)) {
1860         // Only store the passphrase if we are the owner.
1861         // TODO(stevenjb): Remove this when chromium-os:12948 is resolved.
1862         if (chromeos::UserManager::Get()->current_user_is_owner())
1863           passphrase_ = passphrase;
1864         return true;
1865       }
1866       break;
1867     }
1868     case PROPERTY_INDEX_PASSPHRASE_REQUIRED:
1869       return value->GetAsBoolean(&passphrase_required_);
1870     case PROPERTY_INDEX_SAVE_CREDENTIALS:
1871       return value->GetAsBoolean(&save_credentials_);
1872     case PROPERTY_INDEX_IDENTITY:
1873       return value->GetAsString(&identity_);
1874     case PROPERTY_INDEX_CERT_PATH:
1875       return value->GetAsString(&cert_path_);
1876     case PROPERTY_INDEX_EAP_IDENTITY:
1877       return value->GetAsString(&eap_identity_);
1878     case PROPERTY_INDEX_EAP_METHOD: {
1879       std::string method;
1880       if (value->GetAsString(&method)) {
1881         eap_method_ = ParseEAPMethod(method);
1882         return true;
1883       }
1884       break;
1885     }
1886     case PROPERTY_INDEX_EAP_PHASE_2_AUTH: {
1887       std::string auth;
1888       if (value->GetAsString(&auth)) {
1889         eap_phase_2_auth_ = ParseEAPPhase2Auth(auth);
1890         return true;
1891       }
1892       break;
1893     }
1894     case PROPERTY_INDEX_EAP_ANONYMOUS_IDENTITY:
1895       return value->GetAsString(&eap_anonymous_identity_);
1896     case PROPERTY_INDEX_EAP_CERT_ID:
1897       return value->GetAsString(&eap_client_cert_pkcs11_id_);
1898     case PROPERTY_INDEX_EAP_CA_CERT_NSS:
1899       return value->GetAsString(&eap_server_ca_cert_nss_nickname_);
1900     case PROPERTY_INDEX_EAP_USE_SYSTEM_CAS:
1901       return value->GetAsBoolean(&eap_use_system_cas_);
1902     case PROPERTY_INDEX_EAP_PASSWORD:
1903       return value->GetAsString(&eap_passphrase_);
1904     case PROPERTY_INDEX_EAP_CLIENT_CERT:
1905     case PROPERTY_INDEX_EAP_CLIENT_CERT_NSS:
1906     case PROPERTY_INDEX_EAP_PRIVATE_KEY:
1907     case PROPERTY_INDEX_EAP_PRIVATE_KEY_PASSWORD:
1908     case PROPERTY_INDEX_EAP_KEY_ID:
1909     case PROPERTY_INDEX_EAP_CA_CERT:
1910     case PROPERTY_INDEX_EAP_CA_CERT_ID:
1911     case PROPERTY_INDEX_EAP_PIN:
1912     case PROPERTY_INDEX_EAP_KEY_MGMT:
1913       // These properties are currently not used in the UI.
1914       return true;
1915     default:
1916       return WirelessNetwork::ParseValue(index, value);
1917   }
1918   return false;
1919 }
1920 
ParseInfo(const DictionaryValue * info)1921 void WifiNetwork::ParseInfo(const DictionaryValue* info) {
1922   Network::ParseInfo(info);
1923   CalculateUniqueId();
1924 }
1925 
GetPassphrase() const1926 const std::string& WifiNetwork::GetPassphrase() const {
1927   if (!user_passphrase_.empty())
1928     return user_passphrase_;
1929   return passphrase_;
1930 }
1931 
SetPassphrase(const std::string & passphrase)1932 void WifiNetwork::SetPassphrase(const std::string& passphrase) {
1933   // Set the user_passphrase_ only; passphrase_ stores the flimflam value.
1934   // If the user sets an empty passphrase, restore it to the passphrase
1935   // remembered by flimflam.
1936   if (!passphrase.empty()) {
1937     user_passphrase_ = passphrase;
1938     passphrase_ = passphrase;
1939   } else {
1940     user_passphrase_ = passphrase_;
1941   }
1942   // Send the change to flimflam. If the format is valid, it will propagate to
1943   // passphrase_ with a service update.
1944   SetOrClearStringProperty(kPassphraseProperty, passphrase, NULL);
1945 }
1946 
SetSaveCredentials(bool save_credentials)1947 void WifiNetwork::SetSaveCredentials(bool save_credentials) {
1948   SetBooleanProperty(kSaveCredentialsProperty, save_credentials,
1949                      &save_credentials_);
1950 }
1951 
1952 // See src/third_party/flimflam/doc/service-api.txt for properties that
1953 // flimflam will forget when SaveCredentials is false.
EraseCredentials()1954 void WifiNetwork::EraseCredentials() {
1955   WipeString(&passphrase_);
1956   WipeString(&user_passphrase_);
1957   WipeString(&eap_client_cert_pkcs11_id_);
1958   WipeString(&eap_identity_);
1959   WipeString(&eap_anonymous_identity_);
1960   WipeString(&eap_passphrase_);
1961 }
1962 
SetIdentity(const std::string & identity)1963 void WifiNetwork::SetIdentity(const std::string& identity) {
1964   SetStringProperty(kIdentityProperty, identity, &identity_);
1965 }
1966 
SetCertPath(const std::string & cert_path)1967 void WifiNetwork::SetCertPath(const std::string& cert_path) {
1968   SetStringProperty(kCertPathProperty, cert_path, &cert_path_);
1969 }
1970 
SetEAPMethod(EAPMethod method)1971 void WifiNetwork::SetEAPMethod(EAPMethod method) {
1972   eap_method_ = method;
1973   switch (method) {
1974     case EAP_METHOD_PEAP:
1975       SetStringProperty(kEapMethodProperty, kEapMethodPEAP, NULL);
1976       break;
1977     case EAP_METHOD_TLS:
1978       SetStringProperty(kEapMethodProperty, kEapMethodTLS, NULL);
1979       break;
1980     case EAP_METHOD_TTLS:
1981       SetStringProperty(kEapMethodProperty, kEapMethodTTLS, NULL);
1982       break;
1983     case EAP_METHOD_LEAP:
1984       SetStringProperty(kEapMethodProperty, kEapMethodLEAP, NULL);
1985       break;
1986     default:
1987       ClearProperty(kEapMethodProperty);
1988       break;
1989   }
1990 }
1991 
SetEAPPhase2Auth(EAPPhase2Auth auth)1992 void WifiNetwork::SetEAPPhase2Auth(EAPPhase2Auth auth) {
1993   eap_phase_2_auth_ = auth;
1994   bool is_peap = (eap_method_ == EAP_METHOD_PEAP);
1995   switch (auth) {
1996     case EAP_PHASE_2_AUTH_AUTO:
1997       ClearProperty(kEapPhase2AuthProperty);
1998       break;
1999     case EAP_PHASE_2_AUTH_MD5:
2000       SetStringProperty(kEapPhase2AuthProperty,
2001                         is_peap ? kEapPhase2AuthPEAPMD5
2002                                 : kEapPhase2AuthTTLSMD5,
2003                         NULL);
2004       break;
2005     case EAP_PHASE_2_AUTH_MSCHAPV2:
2006       SetStringProperty(kEapPhase2AuthProperty,
2007                         is_peap ? kEapPhase2AuthPEAPMSCHAPV2
2008                                 : kEapPhase2AuthTTLSMSCHAPV2,
2009                         NULL);
2010       break;
2011     case EAP_PHASE_2_AUTH_MSCHAP:
2012       SetStringProperty(kEapPhase2AuthProperty, kEapPhase2AuthTTLSMSCHAP, NULL);
2013       break;
2014     case EAP_PHASE_2_AUTH_PAP:
2015       SetStringProperty(kEapPhase2AuthProperty, kEapPhase2AuthTTLSPAP, NULL);
2016       break;
2017     case EAP_PHASE_2_AUTH_CHAP:
2018       SetStringProperty(kEapPhase2AuthProperty, kEapPhase2AuthTTLSCHAP, NULL);
2019       break;
2020   }
2021 }
2022 
SetEAPServerCaCertNssNickname(const std::string & nss_nickname)2023 void WifiNetwork::SetEAPServerCaCertNssNickname(
2024     const std::string& nss_nickname) {
2025   VLOG(1) << "SetEAPServerCaCertNssNickname " << nss_nickname;
2026   SetOrClearStringProperty(kEapCaCertNssProperty, nss_nickname,
2027                            &eap_server_ca_cert_nss_nickname_);
2028 }
2029 
SetEAPClientCertPkcs11Id(const std::string & pkcs11_id)2030 void WifiNetwork::SetEAPClientCertPkcs11Id(const std::string& pkcs11_id) {
2031   VLOG(1) << "SetEAPClientCertPkcs11Id " << pkcs11_id;
2032   SetOrClearStringProperty(kEapCertIDProperty, pkcs11_id,
2033                            &eap_client_cert_pkcs11_id_);
2034 }
2035 
SetEAPUseSystemCAs(bool use_system_cas)2036 void WifiNetwork::SetEAPUseSystemCAs(bool use_system_cas) {
2037   SetBooleanProperty(kEapUseSystemCAsProperty, use_system_cas,
2038                      &eap_use_system_cas_);
2039 }
2040 
SetEAPIdentity(const std::string & identity)2041 void WifiNetwork::SetEAPIdentity(const std::string& identity) {
2042   SetOrClearStringProperty(kEapIdentityProperty, identity, &eap_identity_);
2043 }
2044 
SetEAPAnonymousIdentity(const std::string & identity)2045 void WifiNetwork::SetEAPAnonymousIdentity(const std::string& identity) {
2046   SetOrClearStringProperty(kEapAnonymousIdentityProperty, identity,
2047                            &eap_anonymous_identity_);
2048 }
2049 
SetEAPPassphrase(const std::string & passphrase)2050 void WifiNetwork::SetEAPPassphrase(const std::string& passphrase) {
2051   SetOrClearStringProperty(kEapPasswordProperty, passphrase, &eap_passphrase_);
2052 }
2053 
GetEncryptionString() const2054 std::string WifiNetwork::GetEncryptionString() const {
2055   switch (encryption_) {
2056     case SECURITY_UNKNOWN:
2057       break;
2058     case SECURITY_NONE:
2059       return "";
2060     case SECURITY_WEP:
2061       return "WEP";
2062     case SECURITY_WPA:
2063       return "WPA";
2064     case SECURITY_RSN:
2065       return "RSN";
2066     case SECURITY_8021X:
2067       return "8021X";
2068     case SECURITY_PSK:
2069       return "PSK";
2070   }
2071   return "Unknown";
2072 }
2073 
IsPassphraseRequired() const2074 bool WifiNetwork::IsPassphraseRequired() const {
2075   // TODO(stevenjb): Remove error_ tests when fixed in flimflam
2076   // (http://crosbug.com/10135).
2077   if (error_ == ERROR_BAD_PASSPHRASE || error_ == ERROR_BAD_WEPKEY)
2078     return true;
2079   // For 802.1x networks, configuration is required if connectable is false.
2080   if (encryption_ == SECURITY_8021X)
2081     return !connectable_;
2082   return passphrase_required_;
2083 }
2084 
2085 // Parse 'path' to determine if the certificate is stored in a pkcs#11 device.
2086 // flimflam recognizes the string "SETTINGS:" to specify authentication
2087 // parameters. 'key_id=' indicates that the certificate is stored in a pkcs#11
2088 // device. See src/third_party/flimflam/files/doc/service-api.txt.
IsCertificateLoaded() const2089 bool WifiNetwork::IsCertificateLoaded() const {
2090   static const std::string settings_string("SETTINGS:");
2091   static const std::string pkcs11_key("key_id");
2092   if (cert_path_.find(settings_string) == 0) {
2093     std::string::size_type idx = cert_path_.find(pkcs11_key);
2094     if (idx != std::string::npos)
2095       idx = cert_path_.find_first_not_of(kWhitespaceASCII,
2096                                          idx + pkcs11_key.length());
2097     if (idx != std::string::npos && cert_path_[idx] == '=')
2098       return true;
2099   }
2100   return false;
2101 }
2102 
2103 ////////////////////////////////////////////////////////////////////////////////
2104 // NetworkLibrary
2105 
2106 class NetworkLibraryImpl : public NetworkLibrary  {
2107  public:
NetworkLibraryImpl()2108   NetworkLibraryImpl()
2109       : network_manager_monitor_(NULL),
2110         data_plan_monitor_(NULL),
2111         ethernet_(NULL),
2112         active_wifi_(NULL),
2113         active_cellular_(NULL),
2114         active_virtual_(NULL),
2115         available_devices_(0),
2116         enabled_devices_(0),
2117         connected_devices_(0),
2118         wifi_scanning_(false),
2119         offline_mode_(false),
2120         is_locked_(false),
2121         sim_operation_(SIM_OPERATION_NONE),
2122         notify_task_(NULL) {
2123     if (EnsureCrosLoaded()) {
2124       Init();
2125       network_manager_monitor_ =
2126           MonitorNetworkManager(&NetworkManagerStatusChangedHandler,
2127                                 this);
2128       data_plan_monitor_ = MonitorCellularDataPlan(&DataPlanUpdateHandler,
2129                                                    this);
2130       network_login_observer_.reset(new NetworkLoginObserver(this));
2131     } else {
2132       InitTestData();
2133     }
2134   }
2135 
~NetworkLibraryImpl()2136   virtual ~NetworkLibraryImpl() {
2137     network_manager_observers_.Clear();
2138     if (network_manager_monitor_)
2139       DisconnectPropertyChangeMonitor(network_manager_monitor_);
2140     data_plan_observers_.Clear();
2141     pin_operation_observers_.Clear();
2142     user_action_observers_.Clear();
2143     if (data_plan_monitor_)
2144       DisconnectDataPlanUpdateMonitor(data_plan_monitor_);
2145     STLDeleteValues(&network_observers_);
2146     STLDeleteValues(&network_device_observers_);
2147     ClearNetworks(true /*delete networks*/);
2148     ClearRememberedNetworks(true /*delete networks*/);
2149     STLDeleteValues(&data_plan_map_);
2150   }
2151 
AddNetworkManagerObserver(NetworkManagerObserver * observer)2152   virtual void AddNetworkManagerObserver(NetworkManagerObserver* observer) {
2153     if (!network_manager_observers_.HasObserver(observer))
2154       network_manager_observers_.AddObserver(observer);
2155   }
2156 
RemoveNetworkManagerObserver(NetworkManagerObserver * observer)2157   virtual void RemoveNetworkManagerObserver(NetworkManagerObserver* observer) {
2158     network_manager_observers_.RemoveObserver(observer);
2159   }
2160 
AddNetworkObserver(const std::string & service_path,NetworkObserver * observer)2161   virtual void AddNetworkObserver(const std::string& service_path,
2162                                   NetworkObserver* observer) {
2163     DCHECK(observer);
2164     if (!EnsureCrosLoaded())
2165       return;
2166     // First, add the observer to the callback map.
2167     NetworkObserverMap::iterator iter = network_observers_.find(service_path);
2168     NetworkObserverList* oblist;
2169     if (iter != network_observers_.end()) {
2170       oblist = iter->second;
2171     } else {
2172       oblist = new NetworkObserverList(this, service_path);
2173       network_observers_[service_path] = oblist;
2174     }
2175     if (!oblist->HasObserver(observer))
2176       oblist->AddObserver(observer);
2177   }
2178 
RemoveNetworkObserver(const std::string & service_path,NetworkObserver * observer)2179   virtual void RemoveNetworkObserver(const std::string& service_path,
2180                                      NetworkObserver* observer) {
2181     DCHECK(observer);
2182     DCHECK(service_path.size());
2183     NetworkObserverMap::iterator map_iter =
2184         network_observers_.find(service_path);
2185     if (map_iter != network_observers_.end()) {
2186       map_iter->second->RemoveObserver(observer);
2187       if (!map_iter->second->size()) {
2188         delete map_iter->second;
2189         network_observers_.erase(map_iter);
2190       }
2191     }
2192   }
2193 
AddNetworkDeviceObserver(const std::string & device_path,NetworkDeviceObserver * observer)2194   virtual void AddNetworkDeviceObserver(const std::string& device_path,
2195                                         NetworkDeviceObserver* observer) {
2196     DCHECK(observer);
2197     if (!EnsureCrosLoaded())
2198       return;
2199     // First, add the observer to the callback map.
2200     NetworkDeviceObserverMap::iterator iter =
2201         network_device_observers_.find(device_path);
2202     NetworkDeviceObserverList* oblist;
2203     if (iter != network_device_observers_.end()) {
2204       oblist = iter->second;
2205       if (!oblist->HasObserver(observer))
2206         oblist->AddObserver(observer);
2207     } else {
2208       LOG(WARNING) << "No NetworkDeviceObserverList found for "
2209                    << device_path;
2210     }
2211   }
2212 
RemoveNetworkDeviceObserver(const std::string & device_path,NetworkDeviceObserver * observer)2213   virtual void RemoveNetworkDeviceObserver(const std::string& device_path,
2214                                            NetworkDeviceObserver* observer) {
2215     DCHECK(observer);
2216     DCHECK(device_path.size());
2217     NetworkDeviceObserverMap::iterator map_iter =
2218         network_device_observers_.find(device_path);
2219     if (map_iter != network_device_observers_.end()) {
2220       map_iter->second->RemoveObserver(observer);
2221     }
2222   }
2223 
RemoveObserverForAllNetworks(NetworkObserver * observer)2224   virtual void RemoveObserverForAllNetworks(NetworkObserver* observer) {
2225     DCHECK(observer);
2226     NetworkObserverMap::iterator map_iter = network_observers_.begin();
2227     while (map_iter != network_observers_.end()) {
2228       map_iter->second->RemoveObserver(observer);
2229       if (!map_iter->second->size()) {
2230         delete map_iter->second;
2231         network_observers_.erase(map_iter++);
2232       } else {
2233         ++map_iter;
2234       }
2235     }
2236   }
2237 
Lock()2238   virtual void Lock() {
2239     if (is_locked_)
2240       return;
2241     is_locked_ = true;
2242     NotifyNetworkManagerChanged(true);  // Forced update.
2243   }
2244 
Unlock()2245   virtual void Unlock() {
2246     DCHECK(is_locked_);
2247     if (!is_locked_)
2248       return;
2249     is_locked_ = false;
2250     NotifyNetworkManagerChanged(true);  // Forced update.
2251   }
2252 
IsLocked()2253   virtual bool IsLocked() {
2254     return is_locked_;
2255   }
2256 
AddCellularDataPlanObserver(CellularDataPlanObserver * observer)2257   virtual void AddCellularDataPlanObserver(CellularDataPlanObserver* observer) {
2258     if (!data_plan_observers_.HasObserver(observer))
2259       data_plan_observers_.AddObserver(observer);
2260   }
2261 
RemoveCellularDataPlanObserver(CellularDataPlanObserver * observer)2262   virtual void RemoveCellularDataPlanObserver(
2263       CellularDataPlanObserver* observer) {
2264     data_plan_observers_.RemoveObserver(observer);
2265   }
2266 
AddPinOperationObserver(PinOperationObserver * observer)2267   virtual void AddPinOperationObserver(PinOperationObserver* observer) {
2268     if (!pin_operation_observers_.HasObserver(observer))
2269       pin_operation_observers_.AddObserver(observer);
2270   }
2271 
RemovePinOperationObserver(PinOperationObserver * observer)2272   virtual void RemovePinOperationObserver(PinOperationObserver* observer) {
2273     pin_operation_observers_.RemoveObserver(observer);
2274   }
2275 
AddUserActionObserver(UserActionObserver * observer)2276   virtual void AddUserActionObserver(UserActionObserver* observer) {
2277     if (!user_action_observers_.HasObserver(observer))
2278       user_action_observers_.AddObserver(observer);
2279   }
2280 
RemoveUserActionObserver(UserActionObserver * observer)2281   virtual void RemoveUserActionObserver(UserActionObserver* observer) {
2282     user_action_observers_.RemoveObserver(observer);
2283   }
2284 
ethernet_network() const2285   virtual const EthernetNetwork* ethernet_network() const { return ethernet_; }
ethernet_connecting() const2286   virtual bool ethernet_connecting() const {
2287     return ethernet_ ? ethernet_->connecting() : false;
2288   }
ethernet_connected() const2289   virtual bool ethernet_connected() const {
2290     return ethernet_ ? ethernet_->connected() : false;
2291   }
2292 
wifi_network() const2293   virtual const WifiNetwork* wifi_network() const { return active_wifi_; }
wifi_connecting() const2294   virtual bool wifi_connecting() const {
2295     return active_wifi_ ? active_wifi_->connecting() : false;
2296   }
wifi_connected() const2297   virtual bool wifi_connected() const {
2298     return active_wifi_ ? active_wifi_->connected() : false;
2299   }
2300 
cellular_network() const2301   virtual const CellularNetwork* cellular_network() const {
2302     return active_cellular_;
2303   }
cellular_connecting() const2304   virtual bool cellular_connecting() const {
2305     return active_cellular_ ? active_cellular_->connecting() : false;
2306   }
cellular_connected() const2307   virtual bool cellular_connected() const {
2308     return active_cellular_ ? active_cellular_->connected() : false;
2309   }
virtual_network() const2310   virtual const VirtualNetwork* virtual_network() const {
2311     return active_virtual_;
2312   }
virtual_network_connecting() const2313   virtual bool virtual_network_connecting() const {
2314     return active_virtual_ ? active_virtual_->connecting() : false;
2315   }
virtual_network_connected() const2316   virtual bool virtual_network_connected() const {
2317     return active_virtual_ ? active_virtual_->connected() : false;
2318   }
2319 
Connected() const2320   bool Connected() const {
2321     return ethernet_connected() || wifi_connected() || cellular_connected();
2322   }
2323 
Connecting() const2324   bool Connecting() const {
2325     return ethernet_connecting() || wifi_connecting() || cellular_connecting();
2326   }
2327 
IPAddress() const2328   const std::string& IPAddress() const {
2329     // Returns IP address for the active network.
2330     // TODO(stevenjb): Fix this for VPNs. See chromium-os:13972.
2331     const Network* result = active_network();
2332     if (!result)
2333       result = connected_network();  // happens if we are connected to a VPN.
2334     if (!result)
2335       result = ethernet_;  // Use non active ethernet addr if no active network.
2336     if (result)
2337       return result->ip_address();
2338     static std::string null_address("0.0.0.0");
2339     return null_address;
2340   }
2341 
wifi_networks() const2342   virtual const WifiNetworkVector& wifi_networks() const {
2343     return wifi_networks_;
2344   }
2345 
remembered_wifi_networks() const2346   virtual const WifiNetworkVector& remembered_wifi_networks() const {
2347     return remembered_wifi_networks_;
2348   }
2349 
cellular_networks() const2350   virtual const CellularNetworkVector& cellular_networks() const {
2351     return cellular_networks_;
2352   }
2353 
virtual_networks() const2354   virtual const VirtualNetworkVector& virtual_networks() const {
2355     return virtual_networks_;
2356   }
2357 
2358   /////////////////////////////////////////////////////////////////////////////
2359 
FindNetworkDeviceByPath(const std::string & path) const2360   virtual const NetworkDevice* FindNetworkDeviceByPath(
2361       const std::string& path) const {
2362     NetworkDeviceMap::const_iterator iter = device_map_.find(path);
2363     if (iter != device_map_.end())
2364       return iter->second;
2365     LOG(WARNING) << "Device path not found: " << path;
2366     return NULL;
2367   }
2368 
FindCellularDevice() const2369   virtual const NetworkDevice* FindCellularDevice() const {
2370     for (NetworkDeviceMap::const_iterator iter = device_map_.begin();
2371          iter != device_map_.end(); ++iter) {
2372       if (iter->second->type() == TYPE_CELLULAR)
2373         return iter->second;
2374     }
2375     return NULL;
2376   }
2377 
FindEthernetDevice() const2378   virtual const NetworkDevice* FindEthernetDevice() const {
2379     for (NetworkDeviceMap::const_iterator iter = device_map_.begin();
2380          iter != device_map_.end(); ++iter) {
2381       if (iter->second->type() == TYPE_ETHERNET)
2382         return iter->second;
2383     }
2384     return NULL;
2385   }
2386 
FindWifiDevice() const2387   virtual const NetworkDevice* FindWifiDevice() const {
2388     for (NetworkDeviceMap::const_iterator iter = device_map_.begin();
2389          iter != device_map_.end(); ++iter) {
2390       if (iter->second->type() == TYPE_WIFI)
2391         return iter->second;
2392     }
2393     return NULL;
2394   }
2395 
FindNetworkByPath(const std::string & path) const2396   virtual Network* FindNetworkByPath(const std::string& path) const {
2397     NetworkMap::const_iterator iter = network_map_.find(path);
2398     if (iter != network_map_.end())
2399       return iter->second;
2400     return NULL;
2401   }
2402 
FindWirelessNetworkByPath(const std::string & path) const2403   WirelessNetwork* FindWirelessNetworkByPath(const std::string& path) const {
2404     Network* network = FindNetworkByPath(path);
2405     if (network &&
2406         (network->type() == TYPE_WIFI || network->type() == TYPE_CELLULAR))
2407       return static_cast<WirelessNetwork*>(network);
2408     return NULL;
2409   }
2410 
FindWifiNetworkByPath(const std::string & path) const2411   virtual WifiNetwork* FindWifiNetworkByPath(const std::string& path) const {
2412     Network* network = FindNetworkByPath(path);
2413     if (network && network->type() == TYPE_WIFI)
2414       return static_cast<WifiNetwork*>(network);
2415     return NULL;
2416   }
2417 
FindCellularNetworkByPath(const std::string & path) const2418   virtual CellularNetwork* FindCellularNetworkByPath(
2419       const std::string& path) const {
2420     Network* network = FindNetworkByPath(path);
2421     if (network && network->type() == TYPE_CELLULAR)
2422       return static_cast<CellularNetwork*>(network);
2423     return NULL;
2424   }
2425 
FindVirtualNetworkByPath(const std::string & path) const2426   virtual VirtualNetwork* FindVirtualNetworkByPath(
2427       const std::string& path) const {
2428     Network* network = FindNetworkByPath(path);
2429     if (network && network->type() == TYPE_VPN)
2430       return static_cast<VirtualNetwork*>(network);
2431     return NULL;
2432   }
2433 
FindNetworkFromRemembered(const Network * remembered) const2434   virtual Network* FindNetworkFromRemembered(
2435       const Network* remembered) const {
2436     NetworkMap::const_iterator found =
2437         network_unique_id_map_.find(remembered->unique_id());
2438     if (found != network_unique_id_map_.end())
2439       return found->second;
2440     return NULL;
2441   }
2442 
GetDataPlans(const std::string & path) const2443   virtual const CellularDataPlanVector* GetDataPlans(
2444       const std::string& path) const {
2445     CellularDataPlanMap::const_iterator iter = data_plan_map_.find(path);
2446     if (iter == data_plan_map_.end())
2447       return NULL;
2448     // If we need a new plan, then ignore any data plans we have.
2449     CellularNetwork* cellular = FindCellularNetworkByPath(path);
2450     if (cellular && cellular->needs_new_plan())
2451       return NULL;
2452     return iter->second;
2453   }
2454 
GetSignificantDataPlan(const std::string & path) const2455   virtual const CellularDataPlan* GetSignificantDataPlan(
2456       const std::string& path) const {
2457     const CellularDataPlanVector* plans = GetDataPlans(path);
2458     if (plans)
2459       return GetSignificantDataPlanFromVector(plans);
2460     return NULL;
2461   }
2462 
2463   /////////////////////////////////////////////////////////////////////////////
2464 
ChangePin(const std::string & old_pin,const std::string & new_pin)2465   virtual void ChangePin(const std::string& old_pin,
2466                          const std::string& new_pin) {
2467     const NetworkDevice* cellular = FindCellularDevice();
2468     if (!cellular) {
2469       NOTREACHED() << "Calling ChangePin method w/o cellular device.";
2470       return;
2471     }
2472     sim_operation_ = SIM_OPERATION_CHANGE_PIN;
2473     chromeos::RequestChangePin(cellular->device_path().c_str(),
2474                                old_pin.c_str(), new_pin.c_str(),
2475                                PinOperationCallback, this);
2476   }
2477 
ChangeRequirePin(bool require_pin,const std::string & pin)2478   virtual void ChangeRequirePin(bool require_pin,
2479                                 const std::string& pin) {
2480     VLOG(1) << "ChangeRequirePin require_pin: " << require_pin
2481             << " pin: " << pin;
2482     const NetworkDevice* cellular = FindCellularDevice();
2483     if (!cellular) {
2484       NOTREACHED() << "Calling ChangeRequirePin method w/o cellular device.";
2485       return;
2486     }
2487     sim_operation_ = SIM_OPERATION_CHANGE_REQUIRE_PIN;
2488     chromeos::RequestRequirePin(cellular->device_path().c_str(),
2489                                 pin.c_str(), require_pin,
2490                                 PinOperationCallback, this);
2491   }
2492 
EnterPin(const std::string & pin)2493   virtual void EnterPin(const std::string& pin) {
2494     const NetworkDevice* cellular = FindCellularDevice();
2495     if (!cellular) {
2496       NOTREACHED() << "Calling EnterPin method w/o cellular device.";
2497       return;
2498     }
2499     sim_operation_ = SIM_OPERATION_ENTER_PIN;
2500     chromeos::RequestEnterPin(cellular->device_path().c_str(),
2501                               pin.c_str(),
2502                               PinOperationCallback, this);
2503   }
2504 
UnblockPin(const std::string & puk,const std::string & new_pin)2505   virtual void UnblockPin(const std::string& puk,
2506                           const std::string& new_pin) {
2507     const NetworkDevice* cellular = FindCellularDevice();
2508     if (!cellular) {
2509       NOTREACHED() << "Calling UnblockPin method w/o cellular device.";
2510       return;
2511     }
2512     sim_operation_ = SIM_OPERATION_UNBLOCK_PIN;
2513     chromeos::RequestUnblockPin(cellular->device_path().c_str(),
2514                                 puk.c_str(), new_pin.c_str(),
2515                                 PinOperationCallback, this);
2516   }
2517 
PinOperationCallback(void * object,const char * path,NetworkMethodErrorType error,const char * error_message)2518   static void PinOperationCallback(void* object,
2519                                    const char* path,
2520                                    NetworkMethodErrorType error,
2521                                    const char* error_message) {
2522     NetworkLibraryImpl* networklib = static_cast<NetworkLibraryImpl*>(object);
2523     DCHECK(networklib);
2524     PinOperationError pin_error;
2525     VLOG(1) << "PinOperationCallback, error: " << error
2526             << " error_msg: " << error_message;
2527     if (error == chromeos::NETWORK_METHOD_ERROR_NONE) {
2528       pin_error = PIN_ERROR_NONE;
2529       VLOG(1) << "Pin operation completed successfuly";
2530       // TODO(nkostylev): Might be cleaned up and exposed in flimflam API.
2531       // http://crosbug.com/14253
2532       // Since this option state is not exposed we have to update it manually.
2533       networklib->FlipSimPinRequiredStateIfNeeded();
2534     } else {
2535       if (error_message &&
2536             (strcmp(error_message, kErrorIncorrectPinMsg) == 0 ||
2537              strcmp(error_message, kErrorPinRequiredMsg) == 0)) {
2538         pin_error = PIN_ERROR_INCORRECT_CODE;
2539       } else if (error_message &&
2540                  strcmp(error_message, kErrorPinBlockedMsg) == 0) {
2541         pin_error = PIN_ERROR_BLOCKED;
2542       } else {
2543         pin_error = PIN_ERROR_UNKNOWN;
2544         NOTREACHED() << "Unknown PIN error: " << error_message;
2545       }
2546     }
2547     networklib->NotifyPinOperationCompleted(pin_error);
2548   }
2549 
RequestCellularScan()2550   virtual void RequestCellularScan() {
2551     const NetworkDevice* cellular = FindCellularDevice();
2552     if (!cellular) {
2553       NOTREACHED() << "Calling RequestCellularScan method w/o cellular device.";
2554       return;
2555     }
2556     chromeos::ProposeScan(cellular->device_path().c_str());
2557   }
2558 
RequestCellularRegister(const std::string & network_id)2559   virtual void RequestCellularRegister(const std::string& network_id) {
2560     const NetworkDevice* cellular = FindCellularDevice();
2561     if (!cellular) {
2562       NOTREACHED() << "Calling CellularRegister method w/o cellular device.";
2563       return;
2564     }
2565     chromeos::RequestCellularRegister(cellular->device_path().c_str(),
2566                                       network_id.c_str(),
2567                                       CellularRegisterCallback,
2568                                       this);
2569   }
2570 
CellularRegisterCallback(void * object,const char * path,NetworkMethodErrorType error,const char * error_message)2571   static void CellularRegisterCallback(void* object,
2572                                        const char* path,
2573                                        NetworkMethodErrorType error,
2574                                        const char* error_message) {
2575     NetworkLibraryImpl* networklib = static_cast<NetworkLibraryImpl*>(object);
2576     DCHECK(networklib);
2577     // TODO(dpolukhin): Notify observers about network registration status
2578     // but not UI doesn't assume such notification so just ignore result.
2579   }
2580 
SetCellularDataRoamingAllowed(bool new_value)2581   virtual void SetCellularDataRoamingAllowed(bool new_value) {
2582     const NetworkDevice* cellular = FindCellularDevice();
2583     if (!cellular) {
2584       NOTREACHED() << "Calling SetCellularDataRoamingAllowed method "
2585                       "w/o cellular device.";
2586       return;
2587     }
2588     scoped_ptr<Value> value(Value::CreateBooleanValue(new_value));
2589     chromeos::SetNetworkDeviceProperty(cellular->device_path().c_str(),
2590                                        kCellularAllowRoamingProperty,
2591                                        value.get());
2592   }
2593 
2594   /////////////////////////////////////////////////////////////////////////////
2595 
RequestNetworkScan()2596   virtual void RequestNetworkScan() {
2597     if (EnsureCrosLoaded()) {
2598       if (wifi_enabled()) {
2599         wifi_scanning_ = true;  // Cleared when updates are received.
2600         chromeos::RequestNetworkScan(kTypeWifi);
2601         RequestRememberedNetworksUpdate();
2602       }
2603       if (cellular_network())
2604         cellular_network()->RefreshDataPlansIfNeeded();
2605     }
2606   }
2607 
GetWifiAccessPoints(WifiAccessPointVector * result)2608   virtual bool GetWifiAccessPoints(WifiAccessPointVector* result) {
2609     if (!EnsureCrosLoaded())
2610       return false;
2611     CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2612     DeviceNetworkList* network_list = GetDeviceNetworkList();
2613     if (network_list == NULL)
2614       return false;
2615     result->clear();
2616     result->reserve(network_list->network_size);
2617     const base::Time now = base::Time::Now();
2618     for (size_t i = 0; i < network_list->network_size; ++i) {
2619       DCHECK(network_list->networks[i].address);
2620       DCHECK(network_list->networks[i].name);
2621       WifiAccessPoint ap;
2622       ap.mac_address = SafeString(network_list->networks[i].address);
2623       ap.name = SafeString(network_list->networks[i].name);
2624       ap.timestamp = now -
2625           base::TimeDelta::FromSeconds(network_list->networks[i].age_seconds);
2626       ap.signal_strength = network_list->networks[i].strength;
2627       ap.channel = network_list->networks[i].channel;
2628       result->push_back(ap);
2629     }
2630     FreeDeviceNetworkList(network_list);
2631     return true;
2632   }
2633 
NetworkConnectCallback(void * object,const char * path,NetworkMethodErrorType error,const char * error_message)2634   static void NetworkConnectCallback(void *object,
2635                                      const char *path,
2636                                      NetworkMethodErrorType error,
2637                                      const char* error_message) {
2638     NetworkLibraryImpl* networklib = static_cast<NetworkLibraryImpl*>(object);
2639     DCHECK(networklib);
2640 
2641     Network* network = networklib->FindNetworkByPath(path);
2642     if (!network) {
2643       LOG(ERROR) << "No network for path: " << path;
2644       return;
2645     }
2646 
2647     if (error != NETWORK_METHOD_ERROR_NONE) {
2648       LOG(WARNING) << "Error from ServiceConnect callback for: "
2649                    << network->name()
2650                    << " Error: " << error << " Message: " << error_message;
2651       if (error_message &&
2652           strcmp(error_message, kErrorPassphraseRequiredMsg) == 0) {
2653         // This will trigger the connection failed notification.
2654         // TODO(stevenjb): Remove if chromium-os:13203 gets fixed.
2655         network->set_state(STATE_FAILURE);
2656         network->set_error(ERROR_BAD_PASSPHRASE);
2657         networklib->NotifyNetworkManagerChanged(true);  // Forced update.
2658       }
2659       return;
2660     }
2661 
2662     VLOG(1) << "Connected to service: " << network->name();
2663 
2664     // Update local cache and notify listeners.
2665     if (network->type() == TYPE_WIFI) {
2666       WifiNetwork* wifi = static_cast<WifiNetwork *>(network);
2667       // If the user asked not to save credentials, flimflam will have
2668       // forgotten them.  Wipe our cache as well.
2669       if (!wifi->save_credentials()) {
2670         wifi->EraseCredentials();
2671       }
2672       networklib->active_wifi_ = wifi;
2673     } else if (network->type() == TYPE_CELLULAR) {
2674       networklib->active_cellular_ = static_cast<CellularNetwork *>(network);
2675     } else if (network->type() == TYPE_VPN) {
2676       networklib->active_virtual_ = static_cast<VirtualNetwork *>(network);
2677     } else {
2678       LOG(ERROR) << "Network of unexpected type: " << network->type();
2679     }
2680 
2681     // If we succeed, this network will be remembered; request an update.
2682     // TODO(stevenjb): flimflam should do this automatically.
2683     networklib->RequestRememberedNetworksUpdate();
2684     // Notify observers.
2685     networklib->NotifyNetworkManagerChanged(true);  // Forced update.
2686     networklib->NotifyUserConnectionInitiated(network);
2687   }
2688 
2689 
CallConnectToNetwork(Network * network)2690   void CallConnectToNetwork(Network* network) {
2691     DCHECK(network);
2692     if (!EnsureCrosLoaded() || !network)
2693       return;
2694     // In order to be certain to trigger any notifications, set the connecting
2695     // state locally and notify observers. Otherwise there might be a state
2696     // change without a forced notify.
2697     network->set_connecting(true);
2698     NotifyNetworkManagerChanged(true);  // Forced update.
2699     RequestNetworkServiceConnect(network->service_path().c_str(),
2700                                  NetworkConnectCallback, this);
2701   }
2702 
ConnectToWifiNetwork(WifiNetwork * wifi)2703   virtual void ConnectToWifiNetwork(WifiNetwork* wifi) {
2704     // This will happen if a network resets or gets out of range.
2705     if (wifi->user_passphrase_ != wifi->passphrase_ ||
2706         wifi->passphrase_required())
2707       wifi->SetPassphrase(wifi->user_passphrase_);
2708     CallConnectToNetwork(wifi);
2709   }
2710 
2711   // Use this to connect to a wifi network by service path.
ConnectToWifiNetwork(const std::string & service_path)2712   virtual void ConnectToWifiNetwork(const std::string& service_path) {
2713     WifiNetwork* wifi = FindWifiNetworkByPath(service_path);
2714     if (!wifi) {
2715       LOG(WARNING) << "Attempt to connect to non existing network: "
2716                    << service_path;
2717       return;
2718     }
2719     ConnectToWifiNetwork(wifi);
2720   }
2721 
2722   // Use this to connect to an unlisted wifi network.
2723   // This needs to request information about the named service.
2724   // The connection attempt will occur in the callback.
ConnectToWifiNetwork(ConnectionSecurity security,const std::string & ssid,const std::string & passphrase,const std::string & identity,const std::string & certpath)2725   virtual void ConnectToWifiNetwork(ConnectionSecurity security,
2726                                     const std::string& ssid,
2727                                     const std::string& passphrase,
2728                                     const std::string& identity,
2729                                     const std::string& certpath) {
2730     if (!EnsureCrosLoaded())
2731       return;
2732     // Store the connection data to be used by the callback.
2733     connect_data_.service_name = ssid;
2734     connect_data_.passphrase = passphrase;
2735     connect_data_.identity = identity;
2736     connect_data_.cert_path = certpath;
2737     // Asynchronously request service properties and call
2738     // WifiServiceUpdateAndConnect.
2739     RequestHiddenWifiNetwork(ssid.c_str(),
2740                              SecurityToString(security),
2741                              WifiServiceUpdateAndConnect,
2742                              this);
2743   }
2744 
2745   // Callback
WifiServiceUpdateAndConnect(void * object,const char * service_path,const Value * info)2746   static void WifiServiceUpdateAndConnect(void* object,
2747                                           const char* service_path,
2748                                           const Value* info) {
2749     NetworkLibraryImpl* networklib = static_cast<NetworkLibraryImpl*>(object);
2750     DCHECK(networklib);
2751     if (service_path && info) {
2752       DCHECK_EQ(info->GetType(), Value::TYPE_DICTIONARY);
2753       const DictionaryValue* dict = static_cast<const DictionaryValue*>(info);
2754       Network* network =
2755           networklib->ParseNetwork(std::string(service_path), dict);
2756       DCHECK(network->type() == TYPE_WIFI);
2757       networklib->ConnectToWifiNetworkUsingConnectData(
2758           static_cast<WifiNetwork*>(network));
2759     }
2760   }
2761 
ConnectToWifiNetworkUsingConnectData(WifiNetwork * wifi)2762   void ConnectToWifiNetworkUsingConnectData(WifiNetwork* wifi) {
2763     ConnectData& data = connect_data_;
2764     if (wifi->name() != data.service_name) {
2765       LOG(WARNING) << "Wifi network name does not match ConnectData: "
2766                    << wifi->name() << " != " << data.service_name;
2767       return;
2768     }
2769     wifi->set_added(true);
2770     wifi->SetIdentity(data.identity);
2771     wifi->SetPassphrase(data.passphrase);
2772     if (!data.cert_path.empty())
2773       wifi->SetCertPath(data.cert_path);
2774 
2775     ConnectToWifiNetwork(wifi);
2776   }
2777 
ConnectToCellularNetwork(CellularNetwork * cellular)2778   virtual void ConnectToCellularNetwork(CellularNetwork* cellular) {
2779     CallConnectToNetwork(cellular);
2780   }
2781 
2782   // Records information that cellular play payment had happened.
SignalCellularPlanPayment()2783   virtual void SignalCellularPlanPayment() {
2784     DCHECK(!HasRecentCellularPlanPayment());
2785     cellular_plan_payment_time_ = base::Time::Now();
2786   }
2787 
2788   // Returns true if cellular plan payment had been recorded recently.
HasRecentCellularPlanPayment()2789   virtual bool HasRecentCellularPlanPayment() {
2790     return (base::Time::Now() -
2791             cellular_plan_payment_time_).InHours() < kRecentPlanPaymentHours;
2792   }
2793 
ConnectToVirtualNetwork(VirtualNetwork * vpn)2794   virtual void ConnectToVirtualNetwork(VirtualNetwork* vpn) {
2795     CallConnectToNetwork(vpn);
2796   }
2797 
ConnectToVirtualNetworkPSK(const std::string & service_name,const std::string & server,const std::string & psk,const std::string & username,const std::string & user_passphrase)2798   virtual void ConnectToVirtualNetworkPSK(
2799       const std::string& service_name,
2800       const std::string& server,
2801       const std::string& psk,
2802       const std::string& username,
2803       const std::string& user_passphrase) {
2804     if (!EnsureCrosLoaded())
2805       return;
2806     // Store the connection data to be used by the callback.
2807     connect_data_.service_name = service_name;
2808     connect_data_.psk_key = psk;
2809     connect_data_.server_hostname = server;
2810     connect_data_.identity = username;
2811     connect_data_.passphrase = user_passphrase;
2812     RequestVirtualNetwork(service_name.c_str(),
2813                           server.c_str(),
2814                           kProviderL2tpIpsec,
2815                           VPNServiceUpdateAndConnect,
2816                           this);
2817   }
2818 
2819   // Callback
VPNServiceUpdateAndConnect(void * object,const char * service_path,const Value * info)2820   static void VPNServiceUpdateAndConnect(void* object,
2821                                          const char* service_path,
2822                                          const Value* info) {
2823     NetworkLibraryImpl* networklib = static_cast<NetworkLibraryImpl*>(object);
2824     DCHECK(networklib);
2825     if (service_path && info) {
2826       VLOG(1) << "Connecting to new VPN Service: " << service_path;
2827       DCHECK_EQ(info->GetType(), Value::TYPE_DICTIONARY);
2828       const DictionaryValue* dict = static_cast<const DictionaryValue*>(info);
2829       Network* network =
2830           networklib->ParseNetwork(std::string(service_path), dict);
2831       DCHECK(network->type() == TYPE_VPN);
2832       networklib->ConnectToVirtualNetworkUsingConnectData(
2833           static_cast<VirtualNetwork*>(network));
2834     } else {
2835       LOG(WARNING) << "Unable to create VPN Service: " << service_path;
2836     }
2837   }
2838 
ConnectToVirtualNetworkUsingConnectData(VirtualNetwork * vpn)2839   void ConnectToVirtualNetworkUsingConnectData(VirtualNetwork* vpn) {
2840     ConnectData& data = connect_data_;
2841     if (vpn->name() != data.service_name) {
2842       LOG(WARNING) << "Virtual network name does not match ConnectData: "
2843                    << vpn->name() << " != " << data.service_name;
2844       return;
2845     }
2846 
2847     vpn->set_added(true);
2848     vpn->set_server_hostname(data.server_hostname);
2849     vpn->SetCACert("");
2850     vpn->SetUserCert("");
2851     vpn->SetUserCertKey("");
2852     vpn->SetPSKPassphrase(data.psk_key);
2853     vpn->SetUsername(data.identity);
2854     vpn->SetUserPassphrase(data.passphrase);
2855 
2856     CallConnectToNetwork(vpn);
2857   }
2858 
DisconnectFromNetwork(const Network * network)2859   virtual void DisconnectFromNetwork(const Network* network) {
2860     DCHECK(network);
2861     if (!EnsureCrosLoaded() || !network)
2862       return;
2863     VLOG(1) << "Disconnect from network: " << network->service_path();
2864     if (chromeos::DisconnectFromNetwork(network->service_path().c_str())) {
2865       // Update local cache and notify listeners.
2866       Network* found_network = FindNetworkByPath(network->service_path());
2867       if (found_network) {
2868         found_network->set_connected(false);
2869         if (found_network == active_wifi_)
2870           active_wifi_ = NULL;
2871         else if (found_network == active_cellular_)
2872           active_cellular_ = NULL;
2873         else if (found_network == active_virtual_)
2874           active_virtual_ = NULL;
2875       }
2876       NotifyNetworkManagerChanged(true);  // Forced update.
2877     }
2878   }
2879 
ForgetWifiNetwork(const std::string & service_path)2880   virtual void ForgetWifiNetwork(const std::string& service_path) {
2881     if (!EnsureCrosLoaded())
2882       return;
2883     DeleteRememberedService(service_path.c_str());
2884     DeleteRememberedWifiNetwork(service_path);
2885     NotifyNetworkManagerChanged(true);  // Forced update.
2886   }
2887 
GetCellularHomeCarrierId() const2888   virtual std::string GetCellularHomeCarrierId() const {
2889     std::string carrier_id;
2890     const NetworkDevice* cellular = FindCellularDevice();
2891     if (cellular) {
2892       return cellular->home_provider_id();
2893 
2894     }
2895     return carrier_id;
2896   }
2897 
ethernet_available() const2898   virtual bool ethernet_available() const {
2899     return available_devices_ & (1 << TYPE_ETHERNET);
2900   }
wifi_available() const2901   virtual bool wifi_available() const {
2902     return available_devices_ & (1 << TYPE_WIFI);
2903   }
cellular_available() const2904   virtual bool cellular_available() const {
2905     return available_devices_ & (1 << TYPE_CELLULAR);
2906   }
2907 
ethernet_enabled() const2908   virtual bool ethernet_enabled() const {
2909     return enabled_devices_ & (1 << TYPE_ETHERNET);
2910   }
wifi_enabled() const2911   virtual bool wifi_enabled() const {
2912     return enabled_devices_ & (1 << TYPE_WIFI);
2913   }
cellular_enabled() const2914   virtual bool cellular_enabled() const {
2915     return enabled_devices_ & (1 << TYPE_CELLULAR);
2916   }
2917 
wifi_scanning() const2918   virtual bool wifi_scanning() const {
2919     return wifi_scanning_;
2920   }
2921 
offline_mode() const2922   virtual bool offline_mode() const { return offline_mode_; }
2923 
2924   // Note: This does not include any virtual networks.
active_network() const2925   virtual const Network* active_network() const {
2926     // Use flimflam's ordering of the services to determine what the active
2927     // network is (i.e. don't assume priority of network types).
2928     Network* result = NULL;
2929     if (ethernet_ && ethernet_->is_active())
2930       result = ethernet_;
2931     if ((active_wifi_ && active_wifi_->is_active()) &&
2932         (!result ||
2933          active_wifi_->priority_order_ < result->priority_order_))
2934       result = active_wifi_;
2935     if ((active_cellular_ && active_cellular_->is_active()) &&
2936         (!result ||
2937          active_cellular_->priority_order_ < result->priority_order_))
2938       result = active_cellular_;
2939     return result;
2940   }
2941 
connected_network() const2942   virtual const Network* connected_network() const {
2943     // Use flimflam's ordering of the services to determine what the connected
2944     // network is (i.e. don't assume priority of network types).
2945     Network* result = NULL;
2946     if (ethernet_ && ethernet_->connected())
2947       result = ethernet_;
2948     if ((active_wifi_ && active_wifi_->connected()) &&
2949         (!result ||
2950          active_wifi_->priority_order_ < result->priority_order_))
2951       result = active_wifi_;
2952     if ((active_cellular_ && active_cellular_->connected()) &&
2953         (!result ||
2954          active_cellular_->priority_order_ < result->priority_order_))
2955       result = active_cellular_;
2956     return result;
2957   }
2958 
EnableEthernetNetworkDevice(bool enable)2959   virtual void EnableEthernetNetworkDevice(bool enable) {
2960     if (is_locked_)
2961       return;
2962     EnableNetworkDeviceType(TYPE_ETHERNET, enable);
2963   }
2964 
EnableWifiNetworkDevice(bool enable)2965   virtual void EnableWifiNetworkDevice(bool enable) {
2966     if (is_locked_)
2967       return;
2968     EnableNetworkDeviceType(TYPE_WIFI, enable);
2969   }
2970 
EnableCellularNetworkDevice(bool enable)2971   virtual void EnableCellularNetworkDevice(bool enable) {
2972     if (is_locked_)
2973       return;
2974     EnableNetworkDeviceType(TYPE_CELLULAR, enable);
2975   }
2976 
EnableOfflineMode(bool enable)2977   virtual void EnableOfflineMode(bool enable) {
2978     if (!EnsureCrosLoaded())
2979       return;
2980 
2981     // If network device is already enabled/disabled, then don't do anything.
2982     if (enable && offline_mode_) {
2983       VLOG(1) << "Trying to enable offline mode when it's already enabled.";
2984       return;
2985     }
2986     if (!enable && !offline_mode_) {
2987       VLOG(1) << "Trying to disable offline mode when it's already disabled.";
2988       return;
2989     }
2990 
2991     if (SetOfflineMode(enable)) {
2992       offline_mode_ = enable;
2993     }
2994   }
2995 
GetIPConfigs(const std::string & device_path,std::string * hardware_address,HardwareAddressFormat format)2996   virtual NetworkIPConfigVector GetIPConfigs(const std::string& device_path,
2997                                              std::string* hardware_address,
2998                                              HardwareAddressFormat format) {
2999     DCHECK(hardware_address);
3000     hardware_address->clear();
3001     NetworkIPConfigVector ipconfig_vector;
3002     if (EnsureCrosLoaded() && !device_path.empty()) {
3003       IPConfigStatus* ipconfig_status = ListIPConfigs(device_path.c_str());
3004       if (ipconfig_status) {
3005         for (int i = 0; i < ipconfig_status->size; i++) {
3006           IPConfig ipconfig = ipconfig_status->ips[i];
3007           ipconfig_vector.push_back(
3008               NetworkIPConfig(device_path, ipconfig.type, ipconfig.address,
3009                               ipconfig.netmask, ipconfig.gateway,
3010                               ipconfig.name_servers));
3011         }
3012         *hardware_address = ipconfig_status->hardware_address;
3013         FreeIPConfigStatus(ipconfig_status);
3014         // Sort the list of ip configs by type.
3015         std::sort(ipconfig_vector.begin(), ipconfig_vector.end());
3016       }
3017     }
3018 
3019     for (size_t i = 0; i < hardware_address->size(); ++i)
3020       (*hardware_address)[i] = toupper((*hardware_address)[i]);
3021     if (format == FORMAT_COLON_SEPARATED_HEX) {
3022       if (hardware_address->size() % 2 == 0) {
3023         std::string output;
3024         for (size_t i = 0; i < hardware_address->size(); ++i) {
3025           if ((i != 0) && (i % 2 == 0))
3026             output.push_back(':');
3027           output.push_back((*hardware_address)[i]);
3028         }
3029         *hardware_address = output;
3030       }
3031     } else {
3032       DCHECK(format == FORMAT_RAW_HEX);
3033     }
3034     return ipconfig_vector;
3035   }
3036 
3037  private:
3038 
3039   typedef std::map<std::string, Network*> NetworkMap;
3040   typedef std::map<std::string, int> PriorityMap;
3041   typedef std::map<std::string, NetworkDevice*> NetworkDeviceMap;
3042   typedef std::map<std::string, CellularDataPlanVector*> CellularDataPlanMap;
3043 
3044   class NetworkObserverList : public ObserverList<NetworkObserver> {
3045    public:
NetworkObserverList(NetworkLibraryImpl * library,const std::string & service_path)3046     NetworkObserverList(NetworkLibraryImpl* library,
3047                         const std::string& service_path) {
3048       network_monitor_ = MonitorNetworkService(&NetworkStatusChangedHandler,
3049                                                service_path.c_str(),
3050                                                library);
3051     }
3052 
~NetworkObserverList()3053     virtual ~NetworkObserverList() {
3054       if (network_monitor_)
3055         DisconnectPropertyChangeMonitor(network_monitor_);
3056     }
3057 
3058    private:
NetworkStatusChangedHandler(void * object,const char * path,const char * key,const Value * value)3059     static void NetworkStatusChangedHandler(void* object,
3060                                             const char* path,
3061                                             const char* key,
3062                                             const Value* value) {
3063       NetworkLibraryImpl* networklib = static_cast<NetworkLibraryImpl*>(object);
3064       DCHECK(networklib);
3065       networklib->UpdateNetworkStatus(path, key, value);
3066     }
3067     PropertyChangeMonitor network_monitor_;
3068     DISALLOW_COPY_AND_ASSIGN(NetworkObserverList);
3069   };
3070 
3071   typedef std::map<std::string, NetworkObserverList*> NetworkObserverMap;
3072 
3073   class NetworkDeviceObserverList : public ObserverList<NetworkDeviceObserver> {
3074    public:
NetworkDeviceObserverList(NetworkLibraryImpl * library,const std::string & device_path)3075     NetworkDeviceObserverList(NetworkLibraryImpl* library,
3076                               const std::string& device_path) {
3077       device_monitor_ = MonitorNetworkDevice(
3078           &NetworkDevicePropertyChangedHandler,
3079           device_path.c_str(),
3080           library);
3081     }
3082 
~NetworkDeviceObserverList()3083     virtual ~NetworkDeviceObserverList() {
3084       if (device_monitor_)
3085         DisconnectPropertyChangeMonitor(device_monitor_);
3086     }
3087 
3088    private:
NetworkDevicePropertyChangedHandler(void * object,const char * path,const char * key,const Value * value)3089     static void NetworkDevicePropertyChangedHandler(void* object,
3090                                                     const char* path,
3091                                                     const char* key,
3092                                                     const Value* value) {
3093       NetworkLibraryImpl* networklib = static_cast<NetworkLibraryImpl*>(object);
3094       DCHECK(networklib);
3095       networklib->UpdateNetworkDeviceStatus(path, key, value);
3096     }
3097     PropertyChangeMonitor device_monitor_;
3098     DISALLOW_COPY_AND_ASSIGN(NetworkDeviceObserverList);
3099   };
3100 
3101   typedef std::map<std::string, NetworkDeviceObserverList*>
3102       NetworkDeviceObserverMap;
3103 
3104   ////////////////////////////////////////////////////////////////////////////
3105   // Callbacks.
3106 
NetworkManagerStatusChangedHandler(void * object,const char * path,const char * key,const Value * value)3107   static void NetworkManagerStatusChangedHandler(void* object,
3108                                                  const char* path,
3109                                                  const char* key,
3110                                                  const Value* value) {
3111     NetworkLibraryImpl* networklib = static_cast<NetworkLibraryImpl*>(object);
3112     DCHECK(networklib);
3113     networklib->NetworkManagerStatusChanged(key, value);
3114   }
3115 
3116   // This processes all Manager update messages.
NetworkManagerStatusChanged(const char * key,const Value * value)3117   void NetworkManagerStatusChanged(const char* key, const Value* value) {
3118     CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3119     base::TimeTicks start = base::TimeTicks::Now();
3120     VLOG(1) << "NetworkManagerStatusChanged: KEY=" << key;
3121     if (!key)
3122       return;
3123     int index = property_index_parser().Get(std::string(key));
3124     switch (index) {
3125       case PROPERTY_INDEX_STATE:
3126         // Currently we ignore the network manager state.
3127         break;
3128       case PROPERTY_INDEX_AVAILABLE_TECHNOLOGIES: {
3129         DCHECK_EQ(value->GetType(), Value::TYPE_LIST);
3130         const ListValue* vlist = static_cast<const ListValue*>(value);
3131         UpdateAvailableTechnologies(vlist);
3132         break;
3133       }
3134       case PROPERTY_INDEX_ENABLED_TECHNOLOGIES: {
3135         DCHECK_EQ(value->GetType(), Value::TYPE_LIST);
3136         const ListValue* vlist = static_cast<const ListValue*>(value);
3137         UpdateEnabledTechnologies(vlist);
3138         break;
3139       }
3140       case PROPERTY_INDEX_CONNECTED_TECHNOLOGIES: {
3141         DCHECK_EQ(value->GetType(), Value::TYPE_LIST);
3142         const ListValue* vlist = static_cast<const ListValue*>(value);
3143         UpdateConnectedTechnologies(vlist);
3144         break;
3145       }
3146       case PROPERTY_INDEX_DEFAULT_TECHNOLOGY:
3147         // Currently we ignore DefaultTechnology.
3148         break;
3149       case PROPERTY_INDEX_OFFLINE_MODE: {
3150         DCHECK_EQ(value->GetType(), Value::TYPE_BOOLEAN);
3151         value->GetAsBoolean(&offline_mode_);
3152         NotifyNetworkManagerChanged(false);  // Not forced.
3153         break;
3154       }
3155       case PROPERTY_INDEX_ACTIVE_PROFILE: {
3156         DCHECK_EQ(value->GetType(), Value::TYPE_STRING);
3157         value->GetAsString(&active_profile_path_);
3158         RequestRememberedNetworksUpdate();
3159         break;
3160       }
3161       case PROPERTY_INDEX_PROFILES:
3162         // Currently we ignore Profiles (list of all profiles).
3163         break;
3164       case PROPERTY_INDEX_SERVICES: {
3165         DCHECK_EQ(value->GetType(), Value::TYPE_LIST);
3166         const ListValue* vlist = static_cast<const ListValue*>(value);
3167         UpdateNetworkServiceList(vlist);
3168         break;
3169       }
3170       case PROPERTY_INDEX_SERVICE_WATCH_LIST: {
3171         DCHECK_EQ(value->GetType(), Value::TYPE_LIST);
3172         const ListValue* vlist = static_cast<const ListValue*>(value);
3173         UpdateWatchedNetworkServiceList(vlist);
3174         break;
3175       }
3176       case PROPERTY_INDEX_DEVICE:
3177       case PROPERTY_INDEX_DEVICES: {
3178         DCHECK_EQ(value->GetType(), Value::TYPE_LIST);
3179         const ListValue* vlist = static_cast<const ListValue*>(value);
3180         UpdateNetworkDeviceList(vlist);
3181         break;
3182       }
3183       default:
3184         LOG(WARNING) << "Unhandled key: " << key;
3185         break;
3186     }
3187     base::TimeDelta delta = base::TimeTicks::Now() - start;
3188     VLOG(1) << "  time: " << delta.InMilliseconds() << " ms.";
3189     HISTOGRAM_TIMES("CROS_NETWORK_UPDATE", delta);
3190   }
3191 
NetworkManagerUpdate(void * object,const char * manager_path,const Value * info)3192   static void NetworkManagerUpdate(void* object,
3193                                    const char* manager_path,
3194                                    const Value* info) {
3195     NetworkLibraryImpl* networklib = static_cast<NetworkLibraryImpl*>(object);
3196     DCHECK(networklib);
3197     if (!info) {
3198       LOG(ERROR) << "Error retrieving manager properties: " << manager_path;
3199       return;
3200     }
3201     VLOG(1) << "Received NetworkManagerUpdate.";
3202     DCHECK_EQ(info->GetType(), Value::TYPE_DICTIONARY);
3203     const DictionaryValue* dict = static_cast<const DictionaryValue*>(info);
3204     networklib->ParseNetworkManager(dict);
3205   }
3206 
ParseNetworkManager(const DictionaryValue * dict)3207   void ParseNetworkManager(const DictionaryValue* dict) {
3208     for (DictionaryValue::key_iterator iter = dict->begin_keys();
3209          iter != dict->end_keys(); ++iter) {
3210       const std::string& key = *iter;
3211       Value* value;
3212       bool res = dict->GetWithoutPathExpansion(key, &value);
3213       CHECK(res);
3214       NetworkManagerStatusChanged(key.c_str(), value);
3215     }
3216   }
3217 
ProfileUpdate(void * object,const char * profile_path,const Value * info)3218   static void ProfileUpdate(void* object,
3219                             const char* profile_path,
3220                             const Value* info) {
3221     NetworkLibraryImpl* networklib = static_cast<NetworkLibraryImpl*>(object);
3222     DCHECK(networklib);
3223     if (!info) {
3224       LOG(ERROR) << "Error retrieving profile: " << profile_path;
3225       return;
3226     }
3227     VLOG(1) << "Received ProfileUpdate for: " << profile_path;
3228     DCHECK_EQ(info->GetType(), Value::TYPE_DICTIONARY);
3229     const DictionaryValue* dict = static_cast<const DictionaryValue*>(info);
3230     ListValue* entries(NULL);
3231     dict->GetList(kEntriesProperty, &entries);
3232     DCHECK(entries);
3233     networklib->UpdateRememberedServiceList(profile_path, entries);
3234   }
3235 
NetworkServiceUpdate(void * object,const char * service_path,const Value * info)3236   static void NetworkServiceUpdate(void* object,
3237                                    const char* service_path,
3238                                    const Value* info) {
3239     NetworkLibraryImpl* networklib = static_cast<NetworkLibraryImpl*>(object);
3240     DCHECK(networklib);
3241     if (service_path) {
3242       if (!info) {
3243         // Network no longer exists.
3244         networklib->DeleteNetwork(std::string(service_path));
3245       } else {
3246         DCHECK_EQ(info->GetType(), Value::TYPE_DICTIONARY);
3247         const DictionaryValue* dict = static_cast<const DictionaryValue*>(info);
3248         networklib->ParseNetwork(std::string(service_path), dict);
3249       }
3250     }
3251   }
3252 
RememberedNetworkServiceUpdate(void * object,const char * service_path,const Value * info)3253   static void RememberedNetworkServiceUpdate(void* object,
3254                                              const char* service_path,
3255                                              const Value* info) {
3256     NetworkLibraryImpl* networklib = static_cast<NetworkLibraryImpl*>(object);
3257     DCHECK(networklib);
3258     if (service_path) {
3259       if (!info) {
3260         // Remembered network no longer exists.
3261         networklib->DeleteRememberedWifiNetwork(std::string(service_path));
3262       } else {
3263         DCHECK_EQ(info->GetType(), Value::TYPE_DICTIONARY);
3264         const DictionaryValue* dict = static_cast<const DictionaryValue*>(info);
3265         networklib->ParseRememberedNetwork(std::string(service_path), dict);
3266       }
3267     }
3268   }
3269 
NetworkDeviceUpdate(void * object,const char * device_path,const Value * info)3270   static void NetworkDeviceUpdate(void* object,
3271                                   const char* device_path,
3272                                   const Value* info) {
3273     NetworkLibraryImpl* networklib = static_cast<NetworkLibraryImpl*>(object);
3274     DCHECK(networklib);
3275     if (device_path) {
3276       if (!info) {
3277         // device no longer exists.
3278         networklib->DeleteDevice(std::string(device_path));
3279       } else {
3280         DCHECK_EQ(info->GetType(), Value::TYPE_DICTIONARY);
3281         const DictionaryValue* dict = static_cast<const DictionaryValue*>(info);
3282         networklib->ParseNetworkDevice(std::string(device_path), dict);
3283       }
3284     }
3285   }
3286 
DataPlanUpdateHandler(void * object,const char * modem_service_path,const CellularDataPlanList * dataplan)3287   static void DataPlanUpdateHandler(void* object,
3288                                     const char* modem_service_path,
3289                                     const CellularDataPlanList* dataplan) {
3290     NetworkLibraryImpl* networklib = static_cast<NetworkLibraryImpl*>(object);
3291     DCHECK(networklib);
3292     if (modem_service_path && dataplan) {
3293       networklib->UpdateCellularDataPlan(std::string(modem_service_path),
3294                                          dataplan);
3295     }
3296   }
3297 
3298   ////////////////////////////////////////////////////////////////////////////
3299   // Network technology functions.
3300 
UpdateTechnologies(const ListValue * technologies,int * bitfieldp)3301   void UpdateTechnologies(const ListValue* technologies, int* bitfieldp) {
3302     DCHECK(bitfieldp);
3303     if (!technologies)
3304       return;
3305     int bitfield = 0;
3306     for (ListValue::const_iterator iter = technologies->begin();
3307          iter != technologies->end(); ++iter) {
3308       std::string technology;
3309       (*iter)->GetAsString(&technology);
3310       if (!technology.empty()) {
3311         ConnectionType type = ParseType(technology);
3312         bitfield |= 1 << type;
3313       }
3314     }
3315     *bitfieldp = bitfield;
3316     NotifyNetworkManagerChanged(false);  // Not forced.
3317   }
3318 
UpdateAvailableTechnologies(const ListValue * technologies)3319   void UpdateAvailableTechnologies(const ListValue* technologies) {
3320     UpdateTechnologies(technologies, &available_devices_);
3321   }
3322 
UpdateEnabledTechnologies(const ListValue * technologies)3323   void UpdateEnabledTechnologies(const ListValue* technologies) {
3324     UpdateTechnologies(technologies, &enabled_devices_);
3325     if (!ethernet_enabled())
3326       ethernet_ = NULL;
3327     if (!wifi_enabled()) {
3328       active_wifi_ = NULL;
3329       wifi_networks_.clear();
3330     }
3331     if (!cellular_enabled()) {
3332       active_cellular_ = NULL;
3333       cellular_networks_.clear();
3334     }
3335   }
3336 
UpdateConnectedTechnologies(const ListValue * technologies)3337   void UpdateConnectedTechnologies(const ListValue* technologies) {
3338     UpdateTechnologies(technologies, &connected_devices_);
3339   }
3340 
3341   ////////////////////////////////////////////////////////////////////////////
3342   // Network list management functions.
3343 
3344   // Note: sometimes flimflam still returns networks when the device type is
3345   // disabled. Always check the appropriate enabled() state before adding
3346   // networks to a list or setting an active network so that we do not show them
3347   // in the UI.
3348 
3349   // This relies on services being requested from flimflam in priority order,
3350   // and the updates getting processed and received in order.
UpdateActiveNetwork(Network * network)3351   void UpdateActiveNetwork(Network* network) {
3352     ConnectionType type(network->type());
3353     if (type == TYPE_ETHERNET) {
3354       if (ethernet_enabled()) {
3355         // Set ethernet_ to the first connected ethernet service, or the first
3356         // disconnected ethernet service if none are connected.
3357         if (ethernet_ == NULL || !ethernet_->connected())
3358           ethernet_ = static_cast<EthernetNetwork*>(network);
3359       }
3360     } else if (type == TYPE_WIFI) {
3361       if (wifi_enabled()) {
3362         // Set active_wifi_ to the first connected or connecting wifi service.
3363         if (active_wifi_ == NULL && network->connecting_or_connected())
3364           active_wifi_ = static_cast<WifiNetwork*>(network);
3365       }
3366     } else if (type == TYPE_CELLULAR) {
3367       if (cellular_enabled()) {
3368         // Set active_cellular_ to first connected/connecting celluar service.
3369         if (active_cellular_ == NULL && network->connecting_or_connected())
3370           active_cellular_ = static_cast<CellularNetwork*>(network);
3371       }
3372     } else if (type == TYPE_VPN) {
3373       // Set active_virtual_ to the first connected or connecting vpn service.
3374       if (active_virtual_ == NULL && network->connecting_or_connected())
3375         active_virtual_ = static_cast<VirtualNetwork*>(network);
3376     }
3377   }
3378 
AddNetwork(Network * network)3379   void AddNetwork(Network* network) {
3380     std::pair<NetworkMap::iterator,bool> result =
3381         network_map_.insert(std::make_pair(network->service_path(), network));
3382     DCHECK(result.second);  // Should only get called with new network.
3383     VLOG(2) << "Adding Network: " << network->service_path()
3384             << " (" << network->name() << ")";
3385     ConnectionType type(network->type());
3386     if (type == TYPE_WIFI) {
3387       if (wifi_enabled())
3388         wifi_networks_.push_back(static_cast<WifiNetwork*>(network));
3389     } else if (type == TYPE_CELLULAR) {
3390       if (cellular_enabled())
3391         cellular_networks_.push_back(static_cast<CellularNetwork*>(network));
3392     } else if (type == TYPE_VPN) {
3393       virtual_networks_.push_back(static_cast<VirtualNetwork*>(network));
3394     }
3395     // Do not set the active network here. Wait until we parse the network.
3396   }
3397 
3398   // This only gets called when NetworkServiceUpdate receives a NULL update
3399   // for an existing network, e.g. an error occurred while fetching a network.
DeleteNetwork(const std::string & service_path)3400   void DeleteNetwork(const std::string& service_path) {
3401     NetworkMap::iterator found = network_map_.find(service_path);
3402     if (found == network_map_.end()) {
3403       // This occurs when we receive an update request followed by a disconnect
3404       // which triggers another update. See UpdateNetworkServiceList.
3405       return;
3406     }
3407     Network* network = found->second;
3408     network_map_.erase(found);
3409     if (!network->unique_id().empty())
3410       network_unique_id_map_.erase(network->unique_id());
3411     ConnectionType type(network->type());
3412     if (type == TYPE_ETHERNET) {
3413       if (network == ethernet_) {
3414         // This should never happen.
3415         LOG(ERROR) << "Deleting active ethernet network: " << service_path;
3416         ethernet_ = NULL;
3417       }
3418     } else if (type == TYPE_WIFI) {
3419       WifiNetworkVector::iterator iter = std::find(
3420           wifi_networks_.begin(), wifi_networks_.end(), network);
3421       if (iter != wifi_networks_.end())
3422         wifi_networks_.erase(iter);
3423       if (network == active_wifi_) {
3424         // This should never happen.
3425         LOG(ERROR) << "Deleting active wifi network: " << service_path;
3426         active_wifi_ = NULL;
3427       }
3428     } else if (type == TYPE_CELLULAR) {
3429       CellularNetworkVector::iterator iter = std::find(
3430           cellular_networks_.begin(), cellular_networks_.end(), network);
3431       if (iter != cellular_networks_.end())
3432         cellular_networks_.erase(iter);
3433       if (network == active_cellular_) {
3434         // This should never happen.
3435         LOG(ERROR) << "Deleting active cellular network: " << service_path;
3436         active_cellular_ = NULL;
3437       }
3438       // Find and delete any existing data plans associated with |service_path|.
3439       CellularDataPlanMap::iterator found =  data_plan_map_.find(service_path);
3440       if (found != data_plan_map_.end()) {
3441         CellularDataPlanVector* data_plans = found->second;
3442         delete data_plans;
3443         data_plan_map_.erase(found);
3444       }
3445     } else if (type == TYPE_VPN) {
3446       VirtualNetworkVector::iterator iter = std::find(
3447           virtual_networks_.begin(), virtual_networks_.end(), network);
3448       if (iter != virtual_networks_.end())
3449         virtual_networks_.erase(iter);
3450       if (network == active_virtual_) {
3451         // This should never happen.
3452         LOG(ERROR) << "Deleting active virtual network: " << service_path;
3453         active_virtual_ = NULL;
3454       }
3455     }
3456     delete network;
3457   }
3458 
AddRememberedWifiNetwork(WifiNetwork * wifi)3459   void AddRememberedWifiNetwork(WifiNetwork* wifi) {
3460     std::pair<NetworkMap::iterator,bool> result =
3461         remembered_network_map_.insert(
3462             std::make_pair(wifi->service_path(), wifi));
3463     DCHECK(result.second);  // Should only get called with new network.
3464     remembered_wifi_networks_.push_back(wifi);
3465   }
3466 
DeleteRememberedWifiNetwork(const std::string & service_path)3467   void DeleteRememberedWifiNetwork(const std::string& service_path) {
3468     NetworkMap::iterator found = remembered_network_map_.find(service_path);
3469     if (found == remembered_network_map_.end()) {
3470       LOG(WARNING) << "Attempt to delete non-existant remembered network: "
3471                    << service_path;
3472       return;
3473     }
3474     Network* remembered_network = found->second;
3475     remembered_network_map_.erase(found);
3476     WifiNetworkVector::iterator iter = std::find(
3477         remembered_wifi_networks_.begin(), remembered_wifi_networks_.end(),
3478         remembered_network);
3479     if (iter != remembered_wifi_networks_.end())
3480       remembered_wifi_networks_.erase(iter);
3481     Network* network = FindNetworkFromRemembered(remembered_network);
3482     if (network && network->type() == TYPE_WIFI) {
3483       // Clear the stored credentials for any visible forgotten networks.
3484       WifiNetwork* wifi = static_cast<WifiNetwork*>(network);
3485       wifi->EraseCredentials();
3486     } else {
3487       // Network is not in visible list.
3488       VLOG(2) << "Remembered Network not found: "
3489               << remembered_network->unique_id();
3490     }
3491     delete remembered_network;
3492   }
3493 
3494   // Update all network lists, and request associated service updates.
UpdateNetworkServiceList(const ListValue * services)3495   void UpdateNetworkServiceList(const ListValue* services) {
3496     // TODO(stevenjb): Wait for wifi_scanning_ to be false.
3497     // Copy the list of existing networks to "old" and clear the map and lists.
3498     NetworkMap old_network_map = network_map_;
3499     ClearNetworks(false /*don't delete*/);
3500     // Clear the list of update requests.
3501     int network_priority_order = 0;
3502     network_update_requests_.clear();
3503     // wifi_scanning_ will remain false unless we request a network update.
3504     wifi_scanning_ = false;
3505     // |services| represents a complete list of visible networks.
3506     for (ListValue::const_iterator iter = services->begin();
3507          iter != services->end(); ++iter) {
3508       std::string service_path;
3509       (*iter)->GetAsString(&service_path);
3510       if (!service_path.empty()) {
3511         // If we find the network in "old", add it immediately to the map
3512         // and lists. Otherwise it will get added when NetworkServiceUpdate
3513         // calls ParseNetwork.
3514         NetworkMap::iterator found = old_network_map.find(service_path);
3515         if (found != old_network_map.end()) {
3516           AddNetwork(found->second);
3517           old_network_map.erase(found);
3518         }
3519         // Always request network updates.
3520         // TODO(stevenjb): Investigate why we are missing updates then
3521         // rely on watched network updates and only request updates here for
3522         // new networks.
3523         // Use update_request map to store network priority.
3524         network_update_requests_[service_path] = network_priority_order++;
3525         wifi_scanning_ = true;
3526         RequestNetworkServiceInfo(service_path.c_str(),
3527                                   &NetworkServiceUpdate,
3528                                   this);
3529       }
3530     }
3531     // Delete any old networks that no longer exist.
3532     for (NetworkMap::iterator iter = old_network_map.begin();
3533          iter != old_network_map.end(); ++iter) {
3534       delete iter->second;
3535     }
3536   }
3537 
3538   // Request updates for watched networks. Does not affect network lists.
3539   // Existing networks will be updated. There should not be any new networks
3540   // in this list, but if there are they will be added appropriately.
UpdateWatchedNetworkServiceList(const ListValue * services)3541   void UpdateWatchedNetworkServiceList(const ListValue* services) {
3542     for (ListValue::const_iterator iter = services->begin();
3543          iter != services->end(); ++iter) {
3544       std::string service_path;
3545       (*iter)->GetAsString(&service_path);
3546       if (!service_path.empty()) {
3547         VLOG(1) << "Watched Service: " << service_path;
3548         RequestNetworkServiceInfo(
3549             service_path.c_str(), &NetworkServiceUpdate, this);
3550       }
3551     }
3552   }
3553 
3554   // Request the active profile which lists the remembered networks.
RequestRememberedNetworksUpdate()3555   void RequestRememberedNetworksUpdate() {
3556     if (!active_profile_path_.empty()) {
3557       RequestNetworkProfile(
3558           active_profile_path_.c_str(), &ProfileUpdate, this);
3559     }
3560   }
3561 
3562   // Update the list of remembered (profile) networks, and request associated
3563   // service updates.
UpdateRememberedServiceList(const char * profile_path,const ListValue * profile_entries)3564   void UpdateRememberedServiceList(const char* profile_path,
3565                                    const ListValue* profile_entries) {
3566     // Copy the list of existing networks to "old" and clear the map and list.
3567     NetworkMap old_network_map = remembered_network_map_;
3568     ClearRememberedNetworks(false /*don't delete*/);
3569     // |profile_entries| represents a complete list of remembered networks.
3570     for (ListValue::const_iterator iter = profile_entries->begin();
3571          iter != profile_entries->end(); ++iter) {
3572       std::string service_path;
3573       (*iter)->GetAsString(&service_path);
3574       if (!service_path.empty()) {
3575         // If we find the network in "old", add it immediately to the map
3576         // and list. Otherwise it will get added when
3577         // RememberedNetworkServiceUpdate calls ParseRememberedNetwork.
3578         NetworkMap::iterator found = old_network_map.find(service_path);
3579         if (found != old_network_map.end()) {
3580           Network* network = found->second;
3581           if (network->type() == TYPE_WIFI) {
3582             WifiNetwork* wifi = static_cast<WifiNetwork*>(network);
3583             AddRememberedWifiNetwork(wifi);
3584             old_network_map.erase(found);
3585           }
3586         }
3587         // Always request updates for remembered networks.
3588         RequestNetworkProfileEntry(profile_path,
3589                                    service_path.c_str(),
3590                                    &RememberedNetworkServiceUpdate,
3591                                    this);
3592       }
3593     }
3594     // Delete any old networks that no longer exist.
3595     for (NetworkMap::iterator iter = old_network_map.begin();
3596          iter != old_network_map.end(); ++iter) {
3597       delete iter->second;
3598     }
3599   }
3600 
CreateNewNetwork(ConnectionType type,const std::string & service_path)3601   Network* CreateNewNetwork(ConnectionType type,
3602                             const std::string& service_path) {
3603     switch (type) {
3604       case TYPE_ETHERNET: {
3605         EthernetNetwork* ethernet = new EthernetNetwork(service_path);
3606         return ethernet;
3607       }
3608       case TYPE_WIFI: {
3609         WifiNetwork* wifi = new WifiNetwork(service_path);
3610         return wifi;
3611       }
3612       case TYPE_CELLULAR: {
3613         CellularNetwork* cellular = new CellularNetwork(service_path);
3614         return cellular;
3615       }
3616       case TYPE_VPN: {
3617         VirtualNetwork* vpn = new VirtualNetwork(service_path);
3618         return vpn;
3619       }
3620       default: {
3621         LOG(WARNING) << "Unknown service type: " << type;
3622         return new Network(service_path, type);
3623       }
3624     }
3625   }
3626 
ParseNetwork(const std::string & service_path,const DictionaryValue * info)3627   Network* ParseNetwork(const std::string& service_path,
3628                         const DictionaryValue* info) {
3629     Network* network = FindNetworkByPath(service_path);
3630     if (!network) {
3631       ConnectionType type = ParseTypeFromDictionary(info);
3632       network = CreateNewNetwork(type, service_path);
3633       AddNetwork(network);
3634     }
3635 
3636     // Erase entry from network_unique_id_map_ in case unique id changes.
3637     if (!network->unique_id().empty())
3638       network_unique_id_map_.erase(network->unique_id());
3639 
3640     network->ParseInfo(info);  // virtual.
3641 
3642     if (!network->unique_id().empty())
3643       network_unique_id_map_[network->unique_id()] = network;
3644 
3645     UpdateActiveNetwork(network);
3646 
3647     // Find and erase entry in update_requests, and set network priority.
3648     PriorityMap::iterator found2 = network_update_requests_.find(service_path);
3649     if (found2 != network_update_requests_.end()) {
3650       network->priority_order_ = found2->second;
3651       network_update_requests_.erase(found2);
3652       if (network_update_requests_.empty()) {
3653         // Clear wifi_scanning_ when we have no pending requests.
3654         wifi_scanning_ = false;
3655       }
3656     } else {
3657       // TODO(stevenjb): Enable warning once UpdateNetworkServiceList is fixed.
3658       // LOG(WARNING) << "ParseNetwork called with no update request entry: "
3659       //              << service_path;
3660     }
3661 
3662     VLOG(1) << "ParseNetwork: " << network->name();
3663     NotifyNetworkManagerChanged(false);  // Not forced.
3664     return network;
3665   }
3666 
3667   // Returns NULL if |service_path| refers to a network that is not a
3668   // remembered type.
ParseRememberedNetwork(const std::string & service_path,const DictionaryValue * info)3669   Network* ParseRememberedNetwork(const std::string& service_path,
3670                                   const DictionaryValue* info) {
3671     Network* network;
3672     NetworkMap::iterator found = remembered_network_map_.find(service_path);
3673     if (found != remembered_network_map_.end()) {
3674       network = found->second;
3675     } else {
3676       ConnectionType type = ParseTypeFromDictionary(info);
3677       if (type == TYPE_WIFI) {
3678         network = CreateNewNetwork(type, service_path);
3679         WifiNetwork* wifi = static_cast<WifiNetwork*>(network);
3680         AddRememberedWifiNetwork(wifi);
3681       } else {
3682         VLOG(1) << "Ignoring remembered network: " << service_path
3683                 << " Type: " << ConnectionTypeToString(type);
3684         return NULL;
3685       }
3686     }
3687     network->ParseInfo(info);  // virtual.
3688     VLOG(1) << "ParseRememberedNetwork: " << network->name();
3689     NotifyNetworkManagerChanged(false);  // Not forced.
3690     return network;
3691   }
3692 
ClearNetworks(bool delete_networks)3693   void ClearNetworks(bool delete_networks) {
3694     if (delete_networks)
3695       STLDeleteValues(&network_map_);
3696     network_map_.clear();
3697     network_unique_id_map_.clear();
3698     ethernet_ = NULL;
3699     active_wifi_ = NULL;
3700     active_cellular_ = NULL;
3701     active_virtual_ = NULL;
3702     wifi_networks_.clear();
3703     cellular_networks_.clear();
3704     virtual_networks_.clear();
3705   }
3706 
ClearRememberedNetworks(bool delete_networks)3707   void ClearRememberedNetworks(bool delete_networks) {
3708     if (delete_networks)
3709       STLDeleteValues(&remembered_network_map_);
3710     remembered_network_map_.clear();
3711     remembered_wifi_networks_.clear();
3712   }
3713 
3714   ////////////////////////////////////////////////////////////////////////////
3715   // NetworkDevice list management functions.
3716 
3717   // Returns pointer to device or NULL if device is not found by path.
3718   // Use FindNetworkDeviceByPath when you're not intending to change device.
GetNetworkDeviceByPath(const std::string & path)3719   NetworkDevice* GetNetworkDeviceByPath(const std::string& path) {
3720     NetworkDeviceMap::iterator iter = device_map_.find(path);
3721     if (iter != device_map_.end())
3722       return iter->second;
3723     LOG(WARNING) << "Device path not found: " << path;
3724     return NULL;
3725   }
3726 
3727   // Update device list, and request associated device updates.
3728   // |devices| represents a complete list of devices.
UpdateNetworkDeviceList(const ListValue * devices)3729   void UpdateNetworkDeviceList(const ListValue* devices) {
3730     NetworkDeviceMap old_device_map = device_map_;
3731     device_map_.clear();
3732     VLOG(2) << "Updating Device List.";
3733     for (ListValue::const_iterator iter = devices->begin();
3734          iter != devices->end(); ++iter) {
3735       std::string device_path;
3736       (*iter)->GetAsString(&device_path);
3737       if (!device_path.empty()) {
3738         NetworkDeviceMap::iterator found = old_device_map.find(device_path);
3739         if (found != old_device_map.end()) {
3740           VLOG(2) << " Adding existing device: " << device_path;
3741           device_map_[device_path] = found->second;
3742           old_device_map.erase(found);
3743         }
3744         RequestNetworkDeviceInfo(
3745             device_path.c_str(), &NetworkDeviceUpdate, this);
3746       }
3747     }
3748     // Delete any old devices that no longer exist.
3749     for (NetworkDeviceMap::iterator iter = old_device_map.begin();
3750          iter != old_device_map.end(); ++iter) {
3751       DeleteDeviceFromDeviceObserversMap(iter->first);
3752       // Delete device.
3753       delete iter->second;
3754     }
3755   }
3756 
DeleteDeviceFromDeviceObserversMap(const std::string & device_path)3757   void DeleteDeviceFromDeviceObserversMap(const std::string& device_path) {
3758     // Delete all device observers associated with this device.
3759     NetworkDeviceObserverMap::iterator map_iter =
3760         network_device_observers_.find(device_path);
3761     if (map_iter != network_device_observers_.end()) {
3762       delete map_iter->second;
3763       network_device_observers_.erase(map_iter);
3764     }
3765   }
3766 
DeleteDevice(const std::string & device_path)3767   void DeleteDevice(const std::string& device_path) {
3768     NetworkDeviceMap::iterator found = device_map_.find(device_path);
3769     if (found == device_map_.end()) {
3770       LOG(WARNING) << "Attempt to delete non-existant device: "
3771                    << device_path;
3772       return;
3773     }
3774     VLOG(2) << " Deleting device: " << device_path;
3775     NetworkDevice* device = found->second;
3776     device_map_.erase(found);
3777     DeleteDeviceFromDeviceObserversMap(device_path);
3778     delete device;
3779   }
3780 
ParseNetworkDevice(const std::string & device_path,const DictionaryValue * info)3781   void ParseNetworkDevice(const std::string& device_path,
3782                           const DictionaryValue* info) {
3783     NetworkDeviceMap::iterator found = device_map_.find(device_path);
3784     NetworkDevice* device;
3785     if (found != device_map_.end()) {
3786       device = found->second;
3787     } else {
3788       device = new NetworkDevice(device_path);
3789       VLOG(2) << " Adding device: " << device_path;
3790       device_map_[device_path] = device;
3791       if (network_device_observers_.find(device_path) ==
3792           network_device_observers_.end()) {
3793         network_device_observers_[device_path] =
3794             new NetworkDeviceObserverList(this, device_path);
3795       }
3796     }
3797     device->ParseInfo(info);
3798     VLOG(1) << "ParseNetworkDevice:" << device->name();
3799     NotifyNetworkManagerChanged(false);  // Not forced.
3800   }
3801 
3802   ////////////////////////////////////////////////////////////////////////////
3803 
EnableNetworkDeviceType(ConnectionType device,bool enable)3804   void EnableNetworkDeviceType(ConnectionType device, bool enable) {
3805     if (!EnsureCrosLoaded())
3806       return;
3807 
3808     // If network device is already enabled/disabled, then don't do anything.
3809     if (enable && (enabled_devices_ & (1 << device))) {
3810       LOG(WARNING) << "Trying to enable a device that's already enabled: "
3811                    << device;
3812       return;
3813     }
3814     if (!enable && !(enabled_devices_ & (1 << device))) {
3815       LOG(WARNING) << "Trying to disable a device that's already disabled: "
3816                    << device;
3817       return;
3818     }
3819 
3820     RequestNetworkDeviceEnable(ConnectionTypeToString(device), enable);
3821   }
3822 
3823   ////////////////////////////////////////////////////////////////////////////
3824   // Notifications.
3825 
3826   // We call this any time something in NetworkLibrary changes.
3827   // TODO(stevenjb): We should consider breaking this into multiple
3828   // notifications, e.g. connection state, devices, services, etc.
NotifyNetworkManagerChanged(bool force_update)3829   void NotifyNetworkManagerChanged(bool force_update) {
3830     CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3831     // Cancel any pending signals.
3832     if (notify_task_) {
3833       notify_task_->Cancel();
3834       notify_task_ = NULL;
3835     }
3836     if (force_update) {
3837       // Signal observers now.
3838       SignalNetworkManagerObservers();
3839     } else {
3840       // Schedule a deleayed signal to limit the frequency of notifications.
3841       notify_task_ = NewRunnableMethod(
3842           this, &NetworkLibraryImpl::SignalNetworkManagerObservers);
3843       BrowserThread::PostDelayedTask(BrowserThread::UI, FROM_HERE, notify_task_,
3844                                      kNetworkNotifyDelayMs);
3845     }
3846   }
3847 
SignalNetworkManagerObservers()3848   void SignalNetworkManagerObservers() {
3849     notify_task_ = NULL;
3850     FOR_EACH_OBSERVER(NetworkManagerObserver,
3851                       network_manager_observers_,
3852                       OnNetworkManagerChanged(this));
3853   }
3854 
NotifyNetworkChanged(Network * network)3855   void NotifyNetworkChanged(Network* network) {
3856     VLOG(2) << "Network changed: " << network->name();
3857     DCHECK(network);
3858     NetworkObserverMap::const_iterator iter = network_observers_.find(
3859         network->service_path());
3860     if (iter != network_observers_.end()) {
3861       FOR_EACH_OBSERVER(NetworkObserver,
3862                         *(iter->second),
3863                         OnNetworkChanged(this, network));
3864     } else {
3865       NOTREACHED() <<
3866           "There weren't supposed to be any property change observers of " <<
3867            network->service_path();
3868     }
3869   }
3870 
NotifyNetworkDeviceChanged(NetworkDevice * device)3871   void NotifyNetworkDeviceChanged(NetworkDevice* device) {
3872     DCHECK(device);
3873     NetworkDeviceObserverMap::const_iterator iter =
3874         network_device_observers_.find(device->device_path());
3875     if (iter != network_device_observers_.end()) {
3876       NetworkDeviceObserverList* device_observer_list = iter->second;
3877       FOR_EACH_OBSERVER(NetworkDeviceObserver,
3878                         *device_observer_list,
3879                         OnNetworkDeviceChanged(this, device));
3880     } else {
3881       NOTREACHED() <<
3882           "There weren't supposed to be any property change observers of " <<
3883            device->device_path();
3884     }
3885   }
3886 
NotifyCellularDataPlanChanged()3887   void NotifyCellularDataPlanChanged() {
3888     FOR_EACH_OBSERVER(CellularDataPlanObserver,
3889                       data_plan_observers_,
3890                       OnCellularDataPlanChanged(this));
3891   }
3892 
NotifyPinOperationCompleted(PinOperationError error)3893   void NotifyPinOperationCompleted(PinOperationError error) {
3894     FOR_EACH_OBSERVER(PinOperationObserver,
3895                       pin_operation_observers_,
3896                       OnPinOperationCompleted(this, error));
3897     sim_operation_ = SIM_OPERATION_NONE;
3898   }
3899 
NotifyUserConnectionInitiated(const Network * network)3900   void NotifyUserConnectionInitiated(const Network* network) {
3901     FOR_EACH_OBSERVER(UserActionObserver,
3902                       user_action_observers_,
3903                       OnConnectionInitiated(this, network));
3904   }
3905 
3906   ////////////////////////////////////////////////////////////////////////////
3907   // Device updates.
3908 
FlipSimPinRequiredStateIfNeeded()3909   void FlipSimPinRequiredStateIfNeeded() {
3910     if (sim_operation_ != SIM_OPERATION_CHANGE_REQUIRE_PIN)
3911       return;
3912 
3913     const NetworkDevice* cellular = FindCellularDevice();
3914     if (cellular) {
3915       NetworkDevice* device = GetNetworkDeviceByPath(cellular->device_path());
3916       if (device->sim_pin_required() == SIM_PIN_NOT_REQUIRED)
3917         device->sim_pin_required_ = SIM_PIN_REQUIRED;
3918       else if (device->sim_pin_required() == SIM_PIN_REQUIRED)
3919         device->sim_pin_required_ = SIM_PIN_NOT_REQUIRED;
3920     }
3921   }
3922 
UpdateNetworkDeviceStatus(const char * path,const char * key,const Value * value)3923   void UpdateNetworkDeviceStatus(const char* path,
3924                                  const char* key,
3925                                  const Value* value) {
3926     CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3927     if (key == NULL || value == NULL)
3928       return;
3929     NetworkDevice* device = GetNetworkDeviceByPath(path);
3930     if (device) {
3931       VLOG(1) << "UpdateNetworkDeviceStatus: " << device->name() << "." << key;
3932       int index = property_index_parser().Get(std::string(key));
3933       if (!device->ParseValue(index, value)) {
3934         LOG(WARNING) << "UpdateNetworkDeviceStatus: Error parsing: "
3935                      << path << "." << key;
3936       } else if (strcmp(key, kCellularAllowRoamingProperty) == 0) {
3937         bool settings_value =
3938             UserCrosSettingsProvider::cached_data_roaming_enabled();
3939         if (device->data_roaming_allowed() != settings_value) {
3940           // Switch back to signed settings value.
3941           SetCellularDataRoamingAllowed(settings_value);
3942           return;
3943         }
3944       }
3945       // Notify only observers on device property change.
3946       NotifyNetworkDeviceChanged(device);
3947       // If a device's power state changes, new properties may become
3948       // defined.
3949       if (strcmp(key, kPoweredProperty) == 0) {
3950         RequestNetworkDeviceInfo(path, &NetworkDeviceUpdate, this);
3951       }
3952     }
3953   }
3954 
3955   ////////////////////////////////////////////////////////////////////////////
3956   // Service updates.
3957 
UpdateNetworkStatus(const char * path,const char * key,const Value * value)3958   void UpdateNetworkStatus(const char* path,
3959                            const char* key,
3960                            const Value* value) {
3961     CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3962     if (key == NULL || value == NULL)
3963       return;
3964     Network* network = FindNetworkByPath(path);
3965     if (network) {
3966       VLOG(2) << "UpdateNetworkStatus: " << network->name() << "." << key;
3967       // Note: ParseValue is virtual.
3968       int index = property_index_parser().Get(std::string(key));
3969       if (!network->ParseValue(index, value)) {
3970         LOG(WARNING) << "UpdateNetworkStatus: Error parsing: "
3971                      << path << "." << key;
3972       }
3973       NotifyNetworkChanged(network);
3974       // Anything observing the manager needs to know about any service change.
3975       NotifyNetworkManagerChanged(false);  // Not forced.
3976     }
3977   }
3978 
3979   ////////////////////////////////////////////////////////////////////////////
3980   // Data Plans.
3981 
GetSignificantDataPlanFromVector(const CellularDataPlanVector * plans) const3982   const CellularDataPlan* GetSignificantDataPlanFromVector(
3983       const CellularDataPlanVector* plans) const {
3984     const CellularDataPlan* significant = NULL;
3985     for (CellularDataPlanVector::const_iterator iter = plans->begin();
3986          iter != plans->end(); ++iter) {
3987       // Set significant to the first plan or to first non metered base plan.
3988       if (significant == NULL ||
3989           significant->plan_type == CELLULAR_DATA_PLAN_METERED_BASE)
3990         significant = *iter;
3991     }
3992     return significant;
3993   }
3994 
GetDataLeft(CellularDataPlanVector * data_plans)3995   CellularNetwork::DataLeft GetDataLeft(
3996       CellularDataPlanVector* data_plans) {
3997     const CellularDataPlan* plan = GetSignificantDataPlanFromVector(data_plans);
3998     if (!plan)
3999       return CellularNetwork::DATA_UNKNOWN;
4000     if (plan->plan_type == CELLULAR_DATA_PLAN_UNLIMITED) {
4001       base::TimeDelta remaining = plan->remaining_time();
4002       if (remaining <= base::TimeDelta::FromSeconds(0))
4003         return CellularNetwork::DATA_NONE;
4004       if (remaining <= base::TimeDelta::FromSeconds(kCellularDataVeryLowSecs))
4005         return CellularNetwork::DATA_VERY_LOW;
4006       if (remaining <= base::TimeDelta::FromSeconds(kCellularDataLowSecs))
4007         return CellularNetwork::DATA_LOW;
4008       return CellularNetwork::DATA_NORMAL;
4009     } else if (plan->plan_type == CELLULAR_DATA_PLAN_METERED_PAID ||
4010                plan->plan_type == CELLULAR_DATA_PLAN_METERED_BASE) {
4011       int64 remaining = plan->remaining_data();
4012       if (remaining <= 0)
4013         return CellularNetwork::DATA_NONE;
4014       if (remaining <= kCellularDataVeryLowBytes)
4015         return CellularNetwork::DATA_VERY_LOW;
4016       // For base plans, we do not care about low data.
4017       if (remaining <= kCellularDataLowBytes &&
4018           plan->plan_type != CELLULAR_DATA_PLAN_METERED_BASE)
4019         return CellularNetwork::DATA_LOW;
4020       return CellularNetwork::DATA_NORMAL;
4021     }
4022     return CellularNetwork::DATA_UNKNOWN;
4023   }
4024 
UpdateCellularDataPlan(const std::string & service_path,const CellularDataPlanList * data_plan_list)4025   void UpdateCellularDataPlan(const std::string& service_path,
4026                               const CellularDataPlanList* data_plan_list) {
4027     VLOG(1) << "Updating cellular data plans for: " << service_path;
4028     CellularDataPlanVector* data_plans = NULL;
4029     // Find and delete any existing data plans associated with |service_path|.
4030     CellularDataPlanMap::iterator found = data_plan_map_.find(service_path);
4031     if (found != data_plan_map_.end()) {
4032       data_plans = found->second;
4033       data_plans->reset();  // This will delete existing data plans.
4034     } else {
4035       data_plans = new CellularDataPlanVector;
4036       data_plan_map_[service_path] = data_plans;
4037     }
4038     for (size_t i = 0; i < data_plan_list->plans_size; i++) {
4039       const CellularDataPlanInfo* info(data_plan_list->GetCellularDataPlan(i));
4040       CellularDataPlan* plan = new CellularDataPlan(*info);
4041       data_plans->push_back(plan);
4042       VLOG(2) << " Plan: " << plan->GetPlanDesciption()
4043               << " : " << plan->GetDataRemainingDesciption();
4044     }
4045     // Now, update any matching cellular network's cached data
4046     CellularNetwork* cellular = FindCellularNetworkByPath(service_path);
4047     if (cellular) {
4048       CellularNetwork::DataLeft data_left;
4049       // If the network needs a new plan, then there's no data.
4050       if (cellular->needs_new_plan())
4051         data_left = CellularNetwork::DATA_NONE;
4052       else
4053         data_left = GetDataLeft(data_plans);
4054       VLOG(2) << " Data left: " << data_left
4055               << " Need plan: " << cellular->needs_new_plan();
4056       cellular->set_data_left(data_left);
4057     }
4058     NotifyCellularDataPlanChanged();
4059   }
4060 
4061   ////////////////////////////////////////////////////////////////////////////
4062 
Init()4063   void Init() {
4064     // First, get the currently available networks. This data is cached
4065     // on the connman side, so the call should be quick.
4066     if (EnsureCrosLoaded()) {
4067       VLOG(1) << "Requesting initial network manager info from libcros.";
4068       RequestNetworkManagerInfo(&NetworkManagerUpdate, this);
4069     }
4070   }
4071 
InitTestData()4072   void InitTestData() {
4073     is_locked_ = false;
4074 
4075     // Devices
4076     int devices =
4077         (1 << TYPE_ETHERNET) | (1 << TYPE_WIFI) | (1 << TYPE_CELLULAR);
4078     available_devices_ = devices;
4079     enabled_devices_ = devices;
4080     connected_devices_ = devices;
4081 
4082     NetworkDevice* cellular = new NetworkDevice("cellular");
4083     scoped_ptr<Value> cellular_type(Value::CreateStringValue(kTypeCellular));
4084     cellular->ParseValue(PROPERTY_INDEX_TYPE, cellular_type.get());
4085     cellular->IMSI_ = "123456789012345";
4086     device_map_["cellular"] = cellular;
4087 
4088     // Networks
4089     ClearNetworks(true /*delete networks*/);
4090 
4091     ethernet_ = new EthernetNetwork("eth1");
4092     ethernet_->set_connected(true);
4093     AddNetwork(ethernet_);
4094 
4095     WifiNetwork* wifi1 = new WifiNetwork("fw1");
4096     wifi1->set_name("Fake Wifi Connected");
4097     wifi1->set_strength(90);
4098     wifi1->set_connected(true);
4099     wifi1->set_active(true);
4100     wifi1->set_encryption(SECURITY_NONE);
4101     AddNetwork(wifi1);
4102 
4103     WifiNetwork* wifi2 = new WifiNetwork("fw2");
4104     wifi2->set_name("Fake Wifi");
4105     wifi2->set_strength(70);
4106     wifi2->set_connected(false);
4107     wifi2->set_encryption(SECURITY_NONE);
4108     AddNetwork(wifi2);
4109 
4110     WifiNetwork* wifi3 = new WifiNetwork("fw3");
4111     wifi3->set_name("Fake Wifi Encrypted");
4112     wifi3->set_strength(60);
4113     wifi3->set_connected(false);
4114     wifi3->set_encryption(SECURITY_WEP);
4115     wifi3->set_passphrase_required(true);
4116     AddNetwork(wifi3);
4117 
4118     WifiNetwork* wifi4 = new WifiNetwork("fw4");
4119     wifi4->set_name("Fake Wifi 802.1x");
4120     wifi4->set_strength(50);
4121     wifi4->set_connected(false);
4122     wifi4->set_connectable(false);
4123     wifi4->set_encryption(SECURITY_8021X);
4124     wifi4->set_identity("nobody@google.com");
4125     wifi4->set_cert_path("SETTINGS:key_id=3,cert_id=3,pin=111111");
4126     AddNetwork(wifi4);
4127 
4128     WifiNetwork* wifi5 = new WifiNetwork("fw5");
4129     wifi5->set_name("Fake Wifi UTF-8 SSID ");
4130     wifi5->SetSsid("Fake Wifi UTF-8 SSID \u3042\u3044\u3046");
4131     wifi5->set_strength(25);
4132     wifi5->set_connected(false);
4133     AddNetwork(wifi5);
4134 
4135     WifiNetwork* wifi6 = new WifiNetwork("fw6");
4136     wifi6->set_name("Fake Wifi latin-1 SSID ");
4137     wifi6->SetSsid("Fake Wifi latin-1 SSID \xc0\xcb\xcc\xd6\xfb");
4138     wifi6->set_strength(20);
4139     wifi6->set_connected(false);
4140     AddNetwork(wifi6);
4141 
4142     active_wifi_ = wifi1;
4143 
4144     CellularNetwork* cellular1 = new CellularNetwork("fc1");
4145     cellular1->set_name("Fake Cellular");
4146     cellular1->set_strength(70);
4147     cellular1->set_connected(true);
4148     cellular1->set_active(true);
4149     cellular1->set_activation_state(ACTIVATION_STATE_ACTIVATED);
4150     cellular1->set_payment_url(std::string("http://www.google.com"));
4151     cellular1->set_usage_url(std::string("http://www.google.com"));
4152     cellular1->set_network_technology(NETWORK_TECHNOLOGY_EVDO);
4153     cellular1->set_roaming_state(ROAMING_STATE_ROAMING);
4154 
4155     CellularDataPlan* base_plan = new CellularDataPlan();
4156     base_plan->plan_name = "Base plan";
4157     base_plan->plan_type = CELLULAR_DATA_PLAN_METERED_BASE;
4158     base_plan->plan_data_bytes = 100ll * 1024 * 1024;
4159     base_plan->data_bytes_used = 75ll * 1024 * 1024;
4160     CellularDataPlanVector* data_plans = new CellularDataPlanVector();
4161     data_plan_map_[cellular1->service_path()] = data_plans;
4162     data_plans->push_back(base_plan);
4163 
4164     CellularDataPlan* paid_plan = new CellularDataPlan();
4165     paid_plan->plan_name = "Paid plan";
4166     paid_plan->plan_type = CELLULAR_DATA_PLAN_METERED_PAID;
4167     paid_plan->plan_data_bytes = 5ll * 1024 * 1024 * 1024;
4168     paid_plan->data_bytes_used = 3ll * 1024 * 1024 * 1024;
4169     data_plans->push_back(paid_plan);
4170 
4171     AddNetwork(cellular1);
4172     active_cellular_ = cellular1;
4173 
4174     CellularNetwork* cellular2 = new CellularNetwork("fc2");
4175     cellular2->set_name("Fake Cellular 2");
4176     cellular2->set_strength(70);
4177     cellular2->set_connected(true);
4178     cellular2->set_activation_state(ACTIVATION_STATE_ACTIVATED);
4179     cellular2->set_network_technology(NETWORK_TECHNOLOGY_UMTS);
4180     AddNetwork(cellular2);
4181 
4182     // Remembered Networks
4183     ClearRememberedNetworks(true /*delete networks*/);
4184     WifiNetwork* remembered_wifi2 = new WifiNetwork("fw2");
4185     remembered_wifi2->set_name("Fake Wifi 2");
4186     remembered_wifi2->set_strength(70);
4187     remembered_wifi2->set_connected(true);
4188     remembered_wifi2->set_encryption(SECURITY_WEP);
4189     AddRememberedWifiNetwork(remembered_wifi2);
4190 
4191     // VPNs.
4192     VirtualNetwork* vpn1 = new VirtualNetwork("fv1");
4193     vpn1->set_name("Fake VPN Provider 1");
4194     vpn1->set_server_hostname("vpn1server.fake.com");
4195     vpn1->set_provider_type(VirtualNetwork::PROVIDER_TYPE_L2TP_IPSEC_PSK);
4196     vpn1->set_username("VPN User 1");
4197     vpn1->set_connected(false);
4198     AddNetwork(vpn1);
4199 
4200     VirtualNetwork* vpn2 = new VirtualNetwork("fv2");
4201     vpn2->set_name("Fake VPN Provider 2");
4202     vpn2->set_server_hostname("vpn2server.fake.com");
4203     vpn2->set_provider_type(VirtualNetwork::PROVIDER_TYPE_L2TP_IPSEC_USER_CERT);
4204     vpn2->set_username("VPN User 2");
4205     vpn2->set_connected(true);
4206     AddNetwork(vpn2);
4207 
4208     VirtualNetwork* vpn3 = new VirtualNetwork("fv3");
4209     vpn3->set_name("Fake VPN Provider 3");
4210     vpn3->set_server_hostname("vpn3server.fake.com");
4211     vpn3->set_provider_type(VirtualNetwork::PROVIDER_TYPE_OPEN_VPN);
4212     vpn3->set_connected(false);
4213     AddNetwork(vpn3);
4214 
4215     active_virtual_ = vpn2;
4216 
4217     wifi_scanning_ = false;
4218     offline_mode_ = false;
4219   }
4220 
4221   // Network manager observer list
4222   ObserverList<NetworkManagerObserver> network_manager_observers_;
4223 
4224   // Cellular data plan observer list
4225   ObserverList<CellularDataPlanObserver> data_plan_observers_;
4226 
4227   // PIN operation observer list.
4228   ObserverList<PinOperationObserver> pin_operation_observers_;
4229 
4230   // User action observer list
4231   ObserverList<UserActionObserver> user_action_observers_;
4232 
4233   // Network observer map
4234   NetworkObserverMap network_observers_;
4235 
4236   // Network device observer map.
4237   NetworkDeviceObserverMap network_device_observers_;
4238 
4239   // For monitoring network manager status changes.
4240   PropertyChangeMonitor network_manager_monitor_;
4241 
4242   // For monitoring data plan changes to the connected cellular network.
4243   DataPlanUpdateMonitor data_plan_monitor_;
4244 
4245   // Network login observer.
4246   scoped_ptr<NetworkLoginObserver> network_login_observer_;
4247 
4248   // A service path based map of all Networks.
4249   NetworkMap network_map_;
4250 
4251   // A unique_id_ based map of Networks.
4252   NetworkMap network_unique_id_map_;
4253 
4254   // A service path based map of all remembered Networks.
4255   NetworkMap remembered_network_map_;
4256 
4257   // A list of services that we are awaiting updates for.
4258   PriorityMap network_update_requests_;
4259 
4260   // A device path based map of all NetworkDevices.
4261   NetworkDeviceMap device_map_;
4262 
4263   // A network service path based map of all CellularDataPlanVectors.
4264   CellularDataPlanMap data_plan_map_;
4265 
4266   // The ethernet network.
4267   EthernetNetwork* ethernet_;
4268 
4269   // The list of available wifi networks.
4270   WifiNetworkVector wifi_networks_;
4271 
4272   // The current connected (or connecting) wifi network.
4273   WifiNetwork* active_wifi_;
4274 
4275   // The remembered wifi networks.
4276   WifiNetworkVector remembered_wifi_networks_;
4277 
4278   // The list of available cellular networks.
4279   CellularNetworkVector cellular_networks_;
4280 
4281   // The current connected (or connecting) cellular network.
4282   CellularNetwork* active_cellular_;
4283 
4284   // The list of available virtual networks.
4285   VirtualNetworkVector virtual_networks_;
4286 
4287   // The current connected (or connecting) virtual network.
4288   VirtualNetwork* active_virtual_;
4289 
4290   // The path of the active profile (for retrieving remembered services).
4291   std::string active_profile_path_;
4292 
4293   // The current available network devices. Bitwise flag of ConnectionTypes.
4294   int available_devices_;
4295 
4296   // The current enabled network devices. Bitwise flag of ConnectionTypes.
4297   int enabled_devices_;
4298 
4299   // The current connected network devices. Bitwise flag of ConnectionTypes.
4300   int connected_devices_;
4301 
4302   // True if we are currently scanning for wifi networks.
4303   bool wifi_scanning_;
4304 
4305   // Currently not implemented. TODO: implement or eliminate.
4306   bool offline_mode_;
4307 
4308   // True if access network library is locked.
4309   bool is_locked_;
4310 
4311   // Type of pending SIM operation, SIM_OPERATION_NONE otherwise.
4312   SimOperationType sim_operation_;
4313 
4314   // Delayed task to notify a network change.
4315   CancelableTask* notify_task_;
4316 
4317   // Cellular plan payment time.
4318   base::Time cellular_plan_payment_time_;
4319 
4320   // Temporary connection data for async connect calls.
4321   struct ConnectData {
4322     std::string service_name;
4323     std::string passphrase;
4324     std::string identity;
4325     std::string cert_path;
4326     std::string psk_key;
4327     std::string server_hostname;
4328   };
4329   ConnectData connect_data_;
4330 
4331   DISALLOW_COPY_AND_ASSIGN(NetworkLibraryImpl);
4332 };
4333 
4334 class NetworkLibraryStubImpl : public NetworkLibrary {
4335  public:
NetworkLibraryStubImpl()4336   NetworkLibraryStubImpl()
4337       : ip_address_("1.1.1.1"),
4338         ethernet_(new EthernetNetwork("eth0")),
4339         active_wifi_(NULL),
4340         active_cellular_(NULL) {
4341   }
~NetworkLibraryStubImpl()4342   ~NetworkLibraryStubImpl() { if (ethernet_) delete ethernet_; }
AddNetworkManagerObserver(NetworkManagerObserver * observer)4343   virtual void AddNetworkManagerObserver(NetworkManagerObserver* observer) {}
RemoveNetworkManagerObserver(NetworkManagerObserver * observer)4344   virtual void RemoveNetworkManagerObserver(NetworkManagerObserver* observer) {}
AddNetworkObserver(const std::string & service_path,NetworkObserver * observer)4345   virtual void AddNetworkObserver(const std::string& service_path,
4346                                   NetworkObserver* observer) {}
RemoveNetworkObserver(const std::string & service_path,NetworkObserver * observer)4347   virtual void RemoveNetworkObserver(const std::string& service_path,
4348                                      NetworkObserver* observer) {}
RemoveObserverForAllNetworks(NetworkObserver * observer)4349   virtual void RemoveObserverForAllNetworks(NetworkObserver* observer) {}
AddNetworkDeviceObserver(const std::string & device_path,NetworkDeviceObserver * observer)4350   virtual void AddNetworkDeviceObserver(const std::string& device_path,
4351                                         NetworkDeviceObserver* observer) {}
RemoveNetworkDeviceObserver(const std::string & device_path,NetworkDeviceObserver * observer)4352   virtual void RemoveNetworkDeviceObserver(const std::string& device_path,
4353                                            NetworkDeviceObserver* observer) {}
Lock()4354   virtual void Lock() {}
Unlock()4355   virtual void Unlock() {}
IsLocked()4356   virtual bool IsLocked() { return false; }
AddCellularDataPlanObserver(CellularDataPlanObserver * observer)4357   virtual void AddCellularDataPlanObserver(
4358       CellularDataPlanObserver* observer) {}
RemoveCellularDataPlanObserver(CellularDataPlanObserver * observer)4359   virtual void RemoveCellularDataPlanObserver(
4360       CellularDataPlanObserver* observer) {}
AddPinOperationObserver(PinOperationObserver * observer)4361   virtual void AddPinOperationObserver(PinOperationObserver* observer) {}
RemovePinOperationObserver(PinOperationObserver * observer)4362   virtual void RemovePinOperationObserver(PinOperationObserver* observer) {}
AddUserActionObserver(UserActionObserver * observer)4363   virtual void AddUserActionObserver(UserActionObserver* observer) {}
RemoveUserActionObserver(UserActionObserver * observer)4364   virtual void RemoveUserActionObserver(UserActionObserver* observer) {}
4365 
ethernet_network() const4366   virtual const EthernetNetwork* ethernet_network() const {
4367     return ethernet_;
4368   }
ethernet_connecting() const4369   virtual bool ethernet_connecting() const { return false; }
ethernet_connected() const4370   virtual bool ethernet_connected() const { return true; }
4371 
wifi_network() const4372   virtual const WifiNetwork* wifi_network() const {
4373     return active_wifi_;
4374   }
wifi_connecting() const4375   virtual bool wifi_connecting() const { return false; }
wifi_connected() const4376   virtual bool wifi_connected() const { return false; }
4377 
cellular_network() const4378   virtual const CellularNetwork* cellular_network() const {
4379     return active_cellular_;
4380   }
cellular_connecting() const4381   virtual bool cellular_connecting() const { return false; }
cellular_connected() const4382   virtual bool cellular_connected() const { return false; }
4383 
virtual_network() const4384   virtual const VirtualNetwork* virtual_network() const {
4385     return active_virtual_;
4386   }
virtual_network_connecting() const4387   virtual bool virtual_network_connecting() const { return false; }
virtual_network_connected() const4388   virtual bool virtual_network_connected() const { return false; }
4389 
Connected() const4390   bool Connected() const { return true; }
Connecting() const4391   bool Connecting() const { return false; }
IPAddress() const4392   const std::string& IPAddress() const { return ip_address_; }
wifi_networks() const4393   virtual const WifiNetworkVector& wifi_networks() const {
4394     return wifi_networks_;
4395   }
remembered_wifi_networks() const4396   virtual const WifiNetworkVector& remembered_wifi_networks() const {
4397     return wifi_networks_;
4398   }
cellular_networks() const4399   virtual const CellularNetworkVector& cellular_networks() const {
4400     return cellular_networks_;
4401   }
virtual_networks() const4402   virtual const VirtualNetworkVector& virtual_networks() const {
4403     return virtual_networks_;
4404   }
has_cellular_networks() const4405   virtual bool has_cellular_networks() const {
4406     return cellular_networks_.begin() != cellular_networks_.end();
4407   }
4408   /////////////////////////////////////////////////////////////////////////////
4409 
FindNetworkDeviceByPath(const std::string & path) const4410   virtual const NetworkDevice* FindNetworkDeviceByPath(
4411       const std::string& path) const { return NULL; }
FindCellularDevice() const4412   virtual const NetworkDevice* FindCellularDevice() const {
4413     return NULL;
4414   }
FindEthernetDevice() const4415   virtual const NetworkDevice* FindEthernetDevice() const {
4416     return NULL;
4417   }
FindWifiDevice() const4418   virtual const NetworkDevice* FindWifiDevice() const {
4419     return NULL;
4420   }
FindNetworkByPath(const std::string & path) const4421   virtual Network* FindNetworkByPath(
4422       const std::string& path) const { return NULL; }
FindWifiNetworkByPath(const std::string & path) const4423   virtual WifiNetwork* FindWifiNetworkByPath(
4424       const std::string& path) const { return NULL; }
FindCellularNetworkByPath(const std::string & path) const4425   virtual CellularNetwork* FindCellularNetworkByPath(
4426       const std::string& path) const { return NULL; }
FindVirtualNetworkByPath(const std::string & path) const4427   virtual VirtualNetwork* FindVirtualNetworkByPath(
4428       const std::string& path) const { return NULL; }
FindNetworkFromRemembered(const Network * remembered) const4429   virtual Network* FindNetworkFromRemembered(
4430       const Network* remembered) const { return NULL; }
GetDataPlans(const std::string & path) const4431   virtual const CellularDataPlanVector* GetDataPlans(
4432       const std::string& path) const { return NULL; }
GetSignificantDataPlan(const std::string & path) const4433   virtual const CellularDataPlan* GetSignificantDataPlan(
4434       const std::string& path) const { return NULL; }
4435 
ChangePin(const std::string & old_pin,const std::string & new_pin)4436   virtual void ChangePin(const std::string& old_pin,
4437                          const std::string& new_pin) {}
ChangeRequirePin(bool require_pin,const std::string & pin)4438   virtual void ChangeRequirePin(bool require_pin, const std::string& pin) {}
EnterPin(const std::string & pin)4439   virtual void EnterPin(const std::string& pin) {}
UnblockPin(const std::string & puk,const std::string & new_pin)4440   virtual void UnblockPin(const std::string& puk, const std::string& new_pin) {}
RequestCellularScan()4441   virtual void RequestCellularScan() {}
RequestCellularRegister(const std::string & network_id)4442   virtual void RequestCellularRegister(const std::string& network_id) {}
SetCellularDataRoamingAllowed(bool new_value)4443   virtual void SetCellularDataRoamingAllowed(bool new_value) {}
4444 
RequestNetworkScan()4445   virtual void RequestNetworkScan() {}
GetWifiAccessPoints(WifiAccessPointVector * result)4446   virtual bool GetWifiAccessPoints(WifiAccessPointVector* result) {
4447     return false;
4448   }
4449 
ConnectToWifiNetwork(WifiNetwork * network)4450   virtual void ConnectToWifiNetwork(WifiNetwork* network) {}
ConnectToWifiNetwork(const std::string & service_path)4451   virtual void ConnectToWifiNetwork(const std::string& service_path) {}
ConnectToWifiNetwork(ConnectionSecurity security,const std::string & ssid,const std::string & passphrase,const std::string & identity,const std::string & certpath)4452   virtual void ConnectToWifiNetwork(ConnectionSecurity security,
4453                                     const std::string& ssid,
4454                                     const std::string& passphrase,
4455                                     const std::string& identity,
4456                                     const std::string& certpath) {}
ConnectToCellularNetwork(CellularNetwork * network)4457   virtual void ConnectToCellularNetwork(CellularNetwork* network) {}
ConnectToVirtualNetwork(VirtualNetwork * network)4458   virtual void ConnectToVirtualNetwork(VirtualNetwork* network) {}
ConnectToVirtualNetworkPSK(const std::string & service_name,const std::string & server,const std::string & psk,const std::string & username,const std::string & user_passphrase)4459   virtual void ConnectToVirtualNetworkPSK(
4460       const std::string& service_name,
4461       const std::string& server,
4462       const std::string& psk,
4463       const std::string& username,
4464       const std::string& user_passphrase) {}
SignalCellularPlanPayment()4465   virtual void SignalCellularPlanPayment() {}
HasRecentCellularPlanPayment()4466   virtual bool HasRecentCellularPlanPayment() { return false; }
DisconnectFromNetwork(const Network * network)4467   virtual void DisconnectFromNetwork(const Network* network) {}
ForgetWifiNetwork(const std::string & service_path)4468   virtual void ForgetWifiNetwork(const std::string& service_path) {}
GetCellularHomeCarrierId() const4469   virtual std::string GetCellularHomeCarrierId() const { return std::string(); }
ethernet_available() const4470   virtual bool ethernet_available() const { return true; }
wifi_available() const4471   virtual bool wifi_available() const { return false; }
cellular_available() const4472   virtual bool cellular_available() const { return false; }
ethernet_enabled() const4473   virtual bool ethernet_enabled() const { return true; }
wifi_enabled() const4474   virtual bool wifi_enabled() const { return false; }
cellular_enabled() const4475   virtual bool cellular_enabled() const { return false; }
wifi_scanning() const4476   virtual bool wifi_scanning() const { return false; }
active_network() const4477   virtual const Network* active_network() const { return NULL; }
connected_network() const4478   virtual const Network* connected_network() const { return NULL; }
offline_mode() const4479   virtual bool offline_mode() const { return false; }
EnableEthernetNetworkDevice(bool enable)4480   virtual void EnableEthernetNetworkDevice(bool enable) {}
EnableWifiNetworkDevice(bool enable)4481   virtual void EnableWifiNetworkDevice(bool enable) {}
EnableCellularNetworkDevice(bool enable)4482   virtual void EnableCellularNetworkDevice(bool enable) {}
EnableOfflineMode(bool enable)4483   virtual void EnableOfflineMode(bool enable) {}
GetIPConfigs(const std::string & device_path,std::string * hardware_address,HardwareAddressFormat)4484   virtual NetworkIPConfigVector GetIPConfigs(const std::string& device_path,
4485                                              std::string* hardware_address,
4486                                              HardwareAddressFormat) {
4487     hardware_address->clear();
4488     return NetworkIPConfigVector();
4489   }
4490 
4491  private:
4492   std::string ip_address_;
4493   EthernetNetwork* ethernet_;
4494   WifiNetwork* active_wifi_;
4495   CellularNetwork* active_cellular_;
4496   VirtualNetwork* active_virtual_;
4497   WifiNetworkVector wifi_networks_;
4498   CellularNetworkVector cellular_networks_;
4499   VirtualNetworkVector virtual_networks_;
4500 };
4501 
4502 // static
GetImpl(bool stub)4503 NetworkLibrary* NetworkLibrary::GetImpl(bool stub) {
4504   if (stub)
4505     return new NetworkLibraryStubImpl();
4506   else
4507     return new NetworkLibraryImpl();
4508 }
4509 
4510 }  // namespace chromeos
4511 
4512 // Allows InvokeLater without adding refcounting. This class is a Singleton and
4513 // won't be deleted until it's last InvokeLater is run.
4514 DISABLE_RUNNABLE_METHOD_REFCOUNT(chromeos::NetworkLibraryImpl);
4515