blob: 3bd7844a211906b34f5d875dd00479542211a659 [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/login/screens/network_screen.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/chromeos/login/help_app_launcher.h"
#include "chrome/browser/chromeos/login/helper.h"
#include "chrome/browser/chromeos/login/login_utils.h"
#include "chrome/browser/chromeos/login/screen_manager.h"
#include "chrome/browser/chromeos/login/screens/screen_observer.h"
#include "chrome/browser/chromeos/login/wizard_controller.h"
#include "chrome/grit/chromium_strings.h"
#include "chrome/grit/generated_resources.h"
#include "chromeos/network/network_handler.h"
#include "chromeos/network/network_state_handler.h"
#include "ui/base/l10n/l10n_util.h"
namespace {
// Time in seconds for connection timeout.
const int kConnectionTimeoutSec = 40;
} // namespace
namespace chromeos {
///////////////////////////////////////////////////////////////////////////////
// NetworkScreen, public:
// static
NetworkScreen* NetworkScreen::Get(ScreenManager* manager) {
return static_cast<NetworkScreen*>(
manager->GetScreen(WizardController::kNetworkScreenName));
}
NetworkScreen::NetworkScreen(ScreenObserver* screen_observer,
NetworkScreenActor* actor)
: BaseScreen(screen_observer),
is_network_subscribed_(false),
continue_pressed_(false),
actor_(actor),
network_state_helper_(new login::NetworkStateHelper) {
DCHECK(actor_);
if (actor_)
actor_->SetDelegate(this);
}
NetworkScreen::~NetworkScreen() {
if (actor_)
actor_->SetDelegate(NULL);
connection_timer_.Stop();
UnsubscribeNetworkNotification();
}
////////////////////////////////////////////////////////////////////////////////
// NetworkScreen, BaseScreen implementation:
void NetworkScreen::PrepareToShow() {
if (actor_)
actor_->PrepareToShow();
}
void NetworkScreen::Show() {
Refresh();
if (actor_)
actor_->Show();
}
void NetworkScreen::Hide() {
if (actor_)
actor_->Hide();
}
std::string NetworkScreen::GetName() const {
return WizardController::kNetworkScreenName;
}
////////////////////////////////////////////////////////////////////////////////
// NetworkScreen, NetworkStateHandlerObserver implementation:
void NetworkScreen::NetworkConnectionStateChanged(const NetworkState* network) {
UpdateStatus();
}
void NetworkScreen::DefaultNetworkChanged(const NetworkState* network) {
UpdateStatus();
}
////////////////////////////////////////////////////////////////////////////////
// NetworkScreen, public:
void NetworkScreen::Refresh() {
SubscribeNetworkNotification();
UpdateStatus();
}
///////////////////////////////////////////////////////////////////////////////
// NetworkScreen, NetworkScreenActor::Delegate implementation:
void NetworkScreen::OnActorDestroyed(NetworkScreenActor* actor) {
if (actor_ == actor)
actor_ = NULL;
}
void NetworkScreen::OnContinuePressed() {
if (network_state_helper_->IsConnected()) {
NotifyOnConnection();
} else {
continue_pressed_ = true;
WaitForConnection(network_id_);
}
}
////////////////////////////////////////////////////////////////////////////////
// NetworkScreen, private:
void NetworkScreen::SetNetworkStateHelperForTest(
login::NetworkStateHelper* helper) {
network_state_helper_.reset(helper);
}
void NetworkScreen::SubscribeNetworkNotification() {
if (!is_network_subscribed_) {
is_network_subscribed_ = true;
NetworkHandler::Get()->network_state_handler()->AddObserver(
this, FROM_HERE);
}
}
void NetworkScreen::UnsubscribeNetworkNotification() {
if (is_network_subscribed_) {
is_network_subscribed_ = false;
NetworkHandler::Get()->network_state_handler()->RemoveObserver(
this, FROM_HERE);
}
}
void NetworkScreen::NotifyOnConnection() {
// TODO(nkostylev): Check network connectivity.
UnsubscribeNetworkNotification();
connection_timer_.Stop();
get_screen_observer()->OnExit(ScreenObserver::NETWORK_CONNECTED);
}
void NetworkScreen::OnConnectionTimeout() {
StopWaitingForConnection(network_id_);
if (!network_state_helper_->IsConnected() && actor_) {
// Show error bubble.
actor_->ShowError(
l10n_util::GetStringFUTF16(
IDS_NETWORK_SELECTION_ERROR,
l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_OS_NAME),
network_id_));
}
}
void NetworkScreen::UpdateStatus() {
if (!actor_)
return;
bool is_connected = network_state_helper_->IsConnected();
if (is_connected)
actor_->ClearErrors();
base::string16 network_name = network_state_helper_->GetCurrentNetworkName();
if (is_connected) {
StopWaitingForConnection(network_name);
} else if (network_state_helper_->IsConnecting()) {
WaitForConnection(network_name);
} else {
StopWaitingForConnection(network_id_);
}
}
void NetworkScreen::StopWaitingForConnection(const base::string16& network_id) {
bool is_connected = network_state_helper_->IsConnected();
if (is_connected && continue_pressed_) {
NotifyOnConnection();
return;
}
continue_pressed_ = false;
connection_timer_.Stop();
network_id_ = network_id;
if (actor_) {
actor_->ShowConnectingStatus(false, network_id_);
actor_->EnableContinue(is_connected);
}
}
void NetworkScreen::WaitForConnection(const base::string16& network_id) {
if (network_id_ != network_id || !connection_timer_.IsRunning()) {
connection_timer_.Stop();
connection_timer_.Start(FROM_HERE,
base::TimeDelta::FromSeconds(kConnectionTimeoutSec),
this,
&NetworkScreen::OnConnectionTimeout);
}
network_id_ = network_id;
if (actor_) {
actor_->ShowConnectingStatus(continue_pressed_, network_id_);
actor_->EnableContinue(false);
}
}
} // namespace chromeos