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