// Copyright (c) 2011 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_login_observer.h"
#include "chrome/browser/chromeos/cros/cros_library.h"
#include "chrome/browser/chromeos/cros/network_library.h"
#include "chrome/browser/chromeos/login/background_view.h"
#include "chrome/browser/chromeos/login/login_utils.h"
#include "chrome/browser/chromeos/options/network_config_view.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/views/window.h"
#include "views/window/dialog_delegate.h"
#include "views/window/window.h"
namespace chromeos {
NetworkLoginObserver::NetworkLoginObserver(NetworkLibrary* netlib) {
RefreshStoredNetworks(netlib->wifi_networks(),
netlib->virtual_networks());
netlib->AddNetworkManagerObserver(this);
}
NetworkLoginObserver::~NetworkLoginObserver() {
CrosLibrary::Get()->GetNetworkLibrary()->RemoveNetworkManagerObserver(this);
}
void NetworkLoginObserver::CreateModalPopup(views::WindowDelegate* view) {
Browser* browser = BrowserList::GetLastActive();
if (browser && browser->type() != Browser::TYPE_NORMAL) {
browser = BrowserList::FindBrowserWithType(browser->profile(),
Browser::TYPE_NORMAL,
true);
}
if (browser) {
views::Window* window = browser::CreateViewsWindow(
browser->window()->GetNativeHandle(), gfx::Rect(), view);
window->SetIsAlwaysOnTop(true);
window->Show();
} else {
// Browser not found, so we should be in login/oobe screen.
BackgroundView* background_view = LoginUtils::Get()->GetBackgroundView();
if (background_view) {
background_view->CreateModalPopup(view);
}
}
}
void NetworkLoginObserver::RefreshStoredNetworks(
const WifiNetworkVector& wifi_networks,
const VirtualNetworkVector& virtual_networks) {
network_failures_.clear();
for (WifiNetworkVector::const_iterator it = wifi_networks.begin();
it != wifi_networks.end(); it++) {
const WifiNetwork* wifi = *it;
network_failures_[wifi->service_path()] = wifi->failed();
}
for (VirtualNetworkVector::const_iterator it = virtual_networks.begin();
it != virtual_networks.end(); it++) {
const VirtualNetwork* vpn = *it;
network_failures_[vpn->service_path()] = vpn->failed();
}
}
void NetworkLoginObserver::OnNetworkManagerChanged(NetworkLibrary* cros) {
const WifiNetworkVector& wifi_networks = cros->wifi_networks();
const VirtualNetworkVector& virtual_networks = cros->virtual_networks();
NetworkConfigView* view = NULL;
// Check to see if we have any newly failed wifi network.
for (WifiNetworkVector::const_iterator it = wifi_networks.begin();
it != wifi_networks.end(); it++) {
WifiNetwork* wifi = *it;
if (wifi->failed()) {
NetworkFailureMap::iterator iter =
network_failures_.find(wifi->service_path());
// If the network did not previously exist, then don't do anything.
// For example, if the user travels to a location and finds a service
// that has previously failed, we don't want to show an error.
if (iter == network_failures_.end())
continue;
// If this network was in a failed state previously, then it's not new.
if (iter->second)
continue;
// Display login dialog again for bad_passphrase and bad_wepkey errors.
// Always re-display the login dialog for added networks that failed to
// connect for any reason (e.g. incorrect security type was chosen).
if (wifi->error() == ERROR_BAD_PASSPHRASE ||
wifi->error() == ERROR_BAD_WEPKEY ||
wifi->added()) {
// The NetworkConfigView will show the appropriate error message.
view = new NetworkConfigView(wifi);
// There should only be one wifi network that failed to connect.
// If for some reason, we have more than one failure,
// we only display the first one. So we break here.
break;
}
}
}
// Check to see if we have any newly failed virtual network.
// See wifi section for detailed comments.
if (!view) {
for (VirtualNetworkVector::const_iterator it = virtual_networks.begin();
it != virtual_networks.end(); it++) {
VirtualNetwork* vpn = *it;
if (vpn->failed()) {
NetworkFailureMap::iterator iter =
network_failures_.find(vpn->service_path());
if (iter == network_failures_.end())
continue; // New network.
if (iter->second)
continue; // Previous failure.
if (vpn->error() == ERROR_BAD_PASSPHRASE || vpn->added()) {
view = new NetworkConfigView(vpn);
break;
}
}
}
}
RefreshStoredNetworks(wifi_networks, virtual_networks);
// Show login box if necessary.
if (view)
CreateModalPopup(view);
}
} // namespace chromeos