Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ash/system/chromeos/network/network_state_notifier.h" | 5 #include "ash/system/chromeos/network/network_state_notifier.h" |
| 6 | 6 |
| 7 #include "ash/shell.h" | 7 #include "ash/shell.h" |
| 8 #include "ash/system/chromeos/network/network_connect.h" | 8 #include "ash/system/chromeos/network/network_connect.h" |
| 9 #include "ash/system/chromeos/network/network_observer.h" | 9 #include "ash/system/tray/system_tray_delegate.h" |
| 10 #include "ash/system/tray/system_tray_notifier.h" | |
| 11 #include "base/strings/string16.h" | 10 #include "base/strings/string16.h" |
| 12 #include "base/strings/string_util.h" | 11 #include "base/strings/string_util.h" |
| 13 #include "base/strings/utf_string_conversions.h" | 12 #include "base/strings/utf_string_conversions.h" |
| 14 #include "chromeos/network/network_configuration_handler.h" | 13 #include "chromeos/network/network_configuration_handler.h" |
| 15 #include "chromeos/network/network_connection_handler.h" | 14 #include "chromeos/network/network_connection_handler.h" |
| 16 #include "chromeos/network/network_event_log.h" | 15 #include "chromeos/network/network_event_log.h" |
| 17 #include "chromeos/network/network_state.h" | 16 #include "chromeos/network/network_state.h" |
| 18 #include "chromeos/network/network_state_handler.h" | 17 #include "chromeos/network/network_state_handler.h" |
| 18 #include "grit/ash_resources.h" | |
| 19 #include "grit/ash_strings.h" | 19 #include "grit/ash_strings.h" |
| 20 #include "third_party/cros_system_api/dbus/service_constants.h" | 20 #include "third_party/cros_system_api/dbus/service_constants.h" |
| 21 #include "ui/base/l10n/l10n_util.h" | 21 #include "ui/base/l10n/l10n_util.h" |
| 22 #include "ui/base/resource/resource_bundle.h" | |
| 23 #include "ui/message_center/message_center.h" | |
| 24 #include "ui/message_center/notification.h" | |
| 22 | 25 |
| 23 using chromeos::NetworkConnectionHandler; | 26 using chromeos::NetworkConnectionHandler; |
| 24 using chromeos::NetworkHandler; | 27 using chromeos::NetworkHandler; |
| 25 using chromeos::NetworkState; | 28 using chromeos::NetworkState; |
| 26 using chromeos::NetworkStateHandler; | 29 using chromeos::NetworkStateHandler; |
| 27 | 30 |
| 28 namespace { | 31 namespace { |
| 29 | 32 |
| 33 const char kNetworkOutOfCreditsNotificationId[] = | |
| 34 "chrome://settings/internet/out-of-credits"; | |
| 35 | |
| 30 const int kMinTimeBetweenOutOfCreditsNotifySeconds = 10 * 60; | 36 const int kMinTimeBetweenOutOfCreditsNotifySeconds = 10 * 60; |
| 31 | 37 |
| 32 // Error messages based on |error_name|, not network_state->error(). | 38 // Error messages based on |error_name|, not network_state->error(). |
| 33 string16 GetConnectErrorString(const std::string& error_name) { | 39 string16 GetConnectErrorString(const std::string& error_name) { |
| 34 if (error_name == NetworkConnectionHandler::kErrorNotFound) | 40 if (error_name == NetworkConnectionHandler::kErrorNotFound) |
| 35 return l10n_util::GetStringUTF16(IDS_CHROMEOS_NETWORK_ERROR_CONNECT_FAILED); | 41 return l10n_util::GetStringUTF16(IDS_CHROMEOS_NETWORK_ERROR_CONNECT_FAILED); |
| 36 if (error_name == NetworkConnectionHandler::kErrorConfigureFailed) | 42 if (error_name == NetworkConnectionHandler::kErrorConfigureFailed) |
| 37 return l10n_util::GetStringUTF16( | 43 return l10n_util::GetStringUTF16( |
| 38 IDS_CHROMEOS_NETWORK_ERROR_CONFIGURE_FAILED); | 44 IDS_CHROMEOS_NETWORK_ERROR_CONFIGURE_FAILED); |
| 39 if (error_name == NetworkConnectionHandler::kErrorActivateFailed) | 45 if (error_name == NetworkConnectionHandler::kErrorActivateFailed) |
| 40 return l10n_util::GetStringUTF16( | 46 return l10n_util::GetStringUTF16( |
| 41 IDS_CHROMEOS_NETWORK_ERROR_ACTIVATION_FAILED); | 47 IDS_CHROMEOS_NETWORK_ERROR_ACTIVATION_FAILED); |
| 42 return string16(); | 48 return string16(); |
| 43 } | 49 } |
| 44 | 50 |
| 51 void ShowErrorNotification(const std::string& notification_id, | |
| 52 const std::string& service_path, | |
| 53 const std::string& network_type, | |
| 54 const base::string16& title, | |
| 55 const base::string16& message, | |
| 56 const base::Closure& callback) { | |
| 57 int icon_id = (network_type == flimflam::kTypeCellular) ? | |
| 58 IDR_AURA_UBER_TRAY_CELLULAR_NETWORK_FAILED : | |
| 59 IDR_AURA_UBER_TRAY_NETWORK_FAILED; | |
| 60 const gfx::Image& icon = | |
| 61 ui::ResourceBundle::GetSharedInstance().GetImageNamed(icon_id); | |
| 62 message_center::MessageCenter::Get()->AddNotification( | |
| 63 message_center::Notification::CreateSystemNotification( | |
| 64 notification_id, title, message, icon, callback)); | |
| 65 } | |
| 66 | |
| 67 void ConfigureNetwork(const std::string& service_path) { | |
| 68 ash::Shell::GetInstance()->system_tray_delegate()->ConfigureNetwork( | |
| 69 service_path); | |
| 70 } | |
| 71 | |
| 45 } // namespace | 72 } // namespace |
| 46 | 73 |
| 47 namespace ash { | 74 namespace ash { |
| 48 | 75 |
| 49 NetworkStateNotifier::NetworkStateNotifier() | 76 NetworkStateNotifier::NetworkStateNotifier() |
| 50 : cellular_out_of_credits_(false), | 77 : did_show_out_of_credits_(false), |
| 51 weak_ptr_factory_(this) { | 78 weak_ptr_factory_(this) { |
| 52 if (!NetworkHandler::IsInitialized()) | 79 if (!NetworkHandler::IsInitialized()) |
| 53 return; | 80 return; |
| 54 NetworkHandler::Get()->network_state_handler()->AddObserver(this, FROM_HERE); | 81 NetworkHandler::Get()->network_state_handler()->AddObserver(this, FROM_HERE); |
| 55 | |
| 56 // Initialize |last_active_network_|. | |
| 57 const NetworkState* default_network = | |
| 58 NetworkHandler::Get()->network_state_handler()->DefaultNetwork(); | |
| 59 if (default_network && default_network->IsConnectedState()) | |
| 60 last_active_network_ = default_network->path(); | |
| 61 } | 82 } |
| 62 | 83 |
| 63 NetworkStateNotifier::~NetworkStateNotifier() { | 84 NetworkStateNotifier::~NetworkStateNotifier() { |
| 64 if (!NetworkHandler::IsInitialized()) | 85 if (!NetworkHandler::IsInitialized()) |
| 65 return; | 86 return; |
| 66 NetworkHandler::Get()->network_state_handler()->RemoveObserver( | 87 NetworkHandler::Get()->network_state_handler()->RemoveObserver( |
| 67 this, FROM_HERE); | 88 this, FROM_HERE); |
| 68 } | 89 } |
| 69 | 90 |
| 70 void NetworkStateNotifier::DefaultNetworkChanged(const NetworkState* network) { | 91 void NetworkStateNotifier::DefaultNetworkChanged(const NetworkState* network) { |
| 71 if (!network || !network->IsConnectedState()) | 92 if (network && network->type() != flimflam::kTypeCellular) { |
| 72 return; | 93 // Allow showing the out of credits notification (after a reasonable delay) |
| 73 if (network->path() != last_active_network_) { | 94 // if we connect to a non cellular network. |
| 74 last_active_network_ = network->path(); | 95 did_show_out_of_credits_ = false; |
| 75 // Reset state for new connected network | |
| 76 cellular_out_of_credits_ = false; | |
| 77 NetworkPropertiesUpdated(network); | |
| 78 } | 96 } |
| 79 } | 97 } |
| 80 | 98 |
| 81 void NetworkStateNotifier::NetworkPropertiesUpdated( | 99 void NetworkStateNotifier::NetworkPropertiesUpdated( |
| 82 const NetworkState* network) { | 100 const NetworkState* network) { |
| 83 // Trigger "Out of credits" notification if the cellular network is the most | 101 if (network->type() != flimflam::kTypeCellular) |
| 84 // recent default network (i.e. we have not switched to another network). | 102 return; |
| 85 if (network->type() == flimflam::kTypeCellular && | 103 UpdateCellularOutOfCredits(network); |
| 86 network->path() == last_active_network_) { | 104 UpdateCellularActivating(network); |
| 87 cellular_network_ = network->path(); | 105 } |
| 88 if (network->cellular_out_of_credits() && | 106 |
| 89 !cellular_out_of_credits_) { | 107 void NetworkStateNotifier::UpdateCellularOutOfCredits( |
| 90 cellular_out_of_credits_ = true; | 108 const NetworkState* cellular) { |
| 91 base::TimeDelta dtime = base::Time::Now() - out_of_credits_notify_time_; | 109 // Only display a notification if we are out of credits and have not |
| 92 if (dtime.InSeconds() > kMinTimeBetweenOutOfCreditsNotifySeconds) { | 110 // already shown a notification (or have since connected to another network). |
| 93 out_of_credits_notify_time_ = base::Time::Now(); | 111 if (!cellular->cellular_out_of_credits() || did_show_out_of_credits_) |
| 94 std::vector<string16> links; | 112 return; |
| 95 links.push_back( | 113 |
| 96 l10n_util::GetStringFUTF16(IDS_NETWORK_OUT_OF_CREDITS_LINK, | 114 // Only display a notification if this is the default network, and we are |
| 97 UTF8ToUTF16(network->name()))); | 115 // not connecting or waiting to connect to another network. |
| 98 ash::Shell::GetInstance()->system_tray_notifier()-> | 116 NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler(); |
| 99 NotifySetNetworkMessage( | 117 const NetworkState* default_network = handler->DefaultNetwork(); |
| 100 this, | 118 if (default_network && default_network != cellular) |
| 101 NetworkObserver::ERROR_OUT_OF_CREDITS, | 119 return; |
| 102 NetworkObserver::GetNetworkTypeForNetworkState(network), | 120 if (handler->ConnectingNetworkByType( |
| 103 l10n_util::GetStringUTF16(IDS_NETWORK_OUT_OF_CREDITS_TITLE), | 121 NetworkStateHandler::kMatchTypeNonVirtual) || |
| 104 l10n_util::GetStringUTF16(IDS_NETWORK_OUT_OF_CREDITS_BODY), | 122 NetworkHandler::Get()->network_connection_handler()-> |
| 105 links); | 123 HasPendingConnectRequest()) |
|
jennyz
2013/08/21 00:02:42
nit: indent at the beginning of the continuing lin
stevenjb
2013/08/21 17:38:49
I don't think there is a nice way to format this,
| |
| 106 } | 124 return; |
| 107 } | 125 |
| 126 // We are either connected to |cellular|, or not connected, and we are not | |
| 127 // connecting to any network. | |
| 128 did_show_out_of_credits_ = true; | |
| 129 base::TimeDelta dtime = base::Time::Now() - out_of_credits_notify_time_; | |
| 130 if (dtime.InSeconds() > kMinTimeBetweenOutOfCreditsNotifySeconds) { | |
| 131 out_of_credits_notify_time_ = base::Time::Now(); | |
| 132 string16 error_msg = l10n_util::GetStringFUTF16( | |
| 133 IDS_NETWORK_OUT_OF_CREDITS_BODY, | |
| 134 UTF8ToUTF16(cellular->name())); | |
| 135 ShowErrorNotification( | |
| 136 kNetworkOutOfCreditsNotificationId, | |
| 137 cellular->path(), | |
| 138 cellular->type(), | |
| 139 l10n_util::GetStringUTF16(IDS_NETWORK_OUT_OF_CREDITS_TITLE), | |
| 140 error_msg, | |
| 141 base::Bind(&ConfigureNetwork, cellular->path())); | |
| 108 } | 142 } |
| 109 } | 143 } |
| 110 | 144 |
| 111 void NetworkStateNotifier::NotificationLinkClicked( | 145 void NetworkStateNotifier::UpdateCellularActivating( |
| 112 NetworkObserver::MessageType message_type, | 146 const NetworkState* cellular) { |
| 113 size_t link_index) { | 147 // Keep track of any activating cellular network. |
| 114 if (message_type == NetworkObserver::ERROR_OUT_OF_CREDITS) { | 148 std::string activation_state = cellular->activation_state(); |
| 115 if (!cellular_network_.empty()) { | 149 if (activation_state == flimflam::kActivationStateActivating) { |
| 116 // This will trigger the activation / portal code. | 150 cellular_activating_.insert(cellular->path()); |
| 117 Shell::GetInstance()->system_tray_delegate()->ConfigureNetwork( | 151 return; |
| 118 cellular_network_); | |
| 119 } | |
| 120 ash::Shell::GetInstance()->system_tray_notifier()-> | |
| 121 NotifyClearNetworkMessage(message_type); | |
| 122 } | 152 } |
| 153 // Only display a notification if this network was activating and is now | |
| 154 // activated. | |
| 155 if (!cellular_activating_.count(cellular->path()) || | |
| 156 activation_state != flimflam::kActivationStateActivated) | |
| 157 return; | |
| 158 | |
| 159 cellular_activating_.erase(cellular->path()); | |
| 160 int icon_id; | |
| 161 if (cellular->network_technology() == flimflam::kNetworkTechnologyLte) | |
| 162 icon_id = IDR_AURA_UBER_TRAY_NOTIFICATION_LTE; | |
| 163 else | |
| 164 icon_id = IDR_AURA_UBER_TRAY_NOTIFICATION_3G; | |
| 165 const gfx::Image& icon = | |
| 166 ui::ResourceBundle::GetSharedInstance().GetImageNamed(icon_id); | |
| 167 message_center::MessageCenter::Get()->AddNotification( | |
| 168 message_center::Notification::CreateSystemNotification( | |
| 169 ash::network_connect::kNetworkActivateNotificationId, | |
| 170 l10n_util::GetStringUTF16(IDS_NETWORK_CELLULAR_ACTIVATED_TITLE), | |
| 171 l10n_util::GetStringFUTF16(IDS_NETWORK_CELLULAR_ACTIVATED, | |
| 172 UTF8ToUTF16((cellular->name()))), | |
| 173 icon, | |
| 174 base::Bind(&ash::network_connect::ShowNetworkSettings, | |
| 175 cellular->path()))); | |
| 123 } | 176 } |
| 124 | 177 |
| 125 void NetworkStateNotifier::ShowNetworkConnectError( | 178 void NetworkStateNotifier::ShowNetworkConnectError( |
| 126 const std::string& error_name, | 179 const std::string& error_name, |
| 127 const std::string& service_path) { | 180 const std::string& service_path) { |
| 181 if (service_path.empty()) { | |
| 182 base::DictionaryValue shill_properties; | |
| 183 ShowConnectErrorNotification(error_name, service_path, shill_properties); | |
| 184 return; | |
| 185 } | |
| 128 // Get the up-to-date properties for the network and display the error. | 186 // Get the up-to-date properties for the network and display the error. |
| 129 NetworkHandler::Get()->network_configuration_handler()->GetProperties( | 187 NetworkHandler::Get()->network_configuration_handler()->GetProperties( |
| 130 service_path, | 188 service_path, |
| 131 base::Bind(&NetworkStateNotifier::ConnectErrorPropertiesSucceeded, | 189 base::Bind(&NetworkStateNotifier::ConnectErrorPropertiesSucceeded, |
| 132 weak_ptr_factory_.GetWeakPtr(), error_name), | 190 weak_ptr_factory_.GetWeakPtr(), error_name), |
| 133 base::Bind(&NetworkStateNotifier::ConnectErrorPropertiesFailed, | 191 base::Bind(&NetworkStateNotifier::ConnectErrorPropertiesFailed, |
| 134 weak_ptr_factory_.GetWeakPtr(), error_name, service_path)); | 192 weak_ptr_factory_.GetWeakPtr(), error_name, service_path)); |
| 135 } | 193 } |
| 136 | 194 |
| 137 void NetworkStateNotifier::ConnectErrorPropertiesSucceeded( | 195 void NetworkStateNotifier::ConnectErrorPropertiesSucceeded( |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 167 service_path); | 225 service_path); |
| 168 | 226 |
| 169 std::string network_name = | 227 std::string network_name = |
| 170 NetworkState::GetNameFromProperties(service_path, shill_properties); | 228 NetworkState::GetNameFromProperties(service_path, shill_properties); |
| 171 std::string network_error_details; | 229 std::string network_error_details; |
| 172 shill_properties.GetStringWithoutPathExpansion( | 230 shill_properties.GetStringWithoutPathExpansion( |
| 173 shill::kErrorDetailsProperty, &network_error_details); | 231 shill::kErrorDetailsProperty, &network_error_details); |
| 174 | 232 |
| 175 string16 error_msg; | 233 string16 error_msg; |
| 176 if (!network_error_details.empty()) { | 234 if (!network_error_details.empty()) { |
| 235 // network_name should never be empty if network_error_details is set. | |
|
jennyz
2013/08/21 00:02:42
Should we add a DCHECK(!network_name.empty())?
stevenjb
2013/08/21 17:38:49
No, we shouldn't crash in that case, it's not an e
| |
| 177 error_msg = l10n_util::GetStringFUTF16( | 236 error_msg = l10n_util::GetStringFUTF16( |
| 178 IDS_NETWORK_CONNECTION_ERROR_MESSAGE_WITH_SERVER_MESSAGE, | 237 IDS_NETWORK_CONNECTION_ERROR_MESSAGE_WITH_SERVER_MESSAGE, |
| 179 UTF8ToUTF16(network_name), error, | 238 UTF8ToUTF16(network_name), error, |
| 180 UTF8ToUTF16(network_error_details)); | 239 UTF8ToUTF16(network_error_details)); |
| 240 } else if (network_name.empty()) { | |
| 241 error_msg = l10n_util::GetStringFUTF16( | |
| 242 IDS_NETWORK_CONNECTION_ERROR_MESSAGE_NO_NAME, error); | |
| 181 } else { | 243 } else { |
| 182 error_msg = l10n_util::GetStringFUTF16( | 244 error_msg = l10n_util::GetStringFUTF16( |
| 183 IDS_NETWORK_CONNECTION_ERROR_MESSAGE_WITH_DETAILS, | 245 IDS_NETWORK_CONNECTION_ERROR_MESSAGE, |
| 184 UTF8ToUTF16(network_name), error); | 246 UTF8ToUTF16(network_name), error); |
| 185 } | 247 } |
| 186 | 248 |
| 187 std::string network_type; | 249 std::string network_type; |
| 188 shill_properties.GetStringWithoutPathExpansion( | 250 shill_properties.GetStringWithoutPathExpansion( |
| 189 flimflam::kTypeProperty, &network_type); | 251 flimflam::kTypeProperty, &network_type); |
| 190 | 252 |
| 191 NetworkObserver::NetworkType type = NetworkObserver::NETWORK_UNKNOWN; | 253 ShowErrorNotification( |
| 192 if (network_type == flimflam::kTypeCellular) { | 254 network_connect::kNetworkConnectNotificationId, |
| 193 std::string network_technology; | 255 service_path, |
| 194 shill_properties.GetStringWithoutPathExpansion( | 256 network_type, |
| 195 flimflam::kNetworkTechnologyProperty, &network_technology); | |
| 196 if (network_technology == flimflam::kNetworkTechnologyLte || | |
| 197 network_technology == flimflam::kNetworkTechnologyLteAdvanced) | |
| 198 type = NetworkObserver::NETWORK_CELLULAR_LTE; | |
| 199 else | |
| 200 type = NetworkObserver::NETWORK_CELLULAR; | |
| 201 } else if (network_type == flimflam::kTypeEthernet) { | |
| 202 type = NetworkObserver:: NETWORK_ETHERNET; | |
| 203 } else if (network_type == flimflam::kTypeWifi) { | |
| 204 type = NetworkObserver:: NETWORK_WIFI; | |
| 205 } else { | |
| 206 NOTREACHED(); | |
| 207 } | |
| 208 | |
| 209 std::vector<string16> no_links; | |
| 210 ash::Shell::GetInstance()->system_tray_notifier()->NotifySetNetworkMessage( | |
| 211 this, | |
| 212 NetworkObserver::ERROR_CONNECT_FAILED, | |
| 213 type, | |
| 214 l10n_util::GetStringUTF16(IDS_NETWORK_CONNECTION_ERROR_TITLE), | 257 l10n_util::GetStringUTF16(IDS_NETWORK_CONNECTION_ERROR_TITLE), |
| 215 error_msg, | 258 error_msg, |
| 216 no_links); | 259 base::Bind(&network_connect::ShowNetworkSettings, service_path)); |
| 217 } | 260 }; |
| 218 | 261 |
| 219 } // namespace ash | 262 } // namespace ash |
| OLD | NEW |