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