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
NetworkScreen(WizardScreenDelegate * delegate)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
~NetworkScreen()53 NetworkScreen::~NetworkScreen() {
54 connection_timer_.Stop();
55 UnsubscribeNetworkNotification();
56 }
57
58 ////////////////////////////////////////////////////////////////////////////////
59 // NetworkScreen, NetworkScreenDelegate implementation:
60
ClearErrors()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
ButtonPressed(views::Button * sender,const views::Event & event)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
OnNetworkManagerChanged(NetworkLibrary * network_lib)85 void NetworkScreen::OnNetworkManagerChanged(NetworkLibrary* network_lib) {
86 UpdateStatus(network_lib);
87 }
88
89 ///////////////////////////////////////////////////////////////////////////////
90 // NetworkScreen, ViewScreen implementation:
91
CreateView()92 void NetworkScreen::CreateView() {
93 language_switch_menu_.InitLanguageMenu();
94 ViewScreen<NetworkSelectionView>::CreateView();
95 }
96
AllocateView()97 NetworkSelectionView* NetworkScreen::AllocateView() {
98 return new NetworkSelectionView(this);
99 }
100
101 ///////////////////////////////////////////////////////////////////////////////
102 // NetworkScreen, views::BubbleDelegate implementation:
103
OnHelpLinkActivated()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
Refresh()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
SubscribeNetworkNotification()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
UnsubscribeNetworkNotification()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
NotifyOnConnection()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
OnConnectionTimeout()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
UpdateStatus(NetworkLibrary * network)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
StopWaitingForConnection(const string16 & network_id)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
WaitForConnection(const string16 & network_id)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