OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ui/webui/chromeos/login/network_screen_handler.h" | 5 #include "chrome/browser/ui/webui/chromeos/login/network_screen_handler.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
9 #include "base/memory/weak_ptr.h" | 9 #include "base/memory/weak_ptr.h" |
10 #include "base/prefs/pref_service.h" | 10 #include "base/prefs/pref_service.h" |
11 #include "base/strings/string16.h" | |
12 #include "base/strings/utf_string_conversions.h" | 11 #include "base/strings/utf_string_conversions.h" |
13 #include "base/task_runner_util.h" | |
14 #include "base/threading/worker_pool.h" | |
15 #include "base/values.h" | 12 #include "base/values.h" |
16 #include "chrome/browser/browser_process.h" | 13 #include "chrome/browser/browser_process.h" |
17 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h" | 14 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h" |
18 #include "chrome/browser/chromeos/base/locale_util.h" | 15 #include "chrome/browser/chromeos/base/locale_util.h" |
19 #include "chrome/browser/chromeos/customization_document.h" | 16 #include "chrome/browser/chromeos/customization_document.h" |
20 #include "chrome/browser/chromeos/idle_detector.h" | 17 #include "chrome/browser/chromeos/idle_detector.h" |
21 #include "chrome/browser/chromeos/login/screens/core_oobe_actor.h" | 18 #include "chrome/browser/chromeos/login/screens/core_oobe_actor.h" |
22 #include "chrome/browser/chromeos/login/ui/input_events_blocker.h" | 19 #include "chrome/browser/chromeos/login/ui/input_events_blocker.h" |
23 #include "chrome/browser/chromeos/system/input_device_settings.h" | 20 #include "chrome/browser/chromeos/system/input_device_settings.h" |
24 #include "chrome/browser/chromeos/system/timezone_util.h" | 21 #include "chrome/browser/chromeos/system/timezone_util.h" |
25 #include "chrome/browser/ui/webui/chromeos/login/l10n_util.h" | 22 #include "chrome/browser/ui/webui/chromeos/login/l10n_util.h" |
26 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h" | 23 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h" |
27 #include "chrome/common/pref_names.h" | 24 #include "chrome/common/pref_names.h" |
28 #include "chrome/grit/generated_resources.h" | 25 #include "chrome/grit/generated_resources.h" |
29 #include "chromeos/ime/extension_ime_util.h" | 26 #include "chromeos/ime/extension_ime_util.h" |
30 #include "chromeos/network/network_handler.h" | 27 #include "chromeos/network/network_handler.h" |
31 #include "chromeos/network/network_state_handler.h" | 28 #include "chromeos/network/network_state_handler.h" |
32 #include "components/user_manager/user_manager.h" | |
33 #include "content/public/browser/browser_thread.h" | |
34 #include "ui/base/l10n/l10n_util.h" | 29 #include "ui/base/l10n/l10n_util.h" |
35 #include "ui/gfx/rect.h" | 30 #include "ui/gfx/rect.h" |
36 #include "ui/views/layout/fill_layout.h" | 31 #include "ui/views/layout/fill_layout.h" |
37 #include "ui/views/widget/widget.h" | 32 #include "ui/views/widget/widget.h" |
38 | 33 |
39 namespace { | 34 namespace { |
40 | 35 |
41 const char kJsScreenPath[] = "login.NetworkScreen"; | 36 const char kJsScreenPath[] = "login.NetworkScreen"; |
42 | 37 |
43 // JS API callbacks names. | 38 // JS API callbacks names. |
44 const char kJsApiNetworkOnExit[] = "networkOnExit"; | 39 const char kJsApiNetworkOnExit[] = "networkOnExit"; |
45 const char kJsApiNetworkOnLanguageChanged[] = "networkOnLanguageChanged"; | 40 const char kJsApiNetworkOnLanguageChanged[] = "networkOnLanguageChanged"; |
46 const char kJsApiNetworkOnInputMethodChanged[] = "networkOnInputMethodChanged"; | 41 const char kJsApiNetworkOnInputMethodChanged[] = "networkOnInputMethodChanged"; |
47 const char kJsApiNetworkOnTimezoneChanged[] = "networkOnTimezoneChanged"; | 42 const char kJsApiNetworkOnTimezoneChanged[] = "networkOnTimezoneChanged"; |
48 | 43 |
| 44 // For "UI Language" drop-down menu at OOBE screen we need to decide which |
| 45 // entry to mark "selected". If user has just selected "requested_locale", |
| 46 // but "loaded_locale" was actually loaded, we mark original user choice |
| 47 // "selected" only if loaded_locale is a backup for "requested_locale". |
| 48 std::string CalculateSelectedLanguage(const std::string& requested_locale, |
| 49 const std::string& loaded_locale) { |
| 50 std::string resolved_locale; |
| 51 if (!l10n_util::CheckAndResolveLocale(requested_locale, &resolved_locale)) |
| 52 return loaded_locale; |
| 53 |
| 54 if (resolved_locale == loaded_locale) |
| 55 return requested_locale; |
| 56 |
| 57 return loaded_locale; |
| 58 } |
| 59 |
49 } // namespace | 60 } // namespace |
50 | 61 |
51 namespace chromeos { | 62 namespace chromeos { |
52 | 63 |
53 // NetworkScreenHandler, public: ----------------------------------------------- | 64 // NetworkScreenHandler, public: ----------------------------------------------- |
54 | 65 |
55 NetworkScreenHandler::NetworkScreenHandler(CoreOobeActor* core_oobe_actor) | 66 NetworkScreenHandler::NetworkScreenHandler(CoreOobeActor* core_oobe_actor) |
56 : BaseScreenHandler(kJsScreenPath), | 67 : BaseScreenHandler(kJsScreenPath), |
57 screen_(NULL), | 68 screen_(NULL), |
58 core_oobe_actor_(core_oobe_actor), | 69 core_oobe_actor_(core_oobe_actor), |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 builder->Add("networkScreenAccessibleTitle", | 163 builder->Add("networkScreenAccessibleTitle", |
153 IDS_NETWORK_SCREEN_ACCESSIBLE_TITLE); | 164 IDS_NETWORK_SCREEN_ACCESSIBLE_TITLE); |
154 builder->Add("selectLanguage", IDS_LANGUAGE_SELECTION_SELECT); | 165 builder->Add("selectLanguage", IDS_LANGUAGE_SELECTION_SELECT); |
155 builder->Add("selectKeyboard", IDS_KEYBOARD_SELECTION_SELECT); | 166 builder->Add("selectKeyboard", IDS_KEYBOARD_SELECTION_SELECT); |
156 builder->Add("selectNetwork", IDS_NETWORK_SELECTION_SELECT); | 167 builder->Add("selectNetwork", IDS_NETWORK_SELECTION_SELECT); |
157 builder->Add("selectTimezone", IDS_OPTIONS_SETTINGS_TIMEZONE_DESCRIPTION); | 168 builder->Add("selectTimezone", IDS_OPTIONS_SETTINGS_TIMEZONE_DESCRIPTION); |
158 builder->Add("proxySettings", IDS_OPTIONS_PROXIES_CONFIGURE_BUTTON); | 169 builder->Add("proxySettings", IDS_OPTIONS_PROXIES_CONFIGURE_BUTTON); |
159 builder->Add("continueButton", IDS_NETWORK_SELECTION_CONTINUE_BUTTON); | 170 builder->Add("continueButton", IDS_NETWORK_SELECTION_CONTINUE_BUTTON); |
160 } | 171 } |
161 | 172 |
162 void NetworkScreenHandler::OnLanguageListResolved( | |
163 scoped_ptr<base::ListValue> new_language_list, | |
164 std::string new_language_list_locale, | |
165 std::string new_selected_language) { | |
166 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
167 | |
168 language_list_.reset(new_language_list.release()); | |
169 language_list_locale_ = new_language_list_locale; | |
170 selected_language_code_ = new_selected_language; | |
171 | |
172 g_browser_process->local_state()->SetString(prefs::kApplicationLocale, | |
173 selected_language_code_); | |
174 ReloadLocalizedContent(); | |
175 } | |
176 | |
177 void NetworkScreenHandler::ScheduleResolveLanguageList( | |
178 scoped_ptr<locale_util::LanguageSwitchResult> language_switch_result) { | |
179 UILanguageListResolvedCallback callback = | |
180 base::Bind(&NetworkScreenHandler::OnLanguageListResolved, | |
181 weak_ptr_factory_.GetWeakPtr()); | |
182 ResolveUILanguageList(language_switch_result.Pass(), callback); | |
183 } | |
184 | |
185 void NetworkScreenHandler::GetAdditionalParameters( | 173 void NetworkScreenHandler::GetAdditionalParameters( |
186 base::DictionaryValue* dict) { | 174 base::DictionaryValue* dict) { |
187 const std::string application_locale = | 175 const std::string application_locale = |
188 g_browser_process->GetApplicationLocale(); | 176 g_browser_process->GetApplicationLocale(); |
| 177 const std::string selected_language = selected_language_code_.empty() ? |
| 178 application_locale : selected_language_code_; |
189 const std::string selected_input_method = | 179 const std::string selected_input_method = |
190 input_method::InputMethodManager::Get() | 180 input_method::InputMethodManager::Get() |
191 ->GetActiveIMEState() | 181 ->GetActiveIMEState() |
192 ->GetCurrentInputMethod() | 182 ->GetCurrentInputMethod() |
193 .id(); | 183 .id(); |
194 | 184 |
195 scoped_ptr<base::ListValue> language_list; | 185 dict->Set("languageList", |
196 if (language_list_.get() && language_list_locale_ == application_locale) { | 186 GetUILanguageList(NULL, selected_language).release()); |
197 language_list.reset(language_list_->DeepCopy()); | 187 dict->Set("inputMethodsList", |
198 } else { | 188 GetAndActivateLoginKeyboardLayouts( |
199 ScheduleResolveLanguageList( | 189 application_locale, selected_input_method).release()); |
200 scoped_ptr<locale_util::LanguageSwitchResult>()); | |
201 | |
202 language_list.reset(GetMinimalUILanguageList().release()); | |
203 } | |
204 | |
205 // GetAdditionalParameters() is called when OOBE language is updated. | |
206 // This happens in two diferent cases: | |
207 // | |
208 // 1) User selects new locale on OOBE screen. We need to sync active input | |
209 // methods with locale, so EnableLoginLayouts() is needed. | |
210 // | |
211 // 2) This is signin to public session. User has selected some locale & input | |
212 // method on "Public Session User POD". After "Login" button is pressed, | |
213 // new user session is created, locale & input method are changed (both | |
214 // asynchronously). | |
215 // But after public user session is started, "Terms of Service" dialog is | |
216 // shown. It is a part of OOBE UI screens, so it initiates reload of UI | |
217 // strings in new locale. It also happens asynchronously, that leads to race | |
218 // between "locale change", "input method change" and | |
219 // "EnableLoginLayouts()". This way EnableLoginLayouts() happens after user | |
220 // input method has been changed, resetting input method to hardware default. | |
221 // | |
222 // So we need to disable activation of login layouts if we are already in | |
223 // active user session. | |
224 // | |
225 const bool enable_layouts = | |
226 !user_manager::UserManager::Get()->IsUserLoggedIn(); | |
227 | |
228 dict->Set("languageList", language_list.release()); | |
229 dict->Set( | |
230 "inputMethodsList", | |
231 GetAndActivateLoginKeyboardLayouts( | |
232 application_locale, selected_input_method, enable_layouts).release()); | |
233 dict->Set("timezoneList", GetTimezoneList()); | 190 dict->Set("timezoneList", GetTimezoneList()); |
234 } | 191 } |
235 | 192 |
236 void NetworkScreenHandler::Initialize() { | 193 void NetworkScreenHandler::Initialize() { |
237 EnableContinue(is_continue_enabled_); | 194 EnableContinue(is_continue_enabled_); |
238 if (show_on_init_) { | 195 if (show_on_init_) { |
239 show_on_init_ = false; | 196 show_on_init_ = false; |
240 Show(); | 197 Show(); |
241 } | 198 } |
242 | 199 |
243 // Reload localized strings if they are already resolved. | |
244 if (language_list_.get()) | |
245 ReloadLocalizedContent(); | |
246 | |
247 timezone_subscription_ = CrosSettings::Get()->AddSettingsObserver( | 200 timezone_subscription_ = CrosSettings::Get()->AddSettingsObserver( |
248 kSystemTimezone, | 201 kSystemTimezone, |
249 base::Bind(&NetworkScreenHandler::OnSystemTimezoneChanged, | 202 base::Bind(&NetworkScreenHandler::OnSystemTimezoneChanged, |
250 base::Unretained(this))); | 203 base::Unretained(this))); |
251 OnSystemTimezoneChanged(); | 204 OnSystemTimezoneChanged(); |
252 } | 205 } |
253 | 206 |
254 // NetworkScreenHandler, WebUIMessageHandler implementation: ------------------- | 207 // NetworkScreenHandler, WebUIMessageHandler implementation: ------------------- |
255 | 208 |
256 void NetworkScreenHandler::RegisterMessages() { | 209 void NetworkScreenHandler::RegisterMessages() { |
257 AddCallback(kJsApiNetworkOnExit, &NetworkScreenHandler::HandleOnExit); | 210 AddCallback(kJsApiNetworkOnExit, &NetworkScreenHandler::HandleOnExit); |
258 AddCallback(kJsApiNetworkOnLanguageChanged, | 211 AddCallback(kJsApiNetworkOnLanguageChanged, |
259 &NetworkScreenHandler::HandleOnLanguageChanged); | 212 &NetworkScreenHandler::HandleOnLanguageChanged); |
260 AddCallback(kJsApiNetworkOnInputMethodChanged, | 213 AddCallback(kJsApiNetworkOnInputMethodChanged, |
261 &NetworkScreenHandler::HandleOnInputMethodChanged); | 214 &NetworkScreenHandler::HandleOnInputMethodChanged); |
262 AddCallback(kJsApiNetworkOnTimezoneChanged, | 215 AddCallback(kJsApiNetworkOnTimezoneChanged, |
263 &NetworkScreenHandler::HandleOnTimezoneChanged); | 216 &NetworkScreenHandler::HandleOnTimezoneChanged); |
264 } | 217 } |
265 | 218 |
266 | 219 |
267 // NetworkScreenHandler, private: ---------------------------------------------- | 220 // NetworkScreenHandler, private: ---------------------------------------------- |
268 | 221 |
269 void NetworkScreenHandler::HandleOnExit() { | 222 void NetworkScreenHandler::HandleOnExit() { |
270 core_oobe_actor_->StopDemoModeDetection(); | 223 core_oobe_actor_->StopDemoModeDetection(); |
271 ClearErrors(); | 224 ClearErrors(); |
272 if (screen_) | 225 if (screen_) |
273 screen_->OnContinuePressed(); | 226 screen_->OnContinuePressed(); |
274 } | 227 } |
275 | 228 |
| 229 struct NetworkScreenHandlerOnLanguageChangedCallbackData { |
| 230 explicit NetworkScreenHandlerOnLanguageChangedCallbackData( |
| 231 const base::WeakPtr<NetworkScreenHandler>& handler) |
| 232 : handler(handler) {} |
| 233 |
| 234 base::WeakPtr<NetworkScreenHandler> handler; |
| 235 |
| 236 // Block UI while resource bundle is being reloaded. |
| 237 chromeos::InputEventsBlocker input_events_blocker; |
| 238 }; |
| 239 |
| 240 // static |
276 void NetworkScreenHandler::OnLanguageChangedCallback( | 241 void NetworkScreenHandler::OnLanguageChangedCallback( |
277 const chromeos::InputEventsBlocker* /* input_events_blocker */, | 242 scoped_ptr<NetworkScreenHandlerOnLanguageChangedCallbackData> context, |
278 const locale_util::LanguageSwitchResult& result) { | 243 const std::string& requested_locale, |
279 if (!selected_language_code_.empty()) { | 244 const std::string& loaded_locale, |
280 // We still do not have device owner, so owner settings are not applied. | 245 const bool success) { |
281 // But Guest session can be started before owner is created, so we need to | 246 if (!context || !context->handler) |
282 // save locale settings directly here. | 247 return; |
283 g_browser_process->local_state()->SetString(prefs::kApplicationLocale, | 248 |
284 selected_language_code_); | 249 NetworkScreenHandler* const self = context->handler.get(); |
| 250 |
| 251 if (success) { |
| 252 if (requested_locale == loaded_locale) { |
| 253 self->selected_language_code_ = requested_locale; |
| 254 } else { |
| 255 self->selected_language_code_ = |
| 256 CalculateSelectedLanguage(requested_locale, loaded_locale); |
| 257 } |
| 258 } else { |
| 259 self->selected_language_code_ = loaded_locale; |
285 } | 260 } |
286 ScheduleResolveLanguageList(scoped_ptr<locale_util::LanguageSwitchResult>( | 261 |
287 new locale_util::LanguageSwitchResult(result))); | 262 self->ReloadLocalizedContent(); |
| 263 |
| 264 // We still do not have device owner, so owner settings are not applied. |
| 265 // But Guest session can be started before owner is created, so we need to |
| 266 // save locale settings directly here. |
| 267 g_browser_process->local_state()->SetString(prefs::kApplicationLocale, |
| 268 self->selected_language_code_); |
288 | 269 |
289 AccessibilityManager::Get()->OnLocaleChanged(); | 270 AccessibilityManager::Get()->OnLocaleChanged(); |
290 } | 271 } |
291 | 272 |
292 void NetworkScreenHandler::HandleOnLanguageChanged(const std::string& locale) { | 273 void NetworkScreenHandler::HandleOnLanguageChanged(const std::string& locale) { |
293 const std::string app_locale = g_browser_process->GetApplicationLocale(); | 274 const std::string app_locale = g_browser_process->GetApplicationLocale(); |
294 if (app_locale == locale) | 275 if (app_locale == locale) |
295 return; | 276 return; |
296 | 277 |
297 // Block UI while resource bundle is being reloaded. | 278 base::WeakPtr<NetworkScreenHandler> weak_self = |
298 // (InputEventsBlocker will live until callback is finished.) | 279 weak_ptr_factory_.GetWeakPtr(); |
299 locale_util::SwitchLanguageCallback callback( | 280 scoped_ptr<NetworkScreenHandlerOnLanguageChangedCallbackData> callback_data( |
300 base::Bind(&NetworkScreenHandler::OnLanguageChangedCallback, | 281 new NetworkScreenHandlerOnLanguageChangedCallbackData(weak_self)); |
301 weak_ptr_factory_.GetWeakPtr(), | 282 scoped_ptr<locale_util::SwitchLanguageCallback> callback( |
302 base::Owned(new chromeos::InputEventsBlocker))); | 283 new locale_util::SwitchLanguageCallback( |
| 284 base::Bind(&NetworkScreenHandler::OnLanguageChangedCallback, |
| 285 base::Passed(callback_data.Pass())))); |
303 locale_util::SwitchLanguage(locale, | 286 locale_util::SwitchLanguage(locale, |
304 true /* enableLocaleKeyboardLayouts */, | 287 true /* enableLocaleKeyboardLayouts */, |
305 true /* login_layouts_only */, | 288 true /* login_layouts_only */, |
306 callback); | 289 callback.Pass()); |
307 } | 290 } |
308 | 291 |
309 void NetworkScreenHandler::HandleOnInputMethodChanged(const std::string& id) { | 292 void NetworkScreenHandler::HandleOnInputMethodChanged(const std::string& id) { |
310 input_method::InputMethodManager::Get() | 293 input_method::InputMethodManager::Get() |
311 ->GetActiveIMEState() | 294 ->GetActiveIMEState() |
312 ->ChangeInputMethod(id, false /* show_message */); | 295 ->ChangeInputMethod(id, false /* show_message */); |
313 } | 296 } |
314 | 297 |
315 void NetworkScreenHandler::HandleOnTimezoneChanged( | 298 void NetworkScreenHandler::HandleOnTimezoneChanged( |
316 const std::string& timezone_id) { | 299 const std::string& timezone_id) { |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
366 timezone_option->SetString("value", timezone_id); | 349 timezone_option->SetString("value", timezone_id); |
367 timezone_option->SetString("title", timezone_name); | 350 timezone_option->SetString("title", timezone_name); |
368 timezone_option->SetBoolean("selected", timezone_id == current_timezone_id); | 351 timezone_option->SetBoolean("selected", timezone_id == current_timezone_id); |
369 timezone_list->Append(timezone_option.release()); | 352 timezone_list->Append(timezone_option.release()); |
370 } | 353 } |
371 | 354 |
372 return timezone_list.release(); | 355 return timezone_list.release(); |
373 } | 356 } |
374 | 357 |
375 } // namespace chromeos | 358 } // namespace chromeos |
OLD | NEW |