Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2301)

Side by Side Diff: chrome/browser/extensions/extension_input_ime_api.cc

Issue 10735074: Moving input_ime to api/ . (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Typo fixed Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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/extensions/extension_input_ime_api.h"
6
7 #include "base/json/json_writer.h"
8 #include "base/stl_util.h"
9 #include "base/string_number_conversions.h"
10 #include "base/values.h"
11 #include "chrome/browser/chromeos/input_method/input_method_engine.h"
12 #include "chrome/browser/extensions/extension_event_router.h"
13 #include "chrome/browser/extensions/extension_input_module_constants.h"
14 #include "chrome/browser/profiles/profile.h"
15
16 namespace keys = extension_input_module_constants;
17
18 namespace {
19
20 const char kStyleNone[] = "none";
21 const char kStyleCheck[] = "check";
22 const char kStyleRadio[] = "radio";
23 const char kStyleSeparator[] = "separator";
24
25 const char kErrorEngineNotAvailable[] = "Engine is not available";
26 const char kErrorBadCandidateList[] = "Invalid candidate list provided";
27 const char kErrorSetMenuItemsFail[] = "Could not create menu Items";
28 const char kErrorUpdateMenuItemsFail[] = "Could not update menu Items";
29
30 bool ReadMenuItems(
31 ListValue* menu_items,
32 std::vector<chromeos::InputMethodEngine::MenuItem>* output) {
33 for (size_t i = 0; i < menu_items->GetSize(); ++i) {
34 DictionaryValue* item_dict;
35 if (!menu_items->GetDictionary(i, &item_dict)) {
36 return false;
37 }
38
39 std::string id;
40 std::string label;
41 chromeos::InputMethodEngine::MenuItemStyle style =
42 chromeos::InputMethodEngine::MENU_ITEM_STYLE_NONE;
43 bool visible = true;
44 bool enabled = true;
45 bool checked = false;
46 std::string icon;
47 chromeos::InputMethodEngine::KeyboardEvent shortcut_key;
48
49 unsigned int modified = 0;
50
51 if (!item_dict->GetString(keys::kIdKey, &id)) {
52 return false;
53 }
54
55 if (item_dict->HasKey(keys::kLabelKey)) {
56 if (!item_dict->GetString(keys::kLabelKey, &label)) {
57 return false;
58 }
59 modified |= chromeos::InputMethodEngine::MENU_ITEM_MODIFIED_LABEL;
60 }
61 if (item_dict->HasKey(keys::kStyleKey)) {
62 std::string style_string;
63 if (!item_dict->GetString(keys::kStyleKey, &style_string)) {
64 return false;
65 }
66
67 if (style_string == kStyleNone) {
68 style = chromeos::InputMethodEngine::MENU_ITEM_STYLE_NONE;
69 } else if (style_string == kStyleCheck) {
70 style = chromeos::InputMethodEngine::MENU_ITEM_STYLE_CHECK;
71 } else if (style_string == kStyleRadio) {
72 style = chromeos::InputMethodEngine::MENU_ITEM_STYLE_RADIO;
73 } else if (style_string == kStyleSeparator) {
74 style = chromeos::InputMethodEngine::MENU_ITEM_STYLE_SEPARATOR;
75 } else {
76 return false;
77 }
78 modified |= chromeos::InputMethodEngine::MENU_ITEM_MODIFIED_STYLE;
79 }
80
81 if (item_dict->HasKey(keys::kVisibleKey)) {
82 if (!item_dict->GetBoolean(keys::kVisibleKey, &visible)) {
83 return false;
84 }
85 modified |= chromeos::InputMethodEngine::MENU_ITEM_MODIFIED_VISIBLE;
86 }
87
88 if (item_dict->HasKey(keys::kCheckedKey)) {
89 if (!item_dict->GetBoolean(keys::kCheckedKey, &checked)) {
90 return false;
91 }
92 modified |= chromeos::InputMethodEngine::MENU_ITEM_MODIFIED_CHECKED;
93 }
94
95 if (item_dict->HasKey(keys::kEnabledKey)) {
96 if (!item_dict->GetBoolean(keys::kEnabledKey, &enabled)) {
97 return false;
98 }
99 modified |= chromeos::InputMethodEngine::MENU_ITEM_MODIFIED_ENABLED;
100 }
101
102 output->push_back(chromeos::InputMethodEngine::MenuItem());
103 output->back().id = id;
104 output->back().label = label;
105 output->back().style = style;
106 output->back().visible = visible;
107 output->back().enabled = enabled;
108 output->back().checked = checked;
109
110 output->back().modified = modified;
111
112 if (item_dict->HasKey(keys::kItemsKey)) {
113 ListValue* sub_list;
114 if (!item_dict->GetList(keys::kItemsKey, &sub_list)) {
115 return false;
116 }
117
118 if (!ReadMenuItems(sub_list, &(output->back().children))) {
119 return false;
120 }
121 }
122 }
123
124 return true;
125 }
126
127 } // namespace
128
129 namespace events {
130
131 const char kOnActivate[] = "input.ime.onActivate";
132 const char kOnDeactivated[] = "input.ime.onDeactivated";
133 const char kOnFocus[] = "input.ime.onFocus";
134 const char kOnBlur[] = "input.ime.onBlur";
135 const char kOnInputContextUpdate[] = "input.ime.onInputContextUpdate";
136 const char kOnKeyEvent[] = "input.ime.onKeyEvent";
137 const char kOnCandidateClicked[] = "input.ime.onCandidateClicked";
138 const char kOnMenuItemActivated[] = "input.ime.onMenuItemActivated";
139
140 } // namespace events
141
142 namespace chromeos {
143 class ImeObserver : public chromeos::InputMethodEngine::Observer {
144 public:
145 ImeObserver(Profile* profile, const std::string& extension_id,
146 const std::string& engine_id) :
147 profile_(profile),
148 extension_id_(extension_id),
149 engine_id_(engine_id) {
150 }
151
152 virtual ~ImeObserver() {}
153
154 virtual void OnActivate(const std::string& engine_id) {
155 if (profile_ == NULL || extension_id_.empty())
156 return;
157
158 ListValue args;
159 args.Append(Value::CreateStringValue(engine_id));
160
161 std::string json_args;
162 base::JSONWriter::Write(&args, &json_args);
163 profile_->GetExtensionEventRouter()->DispatchEventToExtension(
164 extension_id_, events::kOnActivate, json_args, profile_, GURL());
165 }
166
167 virtual void OnDeactivated(const std::string& engine_id) {
168 if (profile_ == NULL || extension_id_.empty())
169 return;
170
171 ListValue args;
172 args.Append(Value::CreateStringValue(engine_id));
173
174 std::string json_args;
175 base::JSONWriter::Write(&args, &json_args);
176 profile_->GetExtensionEventRouter()->DispatchEventToExtension(
177 extension_id_, events::kOnDeactivated, json_args, profile_, GURL());
178 }
179
180 virtual void OnFocus(const InputMethodEngine::InputContext& context) {
181 if (profile_ == NULL || extension_id_.empty())
182 return;
183
184 DictionaryValue* dict = new DictionaryValue();
185 dict->SetInteger("contextID", context.id);
186 dict->SetString("type", context.type);
187
188 ListValue args;
189 args.Append(dict);
190
191 std::string json_args;
192 base::JSONWriter::Write(&args, &json_args);
193 profile_->GetExtensionEventRouter()->DispatchEventToExtension(
194 extension_id_, events::kOnFocus, json_args, profile_, GURL());
195 }
196
197 virtual void OnBlur(int context_id) {
198 if (profile_ == NULL || extension_id_.empty())
199 return;
200
201 ListValue args;
202 args.Append(Value::CreateIntegerValue(context_id));
203
204 std::string json_args;
205 base::JSONWriter::Write(&args, &json_args);
206 profile_->GetExtensionEventRouter()->DispatchEventToExtension(
207 extension_id_, events::kOnBlur, json_args, profile_, GURL());
208 }
209
210 virtual void OnInputContextUpdate(
211 const InputMethodEngine::InputContext& context) {
212 if (profile_ == NULL || extension_id_.empty())
213 return;
214
215 DictionaryValue* dict = new DictionaryValue();
216 dict->SetInteger("contextID", context.id);
217 dict->SetString("type", context.type);
218
219 ListValue args;
220 args.Append(dict);
221
222 std::string json_args;
223 base::JSONWriter::Write(&args, &json_args);
224 profile_->GetExtensionEventRouter()->DispatchEventToExtension(
225 extension_id_, events::kOnInputContextUpdate, json_args, profile_,
226 GURL());
227 }
228
229 virtual void OnKeyEvent(const std::string& engine_id,
230 const InputMethodEngine::KeyboardEvent& event,
231 chromeos::input_method::KeyEventHandle* key_data) {
232 if (profile_ == NULL || extension_id_.empty())
233 return;
234
235 std::string request_id =
236 ExtensionInputImeEventRouter::GetInstance()->AddRequest(engine_id,
237 key_data);
238
239 DictionaryValue* dict = new DictionaryValue();
240 dict->SetString("type", event.type);
241 dict->SetString("requestId", request_id);
242 dict->SetString("key", event.key);
243 dict->SetBoolean("altKey", event.alt_key);
244 dict->SetBoolean("ctrlKey", event.ctrl_key);
245 dict->SetBoolean("shiftKey", event.shift_key);
246
247 ListValue args;
248 args.Append(Value::CreateStringValue(engine_id));
249 args.Append(dict);
250
251 std::string json_args;
252 base::JSONWriter::Write(&args, &json_args);
253 profile_->GetExtensionEventRouter()->DispatchEventToExtension(
254 extension_id_, events::kOnKeyEvent, json_args, profile_, GURL());
255 }
256
257 virtual void OnCandidateClicked(
258 const std::string& engine_id,
259 int candidate_id,
260 chromeos::InputMethodEngine::MouseButtonEvent button) {
261 if (profile_ == NULL || extension_id_.empty())
262 return;
263
264 ListValue args;
265 args.Append(Value::CreateStringValue(engine_id));
266 args.Append(Value::CreateIntegerValue(candidate_id));
267 switch (button) {
268 case chromeos::InputMethodEngine::MOUSE_BUTTON_MIDDLE:
269 args.Append(Value::CreateStringValue("middle"));
270 break;
271
272 case chromeos::InputMethodEngine::MOUSE_BUTTON_RIGHT:
273 args.Append(Value::CreateStringValue("right"));
274 break;
275
276 case chromeos::InputMethodEngine::MOUSE_BUTTON_LEFT:
277 // Default to left.
278 default:
279 args.Append(Value::CreateStringValue("left"));
280 break;
281 }
282
283 std::string json_args;
284 base::JSONWriter::Write(&args, &json_args);
285 profile_->GetExtensionEventRouter()->DispatchEventToExtension(
286 extension_id_, events::kOnCandidateClicked, json_args, profile_,
287 GURL());
288 }
289
290 virtual void OnMenuItemActivated(const std::string& engine_id,
291 const std::string& menu_id) {
292 if (profile_ == NULL || extension_id_.empty())
293 return;
294
295 ListValue args;
296 args.Append(Value::CreateStringValue(engine_id));
297 args.Append(Value::CreateStringValue(menu_id));
298
299 std::string json_args;
300 base::JSONWriter::Write(&args, &json_args);
301 profile_->GetExtensionEventRouter()->DispatchEventToExtension(
302 extension_id_, events::kOnMenuItemActivated, json_args, profile_,
303 GURL());
304 }
305
306 private:
307 Profile* profile_;
308 std::string extension_id_;
309 std::string engine_id_;
310
311 DISALLOW_COPY_AND_ASSIGN(ImeObserver);
312 };
313
314 } // namespace chromeos
315
316 ExtensionInputImeEventRouter*
317 ExtensionInputImeEventRouter::GetInstance() {
318 return Singleton<ExtensionInputImeEventRouter>::get();
319 }
320
321 void ExtensionInputImeEventRouter::Init() {}
322
323 #if defined(OS_CHROMEOS)
324 bool ExtensionInputImeEventRouter::RegisterIme(
325 Profile* profile,
326 const std::string& extension_id,
327 const extensions::Extension::InputComponentInfo& component) {
328 VLOG(1) << "RegisterIme: " << extension_id << " id: " << component.id;
329
330 std::map<std::string, chromeos::InputMethodEngine*>& engine_map =
331 engines_[extension_id];
332
333 std::map<std::string, chromeos::InputMethodEngine*>::iterator engine_ix =
334 engine_map.find(component.id);
335 if (engine_ix != engine_map.end()) {
336 return false;
337 }
338
339 std::string error;
340 chromeos::ImeObserver* observer = new chromeos::ImeObserver(profile,
341 extension_id,
342 component.id);
343 std::vector<std::string> layouts;
344 layouts.assign(component.layouts.begin(), component.layouts.end());
345
346 chromeos::InputMethodEngine* engine =
347 chromeos::InputMethodEngine::CreateEngine(
348 observer, component.name.c_str(), extension_id.c_str(),
349 component.id.c_str(), component.description.c_str(),
350 component.language.c_str(), layouts, &error);
351 if (!engine) {
352 delete observer;
353 LOG(ERROR) << "RegisterIme: " << error;
354 return false;
355 }
356
357 engine_map[component.id] = engine;
358
359 std::map<std::string, chromeos::ImeObserver*>& observer_list =
360 observers_[extension_id];
361
362 observer_list[component.id] = observer;
363
364 return true;
365 }
366
367 void ExtensionInputImeEventRouter::UnregisterAllImes(
368 Profile* profile, const std::string& extension_id) {
369 std::map<std::string,
370 std::map<std::string,
371 chromeos::InputMethodEngine*> >::iterator engine_map =
372 engines_.find(extension_id);
373 if (engine_map != engines_.end()) {
374 STLDeleteContainerPairSecondPointers(engine_map->second.begin(),
375 engine_map->second.end());
376 engines_.erase(engine_map);
377 }
378
379 std::map<std::string,
380 std::map<std::string,
381 chromeos::ImeObserver*> >::iterator observer_list =
382 observers_.find(extension_id);
383 if (observer_list != observers_.end()) {
384 STLDeleteContainerPairSecondPointers(observer_list->second.begin(),
385 observer_list->second.end());
386 observers_.erase(observer_list);
387 }
388 }
389 #endif
390
391 chromeos::InputMethodEngine* ExtensionInputImeEventRouter::GetEngine(
392 const std::string& extension_id, const std::string& engine_id) {
393 std::map<std::string,
394 std::map<std::string, chromeos::InputMethodEngine*> >::const_iterator
395 engine_list = engines_.find(extension_id);
396 if (engine_list != engines_.end()) {
397 std::map<std::string, chromeos::InputMethodEngine*>::const_iterator
398 engine_ix = engine_list->second.find(engine_id);
399 if (engine_ix != engine_list->second.end()) {
400 return engine_ix->second;
401 }
402 }
403 return NULL;
404 }
405
406 chromeos::InputMethodEngine* ExtensionInputImeEventRouter::GetActiveEngine(
407 const std::string& extension_id) {
408 std::map<std::string,
409 std::map<std::string, chromeos::InputMethodEngine*> >::const_iterator
410 engine_list = engines_.find(extension_id);
411 if (engine_list != engines_.end()) {
412 std::map<std::string, chromeos::InputMethodEngine*>::const_iterator
413 engine_ix;
414 for (engine_ix = engine_list->second.begin();
415 engine_ix != engine_list->second.end();
416 ++engine_ix) {
417 if (engine_ix->second->IsActive()) {
418 return engine_ix->second;
419 }
420 }
421 }
422 return NULL;
423 }
424
425 void ExtensionInputImeEventRouter::OnEventHandled(
426 const std::string& extension_id,
427 const std::string& request_id,
428 bool handled) {
429 RequestMap::iterator request = request_map_.find(request_id);
430 if (request == request_map_.end()) {
431 LOG(ERROR) << "Request ID not found: " << request_id;
432 return;
433 }
434
435 std::string engine_id = request->second.first;
436 chromeos::input_method::KeyEventHandle* key_data = request->second.second;
437 request_map_.erase(request);
438
439 chromeos::InputMethodEngine* engine = GetEngine(extension_id, engine_id);
440 if (!engine) {
441 LOG(ERROR) << "Engine does not exist: " << engine_id;
442 return;
443 }
444
445 engine->KeyEventDone(key_data, handled);
446 }
447
448 std::string ExtensionInputImeEventRouter::AddRequest(
449 const std::string& engine_id,
450 chromeos::input_method::KeyEventHandle* key_data) {
451 std::string request_id = base::IntToString(next_request_id_);
452 ++next_request_id_;
453
454 request_map_[request_id] = std::make_pair(engine_id, key_data);
455
456 return request_id;
457 }
458
459 ExtensionInputImeEventRouter::ExtensionInputImeEventRouter()
460 : next_request_id_(1) {
461 }
462
463 ExtensionInputImeEventRouter::~ExtensionInputImeEventRouter() {}
464
465 bool SetCompositionFunction::RunImpl() {
466 chromeos::InputMethodEngine* engine =
467 ExtensionInputImeEventRouter::GetInstance()->
468 GetActiveEngine(extension_id());
469 if (!engine) {
470 result_.reset(Value::CreateBooleanValue(false));
471 return true;
472 }
473
474 DictionaryValue* args;
475 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &args));
476 int context_id;
477 std::string text;
478 int selection_start;
479 int selection_end;
480 int cursor;
481 std::vector<chromeos::InputMethodEngine::SegmentInfo> segments;
482
483 EXTENSION_FUNCTION_VALIDATE(args->GetInteger(keys::kContextIdKey,
484 &context_id));
485 EXTENSION_FUNCTION_VALIDATE(args->GetString(keys::kTextKey, &text));
486 EXTENSION_FUNCTION_VALIDATE(args->GetInteger(keys::kCursorKey, &cursor));
487 if (args->HasKey(keys::kSelectionStartKey)) {
488 EXTENSION_FUNCTION_VALIDATE(args->GetInteger(keys::kSelectionStartKey,
489 &selection_start));
490 } else {
491 selection_start = cursor;
492 }
493 if (args->HasKey(keys::kSelectionEndKey)) {
494 EXTENSION_FUNCTION_VALIDATE(args->GetInteger(keys::kSelectionEndKey,
495 &selection_end));
496 } else {
497 selection_end = cursor;
498 }
499
500 if (args->HasKey(keys::kSegmentsKey)) {
501 ListValue* segment_list = NULL;
502 EXTENSION_FUNCTION_VALIDATE(args->GetList(keys::kSegmentsKey,
503 &segment_list));
504
505 for (size_t i = 0; i < segment_list->GetSize(); ++i) {
506 DictionaryValue* segment = NULL;
507 if (!segment_list->GetDictionary(i, &segment))
508 continue;
509
510 int start;
511 int end;
512 std::string style;
513
514 EXTENSION_FUNCTION_VALIDATE(segment->GetInteger(keys::kStartKey,
515 &start));
516 EXTENSION_FUNCTION_VALIDATE(segment->GetInteger(keys::kEndKey, &end));
517 EXTENSION_FUNCTION_VALIDATE(segment->GetString(keys::kStyleKey, &style));
518
519 segments.push_back(chromeos::InputMethodEngine::SegmentInfo());
520 segments.back().start = start;
521 segments.back().end = end;
522 if (style == keys::kStyleUnderline) {
523 segments.back().style =
524 chromeos::InputMethodEngine::SEGMENT_STYLE_UNDERLINE;
525 } else if (style == keys::kStyleDoubleUnderline) {
526 segments.back().style =
527 chromeos::InputMethodEngine::SEGMENT_STYLE_DOUBLE_UNDERLINE;
528 }
529 }
530 }
531
532 if (engine->SetComposition(context_id, text.c_str(), selection_start,
533 selection_end, cursor, segments, &error_)) {
534 result_.reset(Value::CreateBooleanValue(true));
535 } else {
536 result_.reset(Value::CreateBooleanValue(false));
537 }
538 return true;
539 }
540
541 bool ClearCompositionFunction::RunImpl() {
542 chromeos::InputMethodEngine* engine =
543 ExtensionInputImeEventRouter::GetInstance()->
544 GetActiveEngine(extension_id());
545 if (!engine) {
546 result_.reset(Value::CreateBooleanValue(false));
547 return true;
548 }
549
550 DictionaryValue* args;
551 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &args));
552 int context_id;
553
554 EXTENSION_FUNCTION_VALIDATE(args->GetInteger(keys::kContextIdKey,
555 &context_id));
556
557 if (engine->ClearComposition(context_id, &error_)) {
558 result_.reset(Value::CreateBooleanValue(true));
559 } else {
560 result_.reset(Value::CreateBooleanValue(false));
561 }
562 return true;
563 }
564
565 bool CommitTextFunction::RunImpl() {
566 // TODO(zork): Support committing when not active.
567 chromeos::InputMethodEngine* engine =
568 ExtensionInputImeEventRouter::GetInstance()->
569 GetActiveEngine(extension_id());
570 if (!engine) {
571 result_.reset(Value::CreateBooleanValue(false));
572 return true;
573 }
574
575 DictionaryValue* args;
576 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &args));
577 int context_id;
578 std::string text;
579
580 EXTENSION_FUNCTION_VALIDATE(args->GetInteger(keys::kContextIdKey,
581 &context_id));
582 EXTENSION_FUNCTION_VALIDATE(args->GetString(keys::kTextKey, &text));
583
584 if (engine->CommitText(context_id, text.c_str(), &error_)) {
585 result_.reset(Value::CreateBooleanValue(true));
586 } else {
587 result_.reset(Value::CreateBooleanValue(false));
588 }
589 return true;
590 }
591
592 bool SetCandidateWindowPropertiesFunction::RunImpl() {
593 DictionaryValue* args;
594 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &args));
595
596 std::string engine_id;
597 EXTENSION_FUNCTION_VALIDATE(args->GetString(keys::kEngineIdKey, &engine_id));
598
599 chromeos::InputMethodEngine* engine =
600 ExtensionInputImeEventRouter::GetInstance()->GetEngine(extension_id(),
601 engine_id);
602 if (!engine) {
603 result_.reset(Value::CreateBooleanValue(false));
604 return true;
605 }
606
607 DictionaryValue* properties;
608 EXTENSION_FUNCTION_VALIDATE(args->GetDictionary(keys::kPropertiesKey,
609 &properties));
610
611 if (properties->HasKey(keys::kVisibleKey)) {
612 bool visible;
613 EXTENSION_FUNCTION_VALIDATE(properties->GetBoolean(keys::kVisibleKey,
614 &visible));
615 if (!engine->SetCandidateWindowVisible(visible, &error_)) {
616 result_.reset(Value::CreateBooleanValue(false));
617 return true;
618 }
619 }
620
621 if (properties->HasKey(keys::kCursorVisibleKey)) {
622 bool visible;
623 EXTENSION_FUNCTION_VALIDATE(properties->GetBoolean(keys::kCursorVisibleKey,
624 &visible));
625 engine->SetCandidateWindowCursorVisible(visible);
626 }
627
628 if (properties->HasKey(keys::kVerticalKey)) {
629 bool vertical;
630 EXTENSION_FUNCTION_VALIDATE(properties->GetBoolean(keys::kVerticalKey,
631 &vertical));
632 engine->SetCandidateWindowVertical(vertical);
633 }
634
635 if (properties->HasKey(keys::kPageSizeKey)) {
636 int page_size;
637 EXTENSION_FUNCTION_VALIDATE(properties->GetInteger(keys::kPageSizeKey,
638 &page_size));
639 engine->SetCandidateWindowPageSize(page_size);
640 }
641
642 if (properties->HasKey(keys::kAuxiliaryTextKey)) {
643 std::string aux_text;
644 EXTENSION_FUNCTION_VALIDATE(properties->GetString(keys::kAuxiliaryTextKey,
645 &aux_text));
646 engine->SetCandidateWindowAuxText(aux_text.c_str());
647 }
648
649 if (properties->HasKey(keys::kAuxiliaryTextVisibleKey)) {
650 bool visible;
651 EXTENSION_FUNCTION_VALIDATE(properties->GetBoolean(
652 keys::kAuxiliaryTextVisibleKey,
653 &visible));
654 engine->SetCandidateWindowAuxTextVisible(visible);
655 }
656
657 result_.reset(Value::CreateBooleanValue(true));
658
659 return true;
660 }
661
662 #if defined(OS_CHROMEOS)
663 bool SetCandidatesFunction::ReadCandidates(
664 ListValue* candidates,
665 std::vector<chromeos::InputMethodEngine::Candidate>* output) {
666 for (size_t i = 0; i < candidates->GetSize(); ++i) {
667 DictionaryValue* candidate_dict;
668 EXTENSION_FUNCTION_VALIDATE(candidates->GetDictionary(i, &candidate_dict));
669
670 std::string candidate;
671 int id;
672 std::string label;
673 std::string annotation;
674
675 EXTENSION_FUNCTION_VALIDATE(candidate_dict->GetString(keys::kCandidateKey,
676 &candidate));
677 EXTENSION_FUNCTION_VALIDATE(candidate_dict->GetInteger(keys::kIdKey, &id));
678
679 if (candidate_dict->HasKey(keys::kLabelKey)) {
680 EXTENSION_FUNCTION_VALIDATE(candidate_dict->GetString(keys::kLabelKey,
681 &label));
682 }
683 if (candidate_dict->HasKey(keys::kAnnotationKey)) {
684 EXTENSION_FUNCTION_VALIDATE(candidate_dict->GetString(
685 keys::kAnnotationKey,
686 &annotation));
687 }
688
689 output->push_back(chromeos::InputMethodEngine::Candidate());
690 output->back().value = candidate;
691 output->back().id = id;
692 output->back().label = label;
693 output->back().annotation = annotation;
694
695 if (candidate_dict->HasKey(keys::kCandidatesKey)) {
696 ListValue* sub_list;
697 EXTENSION_FUNCTION_VALIDATE(candidate_dict->GetList(keys::kCandidatesKey,
698 &sub_list));
699 if (!ReadCandidates(sub_list, &(output->back().candidates))) {
700 error_ = kErrorBadCandidateList;
701 return false;
702 }
703 }
704 }
705
706 return true;
707 }
708
709 bool SetCandidatesFunction::RunImpl() {
710 chromeos::InputMethodEngine* engine =
711 ExtensionInputImeEventRouter::GetInstance()->
712 GetActiveEngine(extension_id());
713 if (!engine) {
714 result_.reset(Value::CreateBooleanValue(false));
715 return true;
716 }
717
718 DictionaryValue* args;
719 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &args));
720
721 int context_id;
722 std::vector<chromeos::InputMethodEngine::Candidate> candidates;
723
724 EXTENSION_FUNCTION_VALIDATE(args->GetInteger(keys::kContextIdKey,
725 &context_id));
726
727 ListValue* candidate_list;
728 EXTENSION_FUNCTION_VALIDATE(args->GetList(keys::kCandidatesKey,
729 &candidate_list));
730 if (!ReadCandidates(candidate_list, &candidates)) {
731 error_ = kErrorBadCandidateList;
732 return false;
733 }
734
735 std::string error;
736 if (engine->SetCandidates(context_id, candidates, &error_)) {
737 result_.reset(Value::CreateBooleanValue(true));
738 } else {
739 result_.reset(Value::CreateBooleanValue(false));
740 }
741 return true;
742 }
743
744 bool SetCursorPositionFunction::RunImpl() {
745 chromeos::InputMethodEngine* engine =
746 ExtensionInputImeEventRouter::GetInstance()->
747 GetActiveEngine(extension_id());
748 if (!engine) {
749 result_.reset(Value::CreateBooleanValue(false));
750 return true;
751 }
752
753 DictionaryValue* args;
754 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &args));
755 int context_id;
756 int candidate_id;
757
758 EXTENSION_FUNCTION_VALIDATE(args->GetInteger(keys::kContextIdKey,
759 &context_id));
760 EXTENSION_FUNCTION_VALIDATE(args->GetInteger(keys::kCandidateIdKey,
761 &candidate_id));
762
763 if (engine->SetCursorPosition(context_id, candidate_id, &error_)) {
764 result_.reset(Value::CreateBooleanValue(true));
765 } else {
766 result_.reset(Value::CreateBooleanValue(false));
767 }
768 return true;
769 }
770
771 bool SetMenuItemsFunction::RunImpl() {
772 DictionaryValue* args;
773 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &args));
774
775 std::string engine_id;
776 EXTENSION_FUNCTION_VALIDATE(args->GetString(keys::kEngineIdKey, &engine_id));
777
778 chromeos::InputMethodEngine* engine =
779 ExtensionInputImeEventRouter::GetInstance()->GetEngine(extension_id(),
780 engine_id);
781 if (!engine) {
782 error_ = kErrorEngineNotAvailable;
783 return false;
784 }
785
786 ListValue* items;
787 EXTENSION_FUNCTION_VALIDATE(args->GetList(keys::kItemsKey, &items));
788
789 std::vector<chromeos::InputMethodEngine::MenuItem> menu_items;
790 EXTENSION_FUNCTION_VALIDATE(ReadMenuItems(items, &menu_items));
791
792 if (!engine->SetMenuItems(menu_items)) {
793 error_ = kErrorSetMenuItemsFail;
794 }
795 return true;
796 }
797
798 bool UpdateMenuItemsFunction::RunImpl() {
799 DictionaryValue* args;
800 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &args));
801
802 std::string engine_id;
803 EXTENSION_FUNCTION_VALIDATE(args->GetString(keys::kEngineIdKey, &engine_id));
804
805 chromeos::InputMethodEngine* engine =
806 ExtensionInputImeEventRouter::GetInstance()->GetEngine(extension_id(),
807 engine_id);
808 if (!engine) {
809 error_ = kErrorEngineNotAvailable;
810 return false;
811 }
812
813 ListValue* items;
814 EXTENSION_FUNCTION_VALIDATE(args->GetList(keys::kItemsKey, &items));
815
816 std::vector<chromeos::InputMethodEngine::MenuItem> menu_items;
817 EXTENSION_FUNCTION_VALIDATE(ReadMenuItems(items, &menu_items));
818
819 if (!engine->UpdateMenuItems(menu_items)) {
820 error_ = kErrorUpdateMenuItemsFail;
821 }
822 return true;
823 }
824
825 bool InputEventHandled::RunImpl() {
826 std::string request_id_str;
827 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &request_id_str));
828
829 bool handled = false;
830 EXTENSION_FUNCTION_VALIDATE(args_->GetBoolean(1, &handled));
831
832 ExtensionInputImeEventRouter::GetInstance()->OnEventHandled(
833 extension_id(), request_id_str, handled);
834
835 return true;
836 }
837 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698