Initialize Tizen 2.3
[framework/system/deviced.git] / src / display / core.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 /**
21  * @file        core.c
22  * @brief       Power manager main loop.
23  *
24  * This file includes Main loop, the FSM, signal processing.
25  */
26 #include <signal.h>
27 #include <errno.h>
28 #include <string.h>
29 #include <unistd.h>
30 #include <limits.h>
31 #include <stdlib.h>
32 #include <stdio.h>
33 #include <stdbool.h>
34 #include <time.h>
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #include <fcntl.h>
38 #include <vconf-keys.h>
39 #include <Ecore.h>
40
41 #include "util.h"
42 #include "core.h"
43 #include "device-node.h"
44 #include "lock-detector.h"
45 #include "display-ops.h"
46 #include "core/queue.h"
47 #include "core/data.h"
48 #include "core/devices.h"
49 #include "core/device-notifier.h"
50 #include "core/device-handler.h"
51 #include "core/udev.h"
52 #include "core/list.h"
53 #include "core/common.h"
54 #include "core/edbus-handler.h"
55 #include "core/config-parser.h"
56 #include "dd-display.h"
57 #include "weaks.h"
58
59 #define PM_STATE_LOG_FILE               "/var/log/pm_state.log"
60 #define DISPLAY_CONF_FILE               "/etc/deviced/display.conf"
61
62 /**
63  * @addtogroup POWER_MANAGER
64  * @{
65  */
66
67 #define SET_BRIGHTNESS_IN_BOOTLOADER    "/usr/bin/save_blenv SLP_LCD_BRIGHT"
68 #define LOCK_SCREEN_INPUT_TIMEOUT       10000
69 #define LOCK_SCREEN_CONTROL_TIMEOUT     5000
70 #define DD_LCDOFF_INPUT_TIMEOUT         3000
71
72 unsigned int pm_status_flag;
73
74 static void (*power_saving_func) (int onoff);
75 static enum device_ops_status status = DEVICE_OPS_STATUS_UNINIT;
76
77 int pm_cur_state;
78 int pm_old_state;
79 Ecore_Timer *timeout_src_id;
80 static int pre_suspend_flag = false;
81 int system_wakeup_flag = false;
82 static unsigned int custom_normal_timeout = 0;
83 static unsigned int custom_dim_timeout = 0;
84 static int custom_holdkey_block = false;
85 static int custom_change_pid = -1;
86 static char *custom_change_name;
87 static int standby_mode = false;
88 static int standby_state = false;
89 static Eina_List *standby_mode_list = NULL;
90 static int (*basic_action) (int);
91 static bool hallic_open = true;
92 static Ecore_Timer *lock_timeout_id;
93 static int lock_screen_timeout = LOCK_SCREEN_INPUT_TIMEOUT;
94 static int hdmi_state = 0;
95 static int tts_state = false;
96 static struct timeval lcdon_tv;
97
98 /* default transition, action fuctions */
99 static int default_trans(int evt);
100 static int default_action(int timeout);
101 static int default_check(int next);
102
103 struct state states[S_END] = {
104         {S_START, default_trans, default_action, default_check,},
105         {S_NORMAL, default_trans, default_action, default_check,},
106         {S_LCDDIM, default_trans, default_action, default_check,},
107         {S_LCDOFF, default_trans, default_action, default_check,},
108         {S_SLEEP, default_trans, default_action, default_check,}
109 };
110
111 static const char state_string[5][10] =
112         { "S_START", "S_NORMAL", "S_LCDDIM", "S_LCDOFF", "S_SLEEP" };
113
114 static int trans_table[S_END][EVENT_END] = {
115         /* Timeout , Input */
116         {S_START, S_START},     /* S_START */
117         {S_LCDDIM, S_NORMAL},   /* S_NORMAL */
118         {S_LCDOFF, S_NORMAL},   /* S_LCDDIM */
119         {S_SLEEP, S_NORMAL},    /* S_LCDOFF */
120         {S_LCDOFF, S_NORMAL},   /* S_SLEEP */
121 };
122
123 #define SHIFT_UNLOCK            4
124 #define MASK_RESET_TIMEOUT      0x8     /* 1000 */
125 #define MASK_MARGIN_TIMEOUT     (0x1 << 8)
126 #define SHIFT_CHANGE_STATE      7
127 #define CHANGE_STATE_BIT        0xF00   /* 1111 0000 0000 */
128 #define SHIFT_LOCK_FLAG 16
129 #define SHIFT_CHANGE_TIMEOUT    20
130 #define CUSTOM_TIMEOUT_BIT      0x1
131 #define CUSTOM_HOLDKEY_BIT      0x2
132 #define HOLD_KEY_BLOCK_BIT      0x1
133 #define STANDBY_MODE_BIT        0x2
134 #define TIMEOUT_NONE            (-1)
135
136 #define S_COVER_TIMEOUT                 8000
137 #define GET_HOLDKEY_BLOCK_STATE(x) ((x >> SHIFT_LOCK_FLAG) & HOLD_KEY_BLOCK_BIT)
138 #define GET_STANDBY_MODE_STATE(x) ((x >> SHIFT_LOCK_FLAG) & STANDBY_MODE_BIT)
139 #define MASK32                          0xffffffff
140 #define BOOTING_DONE_WATING_TIME        60000   /* 1 minute */
141 #define LOCK_TIME_ERROR                 600     /* 600 seconds */
142 #define LOCK_TIME_WARNING               60      /* 60 seconds */
143
144 #define ACTIVE_ACT "active"
145 #define INACTIVE_ACT "inactive"
146 #define SIGNAL_LCD_ON "LCDOn"
147 #define SIGNAL_LCD_OFF "LCDOff"
148
149 #define LOCK_SCREEN_WATING_TIME         0.3     /* 0.3 second */
150 #define LONG_PRESS_INTERVAL             2       /* 2 seconds */
151 #define SAMPLING_INTERVAL               1       /* 1 sec */
152 #define BRIGHTNESS_CHANGE_STEP          10
153 #define HBM_LUX_THRESHOLD               32768   /* lux */
154 #define LCD_ALWAYS_ON                   0
155 #define LCDOFF_TIMEOUT                  500     /* milli second */
156
157 #define DIFF_TIMEVAL_MS(a, b) \
158         (((a.tv_sec * 1000000 + a.tv_usec) - \
159         (b.tv_sec * 1000000 + b.tv_usec)) \
160         / 1000)
161
162 struct display_config display_conf = {
163         .lock_wait_time         = LOCK_SCREEN_WATING_TIME,
164         .longpress_interval     = LONG_PRESS_INTERVAL,
165         .lightsensor_interval   = SAMPLING_INTERVAL,
166         .lcdoff_timeout         = LCDOFF_TIMEOUT,
167         .brightness_change_step = BRIGHTNESS_CHANGE_STEP,
168         .hbm_lux_threshold      = HBM_LUX_THRESHOLD,
169         .lcd_always_on          = LCD_ALWAYS_ON,
170         .framerate_app          = {0,0,0,0},
171         .control_display        = 0,
172         .powerkey_doublepress   = 0,
173         .alpm_on                = 0,
174 };
175
176 struct display_function_info display_info = {
177         .update_auto_brightness         = NULL,
178         .set_autobrightness_min         = NULL,
179         .reset_autobrightness_min       = NULL,
180         .face_detection                 = NULL,
181 };
182
183 typedef struct _pm_lock_node {
184         pid_t pid;
185         Ecore_Timer *timeout_id;
186         time_t time;
187         bool holdkey_block;
188         struct _pm_lock_node *next;
189 } PmLockNode;
190
191 static PmLockNode *cond_head[S_END];
192
193 static void set_process_active(bool flag, pid_t pid)
194 {
195         char str[6];
196         char *arr[2];
197         int ret;
198
199         if (pid >= INTERNAL_LOCK_BASE)
200                 return;
201
202         sprintf(str, "%d", (int)pid);
203
204         arr[0] = (flag ? ACTIVE_ACT : INACTIVE_ACT);
205         arr[1] = str;
206
207         /* Send dbug to resourced */
208         ret = broadcast_edbus_signal(RESOURCED_PATH_PROCESS,
209             RESOURCED_INTERFACE_PROCESS, RESOURCED_METHOD_ACTIVE, "si", arr);
210         if (ret < 0)
211                 _E("Fail to send dbus signal to resourced!!");
212 }
213
214 int get_standby_state(void)
215 {
216         return standby_state;
217 }
218
219 static inline void set_standby_state(bool state)
220 {
221         if (standby_state != state)
222                 standby_state = state;
223 }
224
225 void broadcast_lcd_on(void)
226 {
227         broadcast_edbus_signal(DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
228             SIGNAL_LCD_ON, NULL, NULL);
229 }
230
231 void broadcast_lcd_off(void)
232 {
233         broadcast_edbus_signal(DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
234             SIGNAL_LCD_OFF, NULL, NULL);
235 }
236
237 void tts_lcd_off(void)
238 {
239         int ret;
240
241         ret = dbus_method_sync(POPUP_BUS_NAME, POPUP_PATH_SERVANT,
242             POPUP_IFACE_SERVANT, POPUP_METHOD_SCREENOFF_TTS, NULL, NULL);
243
244         if (ret < 0)
245                 _E("Failed to tts(%d)", ret);
246 }
247
248 inline void lcd_on_procedure(void)
249 {
250         broadcast_lcd_on();
251         /* AMOLED Low Power Mode off */
252         if (display_conf.alpm_on == true &&
253             alpm_set_state != NULL) {
254                 if (alpm_set_state(false) < 0)
255                         _E("Failed to ALPM off");
256         }
257         backlight_ops.update();
258         backlight_ops.on();
259         touch_ops.screen_on();
260 }
261
262 inline void lcd_off_procedure(void)
263 {
264         if (standby_mode) {
265                 _D("standby mode! lcd off logic is skipped");
266                 return;
267         }
268         /* AMOLED Low Power Mode on */
269         if (display_conf.alpm_on == true &&
270             alpm_set_state != NULL) {
271                 if (alpm_set_state(true) < 0)
272                         _E("Failed to ALPM on!");
273         }
274         broadcast_lcd_off();
275         backlight_ops.off();
276         touch_ops.screen_off();
277
278         if (tts_state)
279                 tts_lcd_off();
280 }
281
282 int low_battery_state(int val)
283 {
284         switch (val) {
285         case VCONFKEY_SYSMAN_BAT_POWER_OFF:
286         case VCONFKEY_SYSMAN_BAT_CRITICAL_LOW:
287         case VCONFKEY_SYSMAN_BAT_REAL_POWER_OFF:
288                 return true;
289         }
290         return false;
291 }
292
293 int get_hallic_open(void)
294 {
295         return hallic_open;
296 }
297
298 static int refresh_app_cond()
299 {
300         trans_condition = 0;
301
302         if (cond_head[S_LCDDIM] != NULL)
303                 trans_condition = trans_condition | MASK_DIM;
304         if (cond_head[S_LCDOFF] != NULL)
305                 trans_condition = trans_condition | MASK_OFF;
306         if (cond_head[S_SLEEP] != NULL)
307                 trans_condition = trans_condition | MASK_SLP;
308
309         return 0;
310 }
311
312 static PmLockNode *find_node(enum state_t s_index, pid_t pid)
313 {
314         PmLockNode *t = cond_head[s_index];
315
316         while (t != NULL) {
317                 if (t->pid == pid)
318                         break;
319                 t = t->next;
320         }
321         return t;
322 }
323
324 static PmLockNode *add_node(enum state_t s_index, pid_t pid, Ecore_Timer *timeout_id,
325                 bool holdkey_block)
326 {
327         PmLockNode *n;
328         time_t now;
329
330         n = (PmLockNode *) malloc(sizeof(PmLockNode));
331         if (n == NULL) {
332                 _E("Not enough memory, add cond. fail");
333                 return NULL;
334         }
335
336         time(&now);
337         n->pid = pid;
338         n->timeout_id = timeout_id;
339         n->time = now;
340         n->holdkey_block = holdkey_block;
341         n->next = cond_head[s_index];
342         cond_head[s_index] = n;
343
344         refresh_app_cond();
345         return n;
346 }
347
348 static int del_node(enum state_t s_index, PmLockNode *n)
349 {
350         PmLockNode *t;
351         PmLockNode *prev;
352
353         if (n == NULL)
354                 return 0;
355
356         t = cond_head[s_index];
357         prev = NULL;
358         while (t != NULL) {
359                 if (t == n) {
360                         if (prev != NULL)
361                                 prev->next = t->next;
362                         else
363                                 cond_head[s_index] = cond_head[s_index]->next;
364                         /* delete timer */
365                         if (t->timeout_id)
366                                 ecore_timer_del(t->timeout_id);
367                         free(t);
368                         break;
369                 }
370                 prev = t;
371                 t = t->next;
372         }
373         refresh_app_cond();
374         return 0;
375 }
376
377 static void print_node(int next)
378 {
379         PmLockNode *n;
380         char buf[30];
381         time_t now;
382         double diff;
383
384         if (next <= S_START || next >= S_END)
385                 return;
386
387         time(&now);
388         n = cond_head[next];
389         while (n != NULL) {
390                 diff = difftime(now, n->time);
391                 ctime_r(&n->time, buf);
392
393                 if (diff > LOCK_TIME_ERROR)
394                         _E("over %.0f s, pid: %5d, lock time: %s", diff, n->pid, buf);
395                 else if (diff > LOCK_TIME_WARNING)
396                         _I("over %.0f s, pid: %5d, lock time: %s", diff, n->pid, buf);
397                 else
398                         _I("pid: %5d, lock time: %s", n->pid, buf);
399
400                 n = n->next;
401         }
402 }
403
404 void get_pname(pid_t pid, char *pname)
405 {
406         char buf[PATH_MAX];
407         int cmdline, r;
408
409         if (pid >= INTERNAL_LOCK_BASE)
410                 snprintf(buf, PATH_MAX, "/proc/%d/cmdline", getpid());
411         else
412                 snprintf(buf, PATH_MAX, "/proc/%d/cmdline", pid);
413
414         cmdline = open(buf, O_RDONLY);
415         if (cmdline < 0) {
416                 pname[0] = '\0';
417                 _E("%d does not exist now(may be dead without unlock)", pid);
418                 return;
419         }
420
421         r = read(cmdline, pname, PATH_MAX);
422         if ((r >= 0) && (r < PATH_MAX))
423                 pname[r] = '\0';
424         else
425                 pname[0] = '\0';
426
427         close(cmdline);
428 }
429
430 static Eina_Bool del_dim_cond(void *data)
431 {
432         PmLockNode *tmp = NULL;
433         char pname[PATH_MAX];
434         pid_t pid = (pid_t)data;
435
436         _I("delete prohibit dim condition by timeout\n");
437
438         tmp = find_node(S_LCDDIM, pid);
439         del_node(S_LCDDIM, tmp);
440         get_pname(pid, pname);
441         set_unlock_time(pname, S_NORMAL);
442
443         if (!timeout_src_id)
444                 states[pm_cur_state].trans(EVENT_TIMEOUT);
445
446         return EINA_FALSE;
447 }
448
449 static Eina_Bool del_off_cond(void *data)
450 {
451         PmLockNode *tmp = NULL;
452         char pname[PATH_MAX];
453         pid_t pid = (pid_t)data;
454
455         _I("delete prohibit off condition by timeout\n");
456
457         tmp = find_node(S_LCDOFF, pid);
458         del_node(S_LCDOFF, tmp);
459         get_pname(pid, pname);
460         set_unlock_time(pname, S_LCDDIM);
461
462         if (!timeout_src_id)
463                 states[pm_cur_state].trans(EVENT_TIMEOUT);
464
465         return EINA_FALSE;
466 }
467
468 static Eina_Bool del_sleep_cond(void *data)
469 {
470         PmLockNode *tmp = NULL;
471         char pname[PATH_MAX];
472         pid_t pid = (pid_t)data;
473
474         _I("delete prohibit sleep condition by timeout\n");
475
476         tmp = find_node(S_SLEEP, pid);
477         del_node(S_SLEEP, tmp);
478         get_pname(pid, pname);
479         set_unlock_time(pname, S_LCDOFF);
480
481         if (!timeout_src_id)
482                 states[pm_cur_state].trans(EVENT_TIMEOUT);
483
484         set_process_active(EINA_FALSE, (pid_t)data);
485         return EINA_FALSE;
486 }
487
488 /* timeout handler  */
489 Eina_Bool timeout_handler(void *data)
490 {
491         _I("Time out state %s\n", state_string[pm_cur_state]);
492
493         if (timeout_src_id) {
494                 ecore_timer_del(timeout_src_id);
495                 timeout_src_id = NULL;
496         }
497
498         states[pm_cur_state].trans(EVENT_TIMEOUT);
499         return EINA_FALSE;
500 }
501
502 inline static void reset_timeout(int timeout)
503 {
504         if (timeout_src_id != 0) {
505                 ecore_timer_del(timeout_src_id);
506                 timeout_src_id = NULL;
507         }
508         if (timeout > 0)
509                 timeout_src_id = ecore_timer_add(MSEC_TO_SEC(timeout),
510                     (Ecore_Task_Cb)timeout_handler, NULL);
511         else if (timeout == 0)
512                 states[pm_cur_state].trans(EVENT_TIMEOUT);
513 }
514
515 /* get configurations from setting */
516 static int get_lcd_timeout_from_settings(void)
517 {
518         int i;
519         int val = 0;
520         int ret = -1;
521         char *buf;
522
523         for (i = 0; i < S_END; i++) {
524                 switch (states[i].state) {
525                 case S_NORMAL:
526                         ret = get_run_timeout(&val);
527                         if (ret != 0) {
528                                 buf = getenv("PM_TO_NORMAL");
529                                 val = (buf ? atoi(buf) : DEFAULT_NORMAL_TIMEOUT);
530                         }
531                         break;
532                 case S_LCDDIM:
533                         get_dim_timeout(&val);
534                         break;
535                 case S_LCDOFF:
536                         val = display_conf.lcdoff_timeout;
537                         break;
538                 default:
539                         /* This state doesn't need to set time out. */
540                         val = 0;
541                         break;
542                 }
543                 if (val > 0)
544                         states[i].timeout = val;
545
546                 _I("%s state : %d ms timeout", state_string[i],
547                         states[i].timeout);
548         }
549
550         return 0;
551 }
552
553 static void update_display_time(void)
554 {
555         int ret, run_timeout, val;
556
557         /* first priority : s cover */
558         if (!hallic_open) {
559                 states[S_NORMAL].timeout = S_COVER_TIMEOUT;
560                 _I("S cover closed : timeout is set by normal(%d ms)",
561                     S_COVER_TIMEOUT);
562                 return;
563         }
564
565         /* second priority : custom timeout */
566         if (custom_normal_timeout > 0) {
567                 states[S_NORMAL].timeout = custom_normal_timeout;
568                 states[S_LCDDIM].timeout = custom_dim_timeout;
569                 _I("CUSTOM : timeout is set by normal(%d ms), dim(%d ms)",
570                     custom_normal_timeout, custom_dim_timeout);
571                 return;
572         }
573
574         /* third priority : lock state */
575         if ((get_lock_screen_state() == VCONFKEY_IDLE_LOCK) &&
576             !get_lock_screen_bg_state()) {
577                 if (pm_status_flag & SMAST_FLAG) {
578                         /* smart stay is on, timeout is always 5 seconds. */
579                         states[S_NORMAL].timeout = LOCK_SCREEN_CONTROL_TIMEOUT;
580                         _I("LOCK : timeout is set, smart stay timeout(%d ms)",
581                             LOCK_SCREEN_CONTROL_TIMEOUT);
582                 } else {
583                         /* timeout is different according to key or event. */
584                         states[S_NORMAL].timeout = lock_screen_timeout;
585                         _I("LOCK : timeout is set by normal(%d ms)",
586                             lock_screen_timeout);
587                 }
588                 return;
589         }
590
591         /* default setting */
592         ret = get_run_timeout(&run_timeout);
593         if (ret < 0 || run_timeout <= 0) {
594                 _E("Can not get run timeout. set default %d ms",
595                     DEFAULT_NORMAL_TIMEOUT);
596                 run_timeout = DEFAULT_NORMAL_TIMEOUT;
597         }
598         states[S_NORMAL].timeout = run_timeout;
599
600         get_dim_timeout(&val);
601         states[S_LCDDIM].timeout = val;
602         
603         _I("Normal: NORMAL timeout is set by %d ms", states[S_NORMAL].timeout);
604         _I("Normal: DIM timeout is set by %d ms", states[S_LCDDIM].timeout);
605 }
606
607 static void update_display_locktime(int time)
608 {
609         lock_screen_timeout = time;
610         update_display_time();
611 }
612
613 void lcd_on_direct(void)
614 {
615         int ret, call_state;
616
617         if (power_ops.get_power_lock_support()
618             && pm_cur_state == S_SLEEP)
619                 power_ops.power_lock();
620
621         if (pre_suspend_flag == true) {
622                 power_ops.post_resume();
623                 pre_suspend_flag = false;
624         }
625 #ifdef MICRO_DD
626         _D("lcd is on directly");
627         gettimeofday(&lcdon_tv, NULL);
628         if (hbm_check_timeout != NULL)
629                 hbm_check_timeout();
630         lcd_on_procedure();
631         reset_timeout(DD_LCDOFF_INPUT_TIMEOUT);
632 #else
633         ret = vconf_get_int(VCONFKEY_CALL_STATE, &call_state);
634         if ((ret >= 0 && call_state != VCONFKEY_CALL_OFF) ||
635             (get_lock_screen_state() == VCONFKEY_IDLE_LOCK)) {
636                 _D("LOCK state, lcd is on directly");
637                 lcd_on_procedure();
638         }
639         reset_timeout(display_conf.lcdoff_timeout);
640 #endif
641         update_display_locktime(LOCK_SCREEN_INPUT_TIMEOUT);
642 }
643
644 int custom_lcdon(int timeout)
645 {
646         struct state *st;
647
648         if (timeout <= 0)
649                 return -EINVAL;
650
651         if (backlight_ops.get_lcd_power() != PM_LCD_POWER_ON)
652                 lcd_on_direct();
653
654         _I("custom lcd on %d ms", timeout);
655         if (set_custom_lcdon_timeout(timeout) == true)
656                 update_display_time();
657
658         /* state transition */
659         pm_old_state = pm_cur_state;
660         pm_cur_state = S_NORMAL;
661         st = &states[pm_cur_state];
662
663         /* enter action */
664         if (st->action) {
665                 st->action(st->timeout);
666         }
667
668         return 0;
669 }
670
671 static int proc_change_state(unsigned int cond, pid_t pid)
672 {
673         int next_state = 0;
674         struct state *st;
675         int i;
676
677         for (i = S_NORMAL; i < S_END; i++) {
678                 if ((cond >> (SHIFT_CHANGE_STATE + i)) & 0x1) {
679                         next_state = i;
680                         break;
681                 }
682         }
683         _I("Change State to %s (%d)", state_string[next_state], pid);
684
685         if (next_state == S_NORMAL) {
686                 if (backlight_ops.get_lcd_power() != PM_LCD_POWER_ON)
687                         lcd_on_direct();
688         } else if (next_state == S_LCDOFF) {
689                 if (backlight_ops.get_lcd_power() != PM_LCD_POWER_OFF)
690                         lcd_off_procedure();
691         }
692
693         if (next_state == S_LCDOFF)
694                 if (set_custom_lcdon_timeout(0) == true)
695                         update_display_time();
696
697         switch (next_state) {
698         case S_NORMAL:
699                 update_display_locktime(LOCK_SCREEN_CONTROL_TIMEOUT);
700                 /* fall through */
701         case S_LCDDIM:
702                 /* fall through */
703         case S_LCDOFF:
704                 /* state transition */
705                 pm_old_state = pm_cur_state;
706                 pm_cur_state = next_state;
707                 st = &states[pm_cur_state];
708
709                 /* pm state is updated to dim because of standby mode */
710                 if (standby_mode && (pm_cur_state == S_LCDOFF))
711                         set_setting_pmstate(S_LCDDIM);
712
713                 /* enter action */
714                 if (st->action) {
715                         st->action(st->timeout);
716                 }
717                 break;
718         case S_SLEEP:
719                 _I("Dangerous requests.");
720                 /* at first LCD_OFF and then goto sleep */
721                 /* state transition */
722                 pm_old_state = pm_cur_state;
723                 pm_cur_state = S_LCDOFF;
724                 st = &states[pm_cur_state];
725                 if (st->action) {
726                         st->action(TIMEOUT_NONE);
727                 }
728                 delete_condition(S_SLEEP);
729                 pm_old_state = pm_cur_state;
730                 pm_cur_state = S_SLEEP;
731                 st = &states[pm_cur_state];
732                 if (st->action) {
733                         st->action(TIMEOUT_NONE);
734                 }
735                 break;
736
737         default:
738                 return -1;
739         }
740
741         return 0;
742 }
743
744 static int standby_action(int timeout)
745 {
746         if (backlight_ops.standby() < 0) {
747                 _E("Fail to start standby mode!");
748                 return -EIO;
749         }
750         if (CHECK_OPS(keyfilter_ops, backlight_enable))
751                 keyfilter_ops->backlight_enable(false);
752         touch_ops.key_off();
753         touch_ops.screen_off();
754
755         set_standby_state(true);
756
757         _I("standby mode (only LCD OFF, But phone is working normal)");
758         reset_timeout(timeout);
759
760         return 0;
761 }
762
763 static void set_standby_mode(pid_t pid, int enable)
764 {
765         Eina_List *l = NULL;
766         Eina_List *l_next = NULL;
767         int *data = 0;
768
769         if (enable) {
770                 EINA_LIST_FOREACH(standby_mode_list, l, data)
771                         if (pid == (int) data) {
772                                 _E("%d already acquired standby mode", pid);
773                                 return;
774                         }
775                 EINA_LIST_APPEND(standby_mode_list, (void *)pid);
776                 _I("%d acquire standby mode", pid);
777                 if (standby_mode)
778                         return;
779                 standby_mode = true;
780                 basic_action = states[S_LCDOFF].action;
781                 states[S_LCDOFF].action = standby_action;
782                 trans_table[S_LCDOFF][EVENT_TIMEOUT] = S_LCDOFF;
783                 _I("Standby mode is enabled!");
784         } else {
785                 if (!standby_mode)
786                         return;
787                 EINA_LIST_FOREACH_SAFE(standby_mode_list, l, l_next, data)
788                         if (pid == (int) data) {
789                                 standby_mode_list = eina_list_remove_list(
790                                                     standby_mode_list, l);
791                                 _I("%d release standby mode", pid);
792                         }
793                 if (standby_mode_list != NULL)
794                         return;
795                 set_standby_state(false);
796                 standby_mode = false;
797                 if (basic_action != NULL) {
798                         states[S_LCDOFF].action = basic_action;
799                 }
800                 trans_table[S_LCDOFF][EVENT_TIMEOUT] = S_SLEEP;
801                 proc_change_state(S_NORMAL << (SHIFT_CHANGE_STATE + S_NORMAL),
802                     getpid());
803                 _I("Standby mode is disabled!");
804         }
805 }
806
807 /* update transition condition for application requrements */
808 static int proc_condition(PMMsg *data)
809 {
810         PmLockNode *tmp = NULL;
811         unsigned int val = data->cond;
812         pid_t pid = data->pid;
813         Ecore_Timer *cond_timeout_id = NULL;
814         bool holdkey_block = 0;
815         int val_timeout;
816
817         if (val == 0)
818                 return 0;
819         /* for debug */
820         char pname[PATH_MAX];
821         time_t now;
822
823         get_pname(pid, pname);
824         val_timeout = val >> SHIFT_CHANGE_TIMEOUT;
825         if (val_timeout & (CUSTOM_TIMEOUT_BIT | CUSTOM_HOLDKEY_BIT)) {
826                 if (data->timeout == 0 && data->timeout2 == 0) {
827                         _I("LCD timeout changed : default setting");
828                         get_lcd_timeout_from_settings();
829                         if (get_lock_screen_state() == VCONFKEY_IDLE_LOCK) {
830                                 _I("LOCK state : setting lock timeout!");
831                                 states[S_NORMAL].timeout = lock_screen_timeout;
832                         }
833                         custom_normal_timeout = custom_dim_timeout = 0;
834                         if (!(val_timeout & CUSTOM_HOLDKEY_BIT))
835                                 custom_change_pid = -1;
836                 } else {
837                         _I("LCD timeout changed : normal(%d s), dim(%d s)",
838                                 data->timeout, data->timeout2);
839                         custom_normal_timeout = SEC_TO_MSEC(data->timeout);
840                         states[S_NORMAL].timeout = custom_normal_timeout;
841                         custom_dim_timeout = SEC_TO_MSEC(data->timeout2);
842                         states[S_LCDDIM].timeout = custom_dim_timeout;
843                         custom_change_pid = pid;
844                 }
845
846                 if (val_timeout & CUSTOM_HOLDKEY_BIT) {
847                         custom_holdkey_block = true;
848                         custom_change_pid = pid;
849                         _I("hold key disabled !");
850                 } else {
851                         custom_holdkey_block = false;
852                         _I("hold key enabled !");
853                 }
854         }
855
856         if (val & MASK_DIM) {
857                 if (data->timeout > 0) {
858                         cond_timeout_id =
859                             ecore_timer_add(MSEC_TO_SEC(data->timeout),
860                                     (Ecore_Task_Cb)del_dim_cond, (void*)pid);
861                 }
862                 holdkey_block = GET_HOLDKEY_BLOCK_STATE(val);
863                 tmp = find_node(S_LCDDIM, pid);
864                 if (tmp == NULL) {
865                         add_node(S_LCDDIM, pid, cond_timeout_id, holdkey_block);
866                 } else {
867                         if (data->timeout > 0) {
868                                 time(&now);
869                                 tmp->time = now;
870                         }
871                         if (tmp->timeout_id) {
872                                 ecore_timer_del(tmp->timeout_id);
873                                 tmp->timeout_id = cond_timeout_id;
874                         }
875                         tmp->holdkey_block = holdkey_block;
876                 }
877                 /* for debug */
878                 _SD("[%s] locked by pid %d - process %s holdkeyblock %d\n",
879                     "S_NORMAL", pid, pname, holdkey_block);
880                 set_lock_time(pname, S_NORMAL);
881         }
882         if (val & MASK_OFF) {
883                 if (data->timeout > 0) {
884                         cond_timeout_id =
885                             ecore_timer_add(MSEC_TO_SEC(data->timeout),
886                                     (Ecore_Task_Cb)del_off_cond, (void*)pid);
887                 }
888                 holdkey_block = GET_HOLDKEY_BLOCK_STATE(val);
889                 tmp = find_node(S_LCDOFF, pid);
890                 if (tmp == NULL) {
891                         add_node(S_LCDOFF, pid, cond_timeout_id, holdkey_block);
892                 } else {
893                         if (data->timeout > 0) {
894                                 time(&now);
895                                 tmp->time = now;
896                         }
897                         if (tmp->timeout_id) {
898                                 ecore_timer_del(tmp->timeout_id);
899                                 tmp->timeout_id = cond_timeout_id;
900                         }
901                         tmp->holdkey_block = holdkey_block;
902                 }
903                 /* for debug */
904                 _SD("[%s] locked by pid %d - process %s holdkeyblock %d\n",
905                     "S_LCDDIM", pid, pname, holdkey_block);
906                 set_lock_time(pname, S_LCDDIM);
907         }
908         if (val & MASK_SLP) {
909                 /*
910                  * pm-state must be changed to LCDOFF,
911                  * to guarantee of LCDOFF-lock
912                  * when system resumes from suspend state.
913                  */
914                 if (pm_cur_state == S_SLEEP)
915                         proc_change_state(S_LCDOFF <<
916                             (SHIFT_CHANGE_STATE + S_LCDOFF), getpid());
917                 if (data->timeout > 0) {
918                         cond_timeout_id =
919                             ecore_timer_add(MSEC_TO_SEC(data->timeout),
920                                     (Ecore_Task_Cb)del_sleep_cond, (void*)pid);
921                 }
922                 if (GET_STANDBY_MODE_STATE(val))
923                         set_standby_mode(pid, true);
924                 tmp = find_node(S_SLEEP, pid);
925                 if (tmp == NULL) {
926                         add_node(S_SLEEP, pid, cond_timeout_id, 0);
927                 } else {
928                         if (data->timeout > 0) {
929                                 time(&now);
930                                 tmp->time = now;
931                         }
932                         if (tmp->timeout_id) {
933                                 ecore_timer_del(tmp->timeout_id);
934                                 tmp->timeout_id = cond_timeout_id;
935                         }
936                         tmp->holdkey_block = 0;
937                 }
938                 set_process_active(EINA_TRUE, pid);
939
940                 /* for debug */
941                 _SD("[%s] locked by pid %d - process %s\n", "S_LCDOFF", pid,
942                         pname);
943                 set_lock_time(pname, S_LCDOFF);
944         }
945
946         /* UNLOCK(GRANT) condition processing */
947         val = val >> SHIFT_UNLOCK;
948         if (val & MASK_DIM) {
949                 tmp = find_node(S_LCDDIM, pid);
950                 del_node(S_LCDDIM, tmp);
951                 _SD("[%s] unlocked by pid %d - process %s\n", "S_NORMAL",
952                         pid, pname);
953                 set_unlock_time(pname, S_NORMAL);
954         }
955         if (val & MASK_OFF) {
956                 tmp = find_node(S_LCDOFF, pid);
957                 del_node(S_LCDOFF, tmp);
958                 _SD("[%s] unlocked by pid %d - process %s\n", "S_LCDDIM",
959                         pid, pname);
960                 set_unlock_time(pname, S_LCDDIM);
961         }
962         if (val & MASK_SLP) {
963                 tmp = find_node(S_SLEEP, pid);
964                 del_node(S_SLEEP, tmp);
965                 if (standby_mode)
966                         set_standby_mode(pid, false);
967                 set_process_active(EINA_FALSE, pid);
968
969                 _SD("[%s] unlocked by pid %d - process %s\n", "S_LCDOFF",
970                         pid, pname);
971                 set_unlock_time(pname, S_LCDOFF);
972         }
973         val = val >> 8;
974         if (val != 0) {
975                 if ((val & 0x1)) {
976                         reset_timeout(states[pm_cur_state].timeout);
977                         _I("reset timeout (%d ms)",
978                             states[pm_cur_state].timeout);
979                 }
980         } else {
981                 /* guard time for suspend */
982                 if (pm_cur_state == S_LCDOFF) {
983                         reset_timeout(states[S_LCDOFF].timeout);
984                         _I("margin timeout (%d ms)",
985                             states[S_LCDOFF].timeout);
986                 }
987         }
988
989         if (timeout_src_id == 0)
990                 states[pm_cur_state].trans(EVENT_TIMEOUT);
991
992         return 0;
993 }
994
995 /* If some changed, return 1 */
996 int check_processes(enum state_t prohibit_state)
997 {
998         PmLockNode *t = cond_head[prohibit_state];
999         PmLockNode *tmp = NULL;
1000         int ret = 0;
1001
1002         while (t != NULL) {
1003                 if (t->pid < INTERNAL_LOCK_BASE && kill(t->pid, 0) == -1) {
1004                         _E("%d process does not exist, delete the REQ"
1005                                 " - prohibit state %d ",
1006                                 t->pid, prohibit_state);
1007                         if (t->pid == custom_change_pid) {
1008                                 get_lcd_timeout_from_settings();
1009                                 custom_normal_timeout = custom_dim_timeout = 0;
1010                                 custom_change_pid = -1;
1011                         }
1012                         if (standby_mode)
1013                                 set_standby_mode(t->pid, false);
1014                         tmp = t;
1015                         ret = 1;
1016                 }
1017                 t = t->next;
1018
1019                 if (tmp != NULL) {
1020                         del_node(prohibit_state, tmp);
1021                         tmp = NULL;
1022                 }
1023         }
1024
1025         return ret;
1026 }
1027
1028 int check_holdkey_block(enum state_t state)
1029 {
1030         PmLockNode *t = cond_head[state];
1031         int ret = 0;
1032
1033         _I("check holdkey block : state of %s", state_string[state]);
1034
1035         if (custom_holdkey_block == true) {
1036                 _I("custom hold key blocked by pid(%d)",
1037                         custom_change_pid);
1038                 return 1;
1039         }
1040
1041         while (t != NULL) {
1042                 if (t->holdkey_block == true) {
1043                         ret = 1;
1044                         _I("Hold key blocked by pid(%d)!", t->pid);
1045                         break;
1046                 }
1047                 t = t->next;
1048         }
1049
1050         return ret;
1051 }
1052
1053 int delete_condition(enum state_t state)
1054 {
1055         PmLockNode *t = cond_head[state];
1056         int ret = 0;
1057         PmLockNode *tmp = NULL;
1058         pid_t pid;
1059         char pname[PATH_MAX];
1060
1061         _I("delete condition : state of %s", state_string[state]);
1062
1063         while (t != NULL) {
1064                 if (t->timeout_id > 0) {
1065                         ecore_timer_del(t->timeout_id);
1066                         t->timeout_id = NULL;
1067                 }
1068                 tmp = t;
1069                 t = t->next;
1070                 pid = tmp->pid;
1071                 if (state == S_SLEEP)
1072                         set_process_active(EINA_FALSE, pid);
1073                 _I("delete node of pid(%d)", pid);
1074                 del_node(state, tmp);
1075                 get_pname(pid, pname);
1076                 set_unlock_time(pname, state-1);
1077         }
1078
1079         return 0;
1080 }
1081
1082 void update_lcdoff_source(int source)
1083 {
1084         if (standby_mode)
1085                 return;
1086
1087         switch(source) {
1088         case VCONFKEY_PM_LCDOFF_BY_TIMEOUT:
1089                 _I("LCD OFF by timeout");
1090                 break;
1091         case VCONFKEY_PM_LCDOFF_BY_POWERKEY:
1092                 _I("LCD OFF by powerkey");
1093                 break;
1094         default:
1095                 _E("Invalid value(%d)", source);
1096                 return;
1097         }
1098         vconf_set_int(VCONFKEY_PM_LCDOFF_SOURCE, source);
1099 }
1100
1101 #ifdef ENABLE_PM_LOG
1102
1103 typedef struct _pm_history {
1104         time_t time;
1105         enum pm_log_type log_type;
1106         int keycode;
1107 } pm_history;
1108
1109 static int max_history_count = MAX_LOG_COUNT;
1110 static pm_history pm_history_log[MAX_LOG_COUNT] = {0,};
1111 static int history_count = 0;
1112
1113 static const char history_string[PM_LOG_MAX][15] =
1114         {"PRESS", "LONG PRESS", "RELEASE", "LCD ON", "LCD ON FAIL",
1115         "LCD DIM", "LCD DIM FAIL", "LCD OFF", "LCD OFF FAIL", "SLEEP"};
1116
1117 void pm_history_init()
1118 {
1119         memset(pm_history_log, 0x0, sizeof(pm_history_log));
1120         history_count = 0;
1121         max_history_count = MAX_LOG_COUNT;
1122 }
1123
1124 void pm_history_save(enum pm_log_type log_type, int code)
1125 {
1126         time_t now;
1127
1128         time(&now);
1129         pm_history_log[history_count].time = now;
1130         pm_history_log[history_count].log_type = log_type;
1131         pm_history_log[history_count].keycode = code;
1132         history_count++;
1133
1134         if (history_count >= max_history_count)
1135                 history_count = 0;
1136 }
1137
1138 void pm_history_print(int fd, int count)
1139 {
1140         int start_index, index, i;
1141         char buf[255];
1142         char time_buf[30];
1143
1144         if (count <= 0 || count > max_history_count)
1145                 return;
1146
1147         start_index = (history_count - count + max_history_count)
1148                     % max_history_count;
1149
1150         for (i = 0; i < count; i++) {
1151                 index = (start_index + i) % max_history_count;
1152
1153                 if (pm_history_log[index].time == 0)
1154                         continue;
1155
1156                 if (pm_history_log[index].log_type < PM_LOG_MIN ||
1157                     pm_history_log[index].log_type >= PM_LOG_MAX)
1158                         continue;
1159                 ctime_r(&pm_history_log[index].time, time_buf);
1160                 snprintf(buf, sizeof(buf), "[%3d] %15s %3d %s",
1161                         index,
1162                         history_string[pm_history_log[index].log_type],
1163                         pm_history_log[index].keycode,
1164                         time_buf);
1165                 write(fd, buf, strlen(buf));
1166         }
1167 }
1168 #endif
1169
1170 /* logging indev_list for debug */
1171 void print_dev_list(int fd)
1172 {
1173         int i;
1174         unsigned int total = 0;
1175         indev *tmp;
1176
1177         total = eina_list_count(indev_list);
1178         _I("***** total list : %d *****", total);
1179         for (i = 0; i < total; i++) {
1180                 tmp = (indev*)eina_list_nth(indev_list, i);
1181                 _I("* %d | path:%s, fd:%d, dev_fd:%d",
1182                         i, tmp->dev_path, tmp->fd, tmp->dev_fd);
1183                 if (fd >= 0) {
1184                         char buf[255];
1185                         snprintf(buf, sizeof(buf), " %2d| path:%s, fd:%d, dev_fd:%d\n",
1186                                 i, tmp->dev_path, tmp->fd, tmp->dev_fd);
1187                         write(fd, buf, strlen(buf));
1188                 }
1189         }
1190         _I("***************************\n");
1191 }
1192
1193 void print_info(int fd)
1194 {
1195         int s_index = 0;
1196         char buf[255];
1197         int i = 1, ret;
1198         Eina_List *l = NULL;
1199         int *data = 0;
1200         char pname[PATH_MAX];
1201
1202         if (fd < 0)
1203                 return;
1204
1205         snprintf(buf, sizeof(buf),
1206                 "\n==========================================="
1207                 "===========================\n");
1208         write(fd, buf, strlen(buf));
1209         snprintf(buf, sizeof(buf),"Timeout Info: Run[%dms] Dim[%dms] Off[%dms]\n",
1210                  states[S_NORMAL].timeout,
1211                  states[S_LCDDIM].timeout, states[S_LCDOFF].timeout);
1212         write(fd, buf, strlen(buf));
1213
1214         snprintf(buf, sizeof(buf), "Tran. Locked : %s %s %s\n",
1215                  (trans_condition & MASK_DIM) ? state_string[S_NORMAL] : "-",
1216                  (trans_condition & MASK_OFF) ? state_string[S_LCDDIM] : "-",
1217                  (trans_condition & MASK_SLP) ? state_string[S_LCDOFF] : "-");
1218         write(fd, buf, strlen(buf));
1219
1220         snprintf(buf, sizeof(buf), "Current State: %s\n",
1221                 state_string[pm_cur_state]);
1222         write(fd, buf, strlen(buf));
1223
1224         snprintf(buf, sizeof(buf), "Current Lock Conditions: \n");
1225         write(fd, buf, strlen(buf));
1226
1227         for (s_index = S_NORMAL; s_index < S_END; s_index++) {
1228                 PmLockNode *t;
1229                 char time_buf[30];
1230                 t = cond_head[s_index];
1231
1232                 while (t != NULL) {
1233                         get_pname((pid_t)t->pid, pname);
1234                         ctime_r(&t->time, time_buf);
1235                         snprintf(buf, sizeof(buf),
1236                                  " %d: [%s] locked by pid %d %s %s",
1237                                  i++, state_string[s_index - 1], t->pid, pname, time_buf);
1238                         write(fd, buf, strlen(buf));
1239                         t = t->next;
1240                 }
1241         }
1242
1243         print_dev_list(fd);
1244
1245         if (standby_mode) {
1246                 snprintf(buf, sizeof(buf), "\n\nstandby mode is on\n");
1247                 write(fd, buf, strlen(buf));
1248
1249                 EINA_LIST_FOREACH(standby_mode_list, l, data) {
1250                         get_pname((pid_t)data, pname);
1251                         snprintf(buf, sizeof(buf),
1252                             "  standby mode acquired by pid %d"
1253                             " - process %s\n", data, pname);
1254                         write(fd, buf, strlen(buf));
1255                 }
1256         }
1257         print_lock_info_list(fd);
1258
1259 #ifdef ENABLE_PM_LOG
1260         pm_history_print(fd, 250);
1261 #endif
1262 }
1263
1264 void save_display_log(void)
1265 {
1266         int fd;
1267         char buf[255];
1268         time_t now_time;
1269         char time_buf[30];
1270
1271         _D("internal state is saved!");
1272
1273         time(&now_time);
1274         ctime_r(&now_time, time_buf);
1275
1276         fd = open(PM_STATE_LOG_FILE, O_CREAT | O_TRUNC | O_WRONLY, 0644);
1277         if (fd != -1) {
1278                 snprintf(buf, sizeof(buf),
1279                         "\npm_state_log now-time : %d(s) %s\n\n",
1280                         (int)now_time, time_buf);
1281                 write(fd, buf, strlen(buf));
1282
1283                 snprintf(buf, sizeof(buf), "pm_status_flag: %x\n", pm_status_flag);
1284                 write(fd, buf, strlen(buf));
1285
1286                 snprintf(buf, sizeof(buf), "screen lock status : %d\n",
1287                         get_lock_screen_state());
1288                 write(fd, buf, strlen(buf));
1289
1290                 print_info(fd);
1291                 close(fd);
1292         }
1293
1294         fd = open("/dev/console", O_WRONLY);
1295         if (fd != -1) {
1296                 print_info(fd);
1297                 close(fd);
1298         }
1299 }
1300
1301 /* SIGHUP signal handler
1302  * For debug... print info to syslog
1303  */
1304 static void sig_hup(int signo)
1305 {
1306         save_display_log();
1307 }
1308
1309 static void sig_usr(int signo)
1310 {
1311         pm_status_flag |= VCALL_FLAG;
1312 }
1313
1314 int check_lcdoff_direct(void)
1315 {
1316         int ret, lock, cradle;
1317
1318         if (standby_mode)
1319                 return false;
1320
1321         lock = get_lock_screen_state();
1322         if (lock != VCONFKEY_IDLE_LOCK && hallic_open)
1323                 return false;
1324
1325         if (hdmi_state)
1326                 return false;
1327
1328         ret = vconf_get_int(VCONFKEY_SYSMAN_CRADLE_STATUS, &cradle);
1329         if (ret >= 0 && cradle == DOCK_SOUND)
1330                 return false;
1331
1332         if (pm_old_state != S_NORMAL)
1333                 return false;
1334
1335         if (pm_cur_state != S_LCDDIM)
1336                 return false;
1337
1338         /*
1339          * goto lcd dim state when battery health is bad
1340          * and abnormal popup shows
1341          */
1342         if ((pm_status_flag & DIMSTAY_FLAG) &&
1343             (check_abnormal_popup() == HEALTH_BAD))
1344                 return false;
1345
1346         _D("Goto LCDOFF direct(%d,%d,%d)", lock, hdmi_state, cradle);
1347
1348         return true;
1349 }
1350
1351 int check_lcdoff_lock_state(void)
1352 {
1353         if (cond_head[S_SLEEP] != NULL)
1354                 return true;
1355
1356         return false;
1357 }
1358
1359 /*
1360  * default transition function
1361  *   1. call check
1362  *   2. transition
1363  *   3. call enter action function
1364  */
1365 static int default_trans(int evt)
1366 {
1367         struct state *st = &states[pm_cur_state];
1368         int next_state;
1369
1370         next_state = (enum state_t)trans_table[pm_cur_state][evt];
1371
1372         /* check conditions */
1373         while (st->check && !st->check(next_state)) {
1374                 /* There is a condition. */
1375                 if (standby_mode) {
1376                         _D("standby mode, goto next_state %s",
1377                             state_string[next_state]);
1378                         break;
1379                 }
1380                 _I("%s -> %s : check fail", state_string[pm_cur_state],
1381                        state_string[next_state]);
1382                 if (!check_processes(next_state)) {
1383                         /* this is valid condition - the application that sent the condition is running now. */
1384                         return -1;
1385                 }
1386         }
1387
1388         /* smart stay */
1389         if (display_info.face_detection &&
1390             (pm_status_flag & SMAST_FLAG) && hallic_open) {
1391                 if (display_info.face_detection(evt, pm_cur_state, next_state))
1392                         return 0;
1393         }
1394
1395         /* state transition */
1396         pm_old_state = pm_cur_state;
1397         pm_cur_state = next_state;
1398         st = &states[pm_cur_state];
1399
1400         /* enter action */
1401         if (st->action) {
1402                 if (pm_cur_state == S_LCDOFF)
1403                         update_lcdoff_source(VCONFKEY_PM_LCDOFF_BY_TIMEOUT);
1404
1405                 if (pm_cur_state == S_NORMAL || pm_cur_state == S_LCDOFF)
1406                         if (set_custom_lcdon_timeout(0) == true)
1407                                 update_display_time();
1408
1409                 if (check_lcdoff_direct() == true) {
1410                         /* enter next state directly */
1411                         states[pm_cur_state].trans(EVENT_TIMEOUT);
1412                 }
1413                 else {
1414                         st->action(st->timeout);
1415                 }
1416         }
1417
1418         return 0;
1419 }
1420
1421 static Eina_Bool lcd_on_expired(void *data)
1422 {
1423         int lock_state, ret;
1424
1425         if (lock_timeout_id)
1426                 lock_timeout_id = NULL;
1427
1428         /* check state of lock */
1429         ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
1430
1431         if (ret > 0 && lock_state == VCONFKEY_IDLE_LOCK)
1432                 return EINA_FALSE;
1433
1434         if (backlight_ops.get_lcd_power() == PM_LCD_POWER_ON)
1435                 return EINA_FALSE;
1436
1437         /* lock screen is not launched yet, but lcd is on */
1438         if (backlight_ops.get_lcd_power() != PM_LCD_POWER_ON)
1439                 lcd_on_procedure();
1440
1441         return EINA_FALSE;
1442 }
1443
1444 static inline void stop_lock_timer(void)
1445 {
1446         if (lock_timeout_id) {
1447                 ecore_timer_del(lock_timeout_id);
1448                 lock_timeout_id = NULL;
1449         }
1450 }
1451
1452 static void check_lock_screen(void)
1453 {
1454         int lock_setting, lock_state, app_state, ret;
1455
1456         stop_lock_timer();
1457
1458         ret = vconf_get_int(VCONFKEY_CALL_STATE, &app_state);
1459         if (ret >= 0 && app_state != VCONFKEY_CALL_OFF)
1460                 goto lcd_on;
1461
1462         /* check setting of lock screen is enabled. */
1463         ret = vconf_get_int(VCONFKEY_SETAPPL_SCREEN_LOCK_TYPE_INT,
1464             &lock_setting);
1465
1466         if (ret < 0 || lock_setting == SETTING_SCREEN_LOCK_TYPE_NONE)
1467                 goto lcd_on;
1468
1469         /* check state of lock */
1470         ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
1471
1472         if (ret < 0 || lock_state == VCONFKEY_IDLE_LOCK)
1473                 goto lcd_on;
1474
1475         /* Use time to check lock is done. */
1476         lock_timeout_id = ecore_timer_add(display_conf.lock_wait_time,
1477             (Ecore_Task_Cb)lcd_on_expired, (void*)NULL);
1478
1479         return;
1480
1481 lcd_on:
1482         if (backlight_ops.get_lcd_power() != PM_LCD_POWER_ON)
1483                 lcd_on_procedure();
1484 }
1485
1486 /* default enter action function */
1487 static int default_action(int timeout)
1488 {
1489         int ret;
1490         int wakeup_count = -1;
1491         char buf[NAME_MAX];
1492         char *pkgname = NULL;
1493         int i = 0;
1494         int lock_state = -1;
1495         int app_state = -1;
1496         time_t now;
1497         double diff;
1498         static time_t last_update_time = 0;
1499         static int last_timeout = 0;
1500         struct timeval now_tv;
1501
1502         if (status != DEVICE_OPS_STATUS_START) {
1503                 _E("display is not started!");
1504                 return -EINVAL;
1505         }
1506
1507         if (pm_cur_state != S_SLEEP) {
1508                 if (pm_cur_state == S_NORMAL &&
1509                     lcdon_tv.tv_sec != 0) {
1510                         gettimeofday(&now_tv, NULL);
1511                         timeout -= DIFF_TIMEVAL_MS(now_tv, lcdon_tv);
1512                         lcdon_tv.tv_sec = 0;
1513                 }
1514                 /* set timer with current state timeout */
1515                 reset_timeout(timeout);
1516
1517                 if (pm_cur_state == S_NORMAL) {
1518                         time(&last_update_time);
1519                         last_timeout = timeout;
1520                 } else {
1521                         _I("timout set: %s state %d ms",
1522                             state_string[pm_cur_state], timeout);
1523                 }
1524         }
1525
1526         if (pm_cur_state != pm_old_state && pm_cur_state != S_SLEEP) {
1527                 if (power_ops.get_power_lock_support())
1528                         power_ops.power_lock();
1529                 if (pm_cur_state != S_LCDOFF)
1530                         set_setting_pmstate(pm_cur_state);
1531                 device_notify(DEVICE_NOTIFIER_LCD, (void *)pm_cur_state);
1532         }
1533
1534         if (pm_old_state == S_NORMAL && pm_cur_state != S_NORMAL) {
1535                 time(&now);
1536                 diff = difftime(now, last_update_time);
1537                 _I("S_NORMAL is changed to %s [%d ms, %.0f s]",
1538                     state_string[pm_cur_state], last_timeout, diff);
1539         }
1540
1541         switch (pm_cur_state) {
1542         case S_NORMAL:
1543                 /*
1544                  * normal state : backlight on and restore
1545                  * the previous brightness
1546                  */
1547                 if (pm_old_state == S_LCDOFF || pm_old_state == S_SLEEP) {
1548                         if (pre_suspend_flag == true) {
1549                                 power_ops.post_resume();
1550                                 pre_suspend_flag = false;
1551                         }
1552                         check_lock_screen();
1553                 } else if (pm_old_state == S_LCDDIM)
1554                         backlight_ops.update();
1555                 set_standby_state(false);
1556                 break;
1557
1558         case S_LCDDIM:
1559                 if (pm_old_state == S_NORMAL &&
1560                     backlight_ops.get_custom_status())
1561                         backlight_ops.save_custom_brightness();
1562                 /* lcd dim state : dim the brightness */
1563                 backlight_ops.dim();
1564                 if (pm_old_state == S_LCDOFF || pm_old_state == S_SLEEP) {
1565                         broadcast_lcd_on();
1566                         backlight_ops.on();
1567                         touch_ops.screen_on();
1568                         touch_ops.key_on();
1569                 }
1570                 set_standby_state(false);
1571                 break;
1572
1573         case S_LCDOFF:
1574                 if (pm_old_state != S_SLEEP && pm_old_state != S_LCDOFF) {
1575                         stop_lock_timer();
1576                         /* lcd off state : turn off the backlight */
1577                         if (backlight_ops.get_lcd_power() != PM_LCD_POWER_OFF)
1578                                 lcd_off_procedure();
1579                         set_setting_pmstate(pm_cur_state);
1580
1581                         if (pre_suspend_flag == false) {
1582                                 pre_suspend_flag = true;
1583                                 power_ops.pre_suspend();
1584                         }
1585                 }
1586
1587                 if (backlight_ops.get_lcd_power() != PM_LCD_POWER_OFF)
1588                         lcd_off_procedure();
1589                 break;
1590
1591         case S_SLEEP:
1592                 if (pm_old_state != S_SLEEP && pm_old_state != S_LCDOFF)
1593                         stop_lock_timer();
1594
1595                 if (backlight_ops.get_lcd_power() != PM_LCD_POWER_OFF)
1596                         lcd_off_procedure();
1597
1598                 if (!power_ops.get_power_lock_support()) {
1599                         /* sleep state : set system mode to SUSPEND */
1600                         if (device_get_property(DEVICE_TYPE_POWER,
1601                             PROP_POWER_WAKEUP_COUNT, &wakeup_count) < 0)
1602                                 _E("wakeup count read error");
1603
1604                         if (wakeup_count < 0) {
1605                                 _I("Wakup Event! Can not enter suspend mode.");
1606                                 goto go_lcd_off;
1607                         }
1608
1609                         if (device_set_property(DEVICE_TYPE_POWER,
1610                             PROP_POWER_WAKEUP_COUNT, wakeup_count) < 0) {
1611                                 _E("wakeup count write error");
1612                                 goto go_lcd_off;
1613                         }
1614                 }
1615                 goto go_suspend;
1616         }
1617
1618         return 0;
1619
1620 go_suspend:
1621 #ifdef ENABLE_PM_LOG
1622         pm_history_save(PM_LOG_SLEEP, pm_cur_state);
1623 #endif
1624         if (power_ops.get_power_lock_support()) {
1625                 if (power_ops.power_unlock() < 0)
1626                         _E("power unlock state error!");
1627         } else {
1628                 power_ops.suspend();
1629                 _I("system wakeup!!");
1630                 system_wakeup_flag = true;
1631                 /* Resume !! */
1632                 if (power_ops.check_wakeup_src() == EVENT_DEVICE)
1633                         /* system waked up by devices */
1634                         states[pm_cur_state].trans(EVENT_DEVICE);
1635                 else
1636                         /* system waked up by user input */
1637                         states[pm_cur_state].trans(EVENT_INPUT);
1638         }
1639         return 0;
1640
1641 go_lcd_off:
1642         if (!power_ops.get_power_lock_support()) {
1643                 /* Resume !! */
1644                 states[pm_cur_state].trans(EVENT_DEVICE);
1645         }
1646         return 0;
1647 }
1648
1649 /*
1650  * default check function
1651  *   return
1652  *    0 : can't transit, others : transitable
1653  */
1654 static int default_check(int next)
1655 {
1656         int trans_cond = trans_condition & MASK_BIT;
1657         int lock_state = -1;
1658         int app_state = -1;
1659
1660         vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
1661         if (lock_state==VCONFKEY_IDLE_LOCK && next != S_SLEEP) {
1662                 while(0) {
1663                         vconf_get_int(VCONFKEY_CALL_STATE, &app_state);
1664                         if (app_state != VCONFKEY_CALL_OFF)
1665                                 break;
1666                         vconf_get_bool(VCONFKEY_ALARM_RINGING, &app_state);
1667                         if (app_state == EINA_TRUE)
1668                                 break;
1669                         _I("default_check:LOCK STATE, it's transitable");
1670                         return 1;
1671                 }
1672         }
1673
1674         switch (next) {
1675         case S_LCDDIM:
1676                 trans_cond = trans_cond & MASK_DIM;
1677                 break;
1678         case S_LCDOFF:
1679                 trans_cond = trans_cond & MASK_OFF;
1680                 break;
1681         case S_SLEEP:
1682                 trans_cond = trans_cond & MASK_SLP;
1683                 break;
1684         default:                /* S_NORMAL is exceptional */
1685                 trans_cond = 0;
1686                 break;
1687         }
1688
1689         if (trans_cond != 0) {
1690                 print_node(next);
1691                 return 0;
1692         }
1693
1694         return 1;               /* transitable */
1695 }
1696
1697 static void default_saving_mode(int onoff)
1698 {
1699         if (onoff) {
1700                 pm_status_flag |= PWRSV_FLAG;
1701                 /* off hbm state, it's power saving mode */
1702                 if (hbm_get_state != NULL &&
1703                     hbm_get_state() == true)
1704                         hbm_set_state_with_timeout(false, 0);
1705         } else {
1706                 pm_status_flag &= ~PWRSV_FLAG;
1707         }
1708         if (pm_cur_state == S_NORMAL)
1709                 backlight_ops.update();
1710 }
1711
1712 static int poll_callback(int condition, PMMsg *data)
1713 {
1714         static time_t last_t;
1715         time_t now;
1716
1717         if (status != DEVICE_OPS_STATUS_START) {
1718                 _E("display logic is not started!");
1719                 return -ECANCELED;
1720         }
1721
1722         if (condition == INPUT_POLL_EVENT) {
1723                 if (pm_cur_state == S_LCDOFF || pm_cur_state == S_SLEEP)
1724                         _I("Power key input");
1725                 time(&now);
1726                 if (last_t != now) {
1727                         states[pm_cur_state].trans(EVENT_INPUT);
1728                         last_t = now;
1729                 }
1730         } else if (condition == PM_CONTROL_EVENT) {
1731                 if (data->cond & MASK_BIT
1732                         || ((data->cond >> SHIFT_UNLOCK) & MASK_BIT)
1733                         || (data->cond >> SHIFT_CHANGE_TIMEOUT))
1734                         proc_condition(data);
1735
1736                 if (data->cond & CHANGE_STATE_BIT)
1737                         proc_change_state(data->cond, data->pid);
1738         }
1739
1740         return 0;
1741 }
1742
1743 static int update_setting(int key_idx, int val)
1744 {
1745         char buf[PATH_MAX];
1746         int ret = -1;
1747         int run_timeout = -1;
1748         int power_saving_stat = -1;
1749         int power_saving_display_stat = -1;
1750
1751         switch (key_idx) {
1752         case SETTING_TO_NORMAL:
1753                 ret = get_run_timeout(&run_timeout);
1754                 if (ret < 0 || run_timeout <= 0) {
1755                         _E("Can not get run timeout. set default %.2f ms",
1756                             DEFAULT_NORMAL_TIMEOUT);
1757                         run_timeout = DEFAULT_NORMAL_TIMEOUT;
1758                 }
1759                 states[S_NORMAL].timeout = run_timeout;
1760                 states[pm_cur_state].trans(EVENT_INPUT);
1761                 break;
1762         case SETTING_HALLIC_OPEN:
1763                 hallic_open = val;
1764                 update_display_time();
1765                 if (pm_cur_state == S_NORMAL || pm_cur_state == S_LCDDIM)
1766                         states[pm_cur_state].trans(EVENT_INPUT);
1767                 else if (pm_cur_state == S_SLEEP && hallic_open)
1768                         proc_change_state(S_LCDOFF <<
1769                             (SHIFT_CHANGE_STATE + S_LCDOFF), getpid());
1770                 break;
1771         case SETTING_LOW_BATT:
1772                 if (low_battery_state(val)) {
1773                         if (!(pm_status_flag & CHRGR_FLAG))
1774                                 power_saving_func(true);
1775                         pm_status_flag |= LOWBT_FLAG;
1776                 } else {
1777                         if (pm_status_flag & PWRSV_FLAG)
1778                                 power_saving_func(false);
1779                         pm_status_flag &= ~LOWBT_FLAG;
1780                         pm_status_flag &= ~BRTCH_FLAG;
1781                         vconf_set_bool(VCONFKEY_PM_BRIGHTNESS_CHANGED_IN_LPM,
1782                             false);
1783                 }
1784                 break;
1785         case SETTING_CHARGING:
1786                 if (val) {
1787                         if (pm_status_flag & LOWBT_FLAG) {
1788                                 power_saving_func(false);
1789                                 pm_status_flag &= ~LOWBT_FLAG;
1790                         }
1791                         pm_status_flag |= CHRGR_FLAG;
1792                 } else {
1793                         int bat_state = VCONFKEY_SYSMAN_BAT_NORMAL;
1794                         vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW,
1795                                 &bat_state);
1796                         if (low_battery_state(bat_state)) {
1797                                 power_saving_func(true);
1798                                 pm_status_flag |= LOWBT_FLAG;
1799                         }
1800                         pm_status_flag &= ~CHRGR_FLAG;
1801                 }
1802                 break;
1803         case SETTING_BRT_LEVEL:
1804                 if (pm_status_flag & PWRSV_FLAG) {
1805                         pm_status_flag |= BRTCH_FLAG;
1806                         vconf_set_bool(VCONFKEY_PM_BRIGHTNESS_CHANGED_IN_LPM,
1807                             true);
1808                         _I("brightness changed in low battery,"
1809                                 "escape dim state");
1810                 }
1811                 backlight_ops.set_default_brt(val);
1812                 snprintf(buf, sizeof(buf), "%d", val);
1813                 _D("Brightness set in bl : %d",val);
1814                 launch_evenif_exist(SET_BRIGHTNESS_IN_BOOTLOADER, buf);
1815                 break;
1816         case SETTING_LOCK_SCREEN:
1817                 set_lock_screen_state(val);
1818                 if (val == VCONFKEY_IDLE_UNLOCK) {
1819                         if (CHECK_OPS(keyfilter_ops, backlight_enable))
1820                                 keyfilter_ops->backlight_enable(false);
1821                 }
1822
1823                 /* LCD on if lock screen show before waiting time */
1824                 if (pm_cur_state == S_NORMAL &&
1825                     val == VCONFKEY_IDLE_LOCK &&
1826                     backlight_ops.get_lcd_power() != PM_LCD_POWER_ON)
1827                         lcd_on_procedure();
1828                 stop_lock_timer();
1829                 update_display_time();
1830                 if (pm_cur_state == S_NORMAL) {
1831                         states[pm_cur_state].trans(EVENT_INPUT);
1832                 }
1833                 break;
1834         case SETTING_LOCK_SCREEN_BG:
1835                 set_lock_screen_bg_state(val);
1836                 update_display_time();
1837                 if (pm_cur_state == S_NORMAL) {
1838                         states[pm_cur_state].trans(EVENT_INPUT);
1839                 }
1840                 break;
1841         case SETTING_POWER_SAVING:
1842                 if (val == 1)
1843                         vconf_get_bool(VCONFKEY_SETAPPL_PWRSV_CUSTMODE_DISPLAY,
1844                                  &power_saving_display_stat);
1845                 if (power_saving_display_stat != 1)
1846                         power_saving_display_stat = 0;
1847                 if (device_set_property(DEVICE_TYPE_DISPLAY, PROP_DISPLAY_FRAME_RATE,
1848                     power_saving_display_stat) < 0) {
1849                         _E("Fail to set display frame rate!");
1850                 }
1851                 backlight_ops.update();
1852                 break;
1853         case SETTING_POWER_SAVING_DISPLAY:
1854                 vconf_get_bool(VCONFKEY_SETAPPL_PWRSV_SYSMODE_STATUS,
1855                         &power_saving_stat);
1856                 if (power_saving_stat == 1) {
1857                         if (val == 1)
1858                                 power_saving_display_stat = 1;
1859                         else
1860                                 power_saving_display_stat = 0;
1861                         if (device_set_property(DEVICE_TYPE_DISPLAY,
1862                             PROP_DISPLAY_FRAME_RATE, power_saving_display_stat) < 0) {
1863                                 _E("Fail to set display frame rate!");
1864                         }
1865                         backlight_ops.update();
1866                 }
1867                 break;
1868         case SETTING_SMART_STAY:
1869                 if (!val) {
1870                         pm_status_flag &= ~SMAST_FLAG;
1871                         _I("Smart Stay Feature off");
1872                 } else {
1873                         pm_status_flag |= SMAST_FLAG;
1874                         _I("Smart Stay Feature on");
1875                 }
1876                 break;
1877         case SETTING_POWEROFF:
1878                 switch (val) {
1879                 case VCONFKEY_SYSMAN_POWER_OFF_NONE:
1880                 case VCONFKEY_SYSMAN_POWER_OFF_POPUP:
1881                         pm_status_flag &= ~PWROFF_FLAG;
1882                         break;
1883                 case VCONFKEY_SYSMAN_POWER_OFF_DIRECT:
1884                 case VCONFKEY_SYSMAN_POWER_OFF_RESTART:
1885                         pm_status_flag |= PWROFF_FLAG;
1886                         break;
1887                 }
1888                 break;
1889         case SETTING_BOOT_POWER_ON_STATUS:
1890                 /*
1891                  * Unlock lcd off after booting is done.
1892                  * deviced guarantees all booting script is executing.
1893                  * Last script of booting unlocks this suspend blocking state.
1894                  */
1895                 if (val == VCONFKEY_DEVICED_BOOT_POWER_ON_DONE) {
1896                         _I("booting done");
1897                         pm_unlock_internal(INTERNAL_LOCK_BOOTING, LCD_OFF, PM_SLEEP_MARGIN);
1898                 }
1899                 break;
1900         case SETTING_POWER_CUSTOM_BRIGHTNESS:
1901                 if (val == VCONFKEY_PM_CUSTOM_BRIGHTNESS_ON)
1902                         backlight_ops.set_custom_status(true);
1903                 else
1904                         backlight_ops.set_custom_status(false);
1905                 break;
1906         case SETTING_ACCESSIBILITY_TTS:
1907                 tts_state = val;
1908                 _I("TTS is %s", (val ? "ON" : "OFF"));
1909                 break;
1910
1911         default:
1912                 return -1;
1913         }
1914         return 0;
1915 }
1916
1917 static void check_seed_status(void)
1918 {
1919         int ret = -1;
1920         int tmp = 0;
1921         int bat_state = VCONFKEY_SYSMAN_BAT_NORMAL;
1922         int max_brt = 0;
1923         int brt = 0;
1924         int lock_state = -1;
1925         int power_saving_stat = -1;
1926         int power_saving_display_stat = -1;
1927         int smart_stay_on = 0;
1928
1929         /* Charging check */
1930         if ((get_charging_status(&tmp) == 0) && (tmp > 0)) {
1931                 pm_status_flag |= CHRGR_FLAG;
1932         }
1933
1934         ret = get_setting_brightness(&tmp);
1935         if (ret != 0 || (tmp < PM_MIN_BRIGHTNESS || tmp > PM_MAX_BRIGHTNESS)) {
1936                 _I("fail to read vconf value for brightness");
1937                 brt = PM_DEFAULT_BRIGHTNESS;
1938                 if (tmp < PM_MIN_BRIGHTNESS || tmp > PM_MAX_BRIGHTNESS)
1939                         vconf_set_int(VCONFKEY_SETAPPL_LCD_BRIGHTNESS, brt);
1940                 tmp = brt;
1941         }
1942         _I("Set brightness from Setting App. %d", tmp);
1943         backlight_ops.set_default_brt(tmp);
1944
1945         vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, &bat_state);
1946         if (low_battery_state(bat_state)) {
1947                 if (!(pm_status_flag & CHRGR_FLAG)) {
1948                         power_saving_func(true);
1949                         pm_status_flag |= LOWBT_FLAG;
1950                 }
1951         }
1952         backlight_ops.update();
1953         backlight_ops.on();
1954         touch_ops.screen_on();
1955         touch_ops.key_on();
1956
1957         /* lock screen check */
1958         ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
1959         set_lock_screen_state(lock_state);
1960         if (lock_state == VCONFKEY_IDLE_LOCK) {
1961                 states[S_NORMAL].timeout = lock_screen_timeout;
1962                 _I("LCD NORMAL timeout is set by %d ms"
1963                         " for lock screen", lock_screen_timeout);
1964         }
1965
1966         /* power saving display stat */
1967         vconf_get_bool(VCONFKEY_SETAPPL_PWRSV_SYSMODE_STATUS,
1968             &power_saving_stat);
1969         if (power_saving_stat <= 0) {
1970                 power_saving_display_stat = 0;
1971         } else {
1972                 vconf_get_bool(VCONFKEY_SETAPPL_PWRSV_CUSTMODE_DISPLAY,
1973                     &power_saving_display_stat);
1974         }
1975         if (power_saving_display_stat < 0) {
1976                 _E("failed to read power saving display stat!");
1977         } else {
1978                 _I("power saving display stat : %d",
1979                     power_saving_display_stat);
1980         }
1981
1982         /* Smart stay status */
1983         vconf_get_int(VCONFKEY_SETAPPL_SMARTSCREEN_SMARTSTAY_STATUS, &smart_stay_on);
1984         if (!smart_stay_on) {
1985                 _I("Smart Stay Feature off");
1986         } else {
1987                 _I("Smart Stay Feature on");
1988                 pm_status_flag |= SMAST_FLAG;
1989         }
1990
1991         /* TTS state */
1992         ret = vconf_get_bool(VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, &tts_state);
1993         if (ret < 0)
1994                 _E("Failed to get TTS setting! (%d)", ret);
1995         _I("TTS is %s", (tts_state ? "ON" : "OFF"));
1996
1997         return;
1998 }
1999
2000 enum {
2001         INIT_SETTING = 0,
2002         INIT_INTERFACE,
2003         INIT_POLL,
2004         INIT_FIFO,
2005         INIT_DBUS,
2006         INIT_END
2007 };
2008
2009 static const char *errMSG[INIT_END] = {
2010         [INIT_SETTING] = "setting init error",
2011         [INIT_INTERFACE] = "lowlevel interface(sysfs or others) init error",
2012         [INIT_POLL] = "input devices poll init error",
2013         [INIT_FIFO] = "FIFO poll init error",
2014         [INIT_DBUS] = "d-bus init error",
2015 };
2016
2017 static int input_action(char* input_act, char* input_path)
2018 {
2019         int ret = -EINVAL;
2020         Eina_List *list_node = NULL;
2021         Eina_List *l = NULL;
2022         Eina_List *l_next = NULL;
2023         indev *data = NULL;
2024         PmLockNode *tmp = NULL;
2025
2026         if (!strcmp("add", input_act)) {
2027                 _I("add input path : %s", input_path);
2028                 ret = init_pm_poll_input(poll_callback, input_path);
2029         } else if (!strcmp("remove", input_act)) {
2030                 EINA_LIST_FOREACH_SAFE(indev_list, l, l_next, data)
2031                         if(!strcmp(input_path, data->dev_path)) {
2032                                 _I("remove %s", input_path);
2033                                 ecore_main_fd_handler_del(data->dev_fd);
2034                                 close(data->fd);
2035                                 free(data->dev_path);
2036                                 free(data);
2037                                 indev_list = eina_list_remove_list(indev_list, l);
2038                         }
2039                 ret = 0;
2040         } else if (!strcmp("change", input_act)) {
2041                 if (!strcmp("ESD", input_path)) {
2042                         _I("ESD on");
2043                         if (pm_cur_state == S_NORMAL) {
2044                                 backlight_ops.off();
2045                                 backlight_ops.on();
2046                         } else if (pm_cur_state == S_LCDDIM) {
2047                                 backlight_ops.off();
2048                                 backlight_ops.dim();
2049                         }
2050                         ret = 0;
2051                 }
2052         }
2053         return ret;
2054 }
2055
2056 int set_lcd_timeout(int on, int dim, int holdkey_block, char *name)
2057 {
2058         if (on == 0 && dim == 0) {
2059                 _I("LCD timeout changed : default setting");
2060                 custom_normal_timeout = custom_dim_timeout = 0;
2061         } else if (on < 0 || dim < 0) {
2062                 _E("fail to set value (%d,%d)", on, dim);
2063                 return -EINVAL;
2064         } else {
2065                 _I("LCD timeout changed : on(%ds), dim(%ds)", on, dim);
2066                 custom_normal_timeout = SEC_TO_MSEC(on);
2067                 custom_dim_timeout = SEC_TO_MSEC(dim);
2068         }
2069         /* Apply new backlight time */
2070         update_display_time();
2071
2072         if (holdkey_block) {
2073                 custom_holdkey_block = true;
2074                 _I("hold key disabled !");
2075         } else {
2076                 custom_holdkey_block = false;
2077                 _I("hold key enabled !");
2078         }
2079
2080         if (custom_change_name) {
2081                 free(custom_change_name);
2082                 custom_change_name = 0;
2083         }
2084
2085         if (custom_normal_timeout == 0 &&
2086             custom_dim_timeout == 0 &&
2087             !holdkey_block)
2088                 return 0;
2089
2090         custom_change_name = strndup(name, strlen(name));
2091         if (!custom_change_name) {
2092                 _E("Malloc falied!");
2093                 custom_normal_timeout = custom_dim_timeout = 0;
2094                 custom_holdkey_block = false;
2095                 return -ENOMEM;
2096         }
2097
2098         return 0;
2099 }
2100
2101 int reset_lcd_timeout(char *name, enum watch_id id)
2102 {
2103         if (!name)
2104                 return -EINVAL;
2105
2106         if (!custom_change_name)
2107                 return -EINVAL;
2108
2109         if (strcmp(name, custom_change_name))
2110                 return -EINVAL;
2111
2112         _I("reset lcd timeout %s: set default timeout", name);
2113
2114         free(custom_change_name);
2115         custom_change_name = 0;
2116         custom_normal_timeout = custom_dim_timeout = 0;
2117         custom_holdkey_block = false;
2118
2119         update_display_time();
2120         if (pm_cur_state == S_NORMAL) {
2121                 states[pm_cur_state].trans(EVENT_INPUT);
2122         }
2123
2124         return 0;
2125 }
2126
2127 int get_hdmi_state(void)
2128 {
2129         return hdmi_state;
2130 }
2131
2132 static int hdmi_changed(void *data)
2133 {
2134         hdmi_state = (int)data;
2135
2136         return 0;
2137 }
2138
2139 static int hall_ic_open(void *data)
2140 {
2141         int open = (int)data;
2142
2143         update_pm_setting(SETTING_HALLIC_OPEN, open);
2144
2145         return 0;
2146 }
2147
2148 static int input_device_add(void *data)
2149 {
2150         char *path = (char *)data;
2151
2152         if (!path)
2153                 return -EINVAL;
2154
2155         input_action(UDEV_ADD, path);
2156
2157         return 0;
2158 }
2159
2160 static int input_device_remove(void *data)
2161 {
2162         char *path = (char *)data;
2163
2164         if (!path)
2165                 return -EINVAL;
2166
2167         input_action(UDEV_REMOVE, path);
2168
2169         return 0;
2170 }
2171
2172 static int booting_done(void *data)
2173 {
2174         static bool done = false;
2175
2176         if (done)
2177                 return 0;
2178
2179         _I("booting done, unlock LCD_OFF");
2180         pm_unlock_internal(INTERNAL_LOCK_BOOTING, LCD_OFF, PM_SLEEP_MARGIN);
2181         done = true;
2182
2183         return 0;
2184 }
2185
2186 static int lcd_esd(void *data)
2187 {
2188         char *path = data;
2189
2190         if (!path)
2191                 return -EINVAL;
2192
2193         input_action(UDEV_CHANGE, path);
2194
2195         return 0;
2196 }
2197
2198 static int battery_health_changed(void *data)
2199 {
2200         int health = (int)data;
2201
2202         if (health == HEALTH_GOOD) {
2203                 _D("battery health good");
2204                 pm_status_flag &= ~DIMSTAY_FLAG;
2205
2206         } else if (health == HEALTH_BAD) {
2207                 _D("battery health bad");
2208                 pm_status_flag |= DIMSTAY_FLAG;
2209         }
2210
2211         return 0;
2212 }
2213
2214 static int display_load_config(struct parse_result *result, void *user_data)
2215 {
2216         struct display_config *c = user_data;
2217
2218         _D("%s,%s,%s", result->section, result->name, result->value);
2219
2220         if (!c)
2221                 return -EINVAL;
2222
2223         if (!MATCH(result->section, "Display"))
2224                 return -EINVAL;
2225
2226         if (MATCH(result->name, "LockScreenWaitingTime")) {
2227                 SET_CONF(c->lock_wait_time, atof(result->value));
2228                 _D("lock wait time is %.3f", c->lock_wait_time);
2229         } else if (MATCH(result->name, "LongPressInterval")) {
2230                 SET_CONF(c->longpress_interval, atof(result->value));
2231                 _D("long press interval is %.3f", c->longpress_interval);
2232         } else if (MATCH(result->name, "LightSensorSamplingInterval")) {
2233                 SET_CONF(c->lightsensor_interval, atof(result->value));
2234                 _D("lightsensor interval is %.3f", c->lightsensor_interval);
2235         } else if (MATCH(result->name, "LCDOffTimeout")) {
2236                 SET_CONF(c->lcdoff_timeout, atoi(result->value));
2237                 _D("lcdoff timeout is %d ms", c->lcdoff_timeout);
2238         } else if (MATCH(result->name, "BrightnessChangeStep")) {
2239                 SET_CONF(c->brightness_change_step, atoi(result->value));
2240                 _D("brightness change step is %d", c->brightness_change_step);
2241         } else if (MATCH(result->name, "HBMLuxThreshold")) {
2242                 SET_CONF(c->hbm_lux_threshold, atoi(result->value));
2243                 _D("HBM lux threshold is %d", c->hbm_lux_threshold);
2244         } else if (MATCH(result->name, "LCDAlwaysOn")) {
2245                 c->lcd_always_on = (MATCH(result->value, "yes") ? 1 : 0);
2246                 _D("LCD always on is %d", c->lcd_always_on);
2247         } else if (MATCH(result->name, "ChangedFrameRateAllowed")) {
2248                 if (strstr(result->value, "setting")) {
2249                         c->framerate_app[REFRESH_SETTING] = 1;
2250                         _D("framerate app is Setting");
2251                 }
2252                 if (strstr(result->value, "all")) {
2253                         memset(c->framerate_app, 1, sizeof(c->framerate_app));
2254                         _D("framerate app is All");
2255                 }
2256         } else if (MATCH(result->name, "ControlDisplay")) {
2257                 c->control_display = (MATCH(result->value, "yes") ? 1 : 0);
2258                 _D("ControlDisplay is %d", c->control_display);
2259         } else if (MATCH(result->name, "PowerKeyDoublePressSupport")) {
2260                 c->powerkey_doublepress = (MATCH(result->value, "yes") ? 1 : 0);
2261                 _D("PowerKeyDoublePressSupport is %d", c->powerkey_doublepress);
2262         } else if (MATCH(result->name, "UseALPM")) {
2263                 c->alpm_on = (MATCH(result->value, "yes") ? 1 : 0);
2264                 _D("UseALPM is %d", c->alpm_on);
2265         }
2266
2267         return 0;
2268 }
2269
2270 /**
2271  * Power manager Main
2272  *
2273  */
2274 static void display_init(void *data)
2275 {
2276         int ret, i;
2277         unsigned int flags = (WITHOUT_STARTNOTI | FLAG_X_DPMS);
2278         int timeout = 0;
2279
2280         _I("Start power manager");
2281
2282         signal(SIGHUP, sig_hup);
2283
2284         power_saving_func = default_saving_mode;
2285         /* noti init for new input device like bt mouse */
2286         indev_list = NULL;
2287
2288         /* load configutation */
2289         ret = config_parse(DISPLAY_CONF_FILE, display_load_config, &display_conf);
2290         if (ret < 0)
2291                 _W("Failed to load %s, %s Use default value!",
2292                     DISPLAY_CONF_FILE, ret);
2293
2294         register_notifier(DEVICE_NOTIFIER_HALLIC_OPEN, hall_ic_open);
2295         register_notifier(DEVICE_NOTIFIER_INPUT_ADD, input_device_add);
2296         register_notifier(DEVICE_NOTIFIER_INPUT_REMOVE, input_device_remove);
2297         register_notifier(DEVICE_NOTIFIER_BOOTING_DONE, booting_done);
2298         register_notifier(DEVICE_NOTIFIER_LCD_ESD, lcd_esd);
2299         register_notifier(DEVICE_NOTIFIER_HDMI, hdmi_changed);
2300         register_notifier(DEVICE_NOTIFIER_BATTERY_HEALTH, battery_health_changed);
2301
2302         for (i = INIT_SETTING; i < INIT_END; i++) {
2303                 switch (i) {
2304                 case INIT_SETTING:
2305                         ret = init_setting(update_setting);
2306                         break;
2307                 case INIT_INTERFACE:
2308                         get_lcd_timeout_from_settings();
2309                         ret = init_sysfs(flags);
2310                         break;
2311                 case INIT_POLL:
2312                         _I("poll init");
2313                         ret = init_pm_poll(poll_callback);
2314                         break;
2315                 case INIT_DBUS:
2316                         _I("dbus init");
2317                         ret = init_pm_dbus();
2318                         break;
2319                 }
2320                 if (ret != 0) {
2321                         _E("%s", errMSG[i]);
2322                         break;
2323                 }
2324         }
2325
2326         if (i == INIT_END) {
2327                 display_ops_init(NULL);
2328 #ifdef ENABLE_PM_LOG
2329                 pm_history_init();
2330 #endif
2331                 check_seed_status();
2332
2333                 if (display_conf.lcd_always_on) {
2334                         _D("LCD always on!");
2335                         trans_table[S_NORMAL][EVENT_TIMEOUT] = S_NORMAL;
2336                 }
2337
2338                 if (flags & WITHOUT_STARTNOTI) {        /* start without noti */
2339                         _I("Start Power managing without noti");
2340                         pm_cur_state = S_NORMAL;
2341                         set_setting_pmstate(pm_cur_state);
2342
2343                         timeout = states[S_NORMAL].timeout;
2344                         /* check minimun lcd on time */
2345                         if (timeout < DEFAULT_NORMAL_TIMEOUT)
2346                                 timeout = DEFAULT_NORMAL_TIMEOUT;
2347
2348                         reset_timeout(timeout);
2349
2350                         /*
2351                          * Lock lcd off until booting is done.
2352                          * deviced guarantees all booting script is executing.
2353                          * Last script of booting unlocks this suspend blocking state.
2354                          */
2355                         pm_lock_internal(INTERNAL_LOCK_BOOTING, LCD_OFF,
2356                             STAY_CUR_STATE, BOOTING_DONE_WATING_TIME);
2357                 }
2358                 if (CHECK_OPS(keyfilter_ops, init))
2359                         keyfilter_ops->init();
2360         }
2361         status = DEVICE_OPS_STATUS_START;
2362 }
2363
2364 static void display_exit(void *data)
2365 {
2366         int i = INIT_END;
2367
2368         status = DEVICE_OPS_STATUS_STOP;
2369
2370         /* Set current state to S_NORMAL */
2371         pm_cur_state = S_NORMAL;
2372         set_setting_pmstate(pm_cur_state);
2373         /* timeout is not needed */
2374         reset_timeout(0);
2375
2376         if (CHECK_OPS(keyfilter_ops, exit))
2377                 keyfilter_ops->exit();
2378
2379         display_ops_exit(NULL);
2380
2381         for (i = i - 1; i >= INIT_SETTING; i--) {
2382                 switch (i) {
2383                 case INIT_SETTING:
2384                         exit_setting();
2385                         break;
2386                 case INIT_INTERFACE:
2387                         exit_sysfs();
2388                         break;
2389                 case INIT_POLL:
2390                         unregister_notifier(DEVICE_NOTIFIER_HALLIC_OPEN, hall_ic_open);
2391                         unregister_notifier(DEVICE_NOTIFIER_INPUT_ADD,
2392                             input_device_add);
2393                         unregister_notifier(DEVICE_NOTIFIER_INPUT_REMOVE,
2394                             input_device_remove);
2395                         unregister_notifier(DEVICE_NOTIFIER_BOOTING_DONE,
2396                             booting_done);
2397                         unregister_notifier(DEVICE_NOTIFIER_LCD_ESD, lcd_esd);
2398                         unregister_notifier(DEVICE_NOTIFIER_HDMI, hdmi_changed);
2399                         unregister_notifier(DEVICE_NOTIFIER_BATTERY_HEALTH,
2400                             battery_health_changed);
2401
2402                         exit_pm_poll();
2403                         break;
2404                 }
2405         }
2406         free_lock_info_list();
2407
2408         _I("Stop power manager");
2409 }
2410
2411 static int display_start(void)
2412 {
2413         if (status == DEVICE_OPS_STATUS_START)
2414                 return -EALREADY;
2415
2416         display_init(NULL);
2417
2418         return 0;
2419 }
2420
2421 static int display_stop(void)
2422 {
2423         if (status == DEVICE_OPS_STATUS_STOP)
2424                 return -EALREADY;
2425
2426         display_exit(NULL);
2427
2428         return 0;
2429 }
2430
2431 static int display_status(void)
2432 {
2433         return status;
2434 }
2435
2436 static const struct device_ops display_device_ops = {
2437         .priority = DEVICE_PRIORITY_HIGH,
2438         .name     = "display",
2439         .init     = display_init,
2440         .exit     = display_exit,
2441         .start    = display_start,
2442         .stop     = display_stop,
2443         .status   = display_status,
2444 };
2445
2446 DEVICE_OPS_REGISTER(&display_device_ops)
2447
2448 /**
2449  * @}
2450  */