blob: 1c6e8b135798c0c00b01c089ca1021e69c08a3c3 [file] [log] [blame]
// 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 "chrome/browser/chromeos/network_message_observer.h"
#include "ash/shell.h"
#include "ash/shell_delegate.h"
#include "ash/system/chromeos/network/network_observer.h"
#include "ash/system/tray/system_tray.h"
#include "ash/system/tray/system_tray_notifier.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/chromeos/cros/cros_library.h"
#include "chrome/browser/chromeos/cros/network_library.h"
#include "chrome/browser/chromeos/notifications/balloon_view_host_chromeos.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/host_desktop.h"
#include "chrome/browser/ui/singleton_tabs.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/time_format.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"
namespace {
ash::NetworkObserver::NetworkType GetAshNetworkType(
chromeos::ConnectionType connection_type) {
switch (connection_type) {
case chromeos::TYPE_CELLULAR:
return ash::NetworkObserver::NETWORK_CELLULAR;
case chromeos::TYPE_ETHERNET:
return ash::NetworkObserver::NETWORK_ETHERNET;
case chromeos::TYPE_WIFI:
return ash::NetworkObserver::NETWORK_WIFI;
case chromeos::TYPE_BLUETOOTH:
return ash::NetworkObserver::NETWORK_BLUETOOTH;
default:
return ash::NetworkObserver::NETWORK_UNKNOWN;
}
}
} // namespace
namespace chromeos {
class NetworkMessageNotification : public ash::NetworkTrayDelegate {
public:
NetworkMessageNotification(Profile* profile,
ash::NetworkObserver::MessageType error_type)
: error_type_(error_type) {
switch (error_type) {
case ash::NetworkObserver::ERROR_CONNECT_FAILED:
title_ = l10n_util::GetStringUTF16(IDS_NETWORK_CONNECTION_ERROR_TITLE);
return;
case ash::NetworkObserver::MESSAGE_DATA_PROMO:
NOTREACHED();
return;
}
NOTREACHED();
}
// Overridden from ash::NetworkTrayDelegate:
virtual void NotificationLinkClicked(size_t index) OVERRIDE {
base::ListValue empty_value;
if (!callback_.is_null())
callback_.Run(&empty_value);
}
void Hide() {
ash::Shell::GetInstance()->system_tray_notifier()->
NotifyClearNetworkMessage(error_type_);
}
void SetTitle(const string16& title) {
title_ = title;
}
void Show(chromeos::ConnectionType connection_type,
const string16& message,
const string16& link_text,
const BalloonViewHost::MessageCallback& callback,
bool urgent, bool sticky) {
callback_ = callback;
std::vector<string16> links;
links.push_back(link_text);
ash::NetworkObserver::NetworkType network_type = GetAshNetworkType(
connection_type);
ash::Shell::GetInstance()->system_tray_notifier()->NotifySetNetworkMessage(
this, error_type_, network_type, title_, message, links);
}
void ShowAlways(chromeos::ConnectionType connection_type,
const string16& message,
const string16& link_text,
const BalloonViewHost::MessageCallback& callback,
bool urgent, bool sticky) {
Show(connection_type, message, link_text, callback, urgent, sticky);
}
private:
string16 title_;
ash::NetworkObserver::MessageType error_type_;
BalloonViewHost::MessageCallback callback_;
};
NetworkMessageObserver::NetworkMessageObserver(Profile* profile) {
notification_connection_error_.reset(
new NetworkMessageNotification(
profile, ash::NetworkObserver::ERROR_CONNECT_FAILED));
NetworkLibrary* netlib = CrosLibrary::Get()->GetNetworkLibrary();
OnNetworkManagerChanged(netlib);
// Note that this gets added as a NetworkManagerObserver
// and UserActionObserver in startup_browser_creator.cc
}
NetworkMessageObserver::~NetworkMessageObserver() {
NetworkLibrary* netlib = CrosLibrary::Get()->GetNetworkLibrary();
netlib->RemoveNetworkManagerObserver(this);
netlib->RemoveUserActionObserver(this);
notification_connection_error_->Hide();
}
void NetworkMessageObserver::OnNetworkManagerChanged(NetworkLibrary* cros) {
const Network* new_failed_network = NULL;
// Check to see if we have any newly failed networks.
for (WifiNetworkVector::const_iterator it = cros->wifi_networks().begin();
it != cros->wifi_networks().end(); it++) {
const WifiNetwork* net = *it;
if (net->notify_failure()) {
new_failed_network = net;
break; // There should only be one failed network.
}
}
if (!new_failed_network) {
for (WimaxNetworkVector::const_iterator it = cros->wimax_networks().begin();
it != cros->wimax_networks().end(); ++it) {
const WimaxNetwork* net = *it;
if (net->notify_failure()) {
new_failed_network = net;
break; // There should only be one failed network.
}
}
}
if (!new_failed_network) {
for (CellularNetworkVector::const_iterator it =
cros->cellular_networks().begin();
it != cros->cellular_networks().end(); it++) {
const CellularNetwork* net = *it;
if (net->notify_failure()) {
new_failed_network = net;
break; // There should only be one failed network.
}
}
}
if (!new_failed_network) {
for (VirtualNetworkVector::const_iterator it =
cros->virtual_networks().begin();
it != cros->virtual_networks().end(); it++) {
const VirtualNetwork* net = *it;
if (net->notify_failure()) {
new_failed_network = net;
break; // There should only be one failed network.
}
}
}
// Show connection error notification if necessary.
if (new_failed_network) {
VLOG(1) << "Failed Network: " << new_failed_network->service_path();
notification_connection_error_->ShowAlways(
new_failed_network->type(),
l10n_util::GetStringFUTF16(
IDS_NETWORK_CONNECTION_ERROR_MESSAGE_WITH_DETAILS,
UTF8ToUTF16(new_failed_network->name()),
UTF8ToUTF16(new_failed_network->GetErrorString())),
string16(), BalloonViewHost::MessageCallback(), false, false);
}
}
void NetworkMessageObserver::OnConnectionInitiated(NetworkLibrary* cros,
const Network* network) {
// If user initiated any network connection, we hide the error notification.
notification_connection_error_->Hide();
}
} // namespace chromeos