• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "ash/system/chromeos/network/network_connect.h"
6 
7 #include "ash/session/session_state_delegate.h"
8 #include "ash/shell.h"
9 #include "ash/system/chromeos/network/network_state_notifier.h"
10 #include "ash/system/system_notifier.h"
11 #include "ash/system/tray/system_tray_delegate.h"
12 #include "ash/system/tray/system_tray_notifier.h"
13 #include "base/bind.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/strings/string_util.h"
16 #include "base/strings/utf_string_conversions.h"
17 #include "base/values.h"
18 #include "chromeos/login/login_state.h"
19 #include "chromeos/network/device_state.h"
20 #include "chromeos/network/network_activation_handler.h"
21 #include "chromeos/network/network_configuration_handler.h"
22 #include "chromeos/network/network_connection_handler.h"
23 #include "chromeos/network/network_event_log.h"
24 #include "chromeos/network/network_handler_callbacks.h"
25 #include "chromeos/network/network_profile.h"
26 #include "chromeos/network/network_profile_handler.h"
27 #include "chromeos/network/network_state.h"
28 #include "chromeos/network/network_state_handler.h"
29 #include "grit/ash_resources.h"
30 #include "grit/ash_strings.h"
31 #include "third_party/cros_system_api/dbus/service_constants.h"
32 #include "ui/base/l10n/l10n_util.h"
33 #include "ui/base/resource/resource_bundle.h"
34 #include "ui/message_center/message_center.h"
35 #include "ui/message_center/notification.h"
36 
37 using chromeos::DeviceState;
38 using chromeos::NetworkConfigurationHandler;
39 using chromeos::NetworkConnectionHandler;
40 using chromeos::NetworkHandler;
41 using chromeos::NetworkProfile;
42 using chromeos::NetworkProfileHandler;
43 using chromeos::NetworkState;
44 using chromeos::NetworkStateHandler;
45 using chromeos::NetworkTypePattern;
46 
47 namespace ash {
48 
49 namespace {
50 
51 // TODO(stevenjb): This should be in service_constants.h
52 const char kErrorInProgress[] = "org.chromium.flimflam.Error.InProgress";
53 
54 // Returns true for carriers that can be activated through Shill instead of
55 // through a WebUI dialog.
IsDirectActivatedCarrier(const std::string & carrier)56 bool IsDirectActivatedCarrier(const std::string& carrier) {
57   if (carrier == shill::kCarrierSprint)
58     return true;
59   return false;
60 }
61 
ShowErrorNotification(const std::string & error_name,const std::string & service_path)62 void ShowErrorNotification(const std::string& error_name,
63                            const std::string& service_path) {
64   Shell::GetInstance()->system_tray_notifier()->network_state_notifier()->
65       ShowNetworkConnectError(error_name, service_path);
66 }
67 
HandleUnconfiguredNetwork(const std::string & service_path)68 void HandleUnconfiguredNetwork(const std::string& service_path) {
69   const NetworkState* network = NetworkHandler::Get()->network_state_handler()->
70       GetNetworkState(service_path);
71   if (!network) {
72     NET_LOG_ERROR("Configuring unknown network", service_path);
73     return;
74   }
75 
76   if (network->type() == shill::kTypeWifi) {
77     // Only show the config view for secure networks, otherwise do nothing.
78     if (network->security() != shill::kSecurityNone) {
79       ash::Shell::GetInstance()->system_tray_delegate()->
80           ShowNetworkConfigure(service_path);
81     }
82     return;
83   }
84 
85   if (network->type() == shill::kTypeWimax ||
86       network->type() == shill::kTypeVPN) {
87     ash::Shell::GetInstance()->system_tray_delegate()->
88         ShowNetworkConfigure(service_path);
89     return;
90   }
91 
92   if (network->type() == shill::kTypeCellular) {
93     if (network->RequiresActivation()) {
94       ash::network_connect::ActivateCellular(service_path);
95       return;
96     }
97     if (network->cellular_out_of_credits()) {
98       ash::network_connect::ShowMobileSetup(service_path);
99       return;
100     }
101     // No special configure or setup for |network|, show the settings UI.
102     if (chromeos::LoginState::Get()->IsUserLoggedIn()) {
103       ash::Shell::GetInstance()->system_tray_delegate()->
104           ShowNetworkSettings(service_path);
105     }
106     return;
107   }
108   NOTREACHED();
109 }
110 
111 // If |shared| is true, sets |profile_path| to the shared profile path.
112 // Otherwise sets |profile_path| to the user profile path if authenticated and
113 // available. Returns 'false' if unable to set |profile_path|.
GetNetworkProfilePath(bool shared,std::string * profile_path)114 bool GetNetworkProfilePath(bool shared, std::string* profile_path) {
115   if (shared) {
116     *profile_path = NetworkProfileHandler::GetSharedProfilePath();
117     return true;
118   }
119 
120   if (!chromeos::LoginState::Get()->UserHasNetworkProfile()) {
121     NET_LOG_ERROR("User profile specified before login", "");
122     return false;
123   }
124 
125   const NetworkProfile* profile  =
126       NetworkHandler::Get()->network_profile_handler()->
127       GetDefaultUserProfile();
128   if (!profile) {
129     NET_LOG_ERROR("No user profile for unshared network configuration", "");
130     return false;
131   }
132 
133   *profile_path = profile->path;
134   return true;
135 }
136 
OnConnectFailed(const std::string & service_path,const std::string & error_name,scoped_ptr<base::DictionaryValue> error_data)137 void OnConnectFailed(const std::string& service_path,
138                      const std::string& error_name,
139                      scoped_ptr<base::DictionaryValue> error_data) {
140   NET_LOG_ERROR("Connect Failed: " + error_name, service_path);
141 
142   if (!ash::Shell::HasInstance())
143     return;
144 
145   // If a new connect attempt canceled this connect, no need to notify the user.
146   if (error_name == NetworkConnectionHandler::kErrorConnectCanceled)
147     return;
148 
149   if (error_name == shill::kErrorBadPassphrase ||
150       error_name == NetworkConnectionHandler::kErrorPassphraseRequired ||
151       error_name == NetworkConnectionHandler::kErrorConfigurationRequired ||
152       error_name == NetworkConnectionHandler::kErrorAuthenticationRequired) {
153     HandleUnconfiguredNetwork(service_path);
154     return;
155   }
156 
157   if (error_name == NetworkConnectionHandler::kErrorCertificateRequired) {
158     if (!ash::Shell::GetInstance()->system_tray_delegate()->EnrollNetwork(
159             service_path)) {
160       HandleUnconfiguredNetwork(service_path);
161     }
162     return;
163   }
164 
165   if (error_name == NetworkConnectionHandler::kErrorActivationRequired) {
166     network_connect::ActivateCellular(service_path);
167     return;
168   }
169 
170   if (error_name == NetworkConnectionHandler::kErrorConnected ||
171       error_name == NetworkConnectionHandler::kErrorConnecting) {
172     network_connect::ShowNetworkSettings(service_path);
173     return;
174   }
175 
176   // ConnectFailed or unknown error; show a notification.
177   ShowErrorNotification(error_name, service_path);
178 
179   // Only show a configure dialog if there was a ConnectFailed error and the
180   // screen is not locked.
181   if (error_name != shill::kErrorConnectFailed ||
182       Shell::GetInstance()->session_state_delegate()->IsScreenLocked())
183     return;
184 
185   // If Shill reports an InProgress error, don't try to configure the network.
186   std::string dbus_error_name;
187   error_data.get()->GetString(
188       chromeos::network_handler::kDbusErrorName, &dbus_error_name);
189   if (dbus_error_name == kErrorInProgress)
190     return;
191 
192   HandleUnconfiguredNetwork(service_path);
193 }
194 
OnConnectSucceeded(const std::string & service_path)195 void OnConnectSucceeded(const std::string& service_path) {
196   NET_LOG_USER("Connect Succeeded", service_path);
197   if (!ash::Shell::HasInstance())
198     return;
199   message_center::MessageCenter::Get()->RemoveNotification(
200       network_connect::kNetworkConnectNotificationId, false /* not by user */);
201 }
202 
203 // If |check_error_state| is true, error state for the network is checked,
204 // otherwise any current error state is ignored (e.g. for recently configured
205 // networks or repeat connect attempts).
CallConnectToNetwork(const std::string & service_path,bool check_error_state)206 void CallConnectToNetwork(const std::string& service_path,
207                           bool check_error_state) {
208   if (!ash::Shell::HasInstance())
209     return;
210   message_center::MessageCenter::Get()->RemoveNotification(
211       network_connect::kNetworkConnectNotificationId, false /* not by user */);
212 
213   NetworkHandler::Get()->network_connection_handler()->ConnectToNetwork(
214       service_path,
215       base::Bind(&OnConnectSucceeded, service_path),
216       base::Bind(&OnConnectFailed, service_path),
217       check_error_state);
218 }
219 
OnActivateFailed(const std::string & service_path,const std::string & error_name,scoped_ptr<base::DictionaryValue> error_data)220 void OnActivateFailed(const std::string& service_path,
221                       const std::string& error_name,
222                       scoped_ptr<base::DictionaryValue> error_data) {
223   NET_LOG_ERROR("Unable to activate network", service_path);
224   ShowErrorNotification(network_connect::kErrorActivateFailed, service_path);
225 }
226 
OnActivateSucceeded(const std::string & service_path)227 void OnActivateSucceeded(const std::string& service_path) {
228   NET_LOG_USER("Activation Succeeded", service_path);
229 }
230 
OnConfigureFailed(const std::string & error_name,scoped_ptr<base::DictionaryValue> error_data)231 void OnConfigureFailed(const std::string& error_name,
232                        scoped_ptr<base::DictionaryValue> error_data) {
233   NET_LOG_ERROR("Unable to configure network", "");
234   ShowErrorNotification(NetworkConnectionHandler::kErrorConfigureFailed, "");
235 }
236 
OnConfigureSucceeded(bool connect_on_configure,const std::string & service_path)237 void OnConfigureSucceeded(bool connect_on_configure,
238                           const std::string& service_path) {
239   NET_LOG_USER("Configure Succeeded", service_path);
240   if (!connect_on_configure)
241     return;
242   // After configuring a network, ignore any (possibly stale) error state.
243   const bool check_error_state = false;
244   CallConnectToNetwork(service_path, check_error_state);
245 }
246 
CallCreateConfiguration(base::DictionaryValue * properties,bool shared,bool connect_on_configure)247 void CallCreateConfiguration(base::DictionaryValue* properties,
248                              bool shared,
249                              bool connect_on_configure) {
250   std::string profile_path;
251   if (!GetNetworkProfilePath(shared, &profile_path)) {
252     ShowErrorNotification(NetworkConnectionHandler::kErrorConfigureFailed, "");
253     return;
254   }
255   properties->SetStringWithoutPathExpansion(
256       shill::kProfileProperty, profile_path);
257   NetworkHandler::Get()->network_configuration_handler()->CreateConfiguration(
258       *properties,
259       base::Bind(&OnConfigureSucceeded, connect_on_configure),
260       base::Bind(&OnConfigureFailed));
261 }
262 
SetPropertiesFailed(const std::string & desc,const std::string & service_path,const std::string & config_error_name,scoped_ptr<base::DictionaryValue> error_data)263 void SetPropertiesFailed(const std::string& desc,
264                          const std::string& service_path,
265                          const std::string& config_error_name,
266                          scoped_ptr<base::DictionaryValue> error_data) {
267   NET_LOG_ERROR(desc + ": Failed: " + config_error_name, service_path);
268   ShowErrorNotification(
269       NetworkConnectionHandler::kErrorConfigureFailed, service_path);
270 }
271 
SetPropertiesToClear(base::DictionaryValue * properties_to_set,std::vector<std::string> * properties_to_clear)272 void SetPropertiesToClear(base::DictionaryValue* properties_to_set,
273                           std::vector<std::string>* properties_to_clear) {
274   // Move empty string properties to properties_to_clear.
275   for (base::DictionaryValue::Iterator iter(*properties_to_set);
276        !iter.IsAtEnd(); iter.Advance()) {
277     std::string value_str;
278     if (iter.value().GetAsString(&value_str) && value_str.empty())
279       properties_to_clear->push_back(iter.key());
280   }
281   // Remove cleared properties from properties_to_set.
282   for (std::vector<std::string>::iterator iter = properties_to_clear->begin();
283        iter != properties_to_clear->end(); ++iter) {
284     properties_to_set->RemoveWithoutPathExpansion(*iter, NULL);
285   }
286 }
287 
ClearPropertiesAndConnect(const std::string & service_path,const std::vector<std::string> & properties_to_clear)288 void ClearPropertiesAndConnect(
289     const std::string& service_path,
290     const std::vector<std::string>& properties_to_clear) {
291   NET_LOG_USER("ClearPropertiesAndConnect", service_path);
292   // After configuring a network, ignore any (possibly stale) error state.
293   const bool check_error_state = false;
294   NetworkHandler::Get()->network_configuration_handler()->ClearProperties(
295       service_path,
296       properties_to_clear,
297       base::Bind(&CallConnectToNetwork,
298                  service_path, check_error_state),
299       base::Bind(&SetPropertiesFailed, "ClearProperties", service_path));
300 }
301 
ConfigureSetProfileSucceeded(const std::string & service_path,scoped_ptr<base::DictionaryValue> properties_to_set)302 void ConfigureSetProfileSucceeded(
303     const std::string& service_path,
304     scoped_ptr<base::DictionaryValue> properties_to_set) {
305   std::vector<std::string> properties_to_clear;
306   SetPropertiesToClear(properties_to_set.get(), &properties_to_clear);
307   NetworkHandler::Get()->network_configuration_handler()->SetProperties(
308       service_path,
309       *properties_to_set,
310       base::Bind(&ClearPropertiesAndConnect,
311                  service_path,
312                  properties_to_clear),
313       base::Bind(&SetPropertiesFailed, "SetProperties", service_path));
314 }
315 
GetNetworkState(const std::string & service_path)316 const NetworkState* GetNetworkState(const std::string& service_path) {
317   return NetworkHandler::Get()->network_state_handler()->
318       GetNetworkState(service_path);
319 }
320 
321 }  // namespace
322 
323 namespace network_connect {
324 
325 const char kNetworkConnectNotificationId[] =
326     "chrome://settings/internet/connect";
327 const char kNetworkActivateNotificationId[] =
328     "chrome://settings/internet/activate";
329 
330 const char kErrorActivateFailed[] = "activate-failed";
331 
ConnectToNetwork(const std::string & service_path)332 void ConnectToNetwork(const std::string& service_path) {
333   NET_LOG_USER("ConnectToNetwork", service_path);
334   const NetworkState* network = GetNetworkState(service_path);
335   if (network) {
336     if (!network->error().empty() && !network->security().empty()) {
337       NET_LOG_USER("Configure: " + network->error(), service_path);
338       // If the network is in an error state, show the configuration UI directly
339       // to avoid a spurious notification.
340       HandleUnconfiguredNetwork(service_path);
341       return;
342     } else if (network->RequiresActivation()) {
343       ActivateCellular(service_path);
344       return;
345     }
346   }
347   const bool check_error_state = true;
348   CallConnectToNetwork(service_path, check_error_state);
349 }
350 
SetTechnologyEnabled(const NetworkTypePattern & technology,bool enabled_state)351 void SetTechnologyEnabled(const NetworkTypePattern& technology,
352                           bool enabled_state) {
353   std::string log_string =
354       base::StringPrintf("technology %s, target state: %s",
355                          technology.ToDebugString().c_str(),
356                          (enabled_state ? "ENABLED" : "DISABLED"));
357   NET_LOG_USER("SetTechnologyEnabled", log_string);
358   NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
359   bool enabled = handler->IsTechnologyEnabled(technology);
360   if (enabled_state == enabled) {
361     NET_LOG_USER("Technology already in target state.", log_string);
362     return;
363   }
364   if (enabled) {
365     // User requested to disable the technology.
366     handler->SetTechnologyEnabled(
367         technology, false, chromeos::network_handler::ErrorCallback());
368     return;
369   }
370   // If we're dealing with a mobile network, then handle SIM lock here.
371   // SIM locking only applies to cellular, so the code below won't execute
372   // if |technology| has been explicitly set to WiMAX.
373   if (technology.MatchesPattern(NetworkTypePattern::Mobile())) {
374     const DeviceState* mobile = handler->GetDeviceStateByType(technology);
375     if (!mobile) {
376       NET_LOG_ERROR("SetTechnologyEnabled with no device", log_string);
377       return;
378     }
379     // The following only applies to cellular.
380     if (mobile->type() == shill::kTypeCellular) {
381       if (mobile->IsSimAbsent()) {
382         // If this is true, then we have a cellular device with no SIM inserted.
383         // TODO(armansito): Chrome should display a notification here, prompting
384         // the user to insert a SIM card and restart the device to enable
385         // cellular. See crbug.com/125171.
386         NET_LOG_USER("Cannot enable cellular device without SIM.", log_string);
387         return;
388       }
389       if (!mobile->sim_lock_type().empty()) {
390         // A SIM has been inserted, but it is locked. Let the user unlock it
391         // via the dialog.
392         ash::Shell::GetInstance()->system_tray_delegate()->
393             ShowMobileSimDialog();
394         return;
395       }
396     }
397   }
398   handler->SetTechnologyEnabled(
399     technology, true, chromeos::network_handler::ErrorCallback());
400 }
401 
ActivateCellular(const std::string & service_path)402 void ActivateCellular(const std::string& service_path) {
403   NET_LOG_USER("ActivateCellular", service_path);
404   const NetworkState* cellular = GetNetworkState(service_path);
405   if (!cellular || cellular->type() != shill::kTypeCellular) {
406     NET_LOG_ERROR("ActivateCellular with no Service", service_path);
407     return;
408   }
409   const DeviceState* cellular_device =
410       NetworkHandler::Get()->network_state_handler()->
411       GetDeviceState(cellular->device_path());
412   if (!cellular_device) {
413     NET_LOG_ERROR("ActivateCellular with no Device", service_path);
414     return;
415   }
416   if (!IsDirectActivatedCarrier(cellular_device->carrier())) {
417     // For non direct activation, show the mobile setup dialog which can be
418     // used to activate the network.
419     ShowMobileSetup(service_path);
420     return;
421   }
422   if (cellular->activation_state() == shill::kActivationStateActivated) {
423     NET_LOG_ERROR("ActivateCellular for activated service", service_path);
424     return;
425   }
426 
427   NetworkHandler::Get()->network_activation_handler()->Activate(
428       service_path,
429       "",  // carrier
430       base::Bind(&OnActivateSucceeded, service_path),
431       base::Bind(&OnActivateFailed, service_path));
432 }
433 
ShowMobileSetup(const std::string & service_path)434 void ShowMobileSetup(const std::string& service_path) {
435   NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
436   const NetworkState* cellular = handler->GetNetworkState(service_path);
437   if (!cellular || cellular->type() != shill::kTypeCellular) {
438     NET_LOG_ERROR("ShowMobileSetup without Cellular network", service_path);
439     return;
440   }
441   if (cellular->activation_state() != shill::kActivationStateActivated &&
442       cellular->activation_type() == shill::kActivationTypeNonCellular &&
443       !handler->DefaultNetwork()) {
444     message_center::MessageCenter::Get()->AddNotification(
445         message_center::Notification::CreateSystemNotification(
446             kNetworkActivateNotificationId,
447             l10n_util::GetStringUTF16(IDS_NETWORK_ACTIVATION_ERROR_TITLE),
448             l10n_util::GetStringFUTF16(IDS_NETWORK_ACTIVATION_NEEDS_CONNECTION,
449                                        base::UTF8ToUTF16(cellular->name())),
450             ui::ResourceBundle::GetSharedInstance().GetImageNamed(
451                 IDR_AURA_UBER_TRAY_CELLULAR_NETWORK_FAILED),
452             ash::system_notifier::kNotifierNetworkError,
453             base::Bind(&ash::network_connect::ShowNetworkSettings,
454                        service_path)));
455     return;
456   }
457   ash::Shell::GetInstance()->system_tray_delegate()->ShowMobileSetupDialog(
458       service_path);
459 }
460 
ConfigureNetworkAndConnect(const std::string & service_path,const base::DictionaryValue & properties,bool shared)461 void ConfigureNetworkAndConnect(const std::string& service_path,
462                                 const base::DictionaryValue& properties,
463                                 bool shared) {
464   NET_LOG_USER("ConfigureNetworkAndConnect", service_path);
465 
466   scoped_ptr<base::DictionaryValue> properties_to_set(properties.DeepCopy());
467 
468   std::string profile_path;
469   if (!GetNetworkProfilePath(shared, &profile_path)) {
470     ShowErrorNotification(
471         NetworkConnectionHandler::kErrorConfigureFailed, service_path);
472     return;
473   }
474   NetworkHandler::Get()->network_configuration_handler()->SetNetworkProfile(
475       service_path, profile_path,
476       base::Bind(&ConfigureSetProfileSucceeded,
477                  service_path, base::Passed(&properties_to_set)),
478       base::Bind(&SetPropertiesFailed,
479                  "SetProfile: " + profile_path, service_path));
480 }
481 
CreateConfigurationAndConnect(base::DictionaryValue * properties,bool shared)482 void CreateConfigurationAndConnect(base::DictionaryValue* properties,
483                                    bool shared) {
484   NET_LOG_USER("CreateConfigurationAndConnect", "");
485   CallCreateConfiguration(properties, shared, true /* connect_on_configure */);
486 }
487 
CreateConfiguration(base::DictionaryValue * properties,bool shared)488 void CreateConfiguration(base::DictionaryValue* properties, bool shared) {
489   NET_LOG_USER("CreateConfiguration", "");
490   CallCreateConfiguration(properties, shared, false /* connect_on_configure */);
491 }
492 
ErrorString(const std::string & error,const std::string & service_path)493 base::string16 ErrorString(const std::string& error,
494                      const std::string& service_path) {
495   if (error.empty())
496     return base::string16();
497   if (error == shill::kErrorOutOfRange)
498     return l10n_util::GetStringUTF16(IDS_CHROMEOS_NETWORK_ERROR_OUT_OF_RANGE);
499   if (error == shill::kErrorPinMissing)
500     return l10n_util::GetStringUTF16(IDS_CHROMEOS_NETWORK_ERROR_PIN_MISSING);
501   if (error == shill::kErrorDhcpFailed)
502     return l10n_util::GetStringUTF16(IDS_CHROMEOS_NETWORK_ERROR_DHCP_FAILED);
503   if (error == shill::kErrorConnectFailed)
504     return l10n_util::GetStringUTF16(IDS_CHROMEOS_NETWORK_ERROR_CONNECT_FAILED);
505   if (error == shill::kErrorBadPassphrase)
506     return l10n_util::GetStringUTF16(IDS_CHROMEOS_NETWORK_ERROR_BAD_PASSPHRASE);
507   if (error == shill::kErrorBadWEPKey)
508     return l10n_util::GetStringUTF16(IDS_CHROMEOS_NETWORK_ERROR_BAD_WEPKEY);
509   if (error == shill::kErrorActivationFailed) {
510     return l10n_util::GetStringUTF16(
511         IDS_CHROMEOS_NETWORK_ERROR_ACTIVATION_FAILED);
512   }
513   if (error == shill::kErrorNeedEvdo)
514     return l10n_util::GetStringUTF16(IDS_CHROMEOS_NETWORK_ERROR_NEED_EVDO);
515   if (error == shill::kErrorNeedHomeNetwork) {
516     return l10n_util::GetStringUTF16(
517         IDS_CHROMEOS_NETWORK_ERROR_NEED_HOME_NETWORK);
518   }
519   if (error == shill::kErrorOtaspFailed)
520     return l10n_util::GetStringUTF16(IDS_CHROMEOS_NETWORK_ERROR_OTASP_FAILED);
521   if (error == shill::kErrorAaaFailed)
522     return l10n_util::GetStringUTF16(IDS_CHROMEOS_NETWORK_ERROR_AAA_FAILED);
523   if (error == shill::kErrorInternal)
524     return l10n_util::GetStringUTF16(IDS_CHROMEOS_NETWORK_ERROR_INTERNAL);
525   if (error == shill::kErrorDNSLookupFailed) {
526     return l10n_util::GetStringUTF16(
527         IDS_CHROMEOS_NETWORK_ERROR_DNS_LOOKUP_FAILED);
528   }
529   if (error == shill::kErrorHTTPGetFailed) {
530     return l10n_util::GetStringUTF16(
531         IDS_CHROMEOS_NETWORK_ERROR_HTTP_GET_FAILED);
532   }
533   if (error == shill::kErrorIpsecPskAuthFailed) {
534     return l10n_util::GetStringUTF16(
535         IDS_CHROMEOS_NETWORK_ERROR_IPSEC_PSK_AUTH_FAILED);
536   }
537   if (error == shill::kErrorIpsecCertAuthFailed) {
538     return l10n_util::GetStringUTF16(
539         IDS_CHROMEOS_NETWORK_ERROR_CERT_AUTH_FAILED);
540   }
541   if (error == shill::kErrorEapAuthenticationFailed) {
542     const NetworkState* network = GetNetworkState(service_path);
543     // TLS always requires a client certificate, so show a cert auth
544     // failed message for TLS. Other EAP methods do not generally require
545     // a client certicate.
546     if (network && network->eap_method() == shill::kEapMethodTLS) {
547       return l10n_util::GetStringUTF16(
548           IDS_CHROMEOS_NETWORK_ERROR_CERT_AUTH_FAILED);
549     } else {
550       return l10n_util::GetStringUTF16(
551           IDS_CHROMEOS_NETWORK_ERROR_EAP_AUTH_FAILED);
552     }
553   }
554   if (error == shill::kErrorEapLocalTlsFailed) {
555     return l10n_util::GetStringUTF16(
556         IDS_CHROMEOS_NETWORK_ERROR_EAP_LOCAL_TLS_FAILED);
557   }
558   if (error == shill::kErrorEapRemoteTlsFailed) {
559     return l10n_util::GetStringUTF16(
560         IDS_CHROMEOS_NETWORK_ERROR_EAP_REMOTE_TLS_FAILED);
561   }
562   if (error == shill::kErrorPppAuthFailed) {
563     return l10n_util::GetStringUTF16(
564         IDS_CHROMEOS_NETWORK_ERROR_PPP_AUTH_FAILED);
565   }
566 
567   if (base::StringToLowerASCII(error) ==
568       base::StringToLowerASCII(std::string(shill::kUnknownString))) {
569     return l10n_util::GetStringUTF16(IDS_CHROMEOS_NETWORK_ERROR_UNKNOWN);
570   }
571   return l10n_util::GetStringFUTF16(IDS_NETWORK_UNRECOGNIZED_ERROR,
572                                     base::UTF8ToUTF16(error));
573 }
574 
ShowNetworkSettings(const std::string & service_path)575 void ShowNetworkSettings(const std::string& service_path) {
576   if (!ash::Shell::HasInstance())
577     return;
578   ash::Shell::GetInstance()->system_tray_delegate()->ShowNetworkSettings(
579       service_path);
580 }
581 
582 }  // network_connect
583 }  // ash
584