Home | History | Annotate | Download | only in login
      1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/chromeos/login/network_screen.h"
      6 
      7 #include "base/logging.h"
      8 #include "base/string16.h"
      9 #include "base/utf_string_conversions.h"
     10 #include "chrome/browser/chromeos/cros/cros_library.h"
     11 #include "chrome/browser/chromeos/login/background_view.h"
     12 #include "chrome/browser/chromeos/login/helper.h"
     13 #include "chrome/browser/chromeos/login/help_app_launcher.h"
     14 #include "chrome/browser/chromeos/login/login_utils.h"
     15 #include "chrome/browser/chromeos/login/network_selection_view.h"
     16 #include "chrome/browser/chromeos/login/screen_observer.h"
     17 #include "grit/chromium_strings.h"
     18 #include "grit/generated_resources.h"
     19 #include "grit/theme_resources.h"
     20 #include "ui/base/l10n/l10n_util.h"
     21 #include "ui/base/resource/resource_bundle.h"
     22 #include "views/controls/menu/menu_2.h"
     23 #include "views/widget/widget.h"
     24 #include "views/window/window.h"
     25 
     26 
     27 namespace {
     28 
     29 // Time in seconds for connection timeout.
     30 const int kConnectionTimeoutSec = 15;
     31 
     32 // Considering 10px shadow from each side & welcome title height at 30px.
     33 const int kWelcomeScreenWidth = 580;
     34 const int kWelcomeScreenHeight = 335;
     35 
     36 }  // namespace
     37 
     38 namespace chromeos {
     39 
     40 ///////////////////////////////////////////////////////////////////////////////
     41 // NetworkScreen, public:
     42 
     43 NetworkScreen::NetworkScreen(WizardScreenDelegate* delegate)
     44     : ViewScreen<NetworkSelectionView>(delegate,
     45                                        kWelcomeScreenWidth,
     46                                        kWelcomeScreenHeight),
     47       is_network_subscribed_(false),
     48       continue_pressed_(false),
     49       bubble_(NULL) {
     50   language_switch_menu_.set_menu_alignment(views::Menu2::ALIGN_TOPLEFT);
     51 }
     52 
     53 NetworkScreen::~NetworkScreen() {
     54   connection_timer_.Stop();
     55   UnsubscribeNetworkNotification();
     56 }
     57 
     58 ////////////////////////////////////////////////////////////////////////////////
     59 // NetworkScreen, NetworkScreenDelegate implementation:
     60 
     61 void NetworkScreen::ClearErrors() {
     62   // bubble_ will be set to NULL in callback.
     63   if (bubble_)
     64     bubble_->Close();
     65 }
     66 
     67 ///////////////////////////////////////////////////////////////////////////////
     68 // views::ButtonListener implementation:
     69 
     70 void NetworkScreen::ButtonPressed(views::Button* sender,
     71                                   const views::Event& event) {
     72   ClearErrors();
     73   NetworkLibrary* network = CrosLibrary::Get()->GetNetworkLibrary();
     74   if (network && network->Connected()) {
     75     NotifyOnConnection();
     76   } else {
     77     continue_pressed_ = true;
     78     WaitForConnection(network_id_);
     79   }
     80 }
     81 
     82 ////////////////////////////////////////////////////////////////////////////////
     83 // NetworkLibrary::NetworkManagerObserver implementation:
     84 
     85 void NetworkScreen::OnNetworkManagerChanged(NetworkLibrary* network_lib) {
     86   UpdateStatus(network_lib);
     87 }
     88 
     89 ///////////////////////////////////////////////////////////////////////////////
     90 // NetworkScreen, ViewScreen implementation:
     91 
     92 void NetworkScreen::CreateView() {
     93   language_switch_menu_.InitLanguageMenu();
     94   ViewScreen<NetworkSelectionView>::CreateView();
     95 }
     96 
     97 NetworkSelectionView* NetworkScreen::AllocateView() {
     98   return new NetworkSelectionView(this);
     99 }
    100 
    101 ///////////////////////////////////////////////////////////////////////////////
    102 // NetworkScreen, views::BubbleDelegate implementation:
    103 
    104 void NetworkScreen::OnHelpLinkActivated() {
    105   ClearErrors();
    106   if (!help_app_.get()) {
    107     help_app_ = new HelpAppLauncher(
    108         LoginUtils::Get()->GetBackgroundView()->GetNativeWindow());
    109   }
    110   help_app_->ShowHelpTopic(HelpAppLauncher::HELP_CONNECTIVITY);
    111 }
    112 
    113 ////////////////////////////////////////////////////////////////////////////////
    114 // NetworkScreen, public:
    115 
    116 void NetworkScreen::Refresh() {
    117   if (CrosLibrary::Get()->EnsureLoaded()) {
    118     SubscribeNetworkNotification();
    119     OnNetworkManagerChanged(chromeos::CrosLibrary::Get()->GetNetworkLibrary());
    120   }
    121 }
    122 
    123 ////////////////////////////////////////////////////////////////////////////////
    124 // NetworkScreen, private:
    125 
    126 void NetworkScreen::SubscribeNetworkNotification() {
    127   if (!is_network_subscribed_) {
    128     is_network_subscribed_ = true;
    129     chromeos::CrosLibrary::Get()->GetNetworkLibrary()
    130         ->AddNetworkManagerObserver(this);
    131   }
    132 }
    133 
    134 void NetworkScreen::UnsubscribeNetworkNotification() {
    135   if (is_network_subscribed_) {
    136     is_network_subscribed_ = false;
    137     chromeos::CrosLibrary::Get()->GetNetworkLibrary()
    138         ->RemoveNetworkManagerObserver(this);
    139   }
    140 }
    141 
    142 void NetworkScreen::NotifyOnConnection() {
    143   // TODO(nkostylev): Check network connectivity.
    144   UnsubscribeNetworkNotification();
    145   connection_timer_.Stop();
    146   delegate()->GetObserver(this)->OnExit(ScreenObserver::NETWORK_CONNECTED);
    147 }
    148 
    149 void NetworkScreen::OnConnectionTimeout() {
    150   StopWaitingForConnection(network_id_);
    151   NetworkLibrary* network = CrosLibrary::Get()->GetNetworkLibrary();
    152   bool is_connected = network && network->Connected();
    153 
    154   if (!is_connected &&
    155       !view()->is_dialog_open() &&
    156       !(help_app_.get() && help_app_->is_open())) {
    157     // Show error bubble.
    158     ClearErrors();
    159     views::View* network_control = view()->GetNetworkControlView();
    160     bubble_ = MessageBubble::Show(
    161         network_control->GetWidget(),
    162         network_control->GetScreenBounds(),
    163         BubbleBorder::LEFT_TOP,
    164         ResourceBundle::GetSharedInstance().GetBitmapNamed(IDR_WARNING),
    165         UTF16ToWide(l10n_util::GetStringFUTF16(
    166             IDS_NETWORK_SELECTION_ERROR,
    167             l10n_util::GetStringUTF16(IDS_PRODUCT_OS_NAME),
    168             network_id_)),
    169         UTF16ToWide(l10n_util::GetStringUTF16(IDS_LEARN_MORE)),
    170         this);
    171     network_control->RequestFocus();
    172   }
    173 }
    174 
    175 void NetworkScreen::UpdateStatus(NetworkLibrary* network) {
    176   if (!view() || !network)
    177     return;
    178 
    179   if (network->Connected())
    180     ClearErrors();
    181 
    182   string16 network_name = GetCurrentNetworkName(network);
    183   if (network->Connected()) {
    184     StopWaitingForConnection(network_name);
    185   } else if (network->Connecting()) {
    186     WaitForConnection(network_name);
    187   } else {
    188     StopWaitingForConnection(network_id_);
    189   }
    190 }
    191 
    192 void NetworkScreen::StopWaitingForConnection(const string16& network_id) {
    193   NetworkLibrary* network = CrosLibrary::Get()->GetNetworkLibrary();
    194   bool is_connected = network && network->Connected();
    195   if (is_connected && continue_pressed_) {
    196     NotifyOnConnection();
    197     return;
    198   }
    199 
    200   continue_pressed_ = false;
    201   connection_timer_.Stop();
    202 
    203   network_id_ = network_id;
    204   view()->ShowConnectingStatus(false, network_id_);
    205   view()->EnableContinue(is_connected);
    206 }
    207 
    208 void NetworkScreen::WaitForConnection(const string16& network_id) {
    209   if (network_id_ != network_id || !connection_timer_.IsRunning()) {
    210     connection_timer_.Stop();
    211     connection_timer_.Start(base::TimeDelta::FromSeconds(kConnectionTimeoutSec),
    212                             this,
    213                             &NetworkScreen::OnConnectionTimeout);
    214   }
    215 
    216   network_id_ = network_id;
    217   view()->ShowConnectingStatus(continue_pressed_, network_id_);
    218 
    219   view()->EnableContinue(false);
    220 }
    221 
    222 }  // namespace chromeos
    223