BookmarkManager: Fix 'new folder text field size changes on clicking it' issue.
[chromium-blink-merge.git] / chrome / browser / chromeos / extensions / input_method_api.cc
bloba98d26241b5e9921b0227a9656cd1e3c8932caf0
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.
5 #include "chrome/browser/chromeos/extensions/input_method_api.h"
7 #include <set>
8 #include <string>
10 #include "base/command_line.h"
11 #include "base/lazy_instance.h"
12 #include "base/values.h"
13 #include "chrome/browser/chromeos/extensions/dictionary_event_router.h"
14 #include "chrome/browser/chromeos/extensions/input_method_event_router.h"
15 #include "chrome/browser/chromeos/input_method/input_method_util.h"
16 #include "chrome/browser/extensions/api/input_ime/input_ime_api.h"
17 #include "chrome/browser/spellchecker/spellcheck_factory.h"
18 #include "chrome/browser/spellchecker/spellcheck_service.h"
19 #include "chrome/browser/sync/profile_sync_service.h"
20 #include "chrome/browser/sync/profile_sync_service_factory.h"
21 #include "chromeos/chromeos_switches.h"
22 #include "extensions/browser/extension_function_registry.h"
23 #include "extensions/browser/extension_system.h"
24 #include "ui/base/ime/chromeos/extension_ime_util.h"
25 #include "ui/base/ime/chromeos/input_method_descriptor.h"
26 #include "ui/base/ime/chromeos/input_method_manager.h"
27 #include "ui/keyboard/keyboard_util.h"
29 namespace {
31 // Prefix, which is used by XKB.
32 const char kXkbPrefix[] = "xkb:";
34 } // namespace
36 namespace extensions {
38 ExtensionFunction::ResponseAction GetInputMethodConfigFunction::Run() {
39 #if !defined(OS_CHROMEOS)
40 EXTENSION_FUNCTION_VALIDATE(false);
41 #else
42 base::DictionaryValue* output = new base::DictionaryValue();
43 output->SetBoolean(
44 "isPhysicalKeyboardAutocorrectEnabled",
45 !base::CommandLine::ForCurrentProcess()->HasSwitch(
46 chromeos::switches::kDisablePhysicalKeyboardAutocorrect));
47 return RespondNow(OneArgument(output));
48 #endif
51 ExtensionFunction::ResponseAction GetCurrentInputMethodFunction::Run() {
52 #if !defined(OS_CHROMEOS)
53 EXTENSION_FUNCTION_VALIDATE(false);
54 #else
55 chromeos::input_method::InputMethodManager* manager =
56 chromeos::input_method::InputMethodManager::Get();
57 return RespondNow(OneArgument(new base::StringValue(
58 manager->GetActiveIMEState()->GetCurrentInputMethod().id())));
59 #endif
62 ExtensionFunction::ResponseAction SetCurrentInputMethodFunction::Run() {
63 #if !defined(OS_CHROMEOS)
64 EXTENSION_FUNCTION_VALIDATE(false);
65 #else
66 std::string new_input_method;
67 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &new_input_method));
68 scoped_refptr<chromeos::input_method::InputMethodManager::State> ime_state =
69 chromeos::input_method::InputMethodManager::Get()->GetActiveIMEState();
70 const std::vector<std::string>& input_methods =
71 ime_state->GetActiveInputMethodIds();
72 for (size_t i = 0; i < input_methods.size(); ++i) {
73 const std::string& input_method = input_methods[i];
74 if (input_method == new_input_method) {
75 ime_state->ChangeInputMethod(new_input_method, false /* show_message */);
76 return RespondNow(NoArguments());
79 return RespondNow(Error("Invalid input method id."));
80 #endif
83 ExtensionFunction::ResponseAction GetInputMethodsFunction::Run() {
84 #if !defined(OS_CHROMEOS)
85 EXTENSION_FUNCTION_VALIDATE(false);
86 #else
87 base::ListValue* output = new base::ListValue();
88 chromeos::input_method::InputMethodManager* manager =
89 chromeos::input_method::InputMethodManager::Get();
90 chromeos::input_method::InputMethodUtil* util = manager->GetInputMethodUtil();
91 scoped_refptr<chromeos::input_method::InputMethodManager::State> ime_state =
92 manager->GetActiveIMEState();
93 scoped_ptr<chromeos::input_method::InputMethodDescriptors> input_methods =
94 ime_state->GetActiveInputMethods();
95 for (size_t i = 0; i < input_methods->size(); ++i) {
96 const chromeos::input_method::InputMethodDescriptor& input_method =
97 (*input_methods)[i];
98 base::DictionaryValue* val = new base::DictionaryValue();
99 val->SetString("id", input_method.id());
100 val->SetString("name", util->GetInputMethodLongName(input_method));
101 val->SetString("indicator", util->GetInputMethodShortName(input_method));
102 output->Append(val);
104 return RespondNow(OneArgument(output));
105 #endif
108 ExtensionFunction::ResponseAction FetchAllDictionaryWordsFunction::Run() {
109 #if !defined(OS_CHROMEOS)
110 EXTENSION_FUNCTION_VALIDATE(false);
111 #else
112 SpellcheckService* spellcheck = SpellcheckServiceFactory::GetForContext(
113 context_);
114 if (!spellcheck) {
115 return RespondNow(Error("Spellcheck service not available."));
117 SpellcheckCustomDictionary* dictionary = spellcheck->GetCustomDictionary();
118 if (!dictionary->IsLoaded()) {
119 return RespondNow(Error("Custom dictionary not loaded yet."));
122 const std::set<std::string>& words = dictionary->GetWords();
123 base::ListValue* output = new base::ListValue();
124 for (auto it = words.begin(); it != words.end(); ++it) {
125 output->AppendString(*it);
127 return RespondNow(OneArgument(output));
128 #endif
131 ExtensionFunction::ResponseAction AddWordToDictionaryFunction::Run() {
132 #if !defined(OS_CHROMEOS)
133 EXTENSION_FUNCTION_VALIDATE(false);
134 #else
135 std::string word;
136 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &word));
137 SpellcheckService* spellcheck = SpellcheckServiceFactory::GetForContext(
138 context_);
139 if (!spellcheck) {
140 return RespondNow(Error("Spellcheck service not available."));
142 SpellcheckCustomDictionary* dictionary = spellcheck->GetCustomDictionary();
143 if (!dictionary->IsLoaded()) {
144 return RespondNow(Error("Custom dictionary not loaded yet."));
147 if (dictionary->AddWord(word))
148 return RespondNow(NoArguments());
149 // Invalid words:
150 // - Already in the dictionary.
151 // - Not a UTF8 string.
152 // - Longer than 99 bytes (MAX_CUSTOM_DICTIONARY_WORD_BYTES).
153 // - Leading/trailing whitespace.
154 // - Empty.
155 return RespondNow(Error("Unable to add invalid word to dictionary."));
156 #endif
159 ExtensionFunction::ResponseAction GetEncryptSyncEnabledFunction::Run() {
160 #if !defined(OS_CHROMEOS)
161 EXTENSION_FUNCTION_VALIDATE(false);
162 #else
163 ProfileSyncService* profile_sync_service =
164 ProfileSyncServiceFactory::GetForProfile(
165 Profile::FromBrowserContext(browser_context()));
166 if (!profile_sync_service)
167 return RespondNow(Error("Sync service is not ready for current profile."));
168 scoped_ptr<base::Value> ret(new base::FundamentalValue(
169 profile_sync_service->IsEncryptEverythingEnabled()));
170 return RespondNow(OneArgument(ret.Pass()));
171 #endif
174 // static
175 const char InputMethodAPI::kOnDictionaryChanged[] =
176 "inputMethodPrivate.onDictionaryChanged";
178 // static
179 const char InputMethodAPI::kOnDictionaryLoaded[] =
180 "inputMethodPrivate.onDictionaryLoaded";
182 // static
183 const char InputMethodAPI::kOnInputMethodChanged[] =
184 "inputMethodPrivate.onChanged";
186 InputMethodAPI::InputMethodAPI(content::BrowserContext* context)
187 : context_(context) {
188 EventRouter::Get(context_)->RegisterObserver(this, kOnInputMethodChanged);
189 EventRouter::Get(context_)->RegisterObserver(this, kOnDictionaryChanged);
190 EventRouter::Get(context_)->RegisterObserver(this, kOnDictionaryLoaded);
191 ExtensionFunctionRegistry* registry =
192 ExtensionFunctionRegistry::GetInstance();
193 registry->RegisterFunction<GetInputMethodConfigFunction>();
194 registry->RegisterFunction<GetCurrentInputMethodFunction>();
195 registry->RegisterFunction<SetCurrentInputMethodFunction>();
196 registry->RegisterFunction<GetInputMethodsFunction>();
197 registry->RegisterFunction<FetchAllDictionaryWordsFunction>();
198 registry->RegisterFunction<AddWordToDictionaryFunction>();
199 registry->RegisterFunction<GetEncryptSyncEnabledFunction>();
202 InputMethodAPI::~InputMethodAPI() {
205 // static
206 std::string InputMethodAPI::GetInputMethodForXkb(const std::string& xkb_id) {
207 std::string xkb_prefix =
208 chromeos::extension_ime_util::GetInputMethodIDByEngineID(kXkbPrefix);
209 size_t prefix_length = xkb_prefix.length();
210 DCHECK(xkb_id.substr(0, prefix_length) == xkb_prefix);
211 return xkb_id.substr(prefix_length);
214 void InputMethodAPI::Shutdown() {
215 EventRouter::Get(context_)->UnregisterObserver(this);
218 void InputMethodAPI::OnListenerAdded(
219 const extensions::EventListenerInfo& details) {
220 if (details.event_name == kOnInputMethodChanged) {
221 if (!input_method_event_router_.get()) {
222 input_method_event_router_.reset(
223 new chromeos::ExtensionInputMethodEventRouter(context_));
225 } else if (details.event_name == kOnDictionaryChanged ||
226 details.event_name == kOnDictionaryLoaded) {
227 if (!dictionary_event_router_.get()) {
228 dictionary_event_router_.reset(
229 new chromeos::ExtensionDictionaryEventRouter(context_));
231 if (details.event_name == kOnDictionaryLoaded) {
232 dictionary_event_router_->DispatchLoadedEventIfLoaded();
237 static base::LazyInstance<BrowserContextKeyedAPIFactory<InputMethodAPI> >
238 g_factory = LAZY_INSTANCE_INITIALIZER;
240 // static
241 BrowserContextKeyedAPIFactory<InputMethodAPI>*
242 InputMethodAPI::GetFactoryInstance() {
243 return g_factory.Pointer();
246 } // namespace extensions