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.
5 #include "chrome/browser/ui/webui/chromeos/login/network_screen_handler.h"
8 #include "base/bind_helpers.h"
9 #include "base/memory/weak_ptr.h"
10 #include "base/prefs/pref_service.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/accessibility/accessibility_manager.h"
15 #include "chrome/browser/chromeos/base/locale_util.h"
16 #include "chrome/browser/chromeos/customization_document.h"
17 #include "chrome/browser/chromeos/idle_detector.h"
18 #include "chrome/browser/chromeos/login/screens/core_oobe_actor.h"
19 #include "chrome/browser/chromeos/login/ui/input_events_blocker.h"
20 #include "chrome/browser/chromeos/system/input_device_settings.h"
21 #include "chrome/browser/chromeos/system/timezone_util.h"
22 #include "chrome/browser/ui/webui/chromeos/login/l10n_util.h"
23 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
24 #include "chrome/common/pref_names.h"
25 #include "chromeos/ime/extension_ime_util.h"
26 #include "chromeos/network/network_handler.h"
27 #include "chromeos/network/network_state_handler.h"
28 #include "grit/chromium_strings.h"
29 #include "grit/generated_resources.h"
30 #include "ui/base/l10n/l10n_util.h"
31 #include "ui/gfx/rect.h"
32 #include "ui/views/layout/fill_layout.h"
33 #include "ui/views/widget/widget.h"
37 const char kJsScreenPath[] = "login.NetworkScreen";
39 // JS API callbacks names.
40 const char kJsApiNetworkOnExit[] = "networkOnExit";
41 const char kJsApiNetworkOnLanguageChanged[] = "networkOnLanguageChanged";
42 const char kJsApiNetworkOnInputMethodChanged[] = "networkOnInputMethodChanged";
43 const char kJsApiNetworkOnTimezoneChanged[] = "networkOnTimezoneChanged";
45 // For "UI Language" drop-down menu at OOBE screen we need to decide which
46 // entry to mark "selected". If user has just selected "requested_locale",
47 // but "loaded_locale" was actually loaded, we mark original user choice
48 // "selected" only if loaded_locale is a backup for "requested_locale".
49 std::string CalculateSelectedLanguage(const std::string& requested_locale,
50 const std::string& loaded_locale) {
52 std::string resolved_locale;
53 if (!l10n_util::CheckAndResolveLocale(requested_locale, &resolved_locale))
56 if (resolved_locale == loaded_locale)
57 return requested_locale;
66 // NetworkScreenHandler, public: -----------------------------------------------
68 NetworkScreenHandler::NetworkScreenHandler(CoreOobeActor* core_oobe_actor)
69 : BaseScreenHandler(kJsScreenPath),
71 core_oobe_actor_(core_oobe_actor),
72 is_continue_enabled_(false),
74 weak_ptr_factory_(this) {
75 DCHECK(core_oobe_actor_);
77 input_method::InputMethodManager* manager =
78 input_method::InputMethodManager::Get();
79 manager->AddObserver(this);
82 NetworkScreenHandler::~NetworkScreenHandler() {
84 screen_->OnActorDestroyed(this);
86 input_method::InputMethodManager* manager =
87 input_method::InputMethodManager::Get();
88 manager->RemoveObserver(this);
91 // NetworkScreenHandler, NetworkScreenActor implementation: --------------------
93 void NetworkScreenHandler::SetDelegate(NetworkScreenActor::Delegate* screen) {
97 void NetworkScreenHandler::PrepareToShow() {
100 void NetworkScreenHandler::Show() {
101 if (!page_is_ready()) {
102 show_on_init_ = true;
106 // Here we should handle default locales, for which we do not have UI
107 // resources. This would load fallback, but properly show "selected" locale
109 if (selected_language_code_.empty()) {
110 const StartupCustomizationDocument* startup_manifest =
111 StartupCustomizationDocument::GetInstance();
112 HandleOnLanguageChanged(startup_manifest->initial_locale_default());
115 PrefService* prefs = g_browser_process->local_state();
116 if (prefs->GetBoolean(prefs::kFactoryResetRequested)) {
117 if (core_oobe_actor_)
118 core_oobe_actor_->ShowDeviceResetScreen();
122 // Make sure all our network technologies are turned on. On OOBE, the user
123 // should be able to select any of the available networks on the device.
124 NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
125 handler->SetTechnologyEnabled(NetworkTypePattern::NonVirtual(),
127 chromeos::network_handler::ErrorCallback());
128 ShowScreen(OobeUI::kScreenOobeNetwork, NULL);
129 core_oobe_actor_->InitDemoModeDetection();
132 void NetworkScreenHandler::Hide() {
135 void NetworkScreenHandler::ShowError(const base::string16& message) {
136 CallJS("showError", message);
139 void NetworkScreenHandler::ClearErrors() {
141 core_oobe_actor_->ClearErrors();
144 void NetworkScreenHandler::ShowConnectingStatus(
146 const base::string16& network_id) {
149 void NetworkScreenHandler::EnableContinue(bool enabled) {
150 is_continue_enabled_ = enabled;
152 CallJS("enableContinueButton", enabled);
155 // NetworkScreenHandler, BaseScreenHandler implementation: --------------------
157 void NetworkScreenHandler::DeclareLocalizedValues(
158 LocalizedValuesBuilder* builder) {
159 if (system::InputDeviceSettings::Get()->ForceKeyboardDrivenUINavigation())
160 builder->Add("networkScreenGreeting", IDS_REMORA_CONFIRM_MESSAGE);
162 builder->Add("networkScreenGreeting", IDS_WELCOME_SCREEN_GREETING);
164 builder->Add("networkScreenTitle", IDS_WELCOME_SCREEN_TITLE);
165 builder->Add("networkScreenAccessibleTitle",
166 IDS_NETWORK_SCREEN_ACCESSIBLE_TITLE);
167 builder->Add("selectLanguage", IDS_LANGUAGE_SELECTION_SELECT);
168 builder->Add("selectKeyboard", IDS_KEYBOARD_SELECTION_SELECT);
169 builder->Add("selectNetwork", IDS_NETWORK_SELECTION_SELECT);
170 builder->Add("selectTimezone", IDS_OPTIONS_SETTINGS_TIMEZONE_DESCRIPTION);
171 builder->Add("proxySettings", IDS_OPTIONS_PROXIES_CONFIGURE_BUTTON);
172 builder->Add("continueButton", IDS_NETWORK_SELECTION_CONTINUE_BUTTON);
175 void NetworkScreenHandler::GetAdditionalParameters(
176 base::DictionaryValue* dict) {
177 const std::string application_locale =
178 g_browser_process->GetApplicationLocale();
179 const std::string selected_language = selected_language_code_.empty() ?
180 application_locale : selected_language_code_;
181 const std::string selected_input_method =
182 input_method::InputMethodManager::Get()->GetCurrentInputMethod().id();
184 dict->Set("languageList",
185 GetUILanguageList(NULL, selected_language).release());
186 dict->Set("inputMethodsList",
187 GetLoginKeyboardLayouts(application_locale,
188 selected_input_method).release());
189 dict->Set("timezoneList", GetTimezoneList());
192 void NetworkScreenHandler::Initialize() {
193 EnableContinue(is_continue_enabled_);
195 show_on_init_ = false;
199 timezone_subscription_ = CrosSettings::Get()->AddSettingsObserver(
201 base::Bind(&NetworkScreenHandler::OnSystemTimezoneChanged,
202 base::Unretained(this)));
203 OnSystemTimezoneChanged();
206 // NetworkScreenHandler, WebUIMessageHandler implementation: -------------------
208 void NetworkScreenHandler::RegisterMessages() {
209 AddCallback(kJsApiNetworkOnExit, &NetworkScreenHandler::HandleOnExit);
210 AddCallback(kJsApiNetworkOnLanguageChanged,
211 &NetworkScreenHandler::HandleOnLanguageChanged);
212 AddCallback(kJsApiNetworkOnInputMethodChanged,
213 &NetworkScreenHandler::HandleOnInputMethodChanged);
214 AddCallback(kJsApiNetworkOnTimezoneChanged,
215 &NetworkScreenHandler::HandleOnTimezoneChanged);
219 // NetworkScreenHandler, private: ----------------------------------------------
221 void NetworkScreenHandler::HandleOnExit() {
222 core_oobe_actor_->StopDemoModeDetection();
225 screen_->OnContinuePressed();
228 struct NetworkScreenHandlerOnLanguageChangedCallbackData {
229 explicit NetworkScreenHandlerOnLanguageChangedCallbackData(
230 base::WeakPtr<NetworkScreenHandler>& handler)
231 : handler_(handler) {}
233 base::WeakPtr<NetworkScreenHandler> handler_;
235 // Block UI while resource bundle is being reloaded.
236 chromeos::InputEventsBlocker input_events_blocker;
240 void NetworkScreenHandler::OnLanguageChangedCallback(
241 scoped_ptr<NetworkScreenHandlerOnLanguageChangedCallbackData> context,
242 const std::string& requested_locale,
243 const std::string& loaded_locale,
244 const bool success) {
245 if (!context or !context->handler_)
248 NetworkScreenHandler* const self = context->handler_.get();
251 if (requested_locale == loaded_locale) {
252 self->selected_language_code_ = requested_locale;
254 self->selected_language_code_ =
255 CalculateSelectedLanguage(requested_locale, loaded_locale);
258 self->selected_language_code_ = loaded_locale;
261 self->ReloadLocalizedContent();
263 // We still do not have device owner, so owner settings are not applied.
264 // But Guest session can be started before owner is created, so we need to
265 // save locale settings directly here.
266 g_browser_process->local_state()->SetString(prefs::kApplicationLocale,
267 self->selected_language_code_);
269 AccessibilityManager::Get()->OnLocaleChanged();
272 void NetworkScreenHandler::HandleOnLanguageChanged(const std::string& locale) {
273 const std::string app_locale = g_browser_process->GetApplicationLocale();
274 if (app_locale == locale)
277 base::WeakPtr<NetworkScreenHandler> weak_self =
278 weak_ptr_factory_.GetWeakPtr();
279 scoped_ptr<NetworkScreenHandlerOnLanguageChangedCallbackData> callback_data(
280 new NetworkScreenHandlerOnLanguageChangedCallbackData(weak_self));
281 scoped_ptr<locale_util::SwitchLanguageCallback> callback(
282 new locale_util::SwitchLanguageCallback(
283 base::Bind(&NetworkScreenHandler::OnLanguageChangedCallback,
284 base::Passed(callback_data.Pass()))));
285 locale_util::SwitchLanguage(locale,
286 true /* enableLocaleKeyboardLayouts */,
287 true /* login_layouts_only */,
291 void NetworkScreenHandler::HandleOnInputMethodChanged(const std::string& id) {
292 input_method::InputMethodManager::Get()->ChangeInputMethod(id);
295 void NetworkScreenHandler::HandleOnTimezoneChanged(
296 const std::string& timezone_id) {
297 std::string current_timezone_id;
298 CrosSettings::Get()->GetString(kSystemTimezone, ¤t_timezone_id);
299 if (current_timezone_id == timezone_id)
302 CrosSettings::Get()->SetString(kSystemTimezone, timezone_id);
305 void NetworkScreenHandler::OnSystemTimezoneChanged() {
306 std::string current_timezone_id;
307 CrosSettings::Get()->GetString(kSystemTimezone, ¤t_timezone_id);
308 CallJS("setTimezone", current_timezone_id);
311 void NetworkScreenHandler::InputMethodChanged(
312 input_method::InputMethodManager* manager, bool show_message) {
313 CallJS("setInputMethod", manager->GetCurrentInputMethod().id());
316 void NetworkScreenHandler::ReloadLocalizedContent() {
317 base::DictionaryValue localized_strings;
318 static_cast<OobeUI*>(web_ui()->GetController())
319 ->GetLocalizedStrings(&localized_strings);
320 core_oobe_actor_->ReloadContent(localized_strings);
322 // Buttons are recreated, updated "Continue" button state.
323 EnableContinue(is_continue_enabled_);
327 base::ListValue* NetworkScreenHandler::GetTimezoneList() {
328 std::string current_timezone_id;
329 CrosSettings::Get()->GetString(kSystemTimezone, ¤t_timezone_id);
331 scoped_ptr<base::ListValue> timezone_list(new base::ListValue);
332 scoped_ptr<base::ListValue> timezones = system::GetTimezoneList().Pass();
333 for (size_t i = 0; i < timezones->GetSize(); ++i) {
334 const base::ListValue* timezone = NULL;
335 CHECK(timezones->GetList(i, &timezone));
337 std::string timezone_id;
338 CHECK(timezone->GetString(0, &timezone_id));
340 std::string timezone_name;
341 CHECK(timezone->GetString(1, &timezone_name));
343 scoped_ptr<base::DictionaryValue> timezone_option(
344 new base::DictionaryValue);
345 timezone_option->SetString("value", timezone_id);
346 timezone_option->SetString("title", timezone_name);
347 timezone_option->SetBoolean("selected", timezone_id == current_timezone_id);
348 timezone_list->Append(timezone_option.release());
351 return timezone_list.release();
354 } // namespace chromeos