OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/l10n_util.h" | 5 #include "chrome/browser/ui/webui/chromeos/login/l10n_util.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <iterator> | 8 #include <iterator> |
9 #include <map> | 9 #include <map> |
10 #include <set> | 10 #include <set> |
11 #include <utility> | 11 #include <utility> |
12 | 12 |
13 #include "base/basictypes.h" | 13 #include "base/basictypes.h" |
| 14 #include "base/bind.h" |
14 #include "base/i18n/rtl.h" | 15 #include "base/i18n/rtl.h" |
| 16 #include "base/location.h" |
15 #include "base/logging.h" | 17 #include "base/logging.h" |
| 18 #include "base/memory/ref_counted.h" |
| 19 #include "base/sequenced_task_runner.h" |
16 #include "base/strings/string16.h" | 20 #include "base/strings/string16.h" |
17 #include "base/strings/stringprintf.h" | 21 #include "base/strings/stringprintf.h" |
18 #include "base/strings/utf_string_conversions.h" | 22 #include "base/strings/utf_string_conversions.h" |
| 23 #include "base/task_runner_util.h" |
| 24 #include "base/threading/sequenced_worker_pool.h" |
19 #include "base/values.h" | 25 #include "base/values.h" |
20 #include "chrome/browser/browser_process.h" | 26 #include "chrome/browser/browser_process.h" |
21 #include "chrome/browser/chromeos/customization_document.h" | 27 #include "chrome/browser/chromeos/customization_document.h" |
22 #include "chrome/browser/chromeos/input_method/input_method_util.h" | 28 #include "chrome/browser/chromeos/input_method/input_method_util.h" |
23 #include "chromeos/ime/component_extension_ime_manager.h" | 29 #include "chromeos/ime/component_extension_ime_manager.h" |
24 #include "chromeos/ime/input_method_descriptor.h" | 30 #include "chromeos/ime/input_method_descriptor.h" |
25 #include "chromeos/ime/input_method_manager.h" | 31 #include "chromeos/ime/input_method_manager.h" |
| 32 #include "content/public/browser/browser_thread.h" |
26 #include "grit/generated_resources.h" | 33 #include "grit/generated_resources.h" |
27 #include "ui/base/l10n/l10n_util.h" | 34 #include "ui/base/l10n/l10n_util.h" |
28 | 35 |
29 namespace chromeos { | 36 namespace chromeos { |
30 | 37 |
31 namespace { | 38 namespace { |
32 | 39 |
33 base::DictionaryValue* CreateInputMethodsEntry( | 40 const char kSequenceToken[] = "chromeos_login_l10n_util"; |
| 41 |
| 42 scoped_ptr<base::DictionaryValue> CreateInputMethodsEntry( |
34 const input_method::InputMethodDescriptor& method, | 43 const input_method::InputMethodDescriptor& method, |
35 const std::string selected) { | 44 const std::string selected) { |
36 input_method::InputMethodUtil* util = | 45 input_method::InputMethodUtil* util = |
37 input_method::InputMethodManager::Get()->GetInputMethodUtil(); | 46 input_method::InputMethodManager::Get()->GetInputMethodUtil(); |
38 const std::string& ime_id = method.id(); | 47 const std::string& ime_id = method.id(); |
39 scoped_ptr<base::DictionaryValue> input_method(new base::DictionaryValue); | 48 scoped_ptr<base::DictionaryValue> input_method(new base::DictionaryValue); |
40 input_method->SetString("value", ime_id); | 49 input_method->SetString("value", ime_id); |
41 input_method->SetString("title", util->GetInputMethodLongName(method)); | 50 input_method->SetString("title", util->GetInputMethodLongName(method)); |
42 input_method->SetBoolean("selected", ime_id == selected); | 51 input_method->SetBoolean("selected", ime_id == selected); |
43 return input_method.release(); | 52 return input_method.Pass(); |
44 } | 53 } |
45 | 54 |
46 // Returns true if element was inserted. | 55 // Returns true if element was inserted. |
47 bool InsertString(const std::string& str, std::set<std::string>& to) { | 56 bool InsertString(const std::string& str, std::set<std::string>& to) { |
48 const std::pair<std::set<std::string>::iterator, bool> result = | 57 const std::pair<std::set<std::string>::iterator, bool> result = |
49 to.insert(str); | 58 to.insert(str); |
50 return result.second; | 59 return result.second; |
51 } | 60 } |
52 | 61 |
53 void AddOptgroupOtherLayouts(base::ListValue* input_methods_list) { | 62 void AddOptgroupOtherLayouts(base::ListValue* input_methods_list) { |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
263 dictionary->SetString("code", pair.first); | 272 dictionary->SetString("code", pair.first); |
264 dictionary->SetString("displayName", out_display_names[i]); | 273 dictionary->SetString("displayName", out_display_names[i]); |
265 dictionary->SetString("textDirection", directionality); | 274 dictionary->SetString("textDirection", directionality); |
266 dictionary->SetString("nativeDisplayName", pair.second); | 275 dictionary->SetString("nativeDisplayName", pair.second); |
267 language_list->Append(dictionary); | 276 language_list->Append(dictionary); |
268 } | 277 } |
269 | 278 |
270 return language_list.Pass(); | 279 return language_list.Pass(); |
271 } | 280 } |
272 | 281 |
| 282 // Invokes |callback| with a list of keyboard layouts that can be used for |
| 283 // |resolved_locale|. |
| 284 void GetKeyboardLayoutsForResolvedLocale( |
| 285 const GetKeyboardLayoutsForLocaleCallback& callback, |
| 286 const std::string& resolved_locale) { |
| 287 input_method::InputMethodUtil* util = |
| 288 input_method::InputMethodManager::Get()->GetInputMethodUtil(); |
| 289 std::vector<std::string> layouts = util->GetHardwareInputMethodIds(); |
| 290 std::vector<std::string> layouts_from_locale; |
| 291 util->GetInputMethodIdsFromLanguageCode( |
| 292 resolved_locale, |
| 293 input_method::kKeyboardLayoutsOnly, |
| 294 &layouts_from_locale); |
| 295 layouts.insert(layouts.end(), layouts_from_locale.begin(), |
| 296 layouts_from_locale.end()); |
| 297 |
| 298 std::string selected; |
| 299 if (!layouts_from_locale.empty()) { |
| 300 selected = |
| 301 util->GetInputMethodDescriptorFromId(layouts_from_locale[0])->id(); |
| 302 } |
| 303 |
| 304 scoped_ptr<base::ListValue> input_methods_list(new base::ListValue); |
| 305 std::set<std::string> input_methods_added; |
| 306 for (std::vector<std::string>::const_iterator it = layouts.begin(); |
| 307 it != layouts.end(); ++it) { |
| 308 const input_method::InputMethodDescriptor* ime = |
| 309 util->GetInputMethodDescriptorFromId(*it); |
| 310 if (!InsertString(ime->id(), input_methods_added)) |
| 311 continue; |
| 312 input_methods_list->Append( |
| 313 CreateInputMethodsEntry(*ime, selected).release()); |
| 314 } |
| 315 |
| 316 callback.Run(input_methods_list.Pass()); |
| 317 } |
| 318 |
273 } // namespace | 319 } // namespace |
274 | 320 |
275 const char kMostRelevantLanguagesDivider[] = "MOST_RELEVANT_LANGUAGES_DIVIDER"; | 321 const char kMostRelevantLanguagesDivider[] = "MOST_RELEVANT_LANGUAGES_DIVIDER"; |
276 | 322 |
277 scoped_ptr<base::ListValue> GetUILanguageList( | 323 scoped_ptr<base::ListValue> GetUILanguageList( |
278 const std::vector<std::string>* most_relevant_language_codes, | 324 const std::vector<std::string>* most_relevant_language_codes, |
279 const std::string& selected) { | 325 const std::string& selected) { |
280 ComponentExtensionIMEManager* manager = | 326 ComponentExtensionIMEManager* manager = |
281 input_method::InputMethodManager::Get()-> | 327 input_method::InputMethodManager::Get()-> |
282 GetComponentExtensionIMEManager(); | 328 GetComponentExtensionIMEManager(); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
352 | 398 |
353 for (std::vector<std::string>::const_iterator i = | 399 for (std::vector<std::string>::const_iterator i = |
354 hardware_login_input_methods.begin(); | 400 hardware_login_input_methods.begin(); |
355 i != hardware_login_input_methods.end(); | 401 i != hardware_login_input_methods.end(); |
356 ++i) { | 402 ++i) { |
357 const input_method::InputMethodDescriptor* ime = | 403 const input_method::InputMethodDescriptor* ime = |
358 util->GetInputMethodDescriptorFromId(*i); | 404 util->GetInputMethodDescriptorFromId(*i); |
359 // Do not crash in case of misconfiguration. | 405 // Do not crash in case of misconfiguration. |
360 if (ime) { | 406 if (ime) { |
361 input_methods_added.insert(*i); | 407 input_methods_added.insert(*i); |
362 input_methods_list->Append(CreateInputMethodsEntry(*ime, selected)); | 408 input_methods_list->Append( |
| 409 CreateInputMethodsEntry(*ime, selected).release()); |
363 } else { | 410 } else { |
364 NOTREACHED(); | 411 NOTREACHED(); |
365 } | 412 } |
366 } | 413 } |
367 | 414 |
368 bool optgroup_added = false; | 415 bool optgroup_added = false; |
369 for (size_t i = 0; i < input_methods->size(); ++i) { | 416 for (size_t i = 0; i < input_methods->size(); ++i) { |
370 // Makes sure the id is in legacy xkb id format. | 417 // Makes sure the id is in legacy xkb id format. |
371 const std::string& ime_id = (*input_methods)[i].id(); | 418 const std::string& ime_id = (*input_methods)[i].id(); |
372 if (!InsertString(ime_id, input_methods_added)) | 419 if (!InsertString(ime_id, input_methods_added)) |
373 continue; | 420 continue; |
374 if (!optgroup_added) { | 421 if (!optgroup_added) { |
375 optgroup_added = true; | 422 optgroup_added = true; |
376 AddOptgroupOtherLayouts(input_methods_list.get()); | 423 AddOptgroupOtherLayouts(input_methods_list.get()); |
377 } | 424 } |
378 input_methods_list->Append(CreateInputMethodsEntry((*input_methods)[i], | 425 input_methods_list->Append(CreateInputMethodsEntry((*input_methods)[i], |
379 selected)); | 426 selected).release()); |
380 } | 427 } |
381 | 428 |
382 // "xkb:us::eng" should always be in the list of available layouts. | 429 // "xkb:us::eng" should always be in the list of available layouts. |
383 const std::string us_keyboard_id = | 430 const std::string us_keyboard_id = |
384 util->GetFallbackInputMethodDescriptor().id(); | 431 util->GetFallbackInputMethodDescriptor().id(); |
385 if (input_methods_added.find(us_keyboard_id) == input_methods_added.end()) { | 432 if (input_methods_added.find(us_keyboard_id) == input_methods_added.end()) { |
386 const input_method::InputMethodDescriptor* us_eng_descriptor = | 433 const input_method::InputMethodDescriptor* us_eng_descriptor = |
387 util->GetInputMethodDescriptorFromId(us_keyboard_id); | 434 util->GetInputMethodDescriptorFromId(us_keyboard_id); |
388 DCHECK(us_eng_descriptor); | 435 DCHECK(us_eng_descriptor); |
389 if (!optgroup_added) { | 436 if (!optgroup_added) { |
390 optgroup_added = true; | 437 optgroup_added = true; |
391 AddOptgroupOtherLayouts(input_methods_list.get()); | 438 AddOptgroupOtherLayouts(input_methods_list.get()); |
392 } | 439 } |
393 input_methods_list->Append(CreateInputMethodsEntry(*us_eng_descriptor, | 440 input_methods_list->Append(CreateInputMethodsEntry(*us_eng_descriptor, |
394 selected)); | 441 selected).release()); |
395 } | 442 } |
396 return input_methods_list.Pass(); | 443 return input_methods_list.Pass(); |
397 } | 444 } |
398 | 445 |
399 scoped_ptr<base::ListValue> GetKeyboardLayoutsForLocale( | 446 void GetKeyboardLayoutsForLocale( |
| 447 const GetKeyboardLayoutsForLocaleCallback& callback, |
400 const std::string& locale) { | 448 const std::string& locale) { |
401 input_method::InputMethodUtil* util = | 449 base::SequencedWorkerPool* worker_pool = |
402 input_method::InputMethodManager::Get()->GetInputMethodUtil(); | 450 content::BrowserThread::GetBlockingPool(); |
403 std::vector<std::string> layouts = util->GetHardwareInputMethodIds(); | 451 scoped_refptr<base::SequencedTaskRunner> background_task_runner = |
404 std::vector<std::string> layouts_from_locale; | 452 worker_pool->GetSequencedTaskRunnerWithShutdownBehavior( |
405 util->GetInputMethodIdsFromLanguageCode( | 453 worker_pool->GetNamedSequenceToken(kSequenceToken), |
406 l10n_util::GetApplicationLocale(locale), | 454 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); |
407 input_method::kKeyboardLayoutsOnly, | |
408 &layouts_from_locale); | |
409 layouts.insert(layouts.end(), layouts_from_locale.begin(), | |
410 layouts_from_locale.end()); | |
411 | 455 |
412 std::string selected; | 456 // Resolve |locale| on a background thread, then continue on the current |
413 if (!layouts_from_locale.empty()) { | 457 // thread. |
414 selected = | 458 base::PostTaskAndReplyWithResult( |
415 util->GetInputMethodDescriptorFromId(layouts_from_locale[0])->id(); | 459 background_task_runner, |
416 } | 460 FROM_HERE, |
| 461 base::Bind(&l10n_util::GetApplicationLocale, |
| 462 locale), |
| 463 base::Bind(&GetKeyboardLayoutsForResolvedLocale, |
| 464 callback)); |
| 465 } |
417 | 466 |
418 scoped_ptr<base::ListValue> input_methods_list(new base::ListValue); | 467 scoped_ptr<base::DictionaryValue> GetCurrentKeyboardLayout() { |
419 std::set<std::string> input_methods_added; | 468 const input_method::InputMethodDescriptor current_input_method = |
420 for (std::vector<std::string>::const_iterator it = layouts.begin(); | 469 input_method::InputMethodManager::Get()->GetCurrentInputMethod(); |
421 it != layouts.end(); ++it) { | 470 return CreateInputMethodsEntry(current_input_method, |
422 const input_method::InputMethodDescriptor* ime = | 471 current_input_method.id()); |
423 util->GetInputMethodDescriptorFromId(*it); | |
424 if (!InsertString(ime->id(), input_methods_added)) | |
425 continue; | |
426 input_methods_list->Append(CreateInputMethodsEntry(*ime, selected)); | |
427 } | |
428 return input_methods_list.Pass(); | |
429 } | 472 } |
430 | 473 |
431 } // namespace chromeos | 474 } // namespace chromeos |
OLD | NEW |