network_screen.cc revision 6e8cce623b6e4fe0c9e4af605d675dd9d0338c38
1// Copyright (c) 2012 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/screens/network_screen.h"
6
7#include "base/location.h"
8#include "base/logging.h"
9#include "base/strings/string16.h"
10#include "base/strings/utf_string_conversions.h"
11#include "chrome/browser/chromeos/login/help_app_launcher.h"
12#include "chrome/browser/chromeos/login/helper.h"
13#include "chrome/browser/chromeos/login/login_utils.h"
14#include "chrome/browser/chromeos/login/screens/screen_observer.h"
15#include "chrome/browser/chromeos/login/wizard_controller.h"
16#include "chrome/grit/chromium_strings.h"
17#include "chrome/grit/generated_resources.h"
18#include "chrome/grit/theme_resources.h"
19#include "chromeos/network/network_handler.h"
20#include "chromeos/network/network_state_handler.h"
21#include "ui/base/l10n/l10n_util.h"
22
23namespace {
24
25// Time in seconds for connection timeout.
26const int kConnectionTimeoutSec = 40;
27
28}  // namespace
29
30namespace chromeos {
31
32///////////////////////////////////////////////////////////////////////////////
33// NetworkScreen, public:
34
35NetworkScreen::NetworkScreen(ScreenObserver* screen_observer,
36                             NetworkScreenActor* actor)
37    : WizardScreen(screen_observer),
38      is_network_subscribed_(false),
39      continue_pressed_(false),
40      actor_(actor),
41      network_state_helper_(new login::NetworkStateHelper) {
42  DCHECK(actor_);
43  if (actor_)
44    actor_->SetDelegate(this);
45}
46
47NetworkScreen::~NetworkScreen() {
48  if (actor_)
49    actor_->SetDelegate(NULL);
50  connection_timer_.Stop();
51  UnsubscribeNetworkNotification();
52}
53
54////////////////////////////////////////////////////////////////////////////////
55// NetworkScreen, WizardScreen implementation:
56
57void NetworkScreen::PrepareToShow() {
58  if (actor_)
59    actor_->PrepareToShow();
60}
61
62void NetworkScreen::Show() {
63  Refresh();
64  if (actor_)
65    actor_->Show();
66}
67
68void NetworkScreen::Hide() {
69  if (actor_)
70    actor_->Hide();
71}
72
73std::string NetworkScreen::GetName() const {
74  return WizardController::kNetworkScreenName;
75}
76
77////////////////////////////////////////////////////////////////////////////////
78// NetworkScreen, NetworkStateHandlerObserver implementation:
79
80void NetworkScreen::NetworkConnectionStateChanged(const NetworkState* network) {
81  UpdateStatus();
82}
83
84void NetworkScreen::DefaultNetworkChanged(const NetworkState* network) {
85  UpdateStatus();
86}
87
88////////////////////////////////////////////////////////////////////////////////
89// NetworkScreen, public:
90
91void NetworkScreen::Refresh() {
92  SubscribeNetworkNotification();
93  UpdateStatus();
94}
95
96///////////////////////////////////////////////////////////////////////////////
97// NetworkScreen, NetworkScreenActor::Delegate implementation:
98
99void NetworkScreen::OnActorDestroyed(NetworkScreenActor* actor) {
100  if (actor_ == actor)
101    actor_ = NULL;
102}
103
104void NetworkScreen::OnContinuePressed() {
105  if (network_state_helper_->IsConnected()) {
106    NotifyOnConnection();
107  } else {
108    continue_pressed_ = true;
109    WaitForConnection(network_id_);
110  }
111}
112
113////////////////////////////////////////////////////////////////////////////////
114// NetworkScreen, private:
115
116void NetworkScreen::SetNetworkStateHelperForTest(
117    login::NetworkStateHelper* helper) {
118  network_state_helper_.reset(helper);
119}
120
121void NetworkScreen::SubscribeNetworkNotification() {
122  if (!is_network_subscribed_) {
123    is_network_subscribed_ = true;
124    NetworkHandler::Get()->network_state_handler()->AddObserver(
125        this, FROM_HERE);
126  }
127}
128
129void NetworkScreen::UnsubscribeNetworkNotification() {
130  if (is_network_subscribed_) {
131    is_network_subscribed_ = false;
132    NetworkHandler::Get()->network_state_handler()->RemoveObserver(
133        this, FROM_HERE);
134  }
135}
136
137void NetworkScreen::NotifyOnConnection() {
138  // TODO(nkostylev): Check network connectivity.
139  UnsubscribeNetworkNotification();
140  connection_timer_.Stop();
141  get_screen_observer()->OnExit(ScreenObserver::NETWORK_CONNECTED);
142}
143
144void NetworkScreen::OnConnectionTimeout() {
145  StopWaitingForConnection(network_id_);
146  if (!network_state_helper_->IsConnected() && actor_) {
147    // Show error bubble.
148    actor_->ShowError(
149        l10n_util::GetStringFUTF16(
150            IDS_NETWORK_SELECTION_ERROR,
151            l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_OS_NAME),
152            network_id_));
153  }
154}
155
156void NetworkScreen::UpdateStatus() {
157  if (!actor_)
158    return;
159
160  bool is_connected = network_state_helper_->IsConnected();
161  if (is_connected)
162    actor_->ClearErrors();
163
164  base::string16 network_name = network_state_helper_->GetCurrentNetworkName();
165  if (is_connected) {
166    StopWaitingForConnection(network_name);
167  } else if (network_state_helper_->IsConnecting()) {
168    WaitForConnection(network_name);
169  } else {
170    StopWaitingForConnection(network_id_);
171  }
172}
173
174void NetworkScreen::StopWaitingForConnection(const base::string16& network_id) {
175  bool is_connected = network_state_helper_->IsConnected();
176  if (is_connected && continue_pressed_) {
177    NotifyOnConnection();
178    return;
179  }
180
181  continue_pressed_ = false;
182  connection_timer_.Stop();
183
184  network_id_ = network_id;
185  if (actor_) {
186    actor_->ShowConnectingStatus(false, network_id_);
187    actor_->EnableContinue(is_connected);
188  }
189}
190
191void NetworkScreen::WaitForConnection(const base::string16& network_id) {
192  if (network_id_ != network_id || !connection_timer_.IsRunning()) {
193    connection_timer_.Stop();
194    connection_timer_.Start(FROM_HERE,
195                            base::TimeDelta::FromSeconds(kConnectionTimeoutSec),
196                            this,
197                            &NetworkScreen::OnConnectionTimeout);
198  }
199
200  network_id_ = network_id;
201  if (actor_) {
202    actor_->ShowConnectingStatus(continue_pressed_, network_id_);
203    actor_->EnableContinue(false);
204  }
205}
206
207}  // namespace chromeos
208