network_screen.cc revision 3345a6884c488ff3a535c2c9acdd33d74b37e311
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 "app/l10n_util.h"
8#include "app/resource_bundle.h"
9#include "base/logging.h"
10#include "base/string16.h"
11#include "base/utf_string_conversions.h"
12#include "chrome/browser/chromeos/cros/cros_library.h"
13#include "chrome/browser/chromeos/login/help_app_launcher.h"
14#include "chrome/browser/chromeos/login/network_selection_view.h"
15#include "chrome/browser/chromeos/login/screen_observer.h"
16#include "grit/chromium_strings.h"
17#include "grit/generated_resources.h"
18#include "grit/theme_resources.h"
19#include "views/widget/widget.h"
20#include "views/window/window.h"
21
22
23namespace {
24
25// Time in seconds for connection timeout.
26const int kConnectionTimeoutSec = 15;
27
28// Considering 10px shadow from each side & welcome title height at 30px.
29const int kWelcomeScreenWidth = 580;
30const int kWelcomeScreenHeight = 335;
31
32}  // namespace
33
34namespace chromeos {
35
36///////////////////////////////////////////////////////////////////////////////
37// NetworkScreen, public:
38
39NetworkScreen::NetworkScreen(WizardScreenDelegate* delegate)
40    : ViewScreen<NetworkSelectionView>(delegate,
41                                       kWelcomeScreenWidth,
42                                       kWelcomeScreenHeight),
43      is_network_subscribed_(false),
44      continue_pressed_(false),
45      bubble_(NULL) {
46}
47
48NetworkScreen::~NetworkScreen() {
49  connection_timer_.Stop();
50  UnsubscribeNetworkNotification();
51}
52
53////////////////////////////////////////////////////////////////////////////////
54// NetworkScreen, NetworkScreenDelegate implementation:
55
56void NetworkScreen::ClearErrors() {
57  // bubble_ will be set to NULL in callback.
58  if (bubble_)
59    bubble_->Close();
60}
61
62///////////////////////////////////////////////////////////////////////////////
63// views::ButtonListener implementation:
64
65void NetworkScreen::ButtonPressed(views::Button* sender,
66                                  const views::Event& event) {
67  ClearErrors();
68  NetworkLibrary* network = CrosLibrary::Get()->GetNetworkLibrary();
69  if (network && network->Connected()) {
70    NotifyOnConnection();
71  } else {
72    continue_pressed_ = true;
73    WaitForConnection(network_id_);
74  }
75}
76
77////////////////////////////////////////////////////////////////////////////////
78// NetworkLibrary::Observer implementation:
79
80void NetworkScreen::NetworkChanged(NetworkLibrary* network_lib) {
81  UpdateStatus(network_lib);
82}
83
84///////////////////////////////////////////////////////////////////////////////
85// NetworkScreen, ViewScreen implementation:
86
87void NetworkScreen::CreateView() {
88  language_switch_menu_.InitLanguageMenu();
89  ViewScreen<NetworkSelectionView>::CreateView();
90}
91
92NetworkSelectionView* NetworkScreen::AllocateView() {
93  return new NetworkSelectionView(this);
94}
95
96///////////////////////////////////////////////////////////////////////////////
97// NetworkScreen, views::InfoBubbleDelegate implementation:
98
99void NetworkScreen::OnHelpLinkActivated() {
100  if (!help_app_.get())
101    help_app_.reset(new HelpAppLauncher(view()->GetNativeWindow()));
102  help_app_->ShowHelpTopic(HelpAppLauncher::HELP_CONNECTIVITY);
103}
104
105////////////////////////////////////////////////////////////////////////////////
106// NetworkScreen, public:
107
108void NetworkScreen::Refresh() {
109  if (CrosLibrary::Get()->EnsureLoaded()) {
110    SubscribeNetworkNotification();
111    NetworkChanged(chromeos::CrosLibrary::Get()->GetNetworkLibrary());
112  }
113}
114
115////////////////////////////////////////////////////////////////////////////////
116// NetworkScreen, private:
117
118void NetworkScreen::SubscribeNetworkNotification() {
119  if (!is_network_subscribed_) {
120    is_network_subscribed_ = true;
121    chromeos::CrosLibrary::Get()->GetNetworkLibrary()->AddObserver(this);
122  }
123}
124
125void NetworkScreen::UnsubscribeNetworkNotification() {
126  if (is_network_subscribed_) {
127    is_network_subscribed_ = false;
128    chromeos::CrosLibrary::Get()->GetNetworkLibrary()->RemoveObserver(this);
129  }
130}
131
132void NetworkScreen::NotifyOnConnection() {
133  // TODO(nkostylev): Check network connectivity.
134  UnsubscribeNetworkNotification();
135  connection_timer_.Stop();
136  delegate()->GetObserver(this)->OnExit(ScreenObserver::NETWORK_CONNECTED);
137}
138
139void NetworkScreen::OnConnectionTimeout() {
140  StopWaitingForConnection(network_id_);
141  // Show error bubble.
142  ClearErrors();
143  views::View* network_control = view()->GetNetworkControlView();
144  bubble_ = MessageBubble::Show(
145      network_control->GetWidget(),
146      network_control->GetScreenBounds(),
147      BubbleBorder::LEFT_TOP,
148      ResourceBundle::GetSharedInstance().GetBitmapNamed(IDR_WARNING),
149      l10n_util::GetStringF(IDS_NETWORK_SELECTION_ERROR,
150                            l10n_util::GetString(IDS_PRODUCT_OS_NAME),
151                            UTF16ToWide(network_id_)),
152      l10n_util::GetString(IDS_NETWORK_SELECTION_ERROR_HELP),
153      this);
154}
155
156void NetworkScreen::UpdateStatus(NetworkLibrary* network) {
157  if (!view() || !network)
158    return;
159
160  if (network->ethernet_connected()) {
161    StopWaitingForConnection(
162        l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_DEVICE_ETHERNET));
163  } else if (network->wifi_connected()) {
164    StopWaitingForConnection(ASCIIToUTF16(network->wifi_name()));
165  } else if (network->cellular_connected()) {
166    StopWaitingForConnection(ASCIIToUTF16(network->cellular_name()));
167  } else if (network->ethernet_connecting()) {
168    WaitForConnection(
169        l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_DEVICE_ETHERNET));
170  } else if (network->wifi_connecting()) {
171    WaitForConnection(ASCIIToUTF16(network->wifi_name()));
172  } else if (network->cellular_connecting()) {
173    WaitForConnection(ASCIIToUTF16(network->cellular_name()));
174  } else {
175    view()->EnableContinue(network->Connected());
176  }
177}
178
179void NetworkScreen::StopWaitingForConnection(const string16& network_id) {
180  NetworkLibrary* network = CrosLibrary::Get()->GetNetworkLibrary();
181  bool is_connected = network && network->Connected();
182  if (is_connected && continue_pressed_) {
183    NotifyOnConnection();
184    return;
185  }
186
187  continue_pressed_ = false;
188  connection_timer_.Stop();
189
190  network_id_ = network_id;
191  view()->ShowConnectingStatus(false, network_id_);
192  view()->EnableContinue(is_connected);
193}
194
195void NetworkScreen::WaitForConnection(const string16& network_id) {
196  connection_timer_.Stop();
197  connection_timer_.Start(base::TimeDelta::FromSeconds(kConnectionTimeoutSec),
198                          this,
199                          &NetworkScreen::OnConnectionTimeout);
200
201  network_id_ = network_id;
202  view()->ShowConnectingStatus(true, network_id_);
203
204  view()->EnableContinue(false);
205}
206
207}  // namespace chromeos
208