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

Side by Side Diff: chrome/browser/chromeos/extensions/input_ime_extension_api.cc

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

Powered by Google App Engine
This is Rietveld 408576698