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/ui/webui/chromeos/login/network_screen_handler.h" 6 7#include "base/bind.h" 8#include "base/bind_helpers.h" 9#include "base/memory/weak_ptr.h" 10#include "base/strings/stringprintf.h" 11#include "base/strings/utf_string_conversions.h" 12#include "base/values.h" 13#include "chrome/browser/browser_process.h" 14#include "chrome/browser/chromeos/base/locale_util.h" 15#include "chrome/browser/chromeos/input_method/input_method_util.h" 16#include "chrome/browser/chromeos/login/input_events_blocker.h" 17#include "chrome/browser/chromeos/login/screens/core_oobe_actor.h" 18#include "chrome/browser/chromeos/system/input_device_settings.h" 19#include "chrome/browser/chromeos/system/timezone_util.h" 20#include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h" 21#include "chrome/browser/ui/webui/options/chromeos/cros_language_options_handler.h" 22#include "chromeos/ime/input_method_manager.h" 23#include "grit/chromium_strings.h" 24#include "grit/generated_resources.h" 25#include "ui/gfx/rect.h" 26#include "ui/views/layout/fill_layout.h" 27#include "ui/views/widget/widget.h" 28 29namespace { 30 31const char kJsScreenPath[] = "login.NetworkScreen"; 32 33// JS API callbacks names. 34const char kJsApiNetworkOnExit[] = "networkOnExit"; 35const char kJsApiNetworkOnLanguageChanged[] = "networkOnLanguageChanged"; 36const char kJsApiNetworkOnInputMethodChanged[] = "networkOnInputMethodChanged"; 37const char kJsApiNetworkOnTimezoneChanged[] = "networkOnTimezoneChanged"; 38 39} // namespace 40 41namespace chromeos { 42 43// NetworkScreenHandler, public: ----------------------------------------------- 44 45NetworkScreenHandler::NetworkScreenHandler(CoreOobeActor* core_oobe_actor) 46 : BaseScreenHandler(kJsScreenPath), 47 screen_(NULL), 48 core_oobe_actor_(core_oobe_actor), 49 is_continue_enabled_(false), 50 show_on_init_(false), 51 weak_ptr_factory_(this) { 52 DCHECK(core_oobe_actor_); 53} 54 55NetworkScreenHandler::~NetworkScreenHandler() { 56 if (screen_) 57 screen_->OnActorDestroyed(this); 58} 59 60// NetworkScreenHandler, NetworkScreenActor implementation: -------------------- 61 62void NetworkScreenHandler::SetDelegate(NetworkScreenActor::Delegate* screen) { 63 screen_ = screen; 64} 65 66void NetworkScreenHandler::PrepareToShow() { 67} 68 69void NetworkScreenHandler::Show() { 70 if (!page_is_ready()) { 71 show_on_init_ = true; 72 return; 73 } 74 75 ShowScreen(OobeUI::kScreenOobeNetwork, NULL); 76} 77 78void NetworkScreenHandler::Hide() { 79} 80 81void NetworkScreenHandler::ShowError(const base::string16& message) { 82 CallJS("showError", message); 83} 84 85void NetworkScreenHandler::ClearErrors() { 86 if (page_is_ready()) 87 core_oobe_actor_->ClearErrors(); 88} 89 90void NetworkScreenHandler::ShowConnectingStatus( 91 bool connecting, 92 const base::string16& network_id) { 93 // base::string16 connecting_label = 94 // l10n_util::GetStringFUTF16(IDS_NETWORK_SELECTION_CONNECTING, 95 // network_id); 96 // CallJS("cr.ui.Oobe.showConnectingStatus", 97 // base::FundamentalValue(connecting), 98 // base::StringValue(network_id), 99 // base::StringValue(connecting_label_value)); 100} 101 102void NetworkScreenHandler::EnableContinue(bool enabled) { 103 is_continue_enabled_ = enabled; 104 if (page_is_ready()) 105 CallJS("enableContinueButton", enabled); 106} 107 108// NetworkScreenHandler, BaseScreenHandler implementation: -------------------- 109 110void NetworkScreenHandler::DeclareLocalizedValues( 111 LocalizedValuesBuilder* builder) { 112 if (system::keyboard_settings::ForceKeyboardDrivenUINavigation()) 113 builder->Add("networkScreenGreeting", IDS_REMORA_CONFIRM_MESSAGE); 114 else 115 builder->Add("networkScreenGreeting", IDS_WELCOME_SCREEN_GREETING); 116 117 builder->Add("networkScreenTitle", IDS_WELCOME_SCREEN_TITLE); 118 builder->Add("selectLanguage", IDS_LANGUAGE_SELECTION_SELECT); 119 builder->Add("selectKeyboard", IDS_KEYBOARD_SELECTION_SELECT); 120 builder->Add("selectNetwork", IDS_NETWORK_SELECTION_SELECT); 121 builder->Add("selectTimezone", IDS_OPTIONS_SETTINGS_TIMEZONE_DESCRIPTION); 122 builder->Add("proxySettings", IDS_OPTIONS_PROXIES_CONFIGURE_BUTTON); 123 builder->Add("continueButton", IDS_NETWORK_SELECTION_CONTINUE_BUTTON); 124} 125 126void NetworkScreenHandler::GetAdditionalParameters( 127 base::DictionaryValue* dict) { 128 dict->Set("languageList", GetLanguageList()); 129 dict->Set("inputMethodsList", GetInputMethods()); 130 dict->Set("timezoneList", GetTimezoneList()); 131} 132 133void NetworkScreenHandler::Initialize() { 134 EnableContinue(is_continue_enabled_); 135 if (show_on_init_) { 136 show_on_init_ = false; 137 Show(); 138 } 139 140 timezone_subscription_ = CrosSettings::Get()->AddSettingsObserver( 141 kSystemTimezone, 142 base::Bind(&NetworkScreenHandler::OnSystemTimezoneChanged, 143 base::Unretained(this))); 144 OnSystemTimezoneChanged(); 145} 146 147// NetworkScreenHandler, WebUIMessageHandler implementation: ------------------- 148 149void NetworkScreenHandler::RegisterMessages() { 150 AddCallback(kJsApiNetworkOnExit, &NetworkScreenHandler::HandleOnExit); 151 AddCallback(kJsApiNetworkOnLanguageChanged, 152 &NetworkScreenHandler::HandleOnLanguageChanged); 153 AddCallback(kJsApiNetworkOnInputMethodChanged, 154 &NetworkScreenHandler::HandleOnInputMethodChanged); 155 AddCallback(kJsApiNetworkOnTimezoneChanged, 156 &NetworkScreenHandler::HandleOnTimezoneChanged); 157} 158 159// NetworkScreenHandler, private: ---------------------------------------------- 160 161void NetworkScreenHandler::HandleOnExit() { 162 ClearErrors(); 163 if (screen_) 164 screen_->OnContinuePressed(); 165} 166 167struct NetworkScreenHandlerOnLanguageChangedCallbackData { 168 explicit NetworkScreenHandlerOnLanguageChangedCallbackData( 169 base::WeakPtr<NetworkScreenHandler>& handler) 170 : handler_(handler) {} 171 172 base::WeakPtr<NetworkScreenHandler> handler_; 173 174 // Block UI while resource bundle is being reloaded. 175 chromeos::InputEventsBlocker input_events_blocker; 176}; 177 178// static 179void NetworkScreenHandler::OnLanguageChangedCallback( 180 scoped_ptr<NetworkScreenHandlerOnLanguageChangedCallbackData> context, 181 const std::string& /*requested locale*/, 182 const std::string& /*loaded_locale*/, 183 const bool /*success*/) { 184 if (!context or !context->handler_) 185 return; 186 187 NetworkScreenHandler* const self = context->handler_.get(); 188 189 DictionaryValue localized_strings; 190 static_cast<OobeUI*>(self->web_ui()->GetController()) 191 ->GetLocalizedStrings(&localized_strings); 192 self->core_oobe_actor_->ReloadContent(localized_strings); 193 194 // Buttons are recreated, updated "Continue" button state. 195 self->EnableContinue(self->is_continue_enabled_); 196} 197 198void NetworkScreenHandler::HandleOnLanguageChanged(const std::string& locale) { 199 const std::string app_locale = g_browser_process->GetApplicationLocale(); 200 if (app_locale == locale) 201 return; 202 203 base::WeakPtr<NetworkScreenHandler> weak_self = 204 weak_ptr_factory_.GetWeakPtr(); 205 scoped_ptr<NetworkScreenHandlerOnLanguageChangedCallbackData> callback_data( 206 new NetworkScreenHandlerOnLanguageChangedCallbackData(weak_self)); 207 scoped_ptr<locale_util::SwitchLanguageCallback> callback( 208 new locale_util::SwitchLanguageCallback( 209 base::Bind(&NetworkScreenHandler::OnLanguageChangedCallback, 210 base::Passed(callback_data.Pass())))); 211 locale_util::SwitchLanguage(locale, true, callback.Pass()); 212} 213 214void NetworkScreenHandler::HandleOnInputMethodChanged(const std::string& id) { 215 input_method::InputMethodManager::Get()->ChangeInputMethod(id); 216} 217 218void NetworkScreenHandler::HandleOnTimezoneChanged( 219 const std::string& timezone_id) { 220 std::string current_timezone_id; 221 CrosSettings::Get()->GetString(kSystemTimezone, ¤t_timezone_id); 222 if (current_timezone_id == timezone_id) 223 return; 224 225 CrosSettings::Get()->SetString(kSystemTimezone, timezone_id); 226} 227 228void NetworkScreenHandler::OnSystemTimezoneChanged() { 229 std::string current_timezone_id; 230 CrosSettings::Get()->GetString(kSystemTimezone, ¤t_timezone_id); 231 CallJS("setTimezone", current_timezone_id); 232} 233 234// static 235ListValue* NetworkScreenHandler::GetLanguageList() { 236 const std::string app_locale = g_browser_process->GetApplicationLocale(); 237 input_method::InputMethodManager* manager = 238 input_method::InputMethodManager::Get(); 239 // GetSupportedInputMethods() never returns NULL. 240 scoped_ptr<input_method::InputMethodDescriptors> descriptors( 241 manager->GetSupportedInputMethods()); 242 ListValue* languages_list = 243 options::CrosLanguageOptionsHandler::GetUILanguageList(*descriptors); 244 for (size_t i = 0; i < languages_list->GetSize(); ++i) { 245 DictionaryValue* language_info = NULL; 246 if (!languages_list->GetDictionary(i, &language_info)) 247 NOTREACHED(); 248 249 std::string value; 250 language_info->GetString("code", &value); 251 std::string display_name; 252 language_info->GetString("displayName", &display_name); 253 std::string native_name; 254 language_info->GetString("nativeDisplayName", &native_name); 255 256 if (display_name != native_name) 257 display_name = base::StringPrintf("%s - %s", 258 display_name.c_str(), 259 native_name.c_str()); 260 261 language_info->SetString("value", value); 262 language_info->SetString("title", display_name); 263 language_info->SetBoolean("selected", value == app_locale); 264 } 265 return languages_list; 266} 267 268// static 269ListValue* NetworkScreenHandler::GetInputMethods() { 270 ListValue* input_methods_list = new ListValue; 271 input_method::InputMethodManager* manager = 272 input_method::InputMethodManager::Get(); 273 input_method::InputMethodUtil* util = manager->GetInputMethodUtil(); 274 scoped_ptr<input_method::InputMethodDescriptors> input_methods( 275 manager->GetActiveInputMethods()); 276 std::string current_input_method_id = manager->GetCurrentInputMethod().id(); 277 for (size_t i = 0; i < input_methods->size(); ++i) { 278 const std::string ime_id = input_methods->at(i).id(); 279 DictionaryValue* input_method = new DictionaryValue; 280 input_method->SetString("value", ime_id); 281 input_method->SetString( 282 "title", 283 util->GetInputMethodLongName(input_methods->at(i))); 284 input_method->SetBoolean("selected", 285 ime_id == current_input_method_id); 286 input_methods_list->Append(input_method); 287 } 288 return input_methods_list; 289} 290 291// static 292base::ListValue* NetworkScreenHandler::GetTimezoneList() { 293 std::string current_timezone_id; 294 CrosSettings::Get()->GetString(kSystemTimezone, ¤t_timezone_id); 295 296 scoped_ptr<base::ListValue> timezone_list(new base::ListValue); 297 scoped_ptr<base::ListValue> timezones = system::GetTimezoneList().Pass(); 298 for (size_t i = 0; i < timezones->GetSize(); ++i) { 299 const base::ListValue* timezone = NULL; 300 CHECK(timezones->GetList(i, &timezone)); 301 302 std::string timezone_id; 303 CHECK(timezone->GetString(0, &timezone_id)); 304 305 std::string timezone_name; 306 CHECK(timezone->GetString(1, &timezone_name)); 307 308 scoped_ptr<base::DictionaryValue> timezone_option( 309 new base::DictionaryValue); 310 timezone_option->SetString("value", timezone_id); 311 timezone_option->SetString("title", timezone_name); 312 timezone_option->SetBoolean("selected", timezone_id == current_timezone_id); 313 timezone_list->Append(timezone_option.release()); 314 } 315 316 return timezone_list.release(); 317} 318 319} // namespace chromeos 320