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