display: Change get_var_display_config return type to const
[platform/core/system/deviced.git] / plugins / mobile / display / key-filter.c
1 /*
2  * deviced
3  *
4  * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the License);
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19
20 #include <stdio.h>
21 #include <unistd.h>
22 #include <stdlib.h>
23 #include <stdbool.h>
24 #include <assert.h>
25 #include <vconf.h>
26 #include <sys/types.h>
27 #include <libsyscommon/libgdbus.h>
28 #include <linux/input.h>
29
30 #include "ambient-mode.h"
31 #include "util.h"
32 #include "core.h"
33 #include "poll.h"
34 #include "display-actor.h"
35 #include "display-ops.h"
36 #include "shared/common.h"
37 #include "shared/devices.h"
38 #include "shared/device-notifier.h"
39 #include "shared/common.h"
40 #include "shared/plugin.h"
41 #include "shared/apps.h"
42 #include "power/power-off.h"
43 #include "power/power-suspend.h"
44 #include "led/touch-key.h"
45 #include "display/display-lock.h"
46
47 #ifndef KEY_SCREENLOCK
48 #define KEY_SCREENLOCK          0x98
49 #endif
50 #ifndef SW_GLOVE
51 #define SW_GLOVE                0x16
52 #endif
53
54 #define PREDEF_LEAVESLEEP       "leavesleep"
55 #define POWEROFF_ACT                    "poweroff"
56 #define USEC_PER_SEC                    1000000
57 #define USEC_PER_MSEC                   1000
58 #define CSC_CONFIG_MODE_RUNNING 1
59
60 #define CAPTURE_COMBINATION_INTERVAL            0.5     /* 0.5 second */
61 #define TORCH_COMBINATION_INTERVAL                      0.1 /* 0.1 second */
62 #define DEFAULT_COMBINATION_INTERVAL            0.1 /* 0.1 second */
63
64 #define LONGKEY_PRESSED_TIME    4       /* 4 second */
65
66 #define KEY_MAX_DELAY_TIME              700     /* ms */
67
68 #define SIGNAL_CHANGE_HARDKEY           "ChangeHardkey"
69 #define SIGNAL_LCDON_BY_POWERKEY        "LCDOnByPowerkey"
70 #define SIGNAL_LCDOFF_BY_POWERKEY       "LCDOffByPowerkey"
71
72 #define NORMAL_POWER                    0
73 #define KEY_TEST_MODE_POWER             2
74
75 #define GLOVE_MODE      1
76
77 enum key_combination_flags {
78         KEY_COMBINATION_STOP            = 0,
79         KEY_COMBINATION_POWERKEY        = BIT(0),
80         KEY_COMBINATION_MENUKEY         = BIT(1),
81         KEY_COMBINATION_VOLUMEUP        = BIT(2),
82         KEY_COMBINATION_VOLUMEDOWN      = BIT(3),
83 };
84
85 enum combination_process {
86         COMBINATION_STOP        = KEY_COMBINATION_STOP,
87         COMBINATION_SCREENCAPTURE       = KEY_COMBINATION_POWERKEY | KEY_COMBINATION_MENUKEY,
88         COMBINATION_TORCH       = KEY_COMBINATION_POWERKEY | KEY_COMBINATION_VOLUMEUP,
89         COMBINATION_QUICKTALK   = KEY_COMBINATION_POWERKEY | KEY_COMBINATION_VOLUMEDOWN,
90 };
91
92 static struct display_plugin *disp_plgn;
93 static struct _backlight_ops *backlight_ops;
94 static struct timeval pressed_time;
95 static guint longkey_timeout_id = 0;
96 static guint longkey_restore_id = 0;
97 static guint displayon_by_powerkey_timeout_id = 0;
98 static int cancel_lcdoff;
99 static int key_combination = KEY_COMBINATION_STOP;
100 static double combination_pressed_time;
101 static bool touch_pressed = false;
102 static int skip_lcd_off = false;
103 static int skip_combination = false;
104 static int bezel_wakeup = true;
105 static const struct device_ops *touchled;
106 static int booting_check = true;
107
108 static inline int current_state_in_on(void)
109 {
110         return ((get_pm_cur_state() == S_LCDDIM) || (get_pm_cur_state() == S_NORMAL));
111 }
112
113 static inline void restore_custom_brightness(void)
114 {
115         if ((get_pm_cur_state() == S_LCDDIM) &&
116             backlight_ops->get_custom_status())
117                 backlight_ops->custom_update();
118 }
119
120 static void longkey_pressed(void)
121 {
122         unsigned int caps;
123
124         _I("Power key long pressed!");
125         cancel_lcdoff = 1;
126
127         caps = display_get_caps(DISPLAY_ACTOR_POWER_KEY);
128
129         if (display_has_caps(caps, DISPLAY_CAPA_LCDON)) {
130                 /* change state - LCD on */
131                 if (disp_plgn->pm_change_internal)
132                         disp_plgn->pm_change_internal(INTERNAL_LOCK_POWERKEY, LCD_NORMAL);
133                 poll_callback(INPUT_POLL_EVENT, NULL);
134         }
135
136         if (!display_has_caps(caps, DISPLAY_CAPA_LCDOFF)) {
137                 _D("No poweroff capability!");
138                 return;
139         }
140 }
141
142 static gboolean longkey_restore_cb(void *data)
143 {
144         device_notify(DEVICE_NOTIFIER_LONGKEY_RESTORE, (void *)NULL);
145         longkey_restore_id = 0;
146
147         return G_SOURCE_REMOVE;
148 }
149
150 static gboolean longkey_pressed_cb(void *data)
151 {
152         longkey_pressed();
153         longkey_timeout_id = 0;
154
155         return G_SOURCE_REMOVE;
156 }
157
158 static unsigned long timediff_usec(struct timeval t1, struct timeval t2)
159 {
160         unsigned long udiff;
161
162         udiff = (t2.tv_sec - t1.tv_sec) * USEC_PER_SEC;
163         udiff += (t2.tv_usec - t1.tv_usec);
164
165         return udiff;
166 }
167
168 static inline void check_key_pair(int code, int new, int *old)
169 {
170         if (new == *old)
171                 _E("key pair is not matched! (%d, %d)", code, new);
172         else
173                 *old = new;
174 }
175
176 static inline void broadcast_lcdon_by_powerkey(void)
177 {
178         gdbus_signal_emit(NULL,
179                                         DEVICED_PATH_DISPLAY,
180                                         DEVICED_INTERFACE_DISPLAY,
181                                         SIGNAL_LCDON_BY_POWERKEY,
182                                         NULL);
183 }
184
185 static inline void broadcast_lcdoff_by_powerkey(void)
186 {
187         gdbus_signal_emit(NULL,
188                                         DEVICED_PATH_DISPLAY,
189                                         DEVICED_INTERFACE_DISPLAY,
190                                         SIGNAL_LCDOFF_BY_POWERKEY,
191                                         NULL);
192 }
193
194 static inline bool switch_on_lcd(enum device_flags flags)
195 {
196         if (current_state_in_on())
197                 return false;
198
199         if (backlight_ops->get_lcd_power() == DPMS_ON) {
200                 if (ambient_get_state() == false)
201                         return false;
202         }
203
204         if (flags & LCD_ON_BY_POWER_KEY)
205                 broadcast_lcdon_by_powerkey();
206         else if (flags & LCD_ON_BY_TOUCH)
207                 _I("Display on by Touch_wakeup event");
208
209         lcd_on_direct(flags);
210
211         return true;
212 }
213
214 static inline void switch_off_lcd(void)
215 {
216         if (!current_state_in_on())
217                 return;
218
219         if (backlight_ops->get_lcd_power() == DPMS_OFF)
220                 return;
221
222         broadcast_lcdoff_by_powerkey();
223
224         lcd_off_procedure(LCD_OFF_BY_POWER_KEY);
225 }
226
227 static void check_key_combination(struct input_event *pinput)
228 {
229         double press_time, diff_time;
230         press_time = (pinput->time).tv_sec + USEC_TO_SEC((pinput->time).tv_usec);
231         diff_time = press_time - combination_pressed_time;
232
233         switch (key_combination) {
234         case COMBINATION_SCREENCAPTURE:
235                 if (diff_time <= CAPTURE_COMBINATION_INTERVAL) {
236                         _I("Combination key : SCREENCAPTURE mode");
237                         skip_combination = true;
238                 }
239                 break;
240         case COMBINATION_TORCH:
241                 if (diff_time <= TORCH_COMBINATION_INTERVAL) {
242                         /* When torch combination, display control should be not change. */
243                         if (displayon_by_powerkey_timeout_id) {
244                                 g_source_remove(displayon_by_powerkey_timeout_id);
245                                 displayon_by_powerkey_timeout_id = 0;
246                         }
247                         _I("Combination key : TORCH mode");
248                         skip_combination = true;
249                 } else
250                         key_combination = COMBINATION_STOP;
251                 break;
252         case COMBINATION_QUICKTALK:
253                 if (diff_time <= DEFAULT_COMBINATION_INTERVAL) {
254                         _I("Combination key : QUICK-TALK mode");
255                         skip_combination = true;
256                         if (longkey_timeout_id) {
257                                 g_source_remove(longkey_timeout_id);
258                                 longkey_timeout_id = 0;
259                         }
260                 }
261                 break;
262         default:
263                 combination_pressed_time = press_time;
264                 return;
265         }
266
267 }
268
269 static void start_key_combination(struct input_event *pinput)
270 {
271         switch (pinput->code) {
272         case KEY_POWER:
273                 key_combination |= KEY_COMBINATION_POWERKEY;
274                 break;
275         case KEY_MENU:
276                 key_combination |= KEY_COMBINATION_MENUKEY;
277                 break;
278         case KEY_VOLUMEUP:
279                 key_combination |= KEY_COMBINATION_VOLUMEUP;
280                 break;
281         case KEY_VOLUMEDOWN:
282                 key_combination |= KEY_COMBINATION_VOLUMEDOWN;
283                 break;
284         default:
285                 return;
286         }
287
288         check_key_combination(pinput);
289 }
290
291 static void stop_key_combination(struct input_event *pinput)
292 {
293         if (pinput == NULL) {
294                 key_combination = KEY_COMBINATION_STOP;
295                 return;
296         }
297
298         switch (pinput->code) {
299         case KEY_POWER:
300                 key_combination &= ~KEY_COMBINATION_POWERKEY;
301                 break;
302         case KEY_MENU:
303                 key_combination &= ~KEY_COMBINATION_MENUKEY;
304                 break;
305         case KEY_VOLUMEUP:
306                 key_combination &= ~KEY_COMBINATION_VOLUMEUP;
307                 break;
308         case KEY_VOLUMEDOWN:
309                 key_combination &= ~KEY_COMBINATION_VOLUMEDOWN;
310                 break;
311         default:
312                 _E("This code(%d) is not combination type.", pinput->code);
313                 break;
314         }
315 }
316
317 static void process_combination_key(struct input_event *pinput)
318 {
319         if (pinput->value == KEY_PRESSED)
320                 start_key_combination(pinput);
321         else if (pinput->value == KEY_RELEASED)
322                 stop_key_combination(pinput);
323 }
324
325 static int process_menu_key(struct input_event *pinput)
326 {
327         int caps;
328
329         caps = display_get_caps(DISPLAY_ACTOR_MENU_KEY);
330
331         if (!display_has_caps(caps, DISPLAY_CAPA_LCDON)) {
332                 if (current_state_in_on())
333                         return false;
334                 _D("No lcd-on capability!");
335                 return true;
336         } else if (pinput->value == KEY_PRESSED)
337                 switch_on_lcd(LCD_ON_BY_POWER_KEY);
338
339         return false;
340 }
341
342 static int decide_lcdoff(void)
343 {
344         /* It's not needed if it's already LCD off state */
345         if (!current_state_in_on() &&
346             backlight_ops->get_lcd_power() != DPMS_ON)
347                 return false;
348
349         /*
350          * This flag is set at the moment
351          * that LCD is turned on by power key
352          * LCD has not to turned off in the situation.
353          */
354         if (skip_lcd_off)
355                 return false;
356
357         /* LCD is not turned off when powerkey is pressed,not released */
358         if (key_combination == KEY_COMBINATION_POWERKEY)
359                 return false;
360
361         /* LCD-off is blocked at the moment poweroff popup shows */
362         if (cancel_lcdoff)
363                 return false;
364
365         /* LCD-off is blocked when powerkey and volmedown key are pressed */
366         if (skip_combination)
367                 return false;
368
369         /* At booting time, display must do not turn off */
370         if (booting_check)
371                 return false;
372
373         return true;
374 }
375
376 static int lcdoff_powerkey(void)
377 {
378         int ignore = true;
379
380         if (decide_lcdoff() == true) {
381                 check_processes(S_NORMAL);
382                 check_processes(S_LCDDIM);
383
384                 if (!check_holdkey_block(S_NORMAL) &&
385                     !check_holdkey_block(S_LCDDIM)) {
386                         if (display_info.update_auto_brightness)
387                                 display_info.update_auto_brightness(false);
388                         switch_off_lcd();
389                         delete_condition(S_NORMAL);
390                         delete_condition(S_LCDDIM);
391                         update_lcdoff_source(VCONFKEY_PM_LCDOFF_BY_POWERKEY);
392                         if (disp_plgn->pm_change_internal)
393                                 disp_plgn->pm_change_internal(INTERNAL_LOCK_POWERKEY, LCD_OFF);
394                 }
395         } else {
396                 ignore = false;
397                 skip_combination = false;
398         }
399         cancel_lcdoff = 0;
400
401         return ignore;
402 }
403
404 static bool key_check_display_on(void)
405 {
406         if (current_state_in_on())
407                 return false;
408
409         if (backlight_ops->get_lcd_power() == DPMS_ON) {
410                 _W("display power was on");
411                 return false;
412         }
413
414         return true;
415 }
416
417 static gboolean display_on_cb(void *data)
418 {
419         if (displayon_by_powerkey_timeout_id == 0)
420                 return G_SOURCE_REMOVE;
421
422         displayon_by_powerkey_timeout_id = 0;
423         if (backlight_ops->get_lcd_power() != DPMS_ON ||
424             current_state_in_on() == false) {
425                 broadcast_lcdon_by_powerkey();
426                 lcd_on_direct(LCD_ON_BY_POWER_KEY);
427
428                 poll_callback(INPUT_POLL_EVENT, NULL);
429         }
430
431         return G_SOURCE_REMOVE;
432 }
433
434 static int process_back_key(struct input_event *pinput)
435 {
436         int ignore = true;
437
438         if (pinput->value == KEY_PRESSED) {
439                 switch_on_lcd(LCD_ON_BY_BACK_KEY);
440                 _I("back key pressed");
441                 ignore = false;
442         }
443
444         return ignore;
445 }
446
447 static int process_power_key(struct input_event *pinput)
448 {
449         int ignore = true;
450         static int value = KEY_RELEASED;
451         unsigned int caps;
452         const struct display_config *display_conf = get_var_display_config();
453         if (!display_conf) {
454                 _E("Failed to get display configuration variable.");
455                 return ignore;
456         }
457
458         caps = display_get_caps(DISPLAY_ACTOR_POWER_KEY);
459
460         switch (pinput->value) {
461         case KEY_RELEASED:
462                 check_key_pair(pinput->code, pinput->value, &value);
463
464                 if (!display_conf->powerkey_doublepress) {
465                         if (display_has_caps(caps, DISPLAY_CAPA_LCDOFF))
466                                 lcdoff_powerkey();
467                         else
468                                 _D("No lcdoff capability!");
469                 } else if (skip_lcd_off)
470                         ignore = false;
471
472                 if (!display_has_caps(caps, DISPLAY_CAPA_LCDON))
473                         ignore = true;
474
475                 if (longkey_timeout_id > 0) {
476                         g_source_remove(longkey_timeout_id);
477                         longkey_timeout_id = 0;
478                 }
479
480                 if (longkey_restore_id > 0) {
481                         g_source_remove(longkey_restore_id);
482                         longkey_restore_id = 0;
483                 }
484
485                 break;
486         case KEY_PRESSED:
487                 if (display_has_caps(caps, DISPLAY_CAPA_LCDON)) {
488                         /*
489                          * LCD does not turn on immediately at mobile.
490                          * It will be turned on after 0.1 second because of torch concept.
491                          */
492                         skip_lcd_off = key_check_display_on();
493                         ignore = true;
494
495                         if (!displayon_by_powerkey_timeout_id &&
496                                 backlight_ops->get_lcd_power() != DPMS_ON &&
497                                 key_combination != COMBINATION_TORCH) {
498                                 displayon_by_powerkey_timeout_id = g_timeout_add(
499                                                 100,
500                                                 display_on_cb, NULL);
501                         }
502                 } else {
503                         _D("No lcdon capability!");
504                         skip_lcd_off = false;
505                 }
506                 check_key_pair(pinput->code, pinput->value, &value);
507                 _I("power key pressed");
508                 pressed_time.tv_sec = (pinput->time).tv_sec;
509                 pressed_time.tv_usec = (pinput->time).tv_usec;
510                 if (key_combination == KEY_COMBINATION_POWERKEY) {
511                         /* add long key timer */
512                         longkey_timeout_id = g_timeout_add(
513                                     display_conf->longpress_interval,
514                                     longkey_pressed_cb, NULL);
515                         /* add long key restore timer */
516                         longkey_restore_id = g_timeout_add_seconds(
517                                     LONGKEY_PRESSED_TIME,
518                                     longkey_restore_cb, NULL);
519                 }
520                 cancel_lcdoff = 0;
521
522                 break;
523         case KEY_BEING_PRESSED:
524                 if (timediff_usec(pressed_time, pinput->time) >
525                     (display_conf->longpress_interval * USEC_PER_MSEC))
526                         longkey_pressed();
527                 break;
528         }
529         return ignore;
530 }
531
532 static int process_screenlock_key(struct input_event *pinput)
533 {
534         if (pinput->value != KEY_RELEASED) {
535                 stop_key_combination(NULL);
536                 return true;
537         }
538
539         if (!current_state_in_on())
540                 return false;
541
542         check_processes(S_NORMAL);
543         check_processes(S_LCDDIM);
544
545         if (!check_holdkey_block(S_NORMAL) && !check_holdkey_block(S_LCDDIM)) {
546                 delete_condition(S_NORMAL);
547                 delete_condition(S_LCDDIM);
548                 update_lcdoff_source(VCONFKEY_PM_LCDOFF_BY_POWERKEY);
549
550                 /* LCD off forcly */
551                 if (disp_plgn->pm_change_internal)
552                         disp_plgn->pm_change_internal(-1, LCD_OFF);
553         }
554
555         return true;
556 }
557
558 static void sound_vibrate_hardkey(void)
559 {
560         /* device notify(vibrator) */
561         /* sound(dbus) */
562         /* Need to notify to deviced-vibrator. deviced-vibrator receives ChangedHardKey signal */
563         gdbus_signal_emit(NULL,
564                                         DEVICED_PATH_KEY,
565                                         DEVICED_INTERFACE_KEY,
566                                         SIGNAL_CHANGE_HARDKEY,
567                                         NULL);
568 }
569
570 static void process_hardkey_backlight(struct input_event *pinput)
571 {
572         int opt;
573
574         _E("pinput->value : %d", pinput->value);
575         if (pinput->value == KEY_PRESSED) {
576                 /* Sound & Vibrate only in unlock state */
577                 if (__get_lock_screen_state() == VCONFKEY_IDLE_UNLOCK
578                     || get_lock_screen_bg_state())
579                         sound_vibrate_hardkey();
580
581                 if (touchled && touchled->execute) {
582                         opt = TOUCHLED_PRESS;
583                         touchled->execute(&opt);
584                 }
585         } else if (pinput->value == KEY_RELEASED) {
586                 /* if lockscreen is idle lock */
587                 if (__get_lock_screen_state() == VCONFKEY_IDLE_LOCK) {
588                         _D("Lock state, key backlight is off when phone is unlocked!");
589                         return;
590                 }
591
592                 if (touchled && touchled->execute) {
593                         opt = TOUCHLED_RELEASE;
594                         touchled->execute(&opt);
595                 }
596         }
597 }
598
599 static void update_vital_state(struct input_event *pinput)
600 {
601         int type;
602
603         /* Change vital state to  VITAL_EXIT only if vital mode is active */
604         if (!vital_mode())
605                 return;
606
607         /* Touch or Menu Key Release Event */
608         if (pinput->type == EV_ABS || (pinput->type == EV_KEY &&
609             pinput->value == KEY_RELEASED && pinput->code == KEY_MENU)) {
610                 /* Enable all services upon receiving user input, else maintain same state */
611                 type = VITAL_EXIT;
612                 device_notify(DEVICE_NOTIFIER_VITAL_STATE, &type);
613         }
614 }
615
616 static int check_key(struct input_event *pinput, int fd)
617 {
618         int ignore = true;
619
620         process_combination_key(pinput);
621         switch (pinput->code) {
622         case KEY_MENU:
623                 ignore = process_menu_key(pinput);
624                 break;
625         case KEY_POWER:
626                 ignore = process_power_key(pinput);
627                 if (current_state_in_on())
628                         ignore = false;
629                 break;
630         case KEY_SCREENLOCK:
631                 ignore = process_screenlock_key(pinput);
632                 break;
633         case KEY_BACK:
634                 ignore = process_back_key(pinput);
635                 stop_key_combination(NULL);
636                 if (current_state_in_on()) {
637                         process_hardkey_backlight(pinput);
638                         ignore = false;
639                 }
640                 break;
641         case KEY_PHONE:
642                 stop_key_combination(NULL);
643                 if (current_state_in_on()) {
644                         process_hardkey_backlight(pinput);
645                         ignore = false;
646                 }
647                 break;
648         case KEY_VOLUMEUP:
649         case KEY_VOLUMEDOWN:
650                 if (current_state_in_on())
651                         ignore = false;
652                 break;
653         case KEY_CAMERA:
654         case KEY_EXIT:
655         case KEY_CONFIG:
656         case KEY_MEDIA:
657         case KEY_MUTE:
658         case KEY_PLAYPAUSE:
659         case KEY_PLAYCD:
660         case KEY_PAUSECD:
661         case KEY_STOPCD:
662         case KEY_NEXTSONG:
663         case KEY_PREVIOUSSONG:
664         case KEY_REWIND:
665         case KEY_FASTFORWARD:
666                 stop_key_combination(NULL);
667                 if (current_state_in_on())
668                         ignore = false;
669                 break;
670         case 0x1DB:
671         case 0x1DC:
672         case 0x1DD:
673         case 0x1DE:
674                 stop_key_combination(NULL);
675                 break;
676         default:
677                 stop_key_combination(NULL);
678                 ignore = false;
679         }
680 #ifdef ENABLE_PM_LOG
681         if (pinput->value == KEY_PRESSED)
682                 pm_history_save(PM_LOG_KEY_PRESS, pinput->code);
683         else if (pinput->value == KEY_RELEASED)
684                 pm_history_save(PM_LOG_KEY_RELEASE, pinput->code);
685 #endif
686         return ignore;
687 }
688
689 static int check_key_filter(void *data, int fd)
690 {
691         struct input_event *pinput = data;
692         int ignore = true;
693         static int old_fd, code, value;
694
695         assert(pinput);
696
697         switch (pinput->type) {
698         case EV_KEY:
699                 if (pinput->code == BTN_TOUCH &&
700                         pinput->value == KEY_RELEASED)
701                         touch_pressed = false;
702                 /*
703                  * Normally, touch press/release events don't occur
704                  * in lcd off state. But touch release events can occur
705                  * in the state abnormally. Then touch events are ignored
706                  * when lcd is off state.
707                  */
708                 if (pinput->code == BTN_TOUCH && !current_state_in_on())
709                         break;
710                 if (pinput->code == code && pinput->value == value) {
711                         _E("Same key(%d, %d) is polled [%d,%d]",
712                                 code, value, old_fd, fd);
713                 }
714                 old_fd = fd;
715                 code = pinput->code;
716                 value = pinput->value;
717
718                 update_vital_state(pinput);
719                 ignore = check_key(pinput, fd);
720                 restore_custom_brightness();
721
722                 break;
723         case EV_REL:
724                 if ((get_pm_cur_state() == S_LCDOFF) && bezel_wakeup) {
725                         switch_on_lcd(LCD_ON_BY_BEZEL);
726                         ignore = false;
727                 } else if (get_pm_cur_state() != S_LCDOFF)
728                         ignore = false;
729                 break;
730         case EV_ABS:
731                 update_vital_state(pinput);
732                 if (pinput->value == KEY_PRESSED) {
733                         switch_on_lcd(LCD_ON_BY_TOUCH);
734                         ignore = false;
735                 }
736
737                 if (current_state_in_on())
738                         ignore = false;
739
740                 restore_custom_brightness();
741
742                 if (pinput->value == KEY_PRESSED)
743                         touch_pressed = true;
744                 else if (pinput->value == KEY_RELEASED)
745                         touch_pressed = false;
746                 break;
747         case EV_SW:
748                 break;
749         }
750
751         if (ignore)
752                 return 1;
753
754         return 0;
755 }
756
757 static int delayed_init_done(void *data)
758 {
759         booting_check = 0;
760
761         return 0;
762 }
763
764 static int bezel_wakeup_cb(void *data)
765 {
766         bezel_wakeup = (int)((intptr_t)data);
767
768         return 0;
769 }
770
771 /*
772  * Default capability
773  * powerkey := LCDON | LCDOFF | POWEROFF
774  * homekey  := LCDON
775  */
776 static struct display_actor_ops display_powerkey_actor = {
777         .id     = DISPLAY_ACTOR_POWER_KEY,
778         .caps   = DISPLAY_CAPA_LCDON |
779                   DISPLAY_CAPA_LCDOFF |
780                   DISPLAY_CAPA_POWEROFF,
781 };
782
783 static struct display_actor_ops display_menukey_actor = {
784         .id     = DISPLAY_ACTOR_MENU_KEY,
785         .caps   = DISPLAY_CAPA_LCDON,
786 };
787
788 static void keyfilter_init(void)
789 {
790         display_add_actor(&display_powerkey_actor);
791         display_add_actor(&display_menukey_actor);
792
793         touchled = find_device(TOUCHLED_NAME);
794
795         register_notifier(DEVICE_NOTIFIER_DELAYED_INIT, delayed_init_done);
796         register_notifier(DEVICE_NOTIFIER_BEZEL_WAKEUP, bezel_wakeup_cb);
797 }
798
799 static void key_backlight_enable(bool enable)
800 {
801         int opt;
802
803         if (!touchled || !touchled->execute)
804                 return;
805
806         if (enable)
807                 opt = TOUCHLED_DIRECT_ON;
808         else
809                 opt = TOUCHLED_DIRECT_OFF;
810
811         touchled->execute(&opt);
812 }
813
814 static const struct display_keyfilter_ops normal_keyfilter_ops = {
815         .init                   = keyfilter_init,
816         .check                  = check_key_filter,
817         .set_powerkey_ignore    = NULL,
818         .powerkey_lcdoff        = NULL,
819         .backlight_enable       = key_backlight_enable,
820 };
821
822 const struct display_keyfilter_ops *keyfilter_ops = &normal_keyfilter_ops;
823
824 static void __CONSTRUCTOR__ initialize(void)
825 {
826         disp_plgn = get_var_display_plugin();
827         if (!disp_plgn) {
828                 _E("Failed to get display plugin variable.");
829         }
830
831         backlight_ops = get_var_backlight_ops();
832         if (!backlight_ops)
833                 _E("Failed to get backlight operator variable.");
834 }