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