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/chromeos/extensions/input_method_api.h" | 5 #include "chrome/browser/chromeos/extensions/input_method_api.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <set> | 8 #include <set> |
9 #include <string> | 9 #include <string> |
10 #include <utility> | 10 #include <utility> |
11 | 11 |
12 #include "base/command_line.h" | 12 #include "base/command_line.h" |
13 #include "base/lazy_instance.h" | 13 #include "base/lazy_instance.h" |
14 #include "base/values.h" | 14 #include "base/values.h" |
15 #include "build/build_config.h" | 15 #include "build/build_config.h" |
16 #include "chrome/browser/chromeos/extensions/dictionary_event_router.h" | 16 #include "chrome/browser/chromeos/extensions/dictionary_event_router.h" |
17 #include "chrome/browser/chromeos/extensions/input_method_event_router.h" | 17 #include "chrome/browser/chromeos/extensions/input_method_event_router.h" |
18 #include "chrome/browser/chromeos/input_method/input_method_util.h" | 18 #include "chrome/browser/chromeos/input_method/input_method_util.h" |
19 #include "chrome/browser/extensions/api/input_ime/input_ime_api.h" | 19 #include "chrome/browser/extensions/api/input_ime/input_ime_api.h" |
20 #include "chrome/browser/spellchecker/spellcheck_factory.h" | 20 #include "chrome/browser/spellchecker/spellcheck_factory.h" |
21 #include "chrome/browser/spellchecker/spellcheck_service.h" | 21 #include "chrome/browser/spellchecker/spellcheck_service.h" |
22 #include "chrome/browser/sync/profile_sync_service_factory.h" | 22 #include "chrome/browser/sync/profile_sync_service_factory.h" |
23 #include "chrome/common/extensions/api/input_method_private.h" | |
23 #include "chromeos/chromeos_switches.h" | 24 #include "chromeos/chromeos_switches.h" |
24 #include "components/browser_sync/browser/profile_sync_service.h" | 25 #include "components/browser_sync/browser/profile_sync_service.h" |
25 #include "extensions/browser/extension_function_registry.h" | 26 #include "extensions/browser/extension_function_registry.h" |
26 #include "extensions/browser/extension_system.h" | 27 #include "extensions/browser/extension_system.h" |
27 #include "ui/base/ime/chromeos/extension_ime_util.h" | 28 #include "ui/base/ime/chromeos/extension_ime_util.h" |
28 #include "ui/base/ime/chromeos/input_method_descriptor.h" | 29 #include "ui/base/ime/chromeos/input_method_descriptor.h" |
29 #include "ui/base/ime/chromeos/input_method_manager.h" | 30 #include "ui/base/ime/chromeos/input_method_manager.h" |
30 #include "ui/keyboard/keyboard_util.h" | 31 #include "ui/keyboard/keyboard_util.h" |
31 | 32 |
33 namespace AddWordToDictionary = | |
34 extensions::api::input_method_private::AddWordToDictionary; | |
35 namespace SetCurrentInputMethod = | |
36 extensions::api::input_method_private::SetCurrentInputMethod; | |
37 namespace OnChanged = extensions::api::input_method_private::OnChanged; | |
38 namespace OnDictionaryChanged = | |
39 extensions::api::input_method_private::OnDictionaryChanged; | |
40 namespace OnDictionaryLoaded = | |
41 extensions::api::input_method_private::OnDictionaryLoaded; | |
42 | |
32 namespace { | 43 namespace { |
33 | 44 |
34 // Prefix, which is used by XKB. | 45 // Prefix, which is used by XKB. |
35 const char kXkbPrefix[] = "xkb:"; | 46 const char kXkbPrefix[] = "xkb:"; |
36 | 47 |
37 } // namespace | 48 } // namespace |
38 | 49 |
39 namespace extensions { | 50 namespace extensions { |
40 | 51 |
41 ExtensionFunction::ResponseAction GetInputMethodConfigFunction::Run() { | 52 ExtensionFunction::ResponseAction |
53 InputMethodPrivateGetInputMethodConfigFunction::Run() { | |
42 #if !defined(OS_CHROMEOS) | 54 #if !defined(OS_CHROMEOS) |
43 EXTENSION_FUNCTION_VALIDATE(false); | 55 EXTENSION_FUNCTION_VALIDATE(false); |
44 #else | 56 #else |
45 base::DictionaryValue* output = new base::DictionaryValue(); | 57 base::DictionaryValue* output = new base::DictionaryValue(); |
46 output->SetBoolean( | 58 output->SetBoolean( |
47 "isPhysicalKeyboardAutocorrectEnabled", | 59 "isPhysicalKeyboardAutocorrectEnabled", |
48 !base::CommandLine::ForCurrentProcess()->HasSwitch( | 60 !base::CommandLine::ForCurrentProcess()->HasSwitch( |
49 chromeos::switches::kDisablePhysicalKeyboardAutocorrect)); | 61 chromeos::switches::kDisablePhysicalKeyboardAutocorrect)); |
50 return RespondNow(OneArgument(output)); | 62 return RespondNow(OneArgument(output)); |
51 #endif | 63 #endif |
52 } | 64 } |
53 | 65 |
54 ExtensionFunction::ResponseAction GetCurrentInputMethodFunction::Run() { | 66 ExtensionFunction::ResponseAction |
67 InputMethodPrivateGetCurrentInputMethodFunction::Run() { | |
55 #if !defined(OS_CHROMEOS) | 68 #if !defined(OS_CHROMEOS) |
56 EXTENSION_FUNCTION_VALIDATE(false); | 69 EXTENSION_FUNCTION_VALIDATE(false); |
57 #else | 70 #else |
58 chromeos::input_method::InputMethodManager* manager = | 71 chromeos::input_method::InputMethodManager* manager = |
59 chromeos::input_method::InputMethodManager::Get(); | 72 chromeos::input_method::InputMethodManager::Get(); |
60 return RespondNow(OneArgument(new base::StringValue( | 73 return RespondNow(OneArgument(new base::StringValue( |
61 manager->GetActiveIMEState()->GetCurrentInputMethod().id()))); | 74 manager->GetActiveIMEState()->GetCurrentInputMethod().id()))); |
62 #endif | 75 #endif |
63 } | 76 } |
64 | 77 |
65 ExtensionFunction::ResponseAction SetCurrentInputMethodFunction::Run() { | 78 ExtensionFunction::ResponseAction |
79 InputMethodPrivateSetCurrentInputMethodFunction::Run() { | |
66 #if !defined(OS_CHROMEOS) | 80 #if !defined(OS_CHROMEOS) |
67 EXTENSION_FUNCTION_VALIDATE(false); | 81 EXTENSION_FUNCTION_VALIDATE(false); |
68 #else | 82 #else |
69 std::string new_input_method; | 83 scoped_ptr<SetCurrentInputMethod::Params> params( |
70 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &new_input_method)); | 84 SetCurrentInputMethod::Params::Create(*args_)); |
85 EXTENSION_FUNCTION_VALIDATE(params.get()); | |
71 scoped_refptr<chromeos::input_method::InputMethodManager::State> ime_state = | 86 scoped_refptr<chromeos::input_method::InputMethodManager::State> ime_state = |
72 chromeos::input_method::InputMethodManager::Get()->GetActiveIMEState(); | 87 chromeos::input_method::InputMethodManager::Get()->GetActiveIMEState(); |
73 const std::vector<std::string>& input_methods = | 88 const std::vector<std::string>& input_methods = |
74 ime_state->GetActiveInputMethodIds(); | 89 ime_state->GetActiveInputMethodIds(); |
75 for (size_t i = 0; i < input_methods.size(); ++i) { | 90 for (size_t i = 0; i < input_methods.size(); ++i) { |
76 const std::string& input_method = input_methods[i]; | 91 const std::string& input_method = input_methods[i]; |
77 if (input_method == new_input_method) { | 92 if (input_method == params->input_method_id) { |
78 ime_state->ChangeInputMethod(new_input_method, false /* show_message */); | 93 ime_state->ChangeInputMethod(params->input_method_id, |
94 false /* show_message */); | |
79 return RespondNow(NoArguments()); | 95 return RespondNow(NoArguments()); |
80 } | 96 } |
81 } | 97 } |
82 return RespondNow(Error("Invalid input method id.")); | 98 return RespondNow(Error("Invalid input method id.")); |
83 #endif | 99 #endif |
84 } | 100 } |
85 | 101 |
86 ExtensionFunction::ResponseAction GetInputMethodsFunction::Run() { | 102 ExtensionFunction::ResponseAction |
103 InputMethodPrivateGetInputMethodsFunction::Run() { | |
87 #if !defined(OS_CHROMEOS) | 104 #if !defined(OS_CHROMEOS) |
88 EXTENSION_FUNCTION_VALIDATE(false); | 105 EXTENSION_FUNCTION_VALIDATE(false); |
89 #else | 106 #else |
90 base::ListValue* output = new base::ListValue(); | 107 base::ListValue* output = new base::ListValue(); |
91 chromeos::input_method::InputMethodManager* manager = | 108 chromeos::input_method::InputMethodManager* manager = |
92 chromeos::input_method::InputMethodManager::Get(); | 109 chromeos::input_method::InputMethodManager::Get(); |
93 chromeos::input_method::InputMethodUtil* util = manager->GetInputMethodUtil(); | 110 chromeos::input_method::InputMethodUtil* util = manager->GetInputMethodUtil(); |
94 scoped_refptr<chromeos::input_method::InputMethodManager::State> ime_state = | 111 scoped_refptr<chromeos::input_method::InputMethodManager::State> ime_state = |
95 manager->GetActiveIMEState(); | 112 manager->GetActiveIMEState(); |
96 scoped_ptr<chromeos::input_method::InputMethodDescriptors> input_methods = | 113 scoped_ptr<chromeos::input_method::InputMethodDescriptors> input_methods = |
97 ime_state->GetActiveInputMethods(); | 114 ime_state->GetActiveInputMethods(); |
98 for (size_t i = 0; i < input_methods->size(); ++i) { | 115 for (size_t i = 0; i < input_methods->size(); ++i) { |
99 const chromeos::input_method::InputMethodDescriptor& input_method = | 116 const chromeos::input_method::InputMethodDescriptor& input_method = |
100 (*input_methods)[i]; | 117 (*input_methods)[i]; |
101 base::DictionaryValue* val = new base::DictionaryValue(); | 118 base::DictionaryValue* val = new base::DictionaryValue(); |
102 val->SetString("id", input_method.id()); | 119 val->SetString("id", input_method.id()); |
103 val->SetString("name", util->GetInputMethodLongName(input_method)); | 120 val->SetString("name", util->GetInputMethodLongName(input_method)); |
104 val->SetString("indicator", util->GetInputMethodShortName(input_method)); | 121 val->SetString("indicator", util->GetInputMethodShortName(input_method)); |
105 output->Append(val); | 122 output->Append(val); |
106 } | 123 } |
107 return RespondNow(OneArgument(output)); | 124 return RespondNow(OneArgument(output)); |
108 #endif | 125 #endif |
109 } | 126 } |
110 | 127 |
111 ExtensionFunction::ResponseAction FetchAllDictionaryWordsFunction::Run() { | 128 ExtensionFunction::ResponseAction |
129 InputMethodPrivateFetchAllDictionaryWordsFunction::Run() { | |
112 #if !defined(OS_CHROMEOS) | 130 #if !defined(OS_CHROMEOS) |
113 EXTENSION_FUNCTION_VALIDATE(false); | 131 EXTENSION_FUNCTION_VALIDATE(false); |
114 #else | 132 #else |
115 SpellcheckService* spellcheck = SpellcheckServiceFactory::GetForContext( | 133 SpellcheckService* spellcheck = SpellcheckServiceFactory::GetForContext( |
116 context_); | 134 context_); |
117 if (!spellcheck) { | 135 if (!spellcheck) { |
118 return RespondNow(Error("Spellcheck service not available.")); | 136 return RespondNow(Error("Spellcheck service not available.")); |
119 } | 137 } |
120 SpellcheckCustomDictionary* dictionary = spellcheck->GetCustomDictionary(); | 138 SpellcheckCustomDictionary* dictionary = spellcheck->GetCustomDictionary(); |
121 if (!dictionary->IsLoaded()) { | 139 if (!dictionary->IsLoaded()) { |
122 return RespondNow(Error("Custom dictionary not loaded yet.")); | 140 return RespondNow(Error("Custom dictionary not loaded yet.")); |
123 } | 141 } |
124 | 142 |
125 const std::set<std::string>& words = dictionary->GetWords(); | 143 const std::set<std::string>& words = dictionary->GetWords(); |
126 base::ListValue* output = new base::ListValue(); | 144 base::ListValue* output = new base::ListValue(); |
127 for (auto it = words.begin(); it != words.end(); ++it) { | 145 for (auto it = words.begin(); it != words.end(); ++it) { |
128 output->AppendString(*it); | 146 output->AppendString(*it); |
129 } | 147 } |
130 return RespondNow(OneArgument(output)); | 148 return RespondNow(OneArgument(output)); |
131 #endif | 149 #endif |
132 } | 150 } |
133 | 151 |
134 ExtensionFunction::ResponseAction AddWordToDictionaryFunction::Run() { | 152 ExtensionFunction::ResponseAction |
153 InputMethodPrivateAddWordToDictionaryFunction::Run() { | |
135 #if !defined(OS_CHROMEOS) | 154 #if !defined(OS_CHROMEOS) |
136 EXTENSION_FUNCTION_VALIDATE(false); | 155 EXTENSION_FUNCTION_VALIDATE(false); |
137 #else | 156 #else |
138 std::string word; | 157 scoped_ptr<AddWordToDictionary::Params> params( |
139 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &word)); | 158 AddWordToDictionary::Params::Create(*args_)); |
159 EXTENSION_FUNCTION_VALIDATE(params.get()); | |
140 SpellcheckService* spellcheck = SpellcheckServiceFactory::GetForContext( | 160 SpellcheckService* spellcheck = SpellcheckServiceFactory::GetForContext( |
141 context_); | 161 context_); |
142 if (!spellcheck) { | 162 if (!spellcheck) { |
143 return RespondNow(Error("Spellcheck service not available.")); | 163 return RespondNow(Error("Spellcheck service not available.")); |
144 } | 164 } |
145 SpellcheckCustomDictionary* dictionary = spellcheck->GetCustomDictionary(); | 165 SpellcheckCustomDictionary* dictionary = spellcheck->GetCustomDictionary(); |
146 if (!dictionary->IsLoaded()) { | 166 if (!dictionary->IsLoaded()) { |
147 return RespondNow(Error("Custom dictionary not loaded yet.")); | 167 return RespondNow(Error("Custom dictionary not loaded yet.")); |
148 } | 168 } |
149 | 169 |
150 if (dictionary->AddWord(word)) | 170 if (dictionary->AddWord(params->word)) |
151 return RespondNow(NoArguments()); | 171 return RespondNow(NoArguments()); |
152 // Invalid words: | 172 // Invalid words: |
153 // - Already in the dictionary. | 173 // - Already in the dictionary. |
154 // - Not a UTF8 string. | 174 // - Not a UTF8 string. |
155 // - Longer than 99 bytes (MAX_CUSTOM_DICTIONARY_WORD_BYTES). | 175 // - Longer than 99 bytes (MAX_CUSTOM_DICTIONARY_WORD_BYTES). |
156 // - Leading/trailing whitespace. | 176 // - Leading/trailing whitespace. |
157 // - Empty. | 177 // - Empty. |
158 return RespondNow(Error("Unable to add invalid word to dictionary.")); | 178 return RespondNow(Error("Unable to add invalid word to dictionary.")); |
159 #endif | 179 #endif |
160 } | 180 } |
161 | 181 |
162 ExtensionFunction::ResponseAction GetEncryptSyncEnabledFunction::Run() { | 182 ExtensionFunction::ResponseAction |
183 InputMethodPrivateGetEncryptSyncEnabledFunction::Run() { | |
163 #if !defined(OS_CHROMEOS) | 184 #if !defined(OS_CHROMEOS) |
164 EXTENSION_FUNCTION_VALIDATE(false); | 185 EXTENSION_FUNCTION_VALIDATE(false); |
165 #else | 186 #else |
166 ProfileSyncService* profile_sync_service = | 187 ProfileSyncService* profile_sync_service = |
167 ProfileSyncServiceFactory::GetForProfile( | 188 ProfileSyncServiceFactory::GetForProfile( |
168 Profile::FromBrowserContext(browser_context())); | 189 Profile::FromBrowserContext(browser_context())); |
169 if (!profile_sync_service) | 190 if (!profile_sync_service) |
170 return RespondNow(Error("Sync service is not ready for current profile.")); | 191 return RespondNow(Error("Sync service is not ready for current profile.")); |
171 scoped_ptr<base::Value> ret(new base::FundamentalValue( | 192 scoped_ptr<base::Value> ret(new base::FundamentalValue( |
172 profile_sync_service->IsEncryptEverythingEnabled())); | 193 profile_sync_service->IsEncryptEverythingEnabled())); |
173 return RespondNow(OneArgument(std::move(ret))); | 194 return RespondNow(OneArgument(std::move(ret))); |
174 #endif | 195 #endif |
175 } | 196 } |
176 | 197 |
177 // static | |
178 const char InputMethodAPI::kOnDictionaryChanged[] = | |
179 "inputMethodPrivate.onDictionaryChanged"; | |
180 | |
181 // static | |
182 const char InputMethodAPI::kOnDictionaryLoaded[] = | |
183 "inputMethodPrivate.onDictionaryLoaded"; | |
184 | |
185 // static | |
186 const char InputMethodAPI::kOnInputMethodChanged[] = | |
187 "inputMethodPrivate.onChanged"; | |
188 | |
189 InputMethodAPI::InputMethodAPI(content::BrowserContext* context) | 198 InputMethodAPI::InputMethodAPI(content::BrowserContext* context) |
190 : context_(context) { | 199 : context_(context) { |
191 EventRouter::Get(context_)->RegisterObserver(this, kOnInputMethodChanged); | |
192 EventRouter::Get(context_)->RegisterObserver(this, kOnDictionaryChanged); | |
193 EventRouter::Get(context_)->RegisterObserver(this, kOnDictionaryLoaded); | |
Devlin
2016/01/15 22:12:03
I didn't think that we registered any event router
| |
194 ExtensionFunctionRegistry* registry = | |
195 ExtensionFunctionRegistry::GetInstance(); | |
196 registry->RegisterFunction<GetInputMethodConfigFunction>(); | |
197 registry->RegisterFunction<GetCurrentInputMethodFunction>(); | |
198 registry->RegisterFunction<SetCurrentInputMethodFunction>(); | |
199 registry->RegisterFunction<GetInputMethodsFunction>(); | |
200 registry->RegisterFunction<FetchAllDictionaryWordsFunction>(); | |
201 registry->RegisterFunction<AddWordToDictionaryFunction>(); | |
202 registry->RegisterFunction<GetEncryptSyncEnabledFunction>(); | |
203 } | 200 } |
204 | 201 |
205 InputMethodAPI::~InputMethodAPI() { | 202 InputMethodAPI::~InputMethodAPI() { |
206 } | 203 } |
207 | 204 |
208 // static | 205 // static |
209 std::string InputMethodAPI::GetInputMethodForXkb(const std::string& xkb_id) { | 206 std::string InputMethodAPI::GetInputMethodForXkb(const std::string& xkb_id) { |
210 std::string xkb_prefix = | 207 std::string xkb_prefix = |
211 chromeos::extension_ime_util::GetInputMethodIDByEngineID(kXkbPrefix); | 208 chromeos::extension_ime_util::GetInputMethodIDByEngineID(kXkbPrefix); |
212 size_t prefix_length = xkb_prefix.length(); | 209 size_t prefix_length = xkb_prefix.length(); |
213 DCHECK(xkb_id.substr(0, prefix_length) == xkb_prefix); | 210 DCHECK(xkb_id.substr(0, prefix_length) == xkb_prefix); |
214 return xkb_id.substr(prefix_length); | 211 return xkb_id.substr(prefix_length); |
215 } | 212 } |
216 | 213 |
217 void InputMethodAPI::Shutdown() { | 214 void InputMethodAPI::Shutdown() { |
218 EventRouter::Get(context_)->UnregisterObserver(this); | 215 EventRouter::Get(context_)->UnregisterObserver(this); |
219 } | 216 } |
220 | 217 |
221 void InputMethodAPI::OnListenerAdded( | 218 void InputMethodAPI::OnListenerAdded( |
222 const extensions::EventListenerInfo& details) { | 219 const extensions::EventListenerInfo& details) { |
223 if (details.event_name == kOnInputMethodChanged) { | 220 if (details.event_name == OnChanged::kEventName && |
224 if (!input_method_event_router_.get()) { | 221 !input_method_event_router_.get()) { |
225 input_method_event_router_.reset( | 222 input_method_event_router_.reset( |
226 new chromeos::ExtensionInputMethodEventRouter(context_)); | 223 new chromeos::ExtensionInputMethodEventRouter(context_)); |
227 } | 224 } else if (details.event_name == OnDictionaryChanged::kEventName || |
228 } else if (details.event_name == kOnDictionaryChanged || | 225 details.event_name == OnDictionaryLoaded::kEventName) { |
229 details.event_name == kOnDictionaryLoaded) { | |
230 if (!dictionary_event_router_.get()) { | 226 if (!dictionary_event_router_.get()) { |
231 dictionary_event_router_.reset( | 227 dictionary_event_router_.reset( |
232 new chromeos::ExtensionDictionaryEventRouter(context_)); | 228 new chromeos::ExtensionDictionaryEventRouter(context_)); |
233 } | 229 } |
234 if (details.event_name == kOnDictionaryLoaded) { | 230 if (details.event_name == OnDictionaryLoaded::kEventName) { |
235 dictionary_event_router_->DispatchLoadedEventIfLoaded(); | 231 dictionary_event_router_->DispatchLoadedEventIfLoaded(); |
236 } | 232 } |
237 } | 233 } |
238 } | 234 } |
239 | 235 |
240 static base::LazyInstance<BrowserContextKeyedAPIFactory<InputMethodAPI> > | 236 static base::LazyInstance<BrowserContextKeyedAPIFactory<InputMethodAPI> > |
241 g_factory = LAZY_INSTANCE_INITIALIZER; | 237 g_factory = LAZY_INSTANCE_INITIALIZER; |
242 | 238 |
243 // static | 239 // static |
244 BrowserContextKeyedAPIFactory<InputMethodAPI>* | 240 BrowserContextKeyedAPIFactory<InputMethodAPI>* |
245 InputMethodAPI::GetFactoryInstance() { | 241 InputMethodAPI::GetFactoryInstance() { |
246 return g_factory.Pointer(); | 242 return g_factory.Pointer(); |
247 } | 243 } |
248 | 244 |
249 } // namespace extensions | 245 } // namespace extensions |
OLD | NEW |