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" |
11 #include "base/strings/utf_string_conversions.h" | 12 #include "base/strings/utf_string_conversions.h" |
| 13 #include "base/task_runner_util.h" |
| 14 #include "base/threading/worker_pool.h" |
12 #include "base/values.h" | 15 #include "base/values.h" |
13 #include "chrome/browser/browser_process.h" | 16 #include "chrome/browser/browser_process.h" |
14 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h" | 17 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h" |
15 #include "chrome/browser/chromeos/base/locale_util.h" | 18 #include "chrome/browser/chromeos/base/locale_util.h" |
16 #include "chrome/browser/chromeos/customization_document.h" | 19 #include "chrome/browser/chromeos/customization_document.h" |
17 #include "chrome/browser/chromeos/idle_detector.h" | 20 #include "chrome/browser/chromeos/idle_detector.h" |
18 #include "chrome/browser/chromeos/login/screens/core_oobe_actor.h" | 21 #include "chrome/browser/chromeos/login/screens/core_oobe_actor.h" |
19 #include "chrome/browser/chromeos/login/ui/input_events_blocker.h" | 22 #include "chrome/browser/chromeos/login/ui/input_events_blocker.h" |
20 #include "chrome/browser/chromeos/system/input_device_settings.h" | 23 #include "chrome/browser/chromeos/system/input_device_settings.h" |
21 #include "chrome/browser/chromeos/system/timezone_util.h" | 24 #include "chrome/browser/chromeos/system/timezone_util.h" |
22 #include "chrome/browser/ui/webui/chromeos/login/l10n_util.h" | 25 #include "chrome/browser/ui/webui/chromeos/login/l10n_util.h" |
23 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h" | 26 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h" |
24 #include "chrome/common/pref_names.h" | 27 #include "chrome/common/pref_names.h" |
25 #include "chrome/grit/generated_resources.h" | 28 #include "chrome/grit/generated_resources.h" |
26 #include "chromeos/ime/extension_ime_util.h" | 29 #include "chromeos/ime/extension_ime_util.h" |
27 #include "chromeos/network/network_handler.h" | 30 #include "chromeos/network/network_handler.h" |
28 #include "chromeos/network/network_state_handler.h" | 31 #include "chromeos/network/network_state_handler.h" |
| 32 #include "components/user_manager/user_manager.h" |
| 33 #include "content/public/browser/browser_thread.h" |
29 #include "ui/base/l10n/l10n_util.h" | 34 #include "ui/base/l10n/l10n_util.h" |
30 #include "ui/gfx/rect.h" | 35 #include "ui/gfx/rect.h" |
31 #include "ui/views/layout/fill_layout.h" | 36 #include "ui/views/layout/fill_layout.h" |
32 #include "ui/views/widget/widget.h" | 37 #include "ui/views/widget/widget.h" |
33 | 38 |
34 namespace { | 39 namespace { |
35 | 40 |
36 const char kJsScreenPath[] = "login.NetworkScreen"; | 41 const char kJsScreenPath[] = "login.NetworkScreen"; |
37 | 42 |
38 // JS API callbacks names. | 43 // JS API callbacks names. |
39 const char kJsApiNetworkOnExit[] = "networkOnExit"; | 44 const char kJsApiNetworkOnExit[] = "networkOnExit"; |
40 const char kJsApiNetworkOnLanguageChanged[] = "networkOnLanguageChanged"; | 45 const char kJsApiNetworkOnLanguageChanged[] = "networkOnLanguageChanged"; |
41 const char kJsApiNetworkOnInputMethodChanged[] = "networkOnInputMethodChanged"; | 46 const char kJsApiNetworkOnInputMethodChanged[] = "networkOnInputMethodChanged"; |
42 const char kJsApiNetworkOnTimezoneChanged[] = "networkOnTimezoneChanged"; | 47 const char kJsApiNetworkOnTimezoneChanged[] = "networkOnTimezoneChanged"; |
43 | 48 |
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 | |
60 } // namespace | 49 } // namespace |
61 | 50 |
62 namespace chromeos { | 51 namespace chromeos { |
63 | 52 |
64 // NetworkScreenHandler, public: ----------------------------------------------- | 53 // NetworkScreenHandler, public: ----------------------------------------------- |
65 | 54 |
66 NetworkScreenHandler::NetworkScreenHandler(CoreOobeActor* core_oobe_actor) | 55 NetworkScreenHandler::NetworkScreenHandler(CoreOobeActor* core_oobe_actor) |
67 : BaseScreenHandler(kJsScreenPath), | 56 : BaseScreenHandler(kJsScreenPath), |
68 screen_(NULL), | 57 screen_(NULL), |
69 core_oobe_actor_(core_oobe_actor), | 58 core_oobe_actor_(core_oobe_actor), |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
163 builder->Add("networkScreenAccessibleTitle", | 152 builder->Add("networkScreenAccessibleTitle", |
164 IDS_NETWORK_SCREEN_ACCESSIBLE_TITLE); | 153 IDS_NETWORK_SCREEN_ACCESSIBLE_TITLE); |
165 builder->Add("selectLanguage", IDS_LANGUAGE_SELECTION_SELECT); | 154 builder->Add("selectLanguage", IDS_LANGUAGE_SELECTION_SELECT); |
166 builder->Add("selectKeyboard", IDS_KEYBOARD_SELECTION_SELECT); | 155 builder->Add("selectKeyboard", IDS_KEYBOARD_SELECTION_SELECT); |
167 builder->Add("selectNetwork", IDS_NETWORK_SELECTION_SELECT); | 156 builder->Add("selectNetwork", IDS_NETWORK_SELECTION_SELECT); |
168 builder->Add("selectTimezone", IDS_OPTIONS_SETTINGS_TIMEZONE_DESCRIPTION); | 157 builder->Add("selectTimezone", IDS_OPTIONS_SETTINGS_TIMEZONE_DESCRIPTION); |
169 builder->Add("proxySettings", IDS_OPTIONS_PROXIES_CONFIGURE_BUTTON); | 158 builder->Add("proxySettings", IDS_OPTIONS_PROXIES_CONFIGURE_BUTTON); |
170 builder->Add("continueButton", IDS_NETWORK_SELECTION_CONTINUE_BUTTON); | 159 builder->Add("continueButton", IDS_NETWORK_SELECTION_CONTINUE_BUTTON); |
171 } | 160 } |
172 | 161 |
| 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 |
173 void NetworkScreenHandler::GetAdditionalParameters( | 185 void NetworkScreenHandler::GetAdditionalParameters( |
174 base::DictionaryValue* dict) { | 186 base::DictionaryValue* dict) { |
175 const std::string application_locale = | 187 const std::string application_locale = |
176 g_browser_process->GetApplicationLocale(); | 188 g_browser_process->GetApplicationLocale(); |
177 const std::string selected_language = selected_language_code_.empty() ? | |
178 application_locale : selected_language_code_; | |
179 const std::string selected_input_method = | 189 const std::string selected_input_method = |
180 input_method::InputMethodManager::Get() | 190 input_method::InputMethodManager::Get() |
181 ->GetActiveIMEState() | 191 ->GetActiveIMEState() |
182 ->GetCurrentInputMethod() | 192 ->GetCurrentInputMethod() |
183 .id(); | 193 .id(); |
184 | 194 |
185 dict->Set("languageList", | 195 scoped_ptr<base::ListValue> language_list; |
186 GetUILanguageList(NULL, selected_language).release()); | 196 if (language_list_.get() && language_list_locale_ == application_locale) { |
187 dict->Set("inputMethodsList", | 197 language_list.reset(language_list_->DeepCopy()); |
188 GetAndActivateLoginKeyboardLayouts( | 198 } else { |
189 application_locale, selected_input_method).release()); | 199 ScheduleResolveLanguageList( |
| 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()); |
190 dict->Set("timezoneList", GetTimezoneList()); | 233 dict->Set("timezoneList", GetTimezoneList()); |
191 } | 234 } |
192 | 235 |
193 void NetworkScreenHandler::Initialize() { | 236 void NetworkScreenHandler::Initialize() { |
194 EnableContinue(is_continue_enabled_); | 237 EnableContinue(is_continue_enabled_); |
195 if (show_on_init_) { | 238 if (show_on_init_) { |
196 show_on_init_ = false; | 239 show_on_init_ = false; |
197 Show(); | 240 Show(); |
198 } | 241 } |
199 | 242 |
| 243 // Reload localized strings if they are already resolved. |
| 244 if (language_list_.get()) |
| 245 ReloadLocalizedContent(); |
| 246 |
200 timezone_subscription_ = CrosSettings::Get()->AddSettingsObserver( | 247 timezone_subscription_ = CrosSettings::Get()->AddSettingsObserver( |
201 kSystemTimezone, | 248 kSystemTimezone, |
202 base::Bind(&NetworkScreenHandler::OnSystemTimezoneChanged, | 249 base::Bind(&NetworkScreenHandler::OnSystemTimezoneChanged, |
203 base::Unretained(this))); | 250 base::Unretained(this))); |
204 OnSystemTimezoneChanged(); | 251 OnSystemTimezoneChanged(); |
205 } | 252 } |
206 | 253 |
207 // NetworkScreenHandler, WebUIMessageHandler implementation: ------------------- | 254 // NetworkScreenHandler, WebUIMessageHandler implementation: ------------------- |
208 | 255 |
209 void NetworkScreenHandler::RegisterMessages() { | 256 void NetworkScreenHandler::RegisterMessages() { |
210 AddCallback(kJsApiNetworkOnExit, &NetworkScreenHandler::HandleOnExit); | 257 AddCallback(kJsApiNetworkOnExit, &NetworkScreenHandler::HandleOnExit); |
211 AddCallback(kJsApiNetworkOnLanguageChanged, | 258 AddCallback(kJsApiNetworkOnLanguageChanged, |
212 &NetworkScreenHandler::SetApplicationLocale); | 259 &NetworkScreenHandler::SetApplicationLocale); |
213 AddCallback(kJsApiNetworkOnInputMethodChanged, | 260 AddCallback(kJsApiNetworkOnInputMethodChanged, |
214 &NetworkScreenHandler::SetInputMethod); | 261 &NetworkScreenHandler::SetInputMethod); |
215 AddCallback(kJsApiNetworkOnTimezoneChanged, | 262 AddCallback(kJsApiNetworkOnTimezoneChanged, |
216 &NetworkScreenHandler::SetTimezone); | 263 &NetworkScreenHandler::SetTimezone); |
217 } | 264 } |
218 | 265 |
219 | 266 |
220 // NetworkScreenHandler, private: ---------------------------------------------- | 267 // NetworkScreenHandler, private: ---------------------------------------------- |
221 | 268 |
222 void NetworkScreenHandler::HandleOnExit() { | 269 void NetworkScreenHandler::HandleOnExit() { |
223 core_oobe_actor_->StopDemoModeDetection(); | 270 core_oobe_actor_->StopDemoModeDetection(); |
224 ClearErrors(); | 271 ClearErrors(); |
225 if (screen_) | 272 if (screen_) |
226 screen_->OnContinuePressed(); | 273 screen_->OnContinuePressed(); |
227 } | 274 } |
228 | 275 |
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 | |
241 void NetworkScreenHandler::OnLanguageChangedCallback( | 276 void NetworkScreenHandler::OnLanguageChangedCallback( |
242 scoped_ptr<NetworkScreenHandlerOnLanguageChangedCallbackData> context, | 277 const chromeos::InputEventsBlocker* /* input_events_blocker */, |
243 const std::string& requested_locale, | 278 const locale_util::LanguageSwitchResult& result) { |
244 const std::string& loaded_locale, | 279 if (!selected_language_code_.empty()) { |
245 const bool success) { | 280 // We still do not have device owner, so owner settings are not applied. |
246 if (!context || !context->handler) | 281 // But Guest session can be started before owner is created, so we need to |
247 return; | 282 // save locale settings directly here. |
248 | 283 g_browser_process->local_state()->SetString(prefs::kApplicationLocale, |
249 NetworkScreenHandler* const self = context->handler.get(); | 284 selected_language_code_); |
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; | |
260 } | 285 } |
261 | 286 ScheduleResolveLanguageList(scoped_ptr<locale_util::LanguageSwitchResult>( |
262 self->ReloadLocalizedContent(); | 287 new locale_util::LanguageSwitchResult(result))); |
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_); | |
269 | 288 |
270 AccessibilityManager::Get()->OnLocaleChanged(); | 289 AccessibilityManager::Get()->OnLocaleChanged(); |
271 } | 290 } |
272 | 291 |
273 std::string NetworkScreenHandler::GetApplicationLocale() const { | 292 std::string NetworkScreenHandler::GetApplicationLocale() const { |
274 return locale_; | 293 return locale_; |
275 } | 294 } |
276 | 295 |
277 std::string NetworkScreenHandler::GetInputMethod() const { | 296 std::string NetworkScreenHandler::GetInputMethod() const { |
278 return input_method_; | 297 return input_method_; |
279 } | 298 } |
280 | 299 |
281 std::string NetworkScreenHandler::GetTimezone() const { | 300 std::string NetworkScreenHandler::GetTimezone() const { |
282 return timezone_; | 301 return timezone_; |
283 } | 302 } |
284 | 303 |
285 void NetworkScreenHandler::SetApplicationLocale(const std::string& locale) { | 304 void NetworkScreenHandler::SetApplicationLocale(const std::string& locale) { |
286 const std::string app_locale = g_browser_process->GetApplicationLocale(); | 305 const std::string app_locale = g_browser_process->GetApplicationLocale(); |
287 if (app_locale == locale) | 306 if (app_locale == locale) |
288 return; | 307 return; |
289 | 308 |
290 locale_ = locale; | 309 locale_ = locale; |
291 base::WeakPtr<NetworkScreenHandler> weak_self = | 310 |
292 weak_ptr_factory_.GetWeakPtr(); | 311 // Block UI while resource bundle is being reloaded. |
293 scoped_ptr<NetworkScreenHandlerOnLanguageChangedCallbackData> callback_data( | 312 // (InputEventsBlocker will live until callback is finished.) |
294 new NetworkScreenHandlerOnLanguageChangedCallbackData(weak_self)); | 313 locale_util::SwitchLanguageCallback callback( |
295 scoped_ptr<locale_util::SwitchLanguageCallback> callback( | 314 base::Bind(&NetworkScreenHandler::OnLanguageChangedCallback, |
296 new locale_util::SwitchLanguageCallback( | 315 weak_ptr_factory_.GetWeakPtr(), |
297 base::Bind(&NetworkScreenHandler::OnLanguageChangedCallback, | 316 base::Owned(new chromeos::InputEventsBlocker))); |
298 base::Passed(callback_data.Pass())))); | |
299 locale_util::SwitchLanguage(locale, | 317 locale_util::SwitchLanguage(locale, |
300 true /* enableLocaleKeyboardLayouts */, | 318 true /* enableLocaleKeyboardLayouts */, |
301 true /* login_layouts_only */, | 319 true /* login_layouts_only */, |
302 callback.Pass()); | 320 callback); |
303 } | 321 } |
304 | 322 |
305 void NetworkScreenHandler::SetInputMethod(const std::string& input_method) { | 323 void NetworkScreenHandler::SetInputMethod(const std::string& input_method) { |
306 input_method_ = input_method; | 324 input_method_ = input_method; |
307 input_method::InputMethodManager::Get() | 325 input_method::InputMethodManager::Get() |
308 ->GetActiveIMEState() | 326 ->GetActiveIMEState() |
309 ->ChangeInputMethod(input_method, false /* show_message */); | 327 ->ChangeInputMethod(input_method, false /* show_message */); |
310 } | 328 } |
311 | 329 |
312 void NetworkScreenHandler::SetTimezone( | 330 void NetworkScreenHandler::SetTimezone( |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
364 timezone_option->SetString("value", timezone_id); | 382 timezone_option->SetString("value", timezone_id); |
365 timezone_option->SetString("title", timezone_name); | 383 timezone_option->SetString("title", timezone_name); |
366 timezone_option->SetBoolean("selected", timezone_id == current_timezone_id); | 384 timezone_option->SetBoolean("selected", timezone_id == current_timezone_id); |
367 timezone_list->Append(timezone_option.release()); | 385 timezone_list->Append(timezone_option.release()); |
368 } | 386 } |
369 | 387 |
370 return timezone_list.release(); | 388 return timezone_list.release(); |
371 } | 389 } |
372 | 390 |
373 } // namespace chromeos | 391 } // namespace chromeos |
OLD | NEW |