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