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