1 // Copyright 2015 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/extensions/api/language_settings_private/language_settings_private_api.h"
12 #include "base/containers/hash_tables.h"
13 #include "base/i18n/rtl.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/strings/string16.h"
16 #include "base/strings/utf_string_conversions.h"
17 #include "base/values.h"
18 #include "chrome/browser/browser_process.h"
19 #include "chrome/browser/extensions/api/language_settings_private/language_settings_private_delegate.h"
20 #include "chrome/browser/extensions/api/language_settings_private/language_settings_private_delegate_factory.h"
21 #include "chrome/browser/profiles/profile.h"
22 #include "chrome/browser/spellchecker/spellcheck_factory.h"
23 #include "chrome/browser/spellchecker/spellcheck_service.h"
24 #include "chrome/browser/translate/chrome_translate_client.h"
25 #include "chrome/browser/translate/translate_service.h"
26 #include "chrome/common/extensions/api/language_settings_private.h"
27 #include "chrome/common/spellcheck_common.h"
28 #include "components/translate/core/browser/translate_download_manager.h"
29 #include "third_party/icu/source/i18n/unicode/coll.h"
30 #include "ui/base/l10n/l10n_util.h"
31 #include "ui/base/l10n/l10n_util_collator.h"
33 namespace extensions
{
35 namespace language_settings_private
= api::language_settings_private
;
37 LanguageSettingsPrivateGetLanguageListFunction::
38 LanguageSettingsPrivateGetLanguageListFunction() {
41 LanguageSettingsPrivateGetLanguageListFunction::
42 ~LanguageSettingsPrivateGetLanguageListFunction() {
45 ExtensionFunction::ResponseAction
46 LanguageSettingsPrivateGetLanguageListFunction::Run() {
47 // Collect the language codes from the supported accept-languages.
48 const std::string app_locale
= g_browser_process
->GetApplicationLocale();
49 std::vector
<std::string
> language_codes
;
50 l10n_util::GetAcceptLanguagesForLocale(app_locale
, &language_codes
);
52 // Map of display name -> {language code, native display name}.
53 typedef std::pair
<std::string
, base::string16
> LanguagePair
;
54 typedef std::map
<base::string16
, LanguagePair
,
55 l10n_util::StringComparator
<base::string16
>> LanguageMap
;
57 // Collator used to sort display names in the current locale.
58 UErrorCode error
= U_ZERO_ERROR
;
59 scoped_ptr
<icu::Collator
> collator(icu::Collator::createInstance(
60 icu::Locale(app_locale
.c_str()), error
));
63 LanguageMap
language_map(
64 l10n_util::StringComparator
<base::string16
>(collator
.get()));
66 // Build the list of display names and the language map.
67 for (const auto& code
: language_codes
) {
68 base::string16 display_name
= l10n_util::GetDisplayNameForLocale(
69 code
, app_locale
, false);
70 base::string16 native_display_name
= l10n_util::GetDisplayNameForLocale(
72 language_map
[display_name
] = std::make_pair(code
, native_display_name
);
75 // Get the list of available locales (display languages) and convert to a set.
76 const std::vector
<std::string
>& locales
= l10n_util::GetAvailableLocales();
77 const base::hash_set
<std::string
> locale_set(
78 locales
.begin(), locales
.end());
80 // Get the list of spell check languages and convert to a set.
81 std::vector
<std::string
> spellcheck_languages
;
82 chrome::spellcheck_common::SpellCheckLanguages(&spellcheck_languages
);
83 const base::hash_set
<std::string
> spellcheck_language_set(
84 spellcheck_languages
.begin(), spellcheck_languages
.end());
86 // Get the list of translatable languages and convert to a set.
87 std::vector
<std::string
> translate_languages
;
88 translate::TranslateDownloadManager::GetSupportedLanguages(
89 &translate_languages
);
90 const base::hash_set
<std::string
> translate_language_set(
91 translate_languages
.begin(), translate_languages
.end());
93 // Build the language list from the language map.
94 scoped_ptr
<base::ListValue
> language_list(new base::ListValue
);
95 for (const auto& entry
: language_map
) {
96 const base::string16
& display_name
= entry
.first
;
97 const LanguagePair
& pair
= entry
.second
;
99 language_settings_private::Language language
;
100 language
.code
= pair
.first
;
102 base::string16
adjusted_display_name(display_name
);
103 base::i18n::AdjustStringForLocaleDirection(&adjusted_display_name
);
104 language
.display_name
= base::UTF16ToUTF8(adjusted_display_name
);
106 base::string16
adjusted_native_display_name(pair
.second
);
107 base::i18n::AdjustStringForLocaleDirection(&adjusted_native_display_name
);
108 language
.native_display_name
=
109 base::UTF16ToUTF8(adjusted_native_display_name
);
111 // Set optional fields only if they differ from the default.
112 if (base::i18n::StringContainsStrongRTLChars(display_name
))
113 language
.display_name_rtl
.reset(new bool(true));
114 if (locale_set
.count(pair
.first
) > 0)
115 language
.supports_ui
.reset(new bool(true));
116 if (spellcheck_language_set
.count(pair
.first
) > 0)
117 language
.supports_spellcheck
.reset(new bool(true));
118 if (translate_language_set
.count(pair
.first
) > 0)
119 language
.supports_translate
.reset(new bool(true));
121 language_list
->Append(language
.ToValue());
123 return RespondNow(OneArgument(language_list
.release()));
126 LanguageSettingsPrivateSetLanguageListFunction::
127 LanguageSettingsPrivateSetLanguageListFunction()
128 : chrome_details_(this) {
131 LanguageSettingsPrivateSetLanguageListFunction::
132 ~LanguageSettingsPrivateSetLanguageListFunction() {
135 ExtensionFunction::ResponseAction
136 LanguageSettingsPrivateSetLanguageListFunction::Run() {
137 scoped_ptr
<language_settings_private::SetLanguageList::Params
> parameters
=
138 language_settings_private::SetLanguageList::Params::Create(*args_
);
139 EXTENSION_FUNCTION_VALIDATE(parameters
.get());
141 scoped_ptr
<translate::TranslatePrefs
> translate_prefs
=
142 ChromeTranslateClient::CreateTranslatePrefs(
143 chrome_details_
.GetProfile()->GetPrefs());
144 translate_prefs
->UpdateLanguageList(parameters
->language_codes
);
146 return RespondNow(NoArguments());
149 LanguageSettingsPrivateGetSpellcheckDictionaryStatusesFunction::
150 LanguageSettingsPrivateGetSpellcheckDictionaryStatusesFunction() {
153 LanguageSettingsPrivateGetSpellcheckDictionaryStatusesFunction::
154 ~LanguageSettingsPrivateGetSpellcheckDictionaryStatusesFunction() {
157 ExtensionFunction::ResponseAction
158 LanguageSettingsPrivateGetSpellcheckDictionaryStatusesFunction::Run() {
159 LanguageSettingsPrivateDelegate
* delegate
=
160 LanguageSettingsPrivateDelegateFactory::GetForBrowserContext(
163 scoped_ptr
<base::ListValue
> return_list(new base::ListValue());
164 for (const auto& status
: delegate
->GetHunspellDictionaryStatuses())
165 return_list
->Append(status
->ToValue());
166 return RespondNow(OneArgument(return_list
.release()));
169 LanguageSettingsPrivateGetSpellcheckWordsFunction::
170 LanguageSettingsPrivateGetSpellcheckWordsFunction() {
173 LanguageSettingsPrivateGetSpellcheckWordsFunction::
174 ~LanguageSettingsPrivateGetSpellcheckWordsFunction() {
177 ExtensionFunction::ResponseAction
178 LanguageSettingsPrivateGetSpellcheckWordsFunction::Run() {
179 SpellcheckService
* service
=
180 SpellcheckServiceFactory::GetForContext(browser_context());
181 SpellcheckCustomDictionary
* dictionary
= service
->GetCustomDictionary();
183 scoped_ptr
<base::ListValue
> word_list(new base::ListValue());
184 // TODO(michaelpg): observe the dictionary and respond later if not loaded.
185 if (dictionary
->IsLoaded()) {
186 const std::set
<std::string
>& words
= dictionary
->GetWords();
187 for (const std::string
& word
: words
)
188 word_list
->AppendString(word
);
190 return RespondNow(OneArgument(word_list
.release()));
193 LanguageSettingsPrivateGetTranslateTargetLanguageFunction::
194 LanguageSettingsPrivateGetTranslateTargetLanguageFunction()
195 : chrome_details_(this) {
198 LanguageSettingsPrivateGetTranslateTargetLanguageFunction::
199 ~LanguageSettingsPrivateGetTranslateTargetLanguageFunction() {
202 ExtensionFunction::ResponseAction
203 LanguageSettingsPrivateGetTranslateTargetLanguageFunction::Run() {
204 return RespondNow(OneArgument(new base::StringValue(
205 TranslateService::GetTargetLanguage(
206 chrome_details_
.GetProfile()->GetPrefs()))));
209 LanguageSettingsPrivateGetInputMethodListsFunction::
210 LanguageSettingsPrivateGetInputMethodListsFunction() {
213 LanguageSettingsPrivateGetInputMethodListsFunction::
214 ~LanguageSettingsPrivateGetInputMethodListsFunction() {
217 ExtensionFunction::ResponseAction
218 LanguageSettingsPrivateGetInputMethodListsFunction::Run() {
219 return RespondNow(OneArgument(new base::DictionaryValue()));
222 LanguageSettingsPrivateAddInputMethodFunction::
223 LanguageSettingsPrivateAddInputMethodFunction() {
226 LanguageSettingsPrivateAddInputMethodFunction::
227 ~LanguageSettingsPrivateAddInputMethodFunction() {
230 ExtensionFunction::ResponseAction
231 LanguageSettingsPrivateAddInputMethodFunction::Run() {
232 return RespondNow(OneArgument(new base::FundamentalValue(true)));
235 LanguageSettingsPrivateRemoveInputMethodFunction::
236 LanguageSettingsPrivateRemoveInputMethodFunction() {
239 LanguageSettingsPrivateRemoveInputMethodFunction::
240 ~LanguageSettingsPrivateRemoveInputMethodFunction() {
243 ExtensionFunction::ResponseAction
244 LanguageSettingsPrivateRemoveInputMethodFunction::Run() {
245 return RespondNow(OneArgument(new base::FundamentalValue(true)));
248 } // namespace extensions