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. 4 5#include "chrome/browser/ui/webui/options/chromeos/cros_language_options_handler.h" 6 7#include "base/bind.h" 8#include "base/bind_helpers.h" 9#include "base/strings/stringprintf.h" 10#include "base/strings/utf_string_conversions.h" 11#include "base/values.h" 12#include "chrome/app/chrome_command_ids.h" 13#include "chrome/browser/chromeos/input_method/input_method_util.h" 14#include "chrome/browser/chromeos/profiles/profile_helper.h" 15#include "chrome/browser/extensions/extension_tab_util.h" 16#include "chrome/browser/lifetime/application_lifetime.h" 17#include "chrome/browser/profiles/profile.h" 18#include "chrome/browser/ui/browser.h" 19#include "chrome/browser/ui/browser_finder.h" 20#include "chrome/browser/ui/browser_window.h" 21#include "chrome/browser/ui/tabs/tab_strip_model.h" 22#include "chrome/browser/ui/webui/chromeos/login/l10n_util.h" 23#include "chrome/common/extensions/manifest_url_handler.h" 24#include "chrome/grit/chromium_strings.h" 25#include "chrome/grit/generated_resources.h" 26#include "chromeos/ime/component_extension_ime_manager.h" 27#include "chromeos/ime/extension_ime_util.h" 28#include "chromeos/ime/input_method_manager.h" 29#include "components/user_manager/user_manager.h" 30#include "components/user_manager/user_type.h" 31#include "content/public/browser/navigation_controller.h" 32#include "content/public/browser/user_metrics.h" 33#include "content/public/browser/web_contents.h" 34#include "extensions/browser/extension_registry.h" 35#include "extensions/common/extension.h" 36#include "ui/base/l10n/l10n_util.h" 37 38using base::UserMetricsAction; 39 40namespace chromeos { 41namespace options { 42 43CrosLanguageOptionsHandler::CrosLanguageOptionsHandler() { 44} 45 46CrosLanguageOptionsHandler::~CrosLanguageOptionsHandler() { 47} 48 49void CrosLanguageOptionsHandler::GetLocalizedValues( 50 base::DictionaryValue* localized_strings) { 51 ::options::LanguageOptionsHandlerCommon::GetLocalizedValues( 52 localized_strings); 53 54 RegisterTitle(localized_strings, "languagePage", 55 IDS_OPTIONS_SETTINGS_LANGUAGES_AND_INPUT_DIALOG_TITLE); 56 localized_strings->SetString("okButton", l10n_util::GetStringUTF16(IDS_OK)); 57 localized_strings->SetString("configure", 58 l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_LANGUAGES_CONFIGURE)); 59 localized_strings->SetString("inputMethod", 60 l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_LANGUAGES_INPUT_METHOD)); 61 localized_strings->SetString("pleaseAddAnotherInputMethod", 62 l10n_util::GetStringUTF16( 63 IDS_OPTIONS_SETTINGS_LANGUAGES_PLEASE_ADD_ANOTHER_INPUT_METHOD)); 64 localized_strings->SetString("inputMethodInstructions", 65 l10n_util::GetStringUTF16( 66 IDS_OPTIONS_SETTINGS_LANGUAGES_INPUT_METHOD_INSTRUCTIONS)); 67 localized_strings->SetString("switchInputMethodsHint", 68 l10n_util::GetStringUTF16( 69 IDS_OPTIONS_SETTINGS_LANGUAGES_SWITCH_INPUT_METHODS_HINT)); 70 localized_strings->SetString("selectPreviousInputMethodHint", 71 l10n_util::GetStringUTF16( 72 IDS_OPTIONS_SETTINGS_LANGUAGES_SELECT_PREVIOUS_INPUT_METHOD_HINT)); 73 localized_strings->SetString("restartButton", 74 l10n_util::GetStringUTF16( 75 IDS_OPTIONS_SETTINGS_LANGUAGES_SIGN_OUT_BUTTON)); 76 localized_strings->SetString("extensionImeLable", 77 l10n_util::GetStringUTF16( 78 IDS_OPTIONS_SETTINGS_LANGUAGES_INPUT_METHOD_EXTENSION_IME)); 79 localized_strings->SetString("extensionImeDescription", 80 l10n_util::GetStringUTF16( 81 IDS_OPTIONS_SETTINGS_LANGUAGES_INPUT_METHOD_EXTENSION_DESCRIPTION)); 82 localized_strings->SetString("noInputMethods", 83 l10n_util::GetStringUTF16( 84 IDS_OPTIONS_SETTINGS_LANGUAGES_NO_INPUT_METHODS)); 85 86 // GetSupportedInputMethods() never returns NULL. 87 localized_strings->Set("languageList", GetAcceptLanguageList().release()); 88 localized_strings->Set("inputMethodList", GetInputMethodList()); 89 90 input_method::InputMethodManager* manager = 91 input_method::InputMethodManager::Get(); 92 input_method::InputMethodDescriptors ext_ime_descriptors; 93 manager->GetActiveIMEState()->GetInputMethodExtensions(&ext_ime_descriptors); 94 95 base::ListValue* ext_ime_list = ConvertInputMethodDescriptorsToIMEList( 96 ext_ime_descriptors); 97 AddImeProvider(ext_ime_list); 98 localized_strings->Set("extensionImeList", ext_ime_list); 99 100 ComponentExtensionIMEManager* component_extension_manager = 101 input_method::InputMethodManager::Get() 102 ->GetComponentExtensionIMEManager(); 103 localized_strings->Set( 104 "componentExtensionImeList", 105 ConvertInputMethodDescriptorsToIMEList( 106 component_extension_manager->GetAllIMEAsInputMethodDescriptor())); 107} 108 109void CrosLanguageOptionsHandler::RegisterMessages() { 110 ::options::LanguageOptionsHandlerCommon::RegisterMessages(); 111 112 web_ui()->RegisterMessageCallback("inputMethodDisable", 113 base::Bind(&CrosLanguageOptionsHandler::InputMethodDisableCallback, 114 base::Unretained(this))); 115 web_ui()->RegisterMessageCallback("inputMethodEnable", 116 base::Bind(&CrosLanguageOptionsHandler::InputMethodEnableCallback, 117 base::Unretained(this))); 118 web_ui()->RegisterMessageCallback("inputMethodOptionsOpen", 119 base::Bind(&CrosLanguageOptionsHandler::InputMethodOptionsOpenCallback, 120 base::Unretained(this))); 121 web_ui()->RegisterMessageCallback("uiLanguageRestart", 122 base::Bind(&CrosLanguageOptionsHandler::RestartCallback, 123 base::Unretained(this))); 124} 125 126// static 127base::ListValue* CrosLanguageOptionsHandler::GetInputMethodList() { 128 input_method::InputMethodManager* manager = 129 input_method::InputMethodManager::Get(); 130 // GetSupportedInputMethods() never return NULL. 131 scoped_ptr<input_method::InputMethodDescriptors> descriptors( 132 manager->GetSupportedInputMethods()); 133 134 base::ListValue* input_method_list = new base::ListValue(); 135 136 for (size_t i = 0; i < descriptors->size(); ++i) { 137 const input_method::InputMethodDescriptor& descriptor = 138 (*descriptors)[i]; 139 const std::string display_name = 140 manager->GetInputMethodUtil()->GetInputMethodDisplayNameFromId( 141 descriptor.id()); 142 base::DictionaryValue* dictionary = new base::DictionaryValue(); 143 dictionary->SetString("id", descriptor.id()); 144 dictionary->SetString("displayName", display_name); 145 146 // One input method can be associated with multiple languages, hence 147 // we use a dictionary here. 148 base::DictionaryValue* languages = new base::DictionaryValue(); 149 for (size_t i = 0; i < descriptor.language_codes().size(); ++i) { 150 languages->SetBoolean(descriptor.language_codes().at(i), true); 151 } 152 dictionary->Set("languageCodeSet", languages); 153 154 input_method_list->Append(dictionary); 155 } 156 157 return input_method_list; 158} 159 160base::ListValue* 161 CrosLanguageOptionsHandler::ConvertInputMethodDescriptorsToIMEList( 162 const input_method::InputMethodDescriptors& descriptors) { 163 scoped_ptr<base::ListValue> ime_ids_list(new base::ListValue()); 164 for (size_t i = 0; i < descriptors.size(); ++i) { 165 const input_method::InputMethodDescriptor& descriptor = descriptors[i]; 166 scoped_ptr<base::DictionaryValue> dictionary(new base::DictionaryValue()); 167 dictionary->SetString("id", descriptor.id()); 168 dictionary->SetString("displayName", descriptor.name()); 169 dictionary->SetString("optionsPage", descriptor.options_page_url().spec()); 170 scoped_ptr<base::DictionaryValue> language_codes( 171 new base::DictionaryValue()); 172 for (size_t i = 0; i < descriptor.language_codes().size(); ++i) 173 language_codes->SetBoolean(descriptor.language_codes().at(i), true); 174 dictionary->Set("languageCodeSet", language_codes.release()); 175 ime_ids_list->Append(dictionary.release()); 176 } 177 return ime_ids_list.release(); 178} 179 180base::string16 CrosLanguageOptionsHandler::GetProductName() { 181 return l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_OS_NAME); 182} 183 184void CrosLanguageOptionsHandler::SetApplicationLocale( 185 const std::string& language_code) { 186 Profile* profile = Profile::FromWebUI(web_ui()); 187 user_manager::UserManager* user_manager = user_manager::UserManager::Get(); 188 189 // Secondary users and public session users cannot change the locale. 190 user_manager::User* user = ProfileHelper::Get()->GetUserByProfile(profile); 191 if (user && 192 user->email() == user_manager->GetPrimaryUser()->email() && 193 user->GetType() != user_manager::USER_TYPE_PUBLIC_ACCOUNT) { 194 profile->ChangeAppLocale(language_code, 195 Profile::APP_LOCALE_CHANGED_VIA_SETTINGS); 196 } 197} 198 199void CrosLanguageOptionsHandler::RestartCallback(const base::ListValue* args) { 200 content::RecordAction(UserMetricsAction("LanguageOptions_SignOut")); 201 chrome::AttemptUserExit(); 202} 203 204void CrosLanguageOptionsHandler::InputMethodDisableCallback( 205 const base::ListValue* args) { 206 const std::string input_method_id = 207 base::UTF16ToASCII(ExtractStringValue(args)); 208 const std::string action = base::StringPrintf( 209 "LanguageOptions_DisableInputMethod_%s", input_method_id.c_str()); 210 content::RecordComputedAction(action); 211} 212 213void CrosLanguageOptionsHandler::InputMethodEnableCallback( 214 const base::ListValue* args) { 215 const std::string input_method_id = 216 base::UTF16ToASCII(ExtractStringValue(args)); 217 const std::string action = base::StringPrintf( 218 "LanguageOptions_EnableInputMethod_%s", input_method_id.c_str()); 219 content::RecordComputedAction(action); 220} 221 222void CrosLanguageOptionsHandler::InputMethodOptionsOpenCallback( 223 const base::ListValue* args) { 224 const std::string input_method_id = 225 base::UTF16ToASCII(ExtractStringValue(args)); 226 const std::string extension_id = 227 extension_ime_util::GetExtensionIDFromInputMethodID(input_method_id); 228 if (extension_id.empty()) 229 return; 230 231 const input_method::InputMethodDescriptor* ime = 232 input_method::InputMethodManager::Get() 233 ->GetActiveIMEState() 234 ->GetInputMethodFromId(input_method_id); 235 if (!ime) 236 return; 237 238 Browser* browser = chrome::FindBrowserWithWebContents( 239 web_ui()->GetWebContents()); 240 content::OpenURLParams params(ime->options_page_url(), 241 content::Referrer(), 242 SINGLETON_TAB, 243 ui::PAGE_TRANSITION_LINK, 244 false); 245 browser->OpenURL(params); 246} 247 248void CrosLanguageOptionsHandler::AddImeProvider(base::ListValue* list) { 249 Profile* profile = Profile::FromWebUI(web_ui()); 250 const extensions::ExtensionSet& enabled_extensions = 251 extensions::ExtensionRegistry::Get(profile)->enabled_extensions(); 252 for (size_t i = 0; i < list->GetSize(); ++i) { 253 base::DictionaryValue* entry; 254 list->GetDictionary(i, &entry); 255 256 std::string input_method_id; 257 entry->GetString("id", &input_method_id); 258 259 std::string extension_id = 260 extension_ime_util::GetExtensionIDFromInputMethodID(input_method_id); 261 const extensions::Extension* extension = 262 enabled_extensions.GetByID(extension_id); 263 if (extension) 264 entry->SetString("extensionName", extension->name()); 265 } 266} 267 268} // namespace options 269} // namespace chromeos 270