普通文本  |  223行  |  6.94 KB

// Copyright (c) 2010 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/network_screen.h"

#include "base/logging.h"
#include "base/string16.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/chromeos/cros/cros_library.h"
#include "chrome/browser/chromeos/login/background_view.h"
#include "chrome/browser/chromeos/login/helper.h"
#include "chrome/browser/chromeos/login/help_app_launcher.h"
#include "chrome/browser/chromeos/login/login_utils.h"
#include "chrome/browser/chromeos/login/network_selection_view.h"
#include "chrome/browser/chromeos/login/screen_observer.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "views/controls/menu/menu_2.h"
#include "views/widget/widget.h"
#include "views/window/window.h"


namespace {

// Time in seconds for connection timeout.
const int kConnectionTimeoutSec = 15;

// Considering 10px shadow from each side & welcome title height at 30px.
const int kWelcomeScreenWidth = 580;
const int kWelcomeScreenHeight = 335;

}  // namespace

namespace chromeos {

///////////////////////////////////////////////////////////////////////////////
// NetworkScreen, public:

NetworkScreen::NetworkScreen(WizardScreenDelegate* delegate)
    : ViewScreen<NetworkSelectionView>(delegate,
                                       kWelcomeScreenWidth,
                                       kWelcomeScreenHeight),
      is_network_subscribed_(false),
      continue_pressed_(false),
      bubble_(NULL) {
  language_switch_menu_.set_menu_alignment(views::Menu2::ALIGN_TOPLEFT);
}

NetworkScreen::~NetworkScreen() {
  connection_timer_.Stop();
  UnsubscribeNetworkNotification();
}

////////////////////////////////////////////////////////////////////////////////
// NetworkScreen, NetworkScreenDelegate implementation:

void NetworkScreen::ClearErrors() {
  // bubble_ will be set to NULL in callback.
  if (bubble_)
    bubble_->Close();
}

///////////////////////////////////////////////////////////////////////////////
// views::ButtonListener implementation:

void NetworkScreen::ButtonPressed(views::Button* sender,
                                  const views::Event& event) {
  ClearErrors();
  NetworkLibrary* network = CrosLibrary::Get()->GetNetworkLibrary();
  if (network && network->Connected()) {
    NotifyOnConnection();
  } else {
    continue_pressed_ = true;
    WaitForConnection(network_id_);
  }
}

////////////////////////////////////////////////////////////////////////////////
// NetworkLibrary::NetworkManagerObserver implementation:

void NetworkScreen::OnNetworkManagerChanged(NetworkLibrary* network_lib) {
  UpdateStatus(network_lib);
}

///////////////////////////////////////////////////////////////////////////////
// NetworkScreen, ViewScreen implementation:

void NetworkScreen::CreateView() {
  language_switch_menu_.InitLanguageMenu();
  ViewScreen<NetworkSelectionView>::CreateView();
}

NetworkSelectionView* NetworkScreen::AllocateView() {
  return new NetworkSelectionView(this);
}

///////////////////////////////////////////////////////////////////////////////
// NetworkScreen, views::BubbleDelegate implementation:

void NetworkScreen::OnHelpLinkActivated() {
  ClearErrors();
  if (!help_app_.get()) {
    help_app_ = new HelpAppLauncher(
        LoginUtils::Get()->GetBackgroundView()->GetNativeWindow());
  }
  help_app_->ShowHelpTopic(HelpAppLauncher::HELP_CONNECTIVITY);
}

////////////////////////////////////////////////////////////////////////////////
// NetworkScreen, public:

void NetworkScreen::Refresh() {
  if (CrosLibrary::Get()->EnsureLoaded()) {
    SubscribeNetworkNotification();
    OnNetworkManagerChanged(chromeos::CrosLibrary::Get()->GetNetworkLibrary());
  }
}

////////////////////////////////////////////////////////////////////////////////
// NetworkScreen, private:

void NetworkScreen::SubscribeNetworkNotification() {
  if (!is_network_subscribed_) {
    is_network_subscribed_ = true;
    chromeos::CrosLibrary::Get()->GetNetworkLibrary()
        ->AddNetworkManagerObserver(this);
  }
}

void NetworkScreen::UnsubscribeNetworkNotification() {
  if (is_network_subscribed_) {
    is_network_subscribed_ = false;
    chromeos::CrosLibrary::Get()->GetNetworkLibrary()
        ->RemoveNetworkManagerObserver(this);
  }
}

void NetworkScreen::NotifyOnConnection() {
  // TODO(nkostylev): Check network connectivity.
  UnsubscribeNetworkNotification();
  connection_timer_.Stop();
  delegate()->GetObserver(this)->OnExit(ScreenObserver::NETWORK_CONNECTED);
}

void NetworkScreen::OnConnectionTimeout() {
  StopWaitingForConnection(network_id_);
  NetworkLibrary* network = CrosLibrary::Get()->GetNetworkLibrary();
  bool is_connected = network && network->Connected();

  if (!is_connected &&
      !view()->is_dialog_open() &&
      !(help_app_.get() && help_app_->is_open())) {
    // Show error bubble.
    ClearErrors();
    views::View* network_control = view()->GetNetworkControlView();
    bubble_ = MessageBubble::Show(
        network_control->GetWidget(),
        network_control->GetScreenBounds(),
        BubbleBorder::LEFT_TOP,
        ResourceBundle::GetSharedInstance().GetBitmapNamed(IDR_WARNING),
        UTF16ToWide(l10n_util::GetStringFUTF16(
            IDS_NETWORK_SELECTION_ERROR,
            l10n_util::GetStringUTF16(IDS_PRODUCT_OS_NAME),
            network_id_)),
        UTF16ToWide(l10n_util::GetStringUTF16(IDS_LEARN_MORE)),
        this);
    network_control->RequestFocus();
  }
}

void NetworkScreen::UpdateStatus(NetworkLibrary* network) {
  if (!view() || !network)
    return;

  if (network->Connected())
    ClearErrors();

  string16 network_name = GetCurrentNetworkName(network);
  if (network->Connected()) {
    StopWaitingForConnection(network_name);
  } else if (network->Connecting()) {
    WaitForConnection(network_name);
  } else {
    StopWaitingForConnection(network_id_);
  }
}

void NetworkScreen::StopWaitingForConnection(const string16& network_id) {
  NetworkLibrary* network = CrosLibrary::Get()->GetNetworkLibrary();
  bool is_connected = network && network->Connected();
  if (is_connected && continue_pressed_) {
    NotifyOnConnection();
    return;
  }

  continue_pressed_ = false;
  connection_timer_.Stop();

  network_id_ = network_id;
  view()->ShowConnectingStatus(false, network_id_);
  view()->EnableContinue(is_connected);
}

void NetworkScreen::WaitForConnection(const string16& network_id) {
  if (network_id_ != network_id || !connection_timer_.IsRunning()) {
    connection_timer_.Stop();
    connection_timer_.Start(base::TimeDelta::FromSeconds(kConnectionTimeoutSec),
                            this,
                            &NetworkScreen::OnConnectionTimeout);
  }

  network_id_ = network_id;
  view()->ShowConnectingStatus(continue_pressed_, network_id_);

  view()->EnableContinue(false);
}

}  // namespace chromeos