Home | History | Annotate | Download | only in network
      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.
     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   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|.
    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 
    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 
    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).
    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 
    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 
    227 void OnActivateSucceeded(const std::string& service_path) {
    228   NET_LOG_USER("Activation Succeeded", service_path);
    229 }
    230 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    482 void CreateConfigurationAndConnect(base::DictionaryValue* properties,
    483                                    bool shared) {
    484   NET_LOG_USER("CreateConfigurationAndConnect", "");
    485   CallCreateConfiguration(properties, shared, true /* connect_on_configure */);
    486 }
    487 
    488 void CreateConfiguration(base::DictionaryValue* properties, bool shared) {
    489   NET_LOG_USER("CreateConfiguration", "");
    490   CallCreateConfiguration(properties, shared, false /* connect_on_configure */);
    491 }
    492 
    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 
    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