diff options
Diffstat (limited to 'chromium/ash/system/chromeos/network/network_state_notifier.cc')
-rw-r--r-- | chromium/ash/system/chromeos/network/network_state_notifier.cc | 184 |
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 |