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& network_type, |
| 53 const base::string16& title, |
| 54 const base::string16& message, |
| 55 const base::Closure& callback) { |
| 56 int icon_id = (network_type == flimflam::kTypeCellular) ? |
| 57 IDR_AURA_UBER_TRAY_CELLULAR_NETWORK_FAILED : |
| 58 IDR_AURA_UBER_TRAY_NETWORK_FAILED; |
| 59 const gfx::Image& icon = |
| 60 ui::ResourceBundle::GetSharedInstance().GetImageNamed(icon_id); |
| 61 message_center::MessageCenter::Get()->AddNotification( |
| 62 message_center::Notification::CreateSystemNotification( |
| 63 notification_id, title, message, icon, callback)); |
| 64 } |
| 65 |
| 66 void ConfigureNetwork(const std::string& service_path) { |
| 67 ash::Shell::GetInstance()->system_tray_delegate()->ConfigureNetwork( |
| 68 service_path); |
| 69 } |
| 70 |
45 } // namespace | 71 } // namespace |
46 | 72 |
47 namespace ash { | 73 namespace ash { |
48 | 74 |
49 NetworkStateNotifier::NetworkStateNotifier() | 75 NetworkStateNotifier::NetworkStateNotifier() |
50 : cellular_out_of_credits_(false), | 76 : did_show_out_of_credits_(false), |
51 weak_ptr_factory_(this) { | 77 weak_ptr_factory_(this) { |
52 if (!NetworkHandler::IsInitialized()) | 78 if (!NetworkHandler::IsInitialized()) |
53 return; | 79 return; |
54 NetworkHandler::Get()->network_state_handler()->AddObserver(this, FROM_HERE); | 80 NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler(); |
55 | 81 handler->AddObserver(this, FROM_HERE); |
56 // Initialize |last_active_network_|. | 82 UpdateDefaultNetwork(handler->DefaultNetwork()); |
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 } | 83 } |
62 | 84 |
63 NetworkStateNotifier::~NetworkStateNotifier() { | 85 NetworkStateNotifier::~NetworkStateNotifier() { |
64 if (!NetworkHandler::IsInitialized()) | 86 if (!NetworkHandler::IsInitialized()) |
65 return; | 87 return; |
66 NetworkHandler::Get()->network_state_handler()->RemoveObserver( | 88 NetworkHandler::Get()->network_state_handler()->RemoveObserver( |
67 this, FROM_HERE); | 89 this, FROM_HERE); |
68 } | 90 } |
69 | 91 |
70 void NetworkStateNotifier::DefaultNetworkChanged(const NetworkState* network) { | 92 void NetworkStateNotifier::DefaultNetworkChanged(const NetworkState* network) { |
71 if (!network || !network->IsConnectedState()) | 93 if (!UpdateDefaultNetwork(network)) |
72 return; | 94 return; |
73 if (network->path() != last_active_network_) { | 95 // If the default network changes to another network, allow the out of |
74 last_active_network_ = network->path(); | 96 // credits notification to be shown again. A delay prevents the notification |
75 // Reset state for new connected network | 97 // from being shown too frequently (see below). |
76 cellular_out_of_credits_ = false; | 98 if (network) |
77 NetworkPropertiesUpdated(network); | 99 did_show_out_of_credits_ = false; |
78 } | |
79 } | 100 } |
80 | 101 |
81 void NetworkStateNotifier::NetworkPropertiesUpdated( | 102 void NetworkStateNotifier::NetworkPropertiesUpdated( |
82 const NetworkState* network) { | 103 const NetworkState* network) { |
83 // Trigger "Out of credits" notification if the cellular network is the most | 104 if (network->type() != flimflam::kTypeCellular) |
84 // recent default network (i.e. we have not switched to another network). | 105 return; |
85 if (network->type() == flimflam::kTypeCellular && | 106 UpdateCellularOutOfCredits(network); |
86 network->path() == last_active_network_) { | 107 UpdateCellularActivating(network); |
87 cellular_network_ = network->path(); | 108 } |
88 if (network->cellular_out_of_credits() && | 109 |
89 !cellular_out_of_credits_) { | 110 bool NetworkStateNotifier::UpdateDefaultNetwork(const NetworkState* network) { |
90 cellular_out_of_credits_ = true; | 111 std::string default_network_path; |
91 base::TimeDelta dtime = base::Time::Now() - out_of_credits_notify_time_; | 112 if (network) |
92 if (dtime.InSeconds() > kMinTimeBetweenOutOfCreditsNotifySeconds) { | 113 default_network_path = network->path(); |
93 out_of_credits_notify_time_ = base::Time::Now(); | 114 if (default_network_path != last_default_network_) { |
94 std::vector<string16> links; | 115 last_default_network_ = default_network_path; |
95 links.push_back( | 116 return true; |
96 l10n_util::GetStringFUTF16(IDS_NETWORK_OUT_OF_CREDITS_LINK, | 117 } |
97 UTF8ToUTF16(network->name()))); | 118 return false; |
98 ash::Shell::GetInstance()->system_tray_notifier()-> | 119 } |
99 NotifySetNetworkMessage( | 120 |
100 this, | 121 void NetworkStateNotifier::UpdateCellularOutOfCredits( |
101 NetworkObserver::ERROR_OUT_OF_CREDITS, | 122 const NetworkState* cellular) { |
102 NetworkObserver::GetNetworkTypeForNetworkState(network), | 123 // Only display a notification if we are out of credits and have not already |
103 l10n_util::GetStringUTF16(IDS_NETWORK_OUT_OF_CREDITS_TITLE), | 124 // shown a notification (or have since connected to another network type). |
104 l10n_util::GetStringUTF16(IDS_NETWORK_OUT_OF_CREDITS_BODY), | 125 if (!cellular->cellular_out_of_credits() || did_show_out_of_credits_) |
105 links); | 126 return; |
106 } | 127 |
107 } | 128 // Only display a notification if not connected, connecting, or waiting to |
| 129 // connect to another network. |
| 130 NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler(); |
| 131 const NetworkState* default_network = handler->DefaultNetwork(); |
| 132 if (default_network && default_network != cellular) |
| 133 return; |
| 134 if (handler->ConnectingNetworkByType( |
| 135 NetworkStateHandler::kMatchTypeNonVirtual) || |
| 136 NetworkHandler::Get()->network_connection_handler() |
| 137 ->HasPendingConnectRequest()) |
| 138 return; |
| 139 |
| 140 did_show_out_of_credits_ = true; |
| 141 base::TimeDelta dtime = base::Time::Now() - out_of_credits_notify_time_; |
| 142 if (dtime.InSeconds() > kMinTimeBetweenOutOfCreditsNotifySeconds) { |
| 143 out_of_credits_notify_time_ = base::Time::Now(); |
| 144 string16 error_msg = l10n_util::GetStringFUTF16( |
| 145 IDS_NETWORK_OUT_OF_CREDITS_BODY, |
| 146 UTF8ToUTF16(cellular->name())); |
| 147 ShowErrorNotification( |
| 148 kNetworkOutOfCreditsNotificationId, |
| 149 cellular->type(), |
| 150 l10n_util::GetStringUTF16(IDS_NETWORK_OUT_OF_CREDITS_TITLE), |
| 151 error_msg, |
| 152 base::Bind(&ConfigureNetwork, cellular->path())); |
108 } | 153 } |
109 } | 154 } |
110 | 155 |
111 void NetworkStateNotifier::NotificationLinkClicked( | 156 void NetworkStateNotifier::UpdateCellularActivating( |
112 NetworkObserver::MessageType message_type, | 157 const NetworkState* cellular) { |
113 size_t link_index) { | 158 // Keep track of any activating cellular network. |
114 if (message_type == NetworkObserver::ERROR_OUT_OF_CREDITS) { | 159 std::string activation_state = cellular->activation_state(); |
115 if (!cellular_network_.empty()) { | 160 if (activation_state == flimflam::kActivationStateActivating) { |
116 // This will trigger the activation / portal code. | 161 cellular_activating_.insert(cellular->path()); |
117 Shell::GetInstance()->system_tray_delegate()->ConfigureNetwork( | 162 return; |
118 cellular_network_); | |
119 } | |
120 ash::Shell::GetInstance()->system_tray_notifier()-> | |
121 NotifyClearNetworkMessage(message_type); | |
122 } | 163 } |
| 164 // Only display a notification if this network was activating and is now |
| 165 // activated. |
| 166 if (!cellular_activating_.count(cellular->path()) || |
| 167 activation_state != flimflam::kActivationStateActivated) |
| 168 return; |
| 169 |
| 170 cellular_activating_.erase(cellular->path()); |
| 171 int icon_id; |
| 172 if (cellular->network_technology() == flimflam::kNetworkTechnologyLte) |
| 173 icon_id = IDR_AURA_UBER_TRAY_NOTIFICATION_LTE; |
| 174 else |
| 175 icon_id = IDR_AURA_UBER_TRAY_NOTIFICATION_3G; |
| 176 const gfx::Image& icon = |
| 177 ui::ResourceBundle::GetSharedInstance().GetImageNamed(icon_id); |
| 178 message_center::MessageCenter::Get()->AddNotification( |
| 179 message_center::Notification::CreateSystemNotification( |
| 180 ash::network_connect::kNetworkActivateNotificationId, |
| 181 l10n_util::GetStringUTF16(IDS_NETWORK_CELLULAR_ACTIVATED_TITLE), |
| 182 l10n_util::GetStringFUTF16(IDS_NETWORK_CELLULAR_ACTIVATED, |
| 183 UTF8ToUTF16((cellular->name()))), |
| 184 icon, |
| 185 base::Bind(&ash::network_connect::ShowNetworkSettings, |
| 186 cellular->path()))); |
123 } | 187 } |
124 | 188 |
125 void NetworkStateNotifier::ShowNetworkConnectError( | 189 void NetworkStateNotifier::ShowNetworkConnectError( |
126 const std::string& error_name, | 190 const std::string& error_name, |
127 const std::string& service_path) { | 191 const std::string& service_path) { |
| 192 if (service_path.empty()) { |
| 193 base::DictionaryValue shill_properties; |
| 194 ShowConnectErrorNotification(error_name, service_path, shill_properties); |
| 195 return; |
| 196 } |
128 // Get the up-to-date properties for the network and display the error. | 197 // Get the up-to-date properties for the network and display the error. |
129 NetworkHandler::Get()->network_configuration_handler()->GetProperties( | 198 NetworkHandler::Get()->network_configuration_handler()->GetProperties( |
130 service_path, | 199 service_path, |
131 base::Bind(&NetworkStateNotifier::ConnectErrorPropertiesSucceeded, | 200 base::Bind(&NetworkStateNotifier::ConnectErrorPropertiesSucceeded, |
132 weak_ptr_factory_.GetWeakPtr(), error_name), | 201 weak_ptr_factory_.GetWeakPtr(), error_name), |
133 base::Bind(&NetworkStateNotifier::ConnectErrorPropertiesFailed, | 202 base::Bind(&NetworkStateNotifier::ConnectErrorPropertiesFailed, |
134 weak_ptr_factory_.GetWeakPtr(), error_name, service_path)); | 203 weak_ptr_factory_.GetWeakPtr(), error_name, service_path)); |
135 } | 204 } |
136 | 205 |
137 void NetworkStateNotifier::ConnectErrorPropertiesSucceeded( | 206 void NetworkStateNotifier::ConnectErrorPropertiesSucceeded( |
(...skipping 29 matching lines...) Expand all Loading... |
167 service_path); | 236 service_path); |
168 | 237 |
169 std::string network_name = | 238 std::string network_name = |
170 NetworkState::GetNameFromProperties(service_path, shill_properties); | 239 NetworkState::GetNameFromProperties(service_path, shill_properties); |
171 std::string network_error_details; | 240 std::string network_error_details; |
172 shill_properties.GetStringWithoutPathExpansion( | 241 shill_properties.GetStringWithoutPathExpansion( |
173 shill::kErrorDetailsProperty, &network_error_details); | 242 shill::kErrorDetailsProperty, &network_error_details); |
174 | 243 |
175 string16 error_msg; | 244 string16 error_msg; |
176 if (!network_error_details.empty()) { | 245 if (!network_error_details.empty()) { |
| 246 // network_name should't be empty if network_error_details is set. |
177 error_msg = l10n_util::GetStringFUTF16( | 247 error_msg = l10n_util::GetStringFUTF16( |
178 IDS_NETWORK_CONNECTION_ERROR_MESSAGE_WITH_SERVER_MESSAGE, | 248 IDS_NETWORK_CONNECTION_ERROR_MESSAGE_WITH_SERVER_MESSAGE, |
179 UTF8ToUTF16(network_name), error, | 249 UTF8ToUTF16(network_name), error, |
180 UTF8ToUTF16(network_error_details)); | 250 UTF8ToUTF16(network_error_details)); |
| 251 } else if (network_name.empty()) { |
| 252 error_msg = l10n_util::GetStringFUTF16( |
| 253 IDS_NETWORK_CONNECTION_ERROR_MESSAGE_NO_NAME, error); |
181 } else { | 254 } else { |
182 error_msg = l10n_util::GetStringFUTF16( | 255 error_msg = l10n_util::GetStringFUTF16( |
183 IDS_NETWORK_CONNECTION_ERROR_MESSAGE_WITH_DETAILS, | 256 IDS_NETWORK_CONNECTION_ERROR_MESSAGE, |
184 UTF8ToUTF16(network_name), error); | 257 UTF8ToUTF16(network_name), error); |
185 } | 258 } |
186 | 259 |
187 std::string network_type; | 260 std::string network_type; |
188 shill_properties.GetStringWithoutPathExpansion( | 261 shill_properties.GetStringWithoutPathExpansion( |
189 flimflam::kTypeProperty, &network_type); | 262 flimflam::kTypeProperty, &network_type); |
190 | 263 |
191 NetworkObserver::NetworkType type = NetworkObserver::NETWORK_UNKNOWN; | 264 ShowErrorNotification( |
192 if (network_type == flimflam::kTypeCellular) { | 265 network_connect::kNetworkConnectNotificationId, |
193 std::string network_technology; | 266 network_type, |
194 shill_properties.GetStringWithoutPathExpansion( | |
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), | 267 l10n_util::GetStringUTF16(IDS_NETWORK_CONNECTION_ERROR_TITLE), |
215 error_msg, | 268 error_msg, |
216 no_links); | 269 base::Bind(&network_connect::ShowNetworkSettings, service_path)); |
217 } | 270 } |
218 | 271 |
219 } // namespace ash | 272 } // namespace ash |
OLD | NEW |