Enable IME support for Ozone Efl
[platform/framework/web/chromium-efl.git] / tizen_src / chromium_impl / ui / ozone / platform / efl / efl_event_handler.cc
1 // Copyright 2021 Samsung Electronics. 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 "ui/ozone/platform/efl/efl_event_handler.h"
6 #include "ui/display/screen.h"
7
8 #include "base/logging.h"
9 #include "base/strings/string_util.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "content/public/browser/native_web_keyboard_event.h"
12 #include "tizen/system_info.h"
13 #include "ui/base/ime/linux/linux_input_method_context_factory.h"
14 #include "ui/events/base_event_utils.h"
15 #include "ui/events/event.h"
16 #include "ui/events/types/event_type.h"
17 #include "ui/gfx/geometry/point_f.h"
18 #include "ui/ozone/platform/efl/efl_keycode_map.h"
19 #include "ui/ozone/platform/efl/efl_platform_event_source.h"
20 #include "ui/ozone/platform/efl/efl_window.h"
21 #include "ui/ozone/platform/efl/im_context_efl.h"
22
23 #if defined(OS_TIZEN)
24 #include "ui/events/keycodes/dom/dom_code.h"
25 #include "ui/events/keycodes/dom/dom_key.h"
26 #include "ui/events/keycodes/dom/keycode_converter.h"
27 #include "ui/events/keycodes/keyboard_code_conversion.h"
28 #endif
29
30 namespace ui {
31
32 namespace {
33 const float kDefaultScrollStep = 20;
34
35 inline bool string_ends_with(std::string const& value,
36                              std::string const& match) {
37   if (match.size() > value.size()) {
38     return false;
39   }
40   return std::equal(match.rbegin(), match.rend(), value.rbegin());
41 }
42
43 inline bool string_starts_with(std::string const& value,
44                                std::string const& match) {
45   if (match.size() > value.size()) {
46     return false;
47   }
48   return std::equal(match.begin(), match.end(), value.begin());
49 }
50
51 // TV RC device names
52 const std::string kDeviceNameSmartView = "SMART_VIEW";
53 const std::string kDeviceNamePanelKey = "wt61p807 panel key device";
54 const std::string kDeviceNameRemote = "wt61p807 rc device";
55 const std::string kDeviceNameSmartRC = "Smart Control";
56 // To allow to receive Tomato send key events
57 const std::string kDeviceNameAutoModeDevice = "AUTO_MODE_DEVICE";
58 const std::string kDeviceNameIME = "ime";
59
60 bool IsRCDevice(Evas_Device_Class device_id, const std::string device_name) {
61   if (device_id == EVAS_DEVICE_CLASS_KEYBOARD) {
62     if (!device_name.compare(kDeviceNameRemote) ||
63         !device_name.compare(kDeviceNameSmartView) ||
64         !device_name.compare(kDeviceNamePanelKey) ||
65         !device_name.compare(kDeviceNameAutoModeDevice) ||
66         device_name.find(kDeviceNameSmartRC) != std::string::npos)
67       return true;
68   }
69   return false;
70 }
71
72 enum { kLeftButton = 1, kMiddleButton = 2, kRightButton = 3 };
73
74 EventFlags EvasToUIMouseButton(int button) {
75   if (button == kLeftButton)
76     return EF_LEFT_MOUSE_BUTTON;
77   if (button == kMiddleButton)
78     return EF_MIDDLE_MOUSE_BUTTON;
79   if (button == kRightButton)
80     return EF_RIGHT_MOUSE_BUTTON;
81
82   return EF_NONE;
83 }
84
85 int GetEventFlagsFromKey(const char* key) {
86   int flags = 0;
87   if (base::StartsWith(key, "Shift", base::CompareCase::SENSITIVE))
88     flags |= EF_SHIFT_DOWN;
89   if (base::StartsWith(key, "Control", base::CompareCase::SENSITIVE))
90     flags |= EF_CONTROL_DOWN;
91   if (base::StartsWith(key, "Alt", base::CompareCase::SENSITIVE))
92     flags |= EF_ALT_DOWN;
93   if (base::StartsWith(key, "Meta", base::CompareCase::SENSITIVE))
94     flags |= EF_COMMAND_DOWN;
95   if (base::StartsWith(key, "Super", base::CompareCase::SENSITIVE))
96     flags |= EF_COMMAND_DOWN;
97
98   return flags;
99 }
100
101 int EvasModifiersToEventFlags(const Evas_Modifier* modifiers,
102                               bool check_super = true) {
103   int flags = 0;
104   if (evas_key_modifier_is_set(modifiers, "Shift"))
105     flags |= EF_SHIFT_DOWN;
106   if (evas_key_modifier_is_set(modifiers, "Control"))
107     flags |= EF_CONTROL_DOWN;
108   if (evas_key_modifier_is_set(modifiers, "Alt"))
109     flags |= EF_ALT_DOWN;
110   if (evas_key_modifier_is_set(modifiers, "Meta"))
111     flags |= EF_COMMAND_DOWN;
112   if (evas_key_modifier_is_set(modifiers, "Super") && check_super)
113     flags |= EF_COMMAND_DOWN;
114
115   return flags;
116 }
117
118 static EventType EvasTouchEventTypeToUI(Evas_Touch_Point_State evas_touch) {
119   switch (evas_touch) {
120     case EVAS_TOUCH_POINT_DOWN:
121       return ET_TOUCH_PRESSED;
122     case EVAS_TOUCH_POINT_MOVE:
123       return ET_TOUCH_MOVED;
124     case EVAS_TOUCH_POINT_UP:
125       return ET_TOUCH_RELEASED;
126     case EVAS_TOUCH_POINT_CANCEL:
127       return ET_TOUCH_CANCELLED;
128     case EVAS_TOUCH_POINT_STILL:
129     // Not handled by chromium, should not be passed here.
130     default:
131       NOTREACHED();
132       return ET_UNKNOWN;
133   }
134 }
135
136 float GetDeviceScaleFactor() {
137   static float device_scale_factor = 0.0f;
138   if (!device_scale_factor) {
139     device_scale_factor =
140         display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
141   }
142   return device_scale_factor;
143 }
144
145 }  // namespace
146
147 EflEventHandler::EflEventHandler(EflWindow* window)
148     : window_(window), native_view_(window->native_view()) {
149   if (IsMobileProfile())
150     touch_events_enabled_ = true;
151
152   RegisterCallbacks();
153
154   evas_object_geometry_get(native_view_, nullptr, &top_controls_height_,
155                            nullptr, nullptr);
156 }
157
158 EflEventHandler::~EflEventHandler() {
159   evas_object_event_callback_del(native_view_, EVAS_CALLBACK_MOUSE_DOWN,
160                                  OnMouseDown);
161   evas_object_event_callback_del(native_view_, EVAS_CALLBACK_MOUSE_UP,
162                                  OnMouseUp);
163   evas_object_event_callback_del(native_view_, EVAS_CALLBACK_MOUSE_MOVE,
164                                  OnMouseMove);
165   evas_object_event_callback_del(native_view_, EVAS_CALLBACK_MOUSE_IN,
166                                  OnMouseIn);
167   evas_object_event_callback_del(native_view_, EVAS_CALLBACK_MOUSE_OUT,
168                                  OnMouseOut);
169   evas_object_event_callback_del(native_view_, EVAS_CALLBACK_MOUSE_WHEEL,
170                                  OnMouseWheel);
171   if (key_events_enabled_)
172     DeleteKeyCallbacks();
173
174   if (touch_events_enabled_)
175     DeleteTouchCallbacks();
176 }
177
178 void EflEventHandler::RegisterCallbacks() {
179   evas_object_event_callback_add(native_view_, EVAS_CALLBACK_MOUSE_DOWN,
180                                  OnMouseDown, this);
181   evas_object_event_callback_add(native_view_, EVAS_CALLBACK_MOUSE_UP,
182                                  OnMouseUp, this);
183   evas_object_event_callback_add(native_view_, EVAS_CALLBACK_MOUSE_MOVE,
184                                  OnMouseMove, this);
185   evas_object_event_callback_add(native_view_, EVAS_CALLBACK_MOUSE_IN,
186                                  OnMouseIn, this);
187   evas_object_event_callback_add(native_view_, EVAS_CALLBACK_MOUSE_OUT,
188                                  OnMouseOut, this);
189   evas_object_event_callback_add(native_view_, EVAS_CALLBACK_MOUSE_WHEEL,
190                                  OnMouseWheel, this);
191   if (key_events_enabled_)
192     AddKeyCallbacks();
193
194   evas_object_focus_set(native_view_, EINA_TRUE);
195
196   if (touch_events_enabled_)
197     AddTouchCallbacks();
198 }
199
200 int EflEventHandler::GetTopControlsHeight() {
201   evas_object_geometry_get(native_view_, nullptr, &top_controls_height_,
202                            nullptr, nullptr);
203   return top_controls_height_;
204 }
205
206 template <typename EVT>
207 bool EflEventHandler::GetTouchEventsEnabled(const EVT* evas_evt) {
208 #if defined(OS_TIZEN_TV_PRODUCT)
209   return (touch_events_enabled_ &&
210           evas_device_class_get(evas_evt->dev) == EVAS_DEVICE_CLASS_TOUCH);
211 #endif
212   return touch_events_enabled_;
213 }
214
215 template <class EVT>
216 MouseEvent MakeWebMouseEvent(EventType type, const EVT* ev, int delta_y) {
217   gfx::PointF location(ev->canvas.x, ev->canvas.y);
218   location.Offset(0, -delta_y);
219   int button = EvasToUIMouseButton(ev->button);
220   int event_flags = EvasModifiersToEventFlags(ev->modifiers);
221   event_flags |= button;
222   MouseEvent event(type, location, location, base::TimeTicks::Now(),
223                    event_flags, button);
224
225 #if defined(OS_TIZEN_TV_PRODUCT)
226   int clickCount = 1;
227   if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)  // dblclick
228     clickCount = 2;
229   if (ev->flags & EVAS_BUTTON_TRIPLE_CLICK)  // triple click
230     clickCount = 3;
231
232   event.SetClickCount(clickCount);
233 #endif
234
235   return event;
236 }
237
238 TouchEvent MakeTouchEvent(Evas_Coord_Point pt,
239                           Evas_Touch_Point_State state,
240                           int id,
241                           unsigned int timestamp,
242                           int delta_y) {
243   base::TimeTicks event_timestamp = base::TimeTicks::FromInternalValue(
244       timestamp * base::Time::kMicrosecondsPerMillisecond);
245
246   if (timestamp == 0)
247     event_timestamp = EventTimeForNow();
248
249   pt.y -= delta_y;
250
251   TouchEvent touch_event(
252       EvasTouchEventTypeToUI(state), gfx::Point(), event_timestamp,
253       PointerDetails(EventPointerType::kTouch, id, 0.0f, 0.0f, 0.0f));
254   gfx::PointF point(pt.x, pt.y);
255   touch_event.set_location_f(point);
256   touch_event.set_root_location_f(point);
257   return touch_event;
258 }
259
260 template <class EVT>
261 KeyEvent MakeWebKeyEvent(bool pressed, const EVT* evt) {
262   EventType type = pressed ? ET_KEY_PRESSED : ET_KEY_RELEASED;
263   int native_key_code = evt->keycode;
264   KeyboardCode windows_key_code = UIKeyCodeFromEflKey(evt->key);
265
266   int flags = 0;
267 #if defined(OS_TIZEN_TV_PRODUCT)
268   // On combinate key "shift+Alt+xxx", the "key" of the "Alt" is
269   // "Meta_L/Meta_R", not the "Alt_L/Alt_R", so use the keyname replace the
270   // "key" to get the flag.
271   if (evt->keyname)
272     flags = GetEventFlagsFromKey(evt->keyname);
273   else
274 #endif
275     flags = GetEventFlagsFromKey(evt->key);
276
277   int key_modifiers = 0;
278   if (evas_key_lock_is_set(evt->locks, "Caps_Lock"))
279     key_modifiers |= EF_CAPS_LOCK_ON;
280
281   key_modifiers |= EvasModifiersToEventFlags(evt->modifiers);
282
283   // For Modifiers Key, need set the modifier when key press,
284   // no need set the modifier when key release.
285   // refer w3c spec: https://w3c.github.io/uievents/#keys-modifierss
286   if (pressed)
287     key_modifiers |= flags;
288   else
289     key_modifiers &= ~flags;
290
291 #if defined(OS_TIZEN)
292   DomCode domCode = KeycodeConverter::NativeKeycodeToDomCode(native_key_code);
293
294   DomKey domKey = KeycodeConverter::KeyStringToDomKey(evt->key);
295   // If the efl key name is not identified, use its domcode to find it in domkey
296   // map
297   if ((domKey == DomKey::NONE) && (domCode != DomCode::NONE)) {
298     int flags = key_modifiers;
299     KeyboardCode windowsKeyCode = VKEY_UNKNOWN;
300     std::ignore =
301         DomCodeToUsLayoutDomKey(domCode, flags, &domKey, &windowsKeyCode);
302   }
303
304   KeyEvent event(type, windows_key_code, domCode, key_modifiers, domKey,
305                  base::TimeTicks::Now(), false);
306 #else
307   KeyEvent event(type, windows_key_code, key_modifiers, base::TimeTicks::Now());
308 #endif
309
310   return event;
311 }
312
313 template KeyEvent MakeWebKeyEvent(bool, const Evas_Event_Key_Down*);
314 template KeyEvent MakeWebKeyEvent(bool, const Evas_Event_Key_Up*);
315
316 void EflEventHandler::SetTouchEventsEnabled(bool enabled) {
317   if (touch_events_enabled_ == enabled)
318     return;
319
320   touch_events_enabled_ = enabled;
321
322   LOG(INFO) << "SetTouchEventsEnabled: " << (enabled ? "enabled" : "disabled");
323   if (enabled)
324     AddTouchCallbacks();
325   else
326     DeleteTouchCallbacks();
327 }
328
329 void EflEventHandler::SetKeyEventsEnabled(bool enabled) {
330   if (key_events_enabled_ == enabled)
331     return;
332
333   key_events_enabled_ = enabled;
334
335   LOG(INFO) << "SetKeyEventsEnabled: " << (enabled ? "enabled" : "disabled");
336   if (enabled)
337     AddKeyCallbacks();
338   else
339     DeleteKeyCallbacks();
340 }
341
342 void EflEventHandler::SendKeyEvent(Evas_Object* ewk_view,
343                                    void* event_info,
344                                    bool is_press) {
345   if (is_press) {
346     OnKeyDown(static_cast<void*>(this), nullptr, ewk_view, event_info);
347   } else {
348     OnKeyUp(static_cast<void*>(this), nullptr, ewk_view, event_info);
349   }
350 }
351
352 static int mouse_pre_x = 0;
353 static int mouse_pre_y = 0;
354
355 void EflEventHandler::SendMouseDown(int button, int x, int y) {
356   Evas_Event_Mouse_Down ev;
357   ev.button = button;
358   ev.flags = EVAS_BUTTON_NONE;
359   ev.canvas.x = x;
360   ev.canvas.y = y;
361   ev.modifiers = 0;
362   ev.timestamp = ecore_time_get();
363
364   OnMouseDown(static_cast<void*>(this), window_->evas(), native_view_, &ev);
365 }
366
367 void EflEventHandler::SendMouseUp(int button, int x, int y) {
368   Evas_Event_Mouse_Up ev;
369   ev.button = button;
370   ev.flags = EVAS_BUTTON_NONE;
371   ev.canvas.x = x;
372   ev.canvas.y = y;
373   ev.modifiers = 0;
374   ev.timestamp = ecore_time_get();
375
376   OnMouseUp(static_cast<void*>(this), window_->evas(), native_view_, &ev);
377 }
378
379 void EflEventHandler::SendMouseMove(int x, int y) {
380   Evas_Event_Mouse_Move ev;
381   ev.buttons = 1;
382   ev.cur.canvas.x = x;
383   ev.cur.canvas.y = y;
384   ev.prev.canvas.x = mouse_pre_x;
385   ev.prev.canvas.y = mouse_pre_y;
386   ev.modifiers = 0;
387   ev.timestamp = ecore_time_get();
388
389   OnMouseMove(static_cast<void*>(this), window_->evas(), native_view_, &ev);
390
391   mouse_pre_x = x;
392   mouse_pre_y = y;
393 }
394
395 void EflEventHandler::SendMouseWheel(bool y_direction, int step, int x, int y) {
396   Evas_Event_Mouse_Wheel ev;
397   ev.direction = y_direction ? 0 : 1;
398   ev.canvas.x = x;
399   ev.canvas.y = y;
400   ev.z = step;
401   ev.modifiers = 0;
402   ev.timestamp = ecore_time_get();
403
404   OnMouseWheel(static_cast<void*>(this), window_->evas(), native_view_, &ev);
405 }
406
407 void EflEventHandler::SendMouseOut() {
408   Evas_Event_Mouse_Out ev;
409   ev.buttons = 0;
410   ev.canvas.x = mouse_pre_x;
411   ev.canvas.y = mouse_pre_y;
412   ev.modifiers = 0;
413   ev.timestamp = ecore_time_get();
414
415   OnMouseOut(static_cast<void*>(this), window_->evas(), native_view_, &ev);
416 }
417
418 void EflEventHandler::AddTouchCallbacks() {
419   evas_object_event_callback_add(native_view_, EVAS_CALLBACK_MULTI_DOWN,
420                                  OnMultiTouchDownEvent, this);
421   evas_object_event_callback_add(native_view_, EVAS_CALLBACK_MULTI_MOVE,
422                                  OnMultiTouchMoveEvent, this);
423   evas_object_event_callback_add(native_view_, EVAS_CALLBACK_MULTI_UP,
424                                  OnMultiTouchUpEvent, this);
425 }
426
427 void EflEventHandler::DeleteTouchCallbacks() {
428   evas_object_event_callback_del(native_view_, EVAS_CALLBACK_MULTI_DOWN,
429                                  OnMultiTouchDownEvent);
430   evas_object_event_callback_del(native_view_, EVAS_CALLBACK_MULTI_MOVE,
431                                  OnMultiTouchMoveEvent);
432   evas_object_event_callback_del(native_view_, EVAS_CALLBACK_MULTI_UP,
433                                  OnMultiTouchUpEvent);
434 }
435
436 void EflEventHandler::AddKeyCallbacks() {
437   evas_object_event_callback_add(native_view_, EVAS_CALLBACK_KEY_DOWN,
438                                  OnKeyDown, this);
439   evas_object_event_callback_add(native_view_, EVAS_CALLBACK_KEY_UP, OnKeyUp,
440                                  this);
441 }
442
443 void EflEventHandler::DeleteKeyCallbacks() {
444   evas_object_event_callback_del(native_view_, EVAS_CALLBACK_KEY_DOWN,
445                                  OnKeyDown);
446   evas_object_event_callback_del(native_view_, EVAS_CALLBACK_KEY_UP, OnKeyUp);
447 }
448
449 // static
450 void EflEventHandler::OnMouseDown(void* data,
451                                   Evas* evas,
452                                   Evas_Object* obj,
453                                   void* event_info) {
454   EflEventHandler* thiz = static_cast<EflEventHandler*>(data);
455   Evas_Event_Mouse_Down* ev = static_cast<Evas_Event_Mouse_Down*>(event_info);
456   LOG(INFO) << "OnMouseDown";
457
458   thiz->window_->UpdateFocus(true);
459
460   if (thiz->GetTouchEventsEnabled(ev)) {
461     thiz->ProcessTouchEvents(ev->timestamp, false);
462   } else {
463     MouseEvent event =
464         MakeWebMouseEvent(ET_MOUSE_PRESSED, ev, thiz->GetTopControlsHeight());
465     EflPlatformEventSource::GetInstance()->DispatchEflEvent(&event);
466   }
467 }
468
469 // static
470 void EflEventHandler::OnMouseUp(void* data,
471                                 Evas* evas,
472                                 Evas_Object* obj,
473                                 void* event_info) {
474   EflEventHandler* thiz = static_cast<EflEventHandler*>(data);
475   Evas_Event_Mouse_Up* ev = static_cast<Evas_Event_Mouse_Up*>(event_info);
476   LOG(INFO) << "OnMouseUp";
477
478   if (thiz->GetTouchEventsEnabled(ev)) {
479     thiz->ProcessTouchEvents(ev->timestamp, false);
480   } else {
481     MouseEvent event =
482         MakeWebMouseEvent(ET_MOUSE_RELEASED, ev, thiz->GetTopControlsHeight());
483     EflPlatformEventSource::GetInstance()->DispatchEflEvent(&event);
484   }
485 }
486
487 // static
488 void EflEventHandler::OnMouseMove(void* data,
489                                   Evas* evas,
490                                   Evas_Object* obj,
491                                   void* event_info) {
492   EflEventHandler* thiz = static_cast<EflEventHandler*>(data);
493
494   Evas_Event_Mouse_Move* ev = static_cast<Evas_Event_Mouse_Move*>(event_info);
495   if (thiz->GetTouchEventsEnabled(ev)) {
496     thiz->ProcessTouchEvents(ev->timestamp, false);
497   } else {
498     gfx::PointF location(ev->cur.canvas.x, ev->cur.canvas.y);
499     location.Offset(0, -thiz->GetTopControlsHeight());
500     int button = EvasToUIMouseButton(ev->buttons);
501     int event_flags = EvasModifiersToEventFlags(ev->modifiers);
502     event_flags |= button;
503     MouseEvent event(ET_MOUSE_MOVED, location, location, base::TimeTicks::Now(),
504                      event_flags, button);
505     const float sf = GetDeviceScaleFactor();
506     ui::MouseEvent::DispatcherApi(&event).set_movement(
507         gfx::Vector2dF((ev->cur.canvas.x / sf - ev->prev.canvas.x / sf),
508                        (ev->cur.canvas.y / sf - ev->prev.canvas.y / sf)));
509     EflPlatformEventSource::GetInstance()->DispatchEflEvent(&event);
510   }
511 }
512
513 // static
514 void EflEventHandler::OnMouseIn(void* data,
515                                 Evas* evas,
516                                 Evas_Object* obj,
517                                 void* event_info) {
518   EflEventHandler* thiz = static_cast<EflEventHandler*>(data);
519   thiz->window_->UpdateFocus(true);
520 }
521
522 // static
523 void EflEventHandler::OnMouseOut(void* data,
524                                  Evas* evas,
525                                  Evas_Object* obj,
526                                  void* event_info) {
527 #if !defined(OS_TIZEN_TV_PRODUCT)
528   EflEventHandler* thiz = static_cast<EflEventHandler*>(data);
529   thiz->window_->UpdateFocus(false);
530 #endif
531 }
532
533 // static
534 void EflEventHandler::OnMouseWheel(void* data,
535                                    Evas* evas,
536                                    Evas_Object* obj,
537                                    void* event_info) {
538   Evas_Event_Mouse_Wheel* ev = static_cast<Evas_Event_Mouse_Wheel*>(event_info);
539
540   gfx::Vector2d offset;
541   if (ev->direction)
542     offset.set_x(ev->z * kDefaultScrollStep);
543   else
544     offset.set_y(-(ev->z * kDefaultScrollStep));
545
546   gfx::PointF location(ev->canvas.x, ev->canvas.y);
547   int event_flags = EvasModifiersToEventFlags(ev->modifiers);
548   MouseWheelEvent event(offset, location, location, base::TimeTicks::Now(),
549                         event_flags, 0);
550   EflPlatformEventSource::GetInstance()->DispatchEflEvent(&event);
551 }
552
553 // static
554 void EflEventHandler::OnKeyDown(void* data,
555                                 Evas* evas,
556                                 Evas_Object* obj,
557                                 void* event_info) {
558   if (!obj || !event_info || !data)
559     return;
560
561   Evas_Event_Key_Down* key_down = static_cast<Evas_Event_Key_Down*>(event_info);
562   EflEventHandler* thiz = static_cast<EflEventHandler*>(data);
563   LOG(INFO) << "OnKeyDown, key : " << key_down->key;
564   LOG(INFO) << "Before consumed check (Key Name: " << key_down->key
565             << ", Key State: Down)";
566
567 #if defined(OS_TIZEN)
568   if (IsMobileProfile() || IsTvProfile()) {
569     if (thiz->FilterIMEKeyDownEvent(key_down)) {
570       LOG(INFO) << "OnKeyDown, IME filtered the key : " << key_down->key;
571       return;
572     }
573   }
574 #endif
575
576   KeyEvent event = MakeWebKeyEvent(true, key_down);
577   auto im_context_efl = thiz->GetIMContextEfl();
578   if (!im_context_efl ||
579       im_context_efl->ShouldHandleImmediately(key_down->key)) {
580     EflPlatformEventSource::GetInstance()->DispatchEflEvent(&event);
581     return;
582   }
583
584   LOG(INFO) << "OnKeyUp,PushToKeyDownEventQueue,key:" << key_down->key;
585   im_context_efl->PushToKeyDownEventQueue(event);
586 }
587
588 // static
589 void EflEventHandler::OnKeyUp(void* data,
590                               Evas* evas,
591                               Evas_Object* obj,
592                               void* event_info) {
593   if (!obj || !event_info || !data)
594     return;
595
596   Evas_Event_Key_Up* key_up = static_cast<Evas_Event_Key_Up*>(event_info);
597   EflEventHandler* thiz = static_cast<EflEventHandler*>(data);
598   LOG(INFO) << "OnKeyUp, key : " << key_up->key;
599   LOG(INFO) << "Before consumed check (Key Name: " << key_up->key
600             << ", Key State: Up)";
601
602 #if defined(OS_TIZEN)
603   if (IsMobileProfile() || IsTvProfile()) {
604     if (thiz->FilterIMEKeyUpEvent(key_up)) {
605       LOG(INFO) << "OnKeyUp, IME filtered the key : " << key_up->key;
606       return;
607     }
608   }
609 #endif
610
611   if (IsTvProfile()) {
612     // For TV IME "Select" and "Cancel" key
613     if (thiz->im_context_efl_ && thiz->im_context_efl_->IsVisible()) {
614       if (!strcmp(key_up->key, "Select") || !strcmp(key_up->key, "Cancel"))
615         thiz->im_context_efl_->HidePanel();
616     }
617   }
618
619   KeyEvent event = MakeWebKeyEvent(false, key_up);
620   auto im_context_efl = thiz->GetIMContextEfl();
621   if (!im_context_efl || im_context_efl->ShouldHandleImmediately(key_up->key)) {
622     EflPlatformEventSource::GetInstance()->DispatchEflEvent(&event);
623     return;
624   }
625
626   LOG(INFO) << "OnKeyUp,PushToKeyUpEventQueue,key:" << key_up->key;
627   im_context_efl->PushToKeyUpEventQueue(event.key_code());
628 }
629
630 bool EflEventHandler::IsIMEHandleKeyEventEnabled() {
631   if (!GetIMContextEfl())
632     return false;
633
634 #if defined(OS_TIZEN_TV_PRODUCT)
635   return GetIMContextEfl()->ImeHandleKeyEventEnabled();
636 #endif
637   return true;
638 }
639
640 bool EflEventHandler::FilterIMEKeyDownEvent(Evas_Event_Key_Down* key_down) {
641   if (!IsIMEHandleKeyEventEnabled())
642     return false;
643
644   bool was_filtered = false;
645   im_context_efl_->HandleKeyDownEvent(key_down, &was_filtered);
646
647   // It is for checking whether key is filtered or not about keyUp event.
648   // Because the process related with key is processed at
649   // EVAS_CALLBACK_KEY_DOWN although key is processed by Ecore_IMF, it isn't
650   // filtered by ecore_imf_context_filter_event about EVAS_CALLBACK_KEY_UP.
651   was_keydown_filtered_by_platform_ = was_filtered;
652
653   if (IsTvProfile() && !strcmp(key_down->key, "Return"))
654     was_return_keydown_filtered_by_platform_ = was_filtered;
655   if (was_filtered)
656     LOG(INFO) << "OnKeyDown,IME filtered the key:" << key_down->key;
657
658   return was_filtered;
659 }
660
661 bool EflEventHandler::FilterIMEKeyUpEvent(Evas_Event_Key_Up* key_up) {
662   if (!IsIMEHandleKeyEventEnabled())
663     return false;
664
665   // IME will change language mode when receive "Alt" keyup event.
666   // For avoiding IME change language when "Alt + Enter" scene,
667   // don't send the "Alt" keyup event when "Alt + Enter" keydown.
668   if (IsTvProfile() &&
669       (!strcmp(key_up->key, "Alt_L") || !strcmp(key_up->key, "Alt_R")) &&
670       was_alt_enter_key_down_) {
671     was_alt_enter_key_down_ = false;
672   } else {
673     bool was_filtered = false;
674     im_context_efl_->HandleKeyUpEvent(key_up, &was_filtered);
675   }
676
677   // Both selected key and retrun key events are emitted together
678   // while typing a single key on OSK by using remote controller.
679   // The redundant retrun key event needs to be ignored here.
680   if (IsTvProfile() && evas_device_name_get(key_up->dev)) {
681     if (!strstr(evas_device_name_get(key_up->dev), "ime") &&
682         im_context_efl_->IsVisible() && !strcmp(key_up->key, "Return")) {
683       return true;
684     }
685   }
686
687   // When IME was focused out in keydown event handler,
688   // 'was_filtered' will not give the right value.
689   // Refer to 'was_return_keydown_filtered_by_platform_' in this case.
690   if (IsTvProfile() && !strcmp(key_up->key, "Return") &&
691       was_return_keydown_filtered_by_platform_) {
692     was_return_keydown_filtered_by_platform_ = false;
693     return true;
694   }
695
696   if (was_keydown_filtered_by_platform_) {
697     was_keydown_filtered_by_platform_ = false;
698     return true;
699   }
700
701   return false;
702 }
703
704 void EflEventHandler::OnMultiTouchDownEvent(void* data,
705                                             Evas* evas,
706                                             Evas_Object* obj,
707                                             void* event_info) {
708   EflEventHandler* thiz = static_cast<EflEventHandler*>(data);
709   thiz->ProcessTouchEvents(
710       static_cast<Evas_Event_Multi_Down*>(event_info)->timestamp, true);
711 }
712
713 void EflEventHandler::OnMultiTouchMoveEvent(void* data,
714                                             Evas* evas,
715                                             Evas_Object* obj,
716                                             void* event_info) {
717   EflEventHandler* thiz = static_cast<EflEventHandler*>(data);
718   thiz->ProcessTouchEvents(
719       static_cast<Evas_Event_Multi_Move*>(event_info)->timestamp, true);
720 }
721
722 void EflEventHandler::OnMultiTouchUpEvent(void* data,
723                                           Evas* evas,
724                                           Evas_Object* obj,
725                                           void* event_info) {
726   EflEventHandler* thiz = static_cast<EflEventHandler*>(data);
727   thiz->ProcessTouchEvents(
728       static_cast<Evas_Event_Multi_Up*>(event_info)->timestamp, true);
729 }
730
731 void EflEventHandler::ProcessTouchEvents(unsigned int timestamp,
732                                          bool is_multi_touch) {
733   unsigned count = evas_touch_point_list_count(window_->evas());
734   if (!count)
735     return;
736
737   int id;
738   Evas_Coord_Point pt;
739   Evas_Touch_Point_State state;
740   for (unsigned i = 0; i < count; ++i) {
741     id = evas_touch_point_list_nth_id_get(window_->evas(), i);
742     if ((id == 0 && is_multi_touch) || (id == 1 && !is_multi_touch))
743       continue;
744     evas_touch_point_list_nth_xy_get(window_->evas(), i, &pt.x, &pt.y);
745     state = evas_touch_point_list_nth_state_get(window_->evas(), i);
746     if (state == EVAS_TOUCH_POINT_STILL)
747       continue;
748
749     TouchEvent touch_event =
750         MakeTouchEvent(pt, state, id, timestamp, top_controls_height_);
751     EflPlatformEventSource::GetInstance()->DispatchEflEvent(&touch_event);
752   }
753 }
754
755 }  // namespace ui