Prefix string16 with base:: in ash/.
[chromium-blink-merge.git] / ash / system / chromeos / network / network_state_notifier.cc
blob79a5d5bd834677fe0c0c81b102c5f0cd0e7729e7
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
3 // found in the LICENSE file.
5 #include "ash/system/chromeos/network/network_state_notifier.h"
7 #include "ash/shell.h"
8 #include "ash/system/chromeos/network/network_connect.h"
9 #include "ash/system/system_notifier.h"
10 #include "ash/system/tray/system_tray_delegate.h"
11 #include "base/strings/string16.h"
12 #include "base/strings/string_util.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "chromeos/network/network_configuration_handler.h"
15 #include "chromeos/network/network_connection_handler.h"
16 #include "chromeos/network/network_event_log.h"
17 #include "chromeos/network/network_state.h"
18 #include "chromeos/network/network_state_handler.h"
19 #include "chromeos/network/shill_property_util.h"
20 #include "grit/ash_resources.h"
21 #include "grit/ash_strings.h"
22 #include "third_party/cros_system_api/dbus/service_constants.h"
23 #include "ui/base/l10n/l10n_util.h"
24 #include "ui/base/resource/resource_bundle.h"
25 #include "ui/message_center/message_center.h"
26 #include "ui/message_center/notification.h"
28 using chromeos::NetworkConnectionHandler;
29 using chromeos::NetworkHandler;
30 using chromeos::NetworkState;
31 using chromeos::NetworkStateHandler;
32 using chromeos::NetworkTypePattern;
34 namespace {
36 const char kNetworkOutOfCreditsNotificationId[] =
37 "chrome://settings/internet/out-of-credits";
39 const int kMinTimeBetweenOutOfCreditsNotifySeconds = 10 * 60;
41 // Error messages based on |error_name|, not network_state->error().
42 base::string16 GetConnectErrorString(const std::string& error_name) {
43 if (error_name == NetworkConnectionHandler::kErrorNotFound)
44 return l10n_util::GetStringUTF16(IDS_CHROMEOS_NETWORK_ERROR_CONNECT_FAILED);
45 if (error_name == NetworkConnectionHandler::kErrorConfigureFailed)
46 return l10n_util::GetStringUTF16(
47 IDS_CHROMEOS_NETWORK_ERROR_CONFIGURE_FAILED);
48 if (error_name == ash::network_connect::kErrorActivateFailed)
49 return l10n_util::GetStringUTF16(
50 IDS_CHROMEOS_NETWORK_ERROR_ACTIVATION_FAILED);
51 return base::string16();
54 void ShowErrorNotification(const std::string& notification_id,
55 const std::string& network_type,
56 const base::string16& title,
57 const base::string16& message,
58 const base::Closure& callback) {
59 int icon_id = (network_type == shill::kTypeCellular) ?
60 IDR_AURA_UBER_TRAY_CELLULAR_NETWORK_FAILED :
61 IDR_AURA_UBER_TRAY_NETWORK_FAILED;
62 const gfx::Image& icon =
63 ui::ResourceBundle::GetSharedInstance().GetImageNamed(icon_id);
64 message_center::MessageCenter::Get()->AddNotification(
65 message_center::Notification::CreateSystemNotification(
66 notification_id,
67 title,
68 message,
69 icon,
70 ash::system_notifier::kNotifierNetworkError,
71 callback));
74 } // namespace
76 namespace ash {
78 NetworkStateNotifier::NetworkStateNotifier()
79 : did_show_out_of_credits_(false),
80 weak_ptr_factory_(this) {
81 if (!NetworkHandler::IsInitialized())
82 return;
83 NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
84 handler->AddObserver(this, FROM_HERE);
85 UpdateDefaultNetwork(handler->DefaultNetwork());
88 NetworkStateNotifier::~NetworkStateNotifier() {
89 if (!NetworkHandler::IsInitialized())
90 return;
91 NetworkHandler::Get()->network_state_handler()->RemoveObserver(
92 this, FROM_HERE);
95 void NetworkStateNotifier::DefaultNetworkChanged(const NetworkState* network) {
96 if (!UpdateDefaultNetwork(network))
97 return;
98 // If the default network changes to another network, allow the out of
99 // credits notification to be shown again. A delay prevents the notification
100 // from being shown too frequently (see below).
101 if (network)
102 did_show_out_of_credits_ = false;
105 void NetworkStateNotifier::NetworkPropertiesUpdated(
106 const NetworkState* network) {
107 if (network->type() != shill::kTypeCellular)
108 return;
109 UpdateCellularOutOfCredits(network);
110 UpdateCellularActivating(network);
113 bool NetworkStateNotifier::UpdateDefaultNetwork(const NetworkState* network) {
114 std::string default_network_path;
115 if (network)
116 default_network_path = network->path();
117 if (default_network_path != last_default_network_) {
118 last_default_network_ = default_network_path;
119 return true;
121 return false;
124 void NetworkStateNotifier::UpdateCellularOutOfCredits(
125 const NetworkState* cellular) {
126 // Only display a notification if we are out of credits and have not already
127 // shown a notification (or have since connected to another network type).
128 if (!cellular->cellular_out_of_credits() || did_show_out_of_credits_)
129 return;
131 // Only display a notification if not connected, connecting, or waiting to
132 // connect to another network.
133 NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
134 const NetworkState* default_network = handler->DefaultNetwork();
135 if (default_network && default_network != cellular)
136 return;
137 if (handler->ConnectingNetworkByType(NetworkTypePattern::NonVirtual()) ||
138 NetworkHandler::Get()->network_connection_handler()
139 ->HasPendingConnectRequest())
140 return;
142 did_show_out_of_credits_ = true;
143 base::TimeDelta dtime = base::Time::Now() - out_of_credits_notify_time_;
144 if (dtime.InSeconds() > kMinTimeBetweenOutOfCreditsNotifySeconds) {
145 out_of_credits_notify_time_ = base::Time::Now();
146 base::string16 error_msg = l10n_util::GetStringFUTF16(
147 IDS_NETWORK_OUT_OF_CREDITS_BODY,
148 UTF8ToUTF16(cellular->name()));
149 ShowErrorNotification(
150 kNetworkOutOfCreditsNotificationId,
151 cellular->type(),
152 l10n_util::GetStringUTF16(IDS_NETWORK_OUT_OF_CREDITS_TITLE),
153 error_msg,
154 base::Bind(&network_connect::ShowNetworkSettings, cellular->path()));
158 void NetworkStateNotifier::UpdateCellularActivating(
159 const NetworkState* cellular) {
160 // Keep track of any activating cellular network.
161 std::string activation_state = cellular->activation_state();
162 if (activation_state == shill::kActivationStateActivating) {
163 cellular_activating_.insert(cellular->path());
164 return;
166 // Only display a notification if this network was activating and is now
167 // activated.
168 if (!cellular_activating_.count(cellular->path()) ||
169 activation_state != shill::kActivationStateActivated)
170 return;
172 cellular_activating_.erase(cellular->path());
173 int icon_id;
174 if (cellular->network_technology() == shill::kNetworkTechnologyLte)
175 icon_id = IDR_AURA_UBER_TRAY_NOTIFICATION_LTE;
176 else
177 icon_id = IDR_AURA_UBER_TRAY_NOTIFICATION_3G;
178 const gfx::Image& icon =
179 ui::ResourceBundle::GetSharedInstance().GetImageNamed(icon_id);
180 message_center::MessageCenter::Get()->AddNotification(
181 message_center::Notification::CreateSystemNotification(
182 ash::network_connect::kNetworkActivateNotificationId,
183 l10n_util::GetStringUTF16(IDS_NETWORK_CELLULAR_ACTIVATED_TITLE),
184 l10n_util::GetStringFUTF16(IDS_NETWORK_CELLULAR_ACTIVATED,
185 UTF8ToUTF16((cellular->name()))),
186 icon,
187 system_notifier::kNotifierNetwork,
188 base::Bind(&ash::network_connect::ShowNetworkSettings,
189 cellular->path())));
192 void NetworkStateNotifier::ShowNetworkConnectError(
193 const std::string& error_name,
194 const std::string& shill_error,
195 const std::string& service_path) {
196 if (service_path.empty()) {
197 base::DictionaryValue shill_properties;
198 ShowConnectErrorNotification(error_name, shill_error, service_path,
199 shill_properties);
200 return;
202 // Get the up-to-date properties for the network and display the error.
203 NetworkHandler::Get()->network_configuration_handler()->GetProperties(
204 service_path,
205 base::Bind(&NetworkStateNotifier::ConnectErrorPropertiesSucceeded,
206 weak_ptr_factory_.GetWeakPtr(), error_name, shill_error),
207 base::Bind(&NetworkStateNotifier::ConnectErrorPropertiesFailed,
208 weak_ptr_factory_.GetWeakPtr(), error_name, shill_error,
209 service_path));
212 void NetworkStateNotifier::ConnectErrorPropertiesSucceeded(
213 const std::string& error_name,
214 const std::string& shill_error,
215 const std::string& service_path,
216 const base::DictionaryValue& shill_properties) {
217 ShowConnectErrorNotification(error_name, shill_error, service_path,
218 shill_properties);
221 void NetworkStateNotifier::ConnectErrorPropertiesFailed(
222 const std::string& error_name,
223 const std::string& shill_error,
224 const std::string& service_path,
225 const std::string& shill_connect_error,
226 scoped_ptr<base::DictionaryValue> shill_error_data) {
227 base::DictionaryValue shill_properties;
228 ShowConnectErrorNotification(error_name, shill_error, service_path,
229 shill_properties);
232 void NetworkStateNotifier::ShowConnectErrorNotification(
233 const std::string& error_name,
234 const std::string& shill_error,
235 const std::string& service_path,
236 const base::DictionaryValue& shill_properties) {
237 base::string16 error = GetConnectErrorString(error_name);
238 if (error.empty()) {
239 // Service.Error gets cleared shortly after State transitions to Failure,
240 // so rely on |shill_error| unless empty.
241 std::string network_error = shill_error;
242 if (network_error.empty()) {
243 shill_properties.GetStringWithoutPathExpansion(
244 shill::kErrorProperty, &network_error);
246 error = network_connect::ErrorString(network_error, service_path);
247 if (error.empty())
248 error = l10n_util::GetStringUTF16(IDS_CHROMEOS_NETWORK_ERROR_UNKNOWN);
250 NET_LOG_ERROR("Connect error notification: " + UTF16ToUTF8(error),
251 service_path);
253 std::string network_name =
254 chromeos::shill_property_util::GetNameFromProperties(service_path,
255 shill_properties);
256 std::string network_error_details;
257 shill_properties.GetStringWithoutPathExpansion(
258 shill::kErrorDetailsProperty, &network_error_details);
260 base::string16 error_msg;
261 if (!network_error_details.empty()) {
262 // network_name should't be empty if network_error_details is set.
263 error_msg = l10n_util::GetStringFUTF16(
264 IDS_NETWORK_CONNECTION_ERROR_MESSAGE_WITH_SERVER_MESSAGE,
265 UTF8ToUTF16(network_name), error,
266 UTF8ToUTF16(network_error_details));
267 } else if (network_name.empty()) {
268 error_msg = l10n_util::GetStringFUTF16(
269 IDS_NETWORK_CONNECTION_ERROR_MESSAGE_NO_NAME, error);
270 } else {
271 error_msg = l10n_util::GetStringFUTF16(
272 IDS_NETWORK_CONNECTION_ERROR_MESSAGE,
273 UTF8ToUTF16(network_name), error);
276 std::string network_type;
277 shill_properties.GetStringWithoutPathExpansion(
278 shill::kTypeProperty, &network_type);
280 ShowErrorNotification(
281 network_connect::kNetworkConnectNotificationId,
282 network_type,
283 l10n_util::GetStringUTF16(IDS_NETWORK_CONNECTION_ERROR_TITLE),
284 error_msg,
285 base::Bind(&network_connect::ShowNetworkSettings, service_path));
288 } // namespace ash