summaryrefslogtreecommitdiff
path: root/chromium/ash/system/chromeos/network/network_state_notifier.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/ash/system/chromeos/network/network_state_notifier.cc')
-rw-r--r--chromium/ash/system/chromeos/network/network_state_notifier.cc184
1 files changed, 184 insertions, 0 deletions
diff --git a/chromium/ash/system/chromeos/network/network_state_notifier.cc b/chromium/ash/system/chromeos/network/network_state_notifier.cc
new file mode 100644
index 00000000000..1c971a32a44
--- /dev/null
+++ b/chromium/ash/system/chromeos/network/network_state_notifier.cc
@@ -0,0 +1,184 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/system/chromeos/network/network_state_notifier.h"
+
+#include "ash/shell.h"
+#include "ash/system/chromeos/network/network_connect.h"
+#include "ash/system/chromeos/network/network_observer.h"
+#include "ash/system/tray/system_tray_notifier.h"
+#include "base/strings/string16.h"
+#include "base/strings/string_util.h"
+#include "base/strings/utf_string_conversions.h"
+#include "chromeos/network/network_connection_handler.h"
+#include "chromeos/network/network_event_log.h"
+#include "chromeos/network/network_state.h"
+#include "chromeos/network/network_state_handler.h"
+#include "grit/ash_strings.h"
+#include "third_party/cros_system_api/dbus/service_constants.h"
+#include "ui/base/l10n/l10n_util.h"
+
+using chromeos::NetworkConnectionHandler;
+using chromeos::NetworkHandler;
+using chromeos::NetworkState;
+using chromeos::NetworkStateHandler;
+
+namespace {
+
+const int kMinTimeBetweenOutOfCreditsNotifySeconds = 10 * 60;
+
+// Error messages based on |error_name|, not network_state->error().
+string16 GetConnectErrorString(const std::string& error_name) {
+ if (error_name == NetworkConnectionHandler::kErrorNotFound)
+ return l10n_util::GetStringUTF16(IDS_CHROMEOS_NETWORK_ERROR_CONNECT_FAILED);
+ if (error_name == NetworkConnectionHandler::kErrorConfigureFailed)
+ return l10n_util::GetStringUTF16(
+ IDS_CHROMEOS_NETWORK_ERROR_CONFIGURE_FAILED);
+ if (error_name == NetworkConnectionHandler::kErrorActivateFailed)
+ return l10n_util::GetStringUTF16(
+ IDS_CHROMEOS_NETWORK_ERROR_ACTIVATION_FAILED);
+ return string16();
+}
+
+} // namespace
+
+namespace ash {
+
+NetworkStateNotifier::NetworkStateNotifier()
+ : cellular_out_of_credits_(false) {
+ if (!NetworkHandler::IsInitialized())
+ return;
+ NetworkHandler::Get()->network_state_handler()->AddObserver(this, FROM_HERE);
+
+ // Initialize |last_active_network_|.
+ const NetworkState* default_network =
+ NetworkHandler::Get()->network_state_handler()->DefaultNetwork();
+ if (default_network && default_network->IsConnectedState())
+ last_active_network_ = default_network->path();
+}
+
+NetworkStateNotifier::~NetworkStateNotifier() {
+ if (!NetworkHandler::IsInitialized())
+ return;
+ NetworkHandler::Get()->network_state_handler()->RemoveObserver(
+ this, FROM_HERE);
+}
+
+void NetworkStateNotifier::NetworkListChanged() {
+ // Trigger any pending connect failed error if the network list changes
+ // (which indicates all NetworkState entries are up to date). This is in
+ // case a connect attempt fails because a network is no longer visible.
+ if (!connect_failed_network_.empty()) {
+ ShowNetworkConnectError(
+ NetworkConnectionHandler::kErrorConnectFailed, connect_failed_network_);
+ }
+}
+
+void NetworkStateNotifier::DefaultNetworkChanged(const NetworkState* network) {
+ if (!network || !network->IsConnectedState())
+ return;
+ if (network->path() != last_active_network_) {
+ last_active_network_ = network->path();
+ // Reset state for new connected network
+ cellular_out_of_credits_ = false;
+ }
+}
+
+void NetworkStateNotifier::NetworkPropertiesUpdated(
+ const NetworkState* network) {
+ DCHECK(network);
+ // Trigger a pending connect failed error for |network| when the Error
+ // property has been set.
+ if (network->path() == connect_failed_network_ && !network->error().empty()) {
+ ShowNetworkConnectError(
+ NetworkConnectionHandler::kErrorConnectFailed, connect_failed_network_);
+ }
+ // Trigger "Out of credits" notification if the cellular network is the most
+ // recent default network (i.e. we have not switched to another network).
+ if (network->type() == flimflam::kTypeCellular &&
+ network->path() == last_active_network_) {
+ cellular_network_ = network->path();
+ if (network->cellular_out_of_credits() &&
+ !cellular_out_of_credits_) {
+ cellular_out_of_credits_ = true;
+ base::TimeDelta dtime = base::Time::Now() - out_of_credits_notify_time_;
+ if (dtime.InSeconds() > kMinTimeBetweenOutOfCreditsNotifySeconds) {
+ out_of_credits_notify_time_ = base::Time::Now();
+ std::vector<string16> links;
+ links.push_back(
+ l10n_util::GetStringFUTF16(IDS_NETWORK_OUT_OF_CREDITS_LINK,
+ UTF8ToUTF16(network->name())));
+ ash::Shell::GetInstance()->system_tray_notifier()->
+ NotifySetNetworkMessage(
+ this,
+ NetworkObserver::ERROR_OUT_OF_CREDITS,
+ NetworkObserver::GetNetworkTypeForNetworkState(network),
+ l10n_util::GetStringUTF16(IDS_NETWORK_OUT_OF_CREDITS_TITLE),
+ l10n_util::GetStringUTF16(IDS_NETWORK_OUT_OF_CREDITS_BODY),
+ links);
+ }
+ }
+ }
+}
+
+void NetworkStateNotifier::NotificationLinkClicked(
+ NetworkObserver::MessageType message_type,
+ size_t link_index) {
+ if (message_type == NetworkObserver::ERROR_OUT_OF_CREDITS) {
+ if (!cellular_network_.empty()) {
+ // This will trigger the activation / portal code.
+ Shell::GetInstance()->system_tray_delegate()->ConfigureNetwork(
+ cellular_network_);
+ }
+ ash::Shell::GetInstance()->system_tray_notifier()->
+ NotifyClearNetworkMessage(message_type);
+ }
+}
+
+void NetworkStateNotifier::ShowNetworkConnectError(
+ const std::string& error_name,
+ const std::string& service_path) {
+ const NetworkState* network = NetworkHandler::Get()->network_state_handler()->
+ GetNetworkState(service_path);
+ if (error_name == NetworkConnectionHandler::kErrorConnectFailed &&
+ service_path != connect_failed_network_) {
+ // Shill may not have set the Error property yet. First request an update
+ // and wait for either the update to complete or the network list to be
+ // updated before displaying the error.
+ connect_failed_network_ = service_path;
+ return;
+ }
+ connect_failed_network_.clear();
+
+ string16 error = GetConnectErrorString(error_name);
+ if (error.empty() && network)
+ error = network_connect::ErrorString(network->error());
+ if (error.empty())
+ error = l10n_util::GetStringUTF16(IDS_CHROMEOS_NETWORK_ERROR_UNKNOWN);
+ NET_LOG_ERROR("Connect error notification: " + UTF16ToUTF8(error),
+ service_path);
+
+ std::string name = network ? network->name() : "";
+ string16 error_msg;
+ if (network && !network->error_details().empty()) {
+ error_msg = l10n_util::GetStringFUTF16(
+ IDS_NETWORK_CONNECTION_ERROR_MESSAGE_WITH_SERVER_MESSAGE,
+ UTF8ToUTF16(name), error, UTF8ToUTF16(network->error_details()));
+ } else {
+ error_msg = l10n_util::GetStringFUTF16(
+ IDS_NETWORK_CONNECTION_ERROR_MESSAGE_WITH_DETAILS,
+ UTF8ToUTF16(name), error);
+ }
+
+ std::vector<string16> no_links;
+ ash::Shell::GetInstance()->system_tray_notifier()->NotifySetNetworkMessage(
+ this,
+ NetworkObserver::ERROR_CONNECT_FAILED,
+ NetworkObserver::GetNetworkTypeForNetworkState(network),
+ l10n_util::GetStringUTF16(IDS_NETWORK_CONNECTION_ERROR_TITLE),
+ error_msg,
+ no_links);
+}
+
+} // namespace ash