display: Change get_var_display_config return type to const
[platform/core/system/deviced.git] / plugins / mobile / 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 <dlfcn.h>
39 #include <fnmatch.h>
40 #include <vconf-keys.h>
41 #include <sys/time.h>
42 #include <libsyscommon/list.h>
43 #include <hal/device/hal-device-power.h>
44
45 #include "ambient-mode.h"
46 #include "util.h"
47 #include "core.h"
48 #include "lock-detector.h"
49 #include "display-ops.h"
50 #include "shared/devices.h"
51 #include "shared/device-notifier.h"
52 #include "core/udev.h"
53 #include "shared/common.h"
54 #include "shared/apps.h"
55 #include "extcon/extcon.h"
56 #include "battery/power-supply.h"
57 #include "power/power.h"
58 #include "power/power-off.h"
59 #include "power/power-suspend.h"
60 #include "power/power-boot.h"
61 #include "power/power-doze.h"
62 #include "display/display-dpms.h"
63 #include "proximity.h"
64 #include "display-info.h"
65 #include "display-signal.h"
66 #include "display-lock.h"
67 #include "shared/plugin.h"
68
69 #define DISPLAY_CONF_FILE    "/etc/deviced/display.conf"
70
71 /**
72  * @addtogroup POWER_MANAGER
73  * @{
74  */
75
76 #define LOCK_SCREEN_INPUT_TIMEOUT       10000
77 #define LOCK_SCREEN_CONTROL_TIMEOUT     5000
78 #define ALWAYS_ON_TIMEOUT               360000000
79 #define LATE_LCD_TRANSIT                1
80
81 #define GESTURE_STR             "gesture"
82 #define POWER_KEY_STR           "powerkey"
83 #define TOUCH_STR               "touch"
84 #define EVENT_STR               "event"
85 #define TIMEOUT_STR             "timeout"
86 #define PROXI_STR               "proximity"
87 #define PALM_STR                "palm"
88 #define UNKNOWN_STR             "unknown"
89
90 extern void init_pm_internal();
91 extern void init_save_userlock(void);
92
93 static struct display_plugin *disp_plgn;
94 static struct _backlight_ops *backlight_ops;
95 static struct battery_plugin *battery_plgn;
96 static int (*fp_get_charging_status) (int *val);
97
98 static void (*power_saving_func) (int onoff);
99 static enum device_ops_status status = DEVICE_OPS_STATUS_UNINIT;
100
101 static guint timeout_src_id;
102 static int system_wakeup_flag = false;
103 static unsigned int custom_normal_timeout = 0;
104 static unsigned int custom_dim_timeout = 0;
105 int custom_holdkey_block = false;
106 static char *custom_change_name;
107 static bool hallic_open = true;
108 static guint lock_timeout_id;
109 static guint transit_timer;
110 static int lock_screen_timeout = LOCK_SCREEN_INPUT_TIMEOUT;
111 static struct timeval lcdon_tv;
112 static int lcd_paneloff_mode = false;
113 static int stay_touchscreen_off = false;
114 GList *lcdon_ops;
115 /*
116  * The two variables(lcdon_broadcast, pmstate_suspend) must be set initial
117  * state because it should be sent from previous state at booting time.
118  */
119 static bool lcdon_broadcast = true;
120
121 static bool touch_blocked = false;
122
123 /* default transition, action fuctions */
124 static int default_trans(int evt);
125 static int default_action(int timeout);
126 static int default_check(int curr, int next);
127
128 static gboolean del_normal_cond(void *data);
129 static gboolean del_dim_cond(void *data);
130 static gboolean del_off_cond(void *data);
131
132 static int default_proc_change_state(unsigned int cond, pid_t pid);
133 static int (*proc_change_state)(unsigned int cond, pid_t pid) = default_proc_change_state;
134
135 static struct state states[S_END] = {
136         { S_START,    "S_START",    NULL,          NULL,           NULL,          NULL            },
137         { S_NORMAL,   "S_NORMAL",   default_trans, default_action, default_check, del_normal_cond },
138         { S_LCDDIM,   "S_LCDDIM",   default_trans, default_action, default_check, del_dim_cond    },
139         { S_LCDOFF,   "S_LCDOFF",   default_trans, default_action, default_check, del_off_cond    },
140         { S_STANDBY,  "S_STANDBY",  NULL,          NULL,           NULL,          NULL            },
141         { S_SLEEP,    "S_SLEEP",    default_trans, default_action, default_check, NULL            },
142         { S_POWEROFF, "S_POWEROFF", NULL,          NULL,           NULL,          NULL            },
143 };
144
145 static int trans_table[S_END][EVENT_END] = {
146         /* Timeout,   Input */
147         { S_START,    S_START    }, /* S_START */
148         { S_LCDDIM,   S_NORMAL   }, /* S_NORMAL */
149         { S_LCDOFF,   S_NORMAL   }, /* S_LCDDIM */
150         { S_SLEEP,    S_NORMAL   }, /* S_LCDOFF */
151         { S_SLEEP,    S_STANDBY  }, /* S_STANDBY */
152         { S_LCDOFF,   S_NORMAL   }, /* S_SLEEP */
153         { S_POWEROFF, S_POWEROFF }, /* S_POWEROFF */
154 };
155
156 #define SHIFT_UNLOCK            4
157 #define SHIFT_CHANGE_STATE      7
158 #define CHANGE_STATE_BIT        0xF00   /* 1111 0000 0000 */
159 #define SHIFT_LOCK_FLAG 16
160 #define SHIFT_CHANGE_TIMEOUT    20
161 #define CUSTOM_TIMEOUT_BIT      0x1
162 #define CUSTOM_HOLDKEY_BIT      0x2
163 #define HOLD_KEY_BLOCK_BIT      0x1
164 #define TIMEOUT_NONE            (-1)
165
166 #define S_COVER_TIMEOUT                 8000
167 #define GET_HOLDKEY_BLOCK_STATE(x) ((x >> SHIFT_LOCK_FLAG) & HOLD_KEY_BLOCK_BIT)
168 #define DELAYED_INIT_WATING_TIME        60000   /* 1 minute */
169
170 #define LOCK_SCREEN_WATING_TIME         300     /* 0.3 second */
171 #define LONG_PRESS_INTERVAL             400       /* 0.4 seconds */
172 #define SAMPLING_INTERVAL               1       /* 1 sec */
173 #define BRIGHTNESS_CHANGE_STEP          10
174 #define LCD_ALWAYS_ON                   0
175 #define ACCEL_SENSOR_ON                 1
176 #define CONTINUOUS_SAMPLING             1
177 #define LCDOFF_TIMEOUT                  300     /* milli second */
178
179 #define DIFF_TIMEVAL_MS(a, b) \
180         (((a.tv_sec * 1000000 + a.tv_usec) - \
181         (b.tv_sec * 1000000 + b.tv_usec)) \
182         / 1000)
183
184 static struct display_config display_conf = {
185         .lock_wait_time         = LOCK_SCREEN_WATING_TIME,
186         .longpress_interval     = LONG_PRESS_INTERVAL,
187         .lightsensor_interval   = SAMPLING_INTERVAL,
188         .lcdoff_timeout         = LCDOFF_TIMEOUT,
189         .pm_default_brightness = 80,
190         .brightness_change_step = BRIGHTNESS_CHANGE_STEP,
191         .lcd_always_on          = LCD_ALWAYS_ON,
192         .dimming                = 1,
193         .framerate_app          = {0, 0, 0, 0},
194         .control_display        = 0,
195         .powerkey_doublepress   = 0,
196         .accel_sensor_on        = ACCEL_SENSOR_ON,
197         .continuous_sampling    = CONTINUOUS_SAMPLING,
198         .timeout_enable         = true,
199         .input_support          = true,
200         .lockcheck_timeout      = 600,
201         .display_init_direction = DISPLAY_INIT_DIRECTION_HORIZONTAL,
202         .aod_enter_level        = 40,
203         .aod_tsp                = true,
204         .touch_wakeup           = false,
205         .display_on_usb_conn_changed = true,
206 };
207
208 struct display_function_info display_info = {
209         .update_auto_brightness         = NULL,
210         .set_autobrightness_min         = NULL,
211         .reset_autobrightness_min       = NULL,
212         .face_detection                 = NULL,
213 };
214
215 inline const struct display_config* get_var_display_config()
216 {
217         return &display_conf;
218 }
219
220 inline struct state* state_st(enum state_t state)
221 {
222         return &states[state];
223 }
224
225 guint get_transition_timer(void)
226 {
227         return timeout_src_id;
228 }
229
230 void change_state_action(enum state_t state, int (*func)(int timeout))
231 {
232         _I("[%s] 'action' is changed.", states[state].name);
233         states[state].action = func;
234 }
235
236 void change_state_trans(enum state_t state, int (*func)(int evt))
237 {
238         _I("[%s] 'trans' is changed.", states[state].name);
239         states[state].trans = func;
240 }
241
242 void change_state_check(enum state_t state, int (*func)(int curr, int next))
243 {
244         _I("[%s] 'check' is changed.", states[state].name);
245         states[state].check = func;
246 }
247
248 void change_state_name(enum state_t state, const char *name)
249 {
250         _I("[%s] 'name' is changed.", states[state].name);
251         states[state].name = name;
252 }
253
254 void change_trans_table(enum state_t state, enum state_t next)
255 {
256         _I("[%s] 'timeout trans table' is changed.", states[state].name);
257         trans_table[state][EVENT_TIMEOUT] = next;
258 }
259
260 void change_proc_change_state(int (*func)(unsigned int cond, pid_t pid))
261 {
262         _I("'proc change state' is changed.");
263         proc_change_state = func;
264 }
265
266 static int display_brightness_changed(void *data)
267 {
268         int brt, ret;
269
270         brt = DATA_VALUE_INT(data);
271
272         ret = gdbus_signal_emit(NULL,
273                                                         DEVICED_PATH_DISPLAY,
274                                                         DEVICED_INTERFACE_DISPLAY,
275                                                         "Brightness",
276                                                         g_variant_new("(i)", brt));
277         if (ret < 0)
278                 _E("Failed to send dbus signal Brightness.");
279
280         return 0;
281 }
282
283 static int display_auto_brightness_sensing(void *data)
284 {
285         if (!transit_timer)
286                 return 0;
287
288         g_source_remove(transit_timer);
289         transit_timer = 0;
290
291         return 0;
292 }
293
294 static const char* __device_flags_to_string(enum device_flags flags)
295 {
296
297         if (flags & (LCD_ON_BY_GESTURE | LCD_OFF_BY_GESTURE))
298                 return GESTURE_STR;
299         else if (flags & (LCD_ON_BY_POWER_KEY | LCD_OFF_BY_POWER_KEY))
300                 return POWER_KEY_STR;
301         else if (flags & (LCD_ON_BY_EVENT | LCD_OFF_BY_EVENT))
302                 return EVENT_STR;
303         else if (flags & LCD_ON_BY_TOUCH)
304                 return TOUCH_STR;
305         else if (flags & LCD_OFF_BY_TIMEOUT)
306                 return TIMEOUT_STR;
307         else if (flags & LCD_OFF_BY_PROXIMITY)
308                 return PROXI_STR;
309         else if (flags & LCD_OFF_BY_PALM)
310                 return PALM_STR;
311         else
312                 return UNKNOWN_STR;
313 }
314
315 static unsigned long get_lcd_on_flags(void)
316 {
317         unsigned long flags = NORMAL_MODE;
318
319         if (lcd_paneloff_mode)
320                 flags |= LCD_PANEL_OFF_MODE;
321
322         if (ambient_get_condition() == true) {
323                 flags |= AMBIENT_MODE;
324                 flags |= LCD_PHASED_TRANSIT_MODE;
325         }
326
327         return flags;
328 }
329
330 bool touch_event_blocked(void)
331 {
332         return touch_blocked;
333 }
334
335 static gboolean late_transit_on(void *data)
336 {
337         if (!transit_timer)
338                 return G_SOURCE_REMOVE;
339
340         g_source_remove(transit_timer);
341         transit_timer = 0;
342
343         backlight_ops->transit_state(DPMS_ON);
344         return G_SOURCE_REMOVE;
345 }
346
347 void lcd_on_procedure(int state, enum device_flags flag)
348 {
349         GList *l = NULL;
350         const struct device_ops *ops = NULL;
351         unsigned long flags = get_lcd_on_flags();
352         flags |= flag;
353
354         /*
355          * Display on procedure
356          * step 1. leave doze
357          * step 2. broadcast lcd on signal with cause
358          * step 3. set brightness
359          * step 4. set pmstate of vconf
360          * step 5. display on operate
361          *  - a. display on
362          *  - b. TSP(touch screen) and touchkey enable
363          * step 6. broadcast lcd on complete signal
364          * step 7. key backlight enable
365          */
366         leave_doze();
367
368         _I("[lcdstep] 0x%lx", flags);
369
370         if (flags & AMBIENT_MODE) {
371                 if (ambient_get_state() == false && backlight_ops->get_lcd_power() == DPMS_ON)
372                         return;
373                 ambient_set_state(false);
374         }
375
376         /* send LCDOn dbus signal */
377         if (!lcdon_broadcast)
378                 broadcast_lcd_on(SIGNAL_PRE, flags);
379
380         if (!(flags & LCD_PHASED_TRANSIT_MODE)) {
381                 /* Update brightness level */
382                 if (state == LCD_DIM)
383                         backlight_ops->dim();
384                 else if (state == LCD_NORMAL)
385                         backlight_ops->update();
386         }
387
388         if (state == LCD_NORMAL)
389                 set_setting_pmstate(S_NORMAL);
390         else if (state == LCD_DIM)
391                 set_setting_pmstate(S_LCDDIM);
392
393         SYS_G_LIST_FOREACH(lcdon_ops, l, ops)
394                 ops->start(flags);
395
396         if (!lcdon_broadcast) {
397         broadcast_lcd_on(SIGNAL_POST, flags);
398                 if (flags & LCD_PHASED_TRANSIT_MODE)
399                         transit_timer = g_timeout_add_seconds(LATE_LCD_TRANSIT,
400                                         late_transit_on, NULL);
401                 lcdon_broadcast = true;
402         }
403
404         if (CHECK_OPS(keyfilter_ops, backlight_enable))
405                 keyfilter_ops->backlight_enable(true);
406
407         touch_blocked = false;
408 }
409
410 static unsigned long get_lcd_off_flags(void)
411 {
412         unsigned long flags = NORMAL_MODE;
413
414         if (ambient_get_condition() == true) {
415                 flags |= AMBIENT_MODE;
416                 flags |= LCD_PHASED_TRANSIT_MODE;
417         }
418
419         if (stay_touchscreen_off)
420                 flags |= TOUCH_SCREEN_OFF_MODE;
421
422         return flags;
423 }
424
425 inline void lcd_off_procedure(enum device_flags flag)
426 {
427         GList *l = NULL;
428         const struct device_ops *ops = NULL;
429         unsigned long flags = get_lcd_off_flags();
430         flags |= flag;
431
432         /*
433          * Display off procedure
434          * step 0. enhance mode off using nofity (e.g mdnie, HBM, LBM)
435          * step 1. broadcast lcd off signal with cause
436          * step 2. set pmstate of vconf
437          * step 3. display off operate
438          *  - a. display off
439          *  - b. TSP(touch screen) and touchkey disable
440          * step 4. broadcast lcd off complete siganl
441          * step 5. enter doze mode if it is enabled
442          */
443         _I("[lcdstep] 0x%lx", flags);
444
445         /* notification */
446
447         device_notify(DEVICE_NOTIFIER_LCD_OFF, NULL);
448
449         if (lcdon_broadcast) {
450                 broadcast_lcd_off(SIGNAL_PRE, flags);
451                 lcdon_broadcast = false;
452         }
453
454         /* operation */
455
456         touch_blocked = true;
457
458         set_setting_pmstate(S_LCDOFF);
459
460         if (CHECK_OPS(keyfilter_ops, backlight_enable))
461                 keyfilter_ops->backlight_enable(false);
462
463         if (transit_timer) {
464                 g_source_remove(transit_timer);
465                 transit_timer = 0;
466         }
467
468         if (flags & LCD_PHASED_TRANSIT_MODE)
469                 backlight_ops->transit_state(DPMS_OFF);
470
471         SYS_G_LIST_FOREACH(lcdon_ops, l, ops)
472                 ops->stop(flags);
473
474         if (flags & AMBIENT_MODE) {
475                 broadcast_lcd_off_late(flags);
476         } else {
477                 broadcast_lcd_off(SIGNAL_POST, flags);
478                 device_notify(DEVICE_NOTIFIER_LCD_OFF_COMPLETE, NULL);
479         }
480
481         enter_doze();
482 }
483
484 void set_stay_touchscreen_off(int val)
485 {
486         _I("Stay touch screen off: %d", val);
487         stay_touchscreen_off = val;
488
489         if (disp_plgn->pm_change_internal)
490                 disp_plgn->pm_change_internal(INTERNAL_LOCK_PM, LCD_NORMAL);
491 }
492
493 void set_lcd_paneloff_mode(int val)
494 {
495         _I("Lcd paneloff mode: %d", val);
496         lcd_paneloff_mode = val;
497
498         if (disp_plgn->pm_change_internal)
499                 disp_plgn->pm_change_internal(INTERNAL_LOCK_PM, LCD_NORMAL);
500 }
501
502 int low_battery_state(int val)
503 {
504         switch (val) {
505         case VCONFKEY_SYSMAN_BAT_POWER_OFF:
506         case VCONFKEY_SYSMAN_BAT_CRITICAL_LOW:
507         case VCONFKEY_SYSMAN_BAT_REAL_POWER_OFF:
508                 return true;
509         }
510         return false;
511 }
512
513 int get_hallic_open(void)
514 {
515         return hallic_open;
516 }
517
518 void get_pname(pid_t pid, char *pname)
519 {
520         char buf[PATH_MAX];
521         int cmdline, r;
522
523         if (pid >= INTERNAL_LOCK_BASE)
524                 snprintf(buf, PATH_MAX, "/proc/%d/cmdline", getpid());
525         else
526                 snprintf(buf, PATH_MAX, "/proc/%d/cmdline", pid);
527
528         cmdline = open(buf, O_RDONLY);
529         if (cmdline < 0) {
530                 pname[0] = '\0';
531                 _E("Process(%d) does not exist now(may be dead without unlock).", pid);
532                 return;
533         }
534
535         r = read(cmdline, pname, PATH_MAX);
536         if ((r >= 0) && (r < PATH_MAX))
537                 pname[r] = '\0';
538         else
539                 pname[0] = '\0';
540
541         close(cmdline);
542 }
543
544 static void del_state_cond(void *data, enum state_t state)
545 {
546         PmLockNode *tmp = NULL;
547         pid_t pid;
548
549         if (!data)
550                 return;
551
552         /* A passed data is a pid_t type data, not a 64bit data. */
553         pid = (pid_t)((intptr_t)data);
554         _I("delete prohibit %s condition by timeout (%d)", states[state].name, pid);
555
556         if (pid == INTERNAL_LOCK_AMBIENT)
557                 ambient_check_invalid_state(pid);
558
559         tmp = find_node(state, pid);
560         del_node(state, tmp);
561         set_unlock_time(pid, state);
562
563         /* Change state only when the two conditions below are satisfied.
564          *   1. There should be no running state-transition timer
565          *   2. Released lock is one of the pm_cur_state's lock
566          * This emulates already expired transition timer */
567         if (!timeout_src_id && get_pm_cur_state() == state)
568                 states[get_pm_cur_state()].trans(EVENT_TIMEOUT);
569
570         if (state == S_LCDOFF)
571                 set_process_active(false, pid);
572 }
573
574 static gboolean del_normal_cond(void *data)
575 {
576         del_state_cond(data, S_NORMAL);
577         return G_SOURCE_REMOVE;
578 }
579
580 static gboolean del_dim_cond(void *data)
581 {
582         del_state_cond(data, S_LCDDIM);
583         return G_SOURCE_REMOVE;
584 }
585
586 static gboolean del_off_cond(void *data)
587 {
588         del_state_cond(data, S_LCDOFF);
589         return G_SOURCE_REMOVE;
590 }
591
592 /* timeout handler  */
593 gboolean timeout_handler(void *data)
594 {
595         _I("Time out state %s", states[get_pm_cur_state()].name);
596
597         if (timeout_src_id) {
598                 g_source_remove(timeout_src_id);
599                 timeout_src_id = 0;
600         }
601
602         states[get_pm_cur_state()].trans(EVENT_TIMEOUT);
603         return G_SOURCE_REMOVE;
604 }
605
606 void reset_timeout(int timeout)
607 {
608         if (!display_conf.timeout_enable)
609                 return;
610
611         if ((get_pm_cur_state() == S_LCDOFF)
612         && (is_emulator() == true || timeout_sleep_support == false))
613                 return;
614
615         _I("Reset timeout(%d ms).", timeout);
616         if (timeout_src_id != 0) {
617                 g_source_remove(timeout_src_id);
618                 timeout_src_id = 0;
619         }
620
621         if (trans_table[get_pm_cur_state()][EVENT_TIMEOUT] == get_pm_cur_state())
622                 return;
623
624         if (timeout > 0)
625                 timeout_src_id = g_timeout_add(timeout,
626                     timeout_handler, NULL);
627         else if (timeout == 0)
628                 states[get_pm_cur_state()].trans(EVENT_TIMEOUT);
629 }
630
631 /* get configurations from setting */
632 static int get_lcd_timeout_from_settings(void)
633 {
634         int i;
635         int val = 0;
636
637         for (i = 0; i < S_END; i++) {
638                 switch (states[i].state) {
639                 case S_NORMAL:
640                         get_run_timeout(&val);
641                         break;
642                 case S_LCDDIM:
643                         get_dim_timeout(&val);
644                         break;
645                 case S_LCDOFF:
646                         val = display_conf.lcdoff_timeout;
647                         break;
648                 default:
649                         /* This state doesn't need to set time out. */
650                         val = 0;
651                         break;
652                 }
653                 if (val > 0)
654                         states[i].timeout = val;
655
656                 _I("State(%s) timeout(%d) ms", states[i].name,
657                         states[i].timeout);
658         }
659
660         return 0;
661 }
662
663 static void update_display_time(void)
664 {
665         int run_timeout, val;
666
667         /* first priority : s cover */
668         if (!hallic_open) {
669                 states[S_NORMAL].timeout = S_COVER_TIMEOUT;
670                 _I("S cover closed: Timeout(%d ms) is set by normal.",
671                     S_COVER_TIMEOUT);
672                 return;
673         }
674
675         /* second priority : custom timeout */
676         if (custom_normal_timeout > 0) {
677                 states[S_NORMAL].timeout = custom_normal_timeout;
678                 states[S_LCDDIM].timeout = custom_dim_timeout;
679                 _I("CUSTOM : timeout is set by normal(%d ms), dim(%d ms)",
680                     custom_normal_timeout, custom_dim_timeout);
681                 return;
682         }
683
684         /* third priority : lock state */
685         if ((__get_lock_screen_state() == VCONFKEY_IDLE_LOCK) &&
686             !get_lock_screen_bg_state()) {
687                 /* timeout is different according to key or event. */
688                 states[S_NORMAL].timeout = lock_screen_timeout;
689                 _I("LOCK: Timeout(%d ms) is set by normal.",
690                     lock_screen_timeout);
691                 return;
692         }
693
694         /* default setting */
695         get_run_timeout(&run_timeout);
696
697         /* for sdk
698          * if the run_timeout is zero, it regards AlwaysOn state
699          */
700         if (run_timeout == 0 || display_conf.lcd_always_on) {
701                 run_timeout = ALWAYS_ON_TIMEOUT;
702                 _I("LCD always on.");
703         }
704
705         states[S_NORMAL].timeout = run_timeout;
706
707         get_dim_timeout(&val);
708         states[S_LCDDIM].timeout = val;
709
710         _I("Normal: NORMAL timeout is set by %d ms", states[S_NORMAL].timeout);
711         _I("Normal: DIM timeout is set by %d ms", states[S_LCDDIM].timeout);
712 }
713
714 static void update_display_locktime(int time)
715 {
716         lock_screen_timeout = time;
717         update_display_time();
718 }
719
720 void set_dim_state(bool on)
721 {
722         _I("Dim state is %d.", on);
723         update_display_time();
724         states[get_pm_cur_state()].trans(EVENT_INPUT);
725 }
726
727 void lcd_on_direct(enum device_flags flags)
728 {
729         enum hal_device_power_transition_reason reason;
730
731         if (flags & LCD_ON_BY_POWER_KEY)
732                 reason = HAL_DEVICE_POWER_TRANSITION_REASON_POWER_KEY;
733         else if (flags & LCD_ON_BY_TOUCH)
734                 reason = HAL_DEVICE_POWER_TRANSITION_REASON_TOUCH_SCREEN;
735         else
736                 reason = HAL_DEVICE_POWER_TRANSITION_REASON_UNKNOWN;
737
738         power_request_change_state_strict(DEVICED_POWER_STATE_SLEEP, DEVICED_POWER_STATE_NORMAL, reason, NULL);
739         set_pm_cur_state(S_NORMAL);
740
741         _D("lcd is on directly");
742         gettimeofday(&lcdon_tv, NULL);
743         lcd_on_procedure(LCD_NORMAL, flags);
744
745         update_display_locktime(LOCK_SCREEN_INPUT_TIMEOUT);
746 }
747
748 static inline bool check_lcd_is_on(void)
749 {
750         if (backlight_ops->get_lcd_power() != DPMS_ON)
751                 return false;
752
753         return true;
754 }
755
756 static gboolean timer_refresh_cb(gpointer data)
757 {
758         struct state *st;
759
760         /* state transition */
761         set_pm_old_state(get_pm_cur_state());
762         set_pm_cur_state(S_NORMAL);
763         st = &states[get_pm_cur_state()];
764
765         if (st->action)
766                 st->action(st->timeout);
767
768         return 0;
769 }
770
771 int custom_lcdon(int timeout)
772 {
773         struct state *st;
774
775         if (timeout <= 0)
776                 return -EINVAL;
777
778         if (check_lcd_is_on() == false)
779                 lcd_on_direct(LCD_ON_BY_GESTURE);
780
781         _I("Custom lcd on timeout(%d ms).", timeout);
782         if (set_custom_lcdon_timeout(timeout) == true)
783                 update_display_time();
784
785         /* state transition */
786         set_pm_old_state(get_pm_cur_state());
787         set_pm_cur_state(S_NORMAL);
788         st = &states[get_pm_cur_state()];
789
790         /* enter action */
791         if (st->action)
792                 st->action(st->timeout);
793
794         g_idle_add(timer_refresh_cb, NULL);
795
796         return 0;
797 }
798
799 int custom_lcdoff(enum device_flags flag)
800 {
801         struct state *st;
802
803         check_processes(S_NORMAL);
804         check_processes(S_LCDDIM);
805
806         /* check holdkey block flag in lock node */
807         if (check_lock_condition(S_NORMAL) || check_lock_condition(S_LCDDIM)) {
808                 /*
809                  * When another proccess is normal lock, device is received call then,
810                  * call app can be changed to lcd state by proximity.
811                  * If proximity is near then normal lock will be unlocked.
812                  */
813                 if (flag & LCD_OFF_BY_PROXIMITY) {
814                         _I("custom lcd off by proximity, delete normal lock");
815                         delete_condition(S_NORMAL);
816                 } else {
817                         _I("skip custom lcd off");
818                         return -ECANCELED;
819                 }
820         }
821
822         _I("custom lcd off by flag(%d)", flag);
823         if (backlight_ops->get_lcd_power() == DPMS_ON)
824                 lcd_off_procedure(flag);
825
826         if (set_custom_lcdon_timeout(0) == true)
827                 update_display_time();
828
829         /* state transition */
830         set_pm_old_state(get_pm_cur_state());
831         set_pm_cur_state(S_LCDOFF);
832         st = &states[get_pm_cur_state()];
833
834         /* enter action */
835         if (st->action)
836                 st->action(st->timeout);
837
838         return 0;
839 }
840
841 int display_on_by_reason(const char *reason, int timeout)
842 {
843         struct state *st;
844         int flag;
845         int str_len;
846
847         str_len = strlen(reason);
848
849         if (!strncmp(reason, GESTURE_STR, str_len))
850                 flag = LCD_ON_BY_GESTURE;
851         else if (!strncmp(reason, EVENT_STR, str_len))
852                 flag = LCD_ON_BY_EVENT;
853         else {
854                 _E("Reason is unknown(%s)", reason);
855                 return -EINVAL;
856         }
857
858         if (timeout <= 0) {
859                 _E("Cannot setting timeout %d", timeout);
860                 return -EINVAL;
861         }
862
863         if (check_lcd_is_on() == false)
864                 lcd_on_direct(flag);
865
866         _I("platform lcd on by %s (%d ms)", reason, timeout);
867         if (set_custom_lcdon_timeout(timeout) == true)
868                 update_display_time();
869
870         /* state transition */
871         set_pm_old_state(get_pm_cur_state());
872         set_pm_cur_state(S_NORMAL);
873         st = &states[get_pm_cur_state()];
874
875         /* enter action */
876         if (st->action)
877                 st->action(st->timeout);
878
879         return 0;
880 }
881
882 int display_off_by_reason(const char *reason)
883 {
884         struct state *st;
885         int flag;
886         int str_len;
887
888         str_len = strlen(reason);
889
890         if (!strncmp(reason, GESTURE_STR, str_len)) {
891                 check_processes(S_NORMAL);
892                 check_processes(S_LCDDIM);
893
894                 /* check holdkey block flag in lock node */
895                 if (check_lock_condition(S_NORMAL) || check_lock_condition(S_LCDDIM)) {
896                         _I("skip platform lcd off by gesture");
897                         return -ECANCELED;
898                 }
899                 flag = LCD_OFF_BY_GESTURE;
900         } else if (!strncmp(reason, PALM_STR, str_len)) {
901                 delete_condition(S_NORMAL);
902                 delete_condition(S_LCDDIM);
903
904                 flag = LCD_OFF_BY_PALM;
905         } else {
906                 _E("Reason is unknown(%s)", reason);
907                 return -EINVAL;
908         }
909
910         _I("platform lcd off by %s", reason);
911         if (backlight_ops->get_lcd_power() == DPMS_ON)
912                 lcd_off_procedure(flag);
913
914         /* state transition */
915         set_pm_old_state(get_pm_cur_state());
916         set_pm_cur_state(S_LCDOFF);
917         st = &states[get_pm_cur_state()];
918
919         /* enter action */
920         if (st->action)
921                 st->action(st->timeout);
922
923         return 0;
924 }
925
926 static void default_proc_change_state_action(enum state_t next, int timeout)
927 {
928         struct state *st;
929
930         set_pm_old_state(get_pm_cur_state());
931         set_pm_cur_state(next);
932
933         st = &states[get_pm_cur_state()];
934
935         if (st && st->action) {
936                 if (timeout < 0)
937                         st->action(st->timeout);
938                 else
939                         st->action(timeout);
940         }
941 }
942
943 static int default_proc_change_state(unsigned int cond, pid_t pid)
944 {
945         enum state_t next;
946
947         next = GET_COND_STATE(cond);
948         _I("Change process(%d) state to %s.", pid, states[next].name);
949
950         switch (next) {
951         case S_NORMAL:
952                 if (check_lcd_is_on() == false)
953                         lcd_on_direct(LCD_ON_BY_EVENT);
954                 update_display_locktime(LOCK_SCREEN_CONTROL_TIMEOUT);
955                 default_proc_change_state_action(next, -1);
956                 break;
957         case S_LCDDIM:
958                 default_proc_change_state_action(next, -1);
959                 break;
960         case S_LCDOFF:
961                 if (backlight_ops->get_lcd_power() == DPMS_ON) {
962                         if (get_proximity_state() == SENSOR_PROXIMITY_NEAR)
963                                 lcd_off_procedure(LCD_OFF_BY_PROXIMITY);
964                         else
965                         lcd_off_procedure(LCD_OFF_BY_EVENT);
966                 }
967                 if (set_custom_lcdon_timeout(0))
968                         update_display_time();
969                 default_proc_change_state_action(next, -1);
970                 break;
971         case S_SLEEP:
972                 _I("Dangerous requests.");
973                 /* at first LCD_OFF and then goto sleep */
974                 /* state transition */
975                 default_proc_change_state_action(S_LCDOFF, TIMEOUT_NONE);
976                 delete_condition(S_NORMAL);
977                 delete_condition(S_LCDDIM);
978                 delete_condition(S_LCDOFF);
979                 if (lcdon_broadcast) {
980                         _I("broadcast lcd off signal at non-lcd device");
981                         broadcast_lcd_off(SIGNAL_PRE, 0);
982                         broadcast_lcd_off(SIGNAL_POST, 0);
983                 }
984                 default_proc_change_state_action(S_SLEEP, TIMEOUT_NONE);
985                 break;
986
987         default:
988                 return -EINVAL;
989         }
990
991         return 0;
992 }
993
994 static void proc_condition_lock(PMMsg *data)
995 {
996         PmLockNode *tmp;
997         guint cond_timeout_id = 0;
998         char pname[PATH_MAX];
999         pid_t pid = data->pid;
1000         enum state_t state;
1001         int holdkey_block, ret;
1002         bool value = true;
1003         unsigned int flags;
1004         const char *lock_type = NULL;
1005
1006         state = GET_COND_STATE(data->cond);
1007         if (state == S_START)
1008                 return;
1009
1010         flags = GET_COND_FLAG(data->cond);
1011         get_pname(pid, pname);
1012
1013         if ((state == S_LCDOFF) && (get_pm_cur_state() == S_SLEEP) &&
1014             (pm_get_power_lock() == POWER_UNLOCK))
1015                 proc_change_state(data->cond, INTERNAL_LOCK_PM);
1016
1017         if (data->timeout > 0) {
1018                 /* To pass a pid_t data through the timer infrastructure
1019                  * without memory allocation, a pid_t data becomes typecast
1020                  * to intptr_t and void *(64bit) type. */
1021                 cond_timeout_id = g_timeout_add(
1022                                 data->timeout,
1023                                 states[state].timeout_cb,
1024                                 (void*)((intptr_t)pid));
1025                 if (!cond_timeout_id)
1026                         _E("Failed to register display timer.");
1027         }
1028
1029         holdkey_block = GET_COND_FLAG(data->cond) & PM_FLAG_BLOCK_HOLDKEY;
1030
1031         tmp = find_node(state, pid);
1032         if (!tmp) {
1033                 tmp = add_node(state, pid, cond_timeout_id, holdkey_block);
1034                 if (!tmp) {
1035                         _E("Failed to acquire lock, state: %d, pid: %d.", state, pid);
1036                         return;
1037                 }
1038         } else {
1039                 update_lock_timer(data, tmp, cond_timeout_id);
1040                 tmp->holdkey_block = holdkey_block;
1041         }
1042
1043         if (state == S_LCDOFF)
1044                 set_process_active(true, pid);
1045
1046         _I("[%s] locked by %5d with %u ms", states[state].name, pid, data->timeout);
1047
1048         if (pid < INTERNAL_LOCK_BASE) {
1049                 /* for debug */
1050                 if (state == S_LCDOFF)
1051                         lock_type = PM_LCDOFF_STR;
1052                 else if (state == S_LCDDIM)
1053                         lock_type = PM_LCDDIM_STR;
1054                 else if (state == S_NORMAL)
1055                         lock_type = PM_LCDON_STR;
1056
1057                 if (lock_type) {
1058                         /* power lock signal */
1059                         ret = gdbus_signal_emit(NULL,
1060                                         DEVICED_PATH_DISPLAY,
1061                                         DEVICED_INTERFACE_DISPLAY,
1062                                         "PowerLock",
1063                                         g_variant_new("(sii)", lock_type, pid, (int)data->timeout));
1064                         if (ret < 0)
1065                                 _E("Failed to send dbus signal PowerLock.");
1066                 }
1067         }
1068         _SD("be requested LOCK info pname(%s), holdkeyblock(%d) flags(%d)",
1069             pname, holdkey_block, flags);
1070         set_lock_time(pid, pname, state);
1071
1072         device_notify(DEVICE_NOTIFIER_DISPLAY_LOCK, (void *)&value);
1073 }
1074
1075 static void proc_condition_unlock(PMMsg *data)
1076 {
1077         pid_t pid = data->pid;
1078         enum state_t state;
1079         PmLockNode *tmp;
1080         char pname[PATH_MAX];
1081         bool value = false;
1082         unsigned int flags;
1083         int ret;
1084         const char *lock_type = NULL;
1085
1086         state = GET_COND_STATE(data->cond);
1087         if (!state)
1088                 return;
1089
1090         flags = GET_COND_FLAG(data->cond);
1091         get_pname(pid, pname);
1092
1093         tmp = find_node(state, pid);
1094         del_node(state, tmp);
1095
1096         if (state == S_LCDOFF)
1097                 set_process_active(false, pid);
1098
1099         _I("[%s] unlocked by %5d", states[state].name, pid);
1100
1101         if (pid < INTERNAL_LOCK_BASE) {
1102                 /* for debug */
1103                 if (state == S_LCDOFF)
1104                         lock_type =  PM_LCDOFF_STR;
1105                 else if (state == S_LCDDIM)
1106                         lock_type = PM_LCDDIM_STR;
1107                 else if (state == S_NORMAL)
1108                         lock_type = PM_LCDON_STR;
1109
1110                 if (lock_type) {
1111                         /* power unlock signal */
1112                         ret = gdbus_signal_emit(NULL,
1113                                         DEVICED_PATH_DISPLAY,
1114                                         DEVICED_INTERFACE_DISPLAY,
1115                                         "PowerUnlock",
1116                                         g_variant_new("(sii)", lock_type, pid, (int)data->timeout));
1117                         if (ret < 0)
1118                                 _E("Failed to send dbus signal PowerUnlock.");
1119                 }
1120         }
1121
1122         _SD("be requested UNLOCK info pname(%s) flag(%d)", pname, flags);
1123         set_unlock_time(pid, state);
1124
1125         device_notify(DEVICE_NOTIFIER_DISPLAY_LOCK, (void *)&value);
1126 }
1127
1128 static int proc_condition(PMMsg *data)
1129 {
1130         unsigned int flags;
1131
1132         if (IS_COND_REQUEST_LOCK(data->cond))
1133                 proc_condition_lock(data);
1134
1135         if (IS_COND_REQUEST_UNLOCK(data->cond))
1136                 proc_condition_unlock(data);
1137
1138         if (!display_conf.timeout_enable)
1139                 return 0;
1140
1141         flags = GET_COND_FLAG(data->cond);
1142         if (flags == 0) {
1143                 /* guard time for suspend */
1144                 if (get_pm_cur_state() == S_LCDOFF)
1145                         reset_timeout(states[S_LCDOFF].timeout);
1146         } else {
1147                 if (flags & PM_FLAG_RESET_TIMER)
1148                         reset_timeout(states[get_pm_cur_state()].timeout);
1149         }
1150
1151         if (!timeout_src_id)
1152                 states[get_pm_cur_state()].trans(EVENT_TIMEOUT);
1153
1154         return 0;
1155 }
1156
1157 void update_lcdoff_source(int source)
1158 {
1159         int ret;
1160
1161         switch (source) {
1162         case VCONFKEY_PM_LCDOFF_BY_TIMEOUT:
1163                 _I("LCD OFF by timeout.");
1164                 break;
1165         case VCONFKEY_PM_LCDOFF_BY_POWERKEY:
1166                 _I("LCD OFF by powerkey.");
1167                 break;
1168         default:
1169                 _E("Invalid value(%d).", source);
1170                 return;
1171         }
1172         ret = vconf_set_int(VCONFKEY_PM_LCDOFF_SOURCE, source);
1173         if (ret < 0)
1174                 _E("Failed to set vconf value for lcd off source: %d", vconf_get_ext_errno());
1175 }
1176
1177 void print_info(int fd)
1178 {
1179         int s_index = 0;
1180         char buf[PATH_MAX + 255];
1181         int i = 1;
1182         int ret;
1183         char pname[PATH_MAX];
1184         PmLockNode *t;
1185         GList *elem;
1186         char time_buf[30];
1187
1188         if (fd < 0)
1189                 return;
1190
1191         snprintf(buf, sizeof(buf),
1192                 "\n==========================================="
1193                 "===========================\n");
1194         ret = write(fd, buf, strlen(buf));
1195         if (ret < 0)
1196                 _E("Write() failed: %d", errno);
1197         snprintf(buf, sizeof(buf), "Timeout Info: Run[%dms] Dim[%dms] Off[%dms]\n",
1198                  states[S_NORMAL].timeout,
1199                  states[S_LCDDIM].timeout, states[S_LCDOFF].timeout);
1200         ret = write(fd, buf, strlen(buf));
1201         if (ret < 0)
1202                 _E("Write() failed: %d", errno);
1203
1204         snprintf(buf, sizeof(buf), "Tran. Locked : %s %s %s\n",
1205                  (get_trans_condition() & MASK_NORMAL) ? states[S_NORMAL].name : "-",
1206                  (get_trans_condition() & MASK_DIM) ? states[S_LCDDIM].name : "-",
1207                  (get_trans_condition() & MASK_OFF) ? states[S_LCDOFF].name : "-");
1208         ret = write(fd, buf, strlen(buf));
1209         if (ret < 0)
1210                 _E("Write() failed: %d", errno);
1211
1212         snprintf(buf, sizeof(buf), "Current State: %s\n",
1213                 states[get_pm_cur_state()].name);
1214         ret = write(fd, buf, strlen(buf));
1215         if (ret < 0)
1216                 _E("Write() failed: %d", errno);
1217
1218         snprintf(buf, sizeof(buf), "Current Lock Conditions: \n");
1219         ret = write(fd, buf, strlen(buf));
1220         if (ret < 0)
1221                 _E("Write() failed: %d", errno);
1222
1223         for (s_index = S_NORMAL; s_index < S_END; s_index++) {
1224                 SYS_G_LIST_FOREACH(get_cond_head(s_index), elem, t) {
1225                         get_pname((pid_t)t->pid, pname);
1226                         ctime_r(&t->time, time_buf);
1227                         time_buf[strlen(time_buf) - 1] = 0;
1228                         snprintf(buf, sizeof(buf),
1229                                  " %d: [%s] locked by pid %d %s %s\n",
1230                                  i++, states[s_index].name, t->pid, pname, time_buf);
1231                         ret = write(fd, buf, strlen(buf));
1232                         if (ret < 0)
1233                                 _E("Write() failed: %d", errno);
1234                 }
1235         }
1236
1237         print_lock_info_list(fd);
1238
1239 #ifdef ENABLE_PM_LOG
1240         pm_history_print(fd, 250);
1241 #endif
1242 }
1243
1244 void save_display_log(const char *path)
1245 {
1246         int fd, ret;
1247         char buf[255];
1248         time_t now_time;
1249         char time_buf[30];
1250
1251         _D("internal state is saved!");
1252
1253         time(&now_time);
1254         ctime_r(&now_time, time_buf);
1255         time_buf[strlen(time_buf) - 1] = 0;
1256
1257         fd = open(path, O_CREAT | O_TRUNC | O_WRONLY, 0644);
1258         if (fd != -1) {
1259                 snprintf(buf, sizeof(buf),
1260                         "\npm_state_log now-time : %d(s) %s\n\n",
1261                         (int)now_time, time_buf);
1262                 ret = write(fd, buf, strlen(buf));
1263                 if (ret < 0)
1264                         _E("write() failed (%d)", errno);
1265
1266                 snprintf(buf, sizeof(buf), "pm_status_flag: %#x\n", get_pm_status_flag());
1267                 ret = write(fd, buf, strlen(buf));
1268                 if (ret < 0)
1269                         _E("write() failed (%d)", errno);
1270
1271                 if (disp_plgn->get_lock_screen_state ) {
1272                         snprintf(buf, sizeof(buf), "screen lock status : %d\n",
1273                                 disp_plgn->get_lock_screen_state());
1274                         ret = write(fd, buf, strlen(buf));
1275                         if (ret < 0)
1276                                 _E("write() failed (%d)", errno);
1277                 }
1278                 print_info(fd);
1279                 close(fd);
1280         }
1281
1282         fd = open("/dev/console", O_WRONLY);
1283         if (fd != -1) {
1284                 print_info(fd);
1285                 close(fd);
1286         }
1287 }
1288
1289 /* SIGHUP signal handler
1290  * For debug... print info to syslog
1291  */
1292 static void sig_hup(int signo)
1293 {
1294         _I("received sig hub %d", signo);
1295
1296         pm_save_logdump();
1297 }
1298
1299 int check_lcdoff_direct(void)
1300 {
1301         int ret, lock, cradle;
1302         int hdmi_state;
1303
1304         if (get_pm_old_state() != S_NORMAL)
1305                 return false;
1306
1307         if (get_pm_cur_state() != S_LCDDIM)
1308                 return false;
1309
1310         if (!display_conf.dimming)
1311                 return true;
1312
1313         lock = __get_lock_screen_state();
1314         if (lock != VCONFKEY_IDLE_LOCK && hallic_open)
1315                 return false;
1316
1317         hdmi_state = extcon_get_status(EXTCON_CABLE_HDMI);
1318         if (hdmi_state)
1319                 return false;
1320
1321         ret = vconf_get_int(VCONFKEY_SYSMAN_CRADLE_STATUS, &cradle);
1322         if (ret >= 0 && cradle == DOCK_SOUND)
1323                 return false;
1324         else if (ret < 0)
1325                 _E("Failed to get vconf value for cradle status: %d", vconf_get_ext_errno());
1326
1327         _D("Goto LCDOFF direct: lock(%d) hdmi(%d) cradle(%d).", lock, hdmi_state, cradle);
1328
1329         return true;
1330 }
1331
1332 /*
1333  * default transition function
1334  *   1. call check
1335  *   2. transition
1336  *   3. call enter action function
1337  */
1338 static int default_trans(int evt)
1339 {
1340         struct state *st = &states[get_pm_cur_state()];
1341         int next_state;
1342
1343         next_state = (enum state_t)trans_table[get_pm_cur_state()][evt];
1344
1345         /* check conditions */
1346         if (st->check && !st->check(get_pm_cur_state(), next_state)) {
1347                 /* There is a condition. */
1348                 _I("%s locked. Trans to %s failed.", states[get_pm_cur_state()].name,
1349                        states[next_state].name);
1350                 return -1;
1351         }
1352
1353         /* state transition */
1354         set_pm_old_state(get_pm_cur_state());
1355         set_pm_cur_state(next_state);
1356         st = &states[get_pm_cur_state()];
1357
1358         /* enter action */
1359         if (st->action) {
1360                 if (get_pm_cur_state() == S_LCDOFF)
1361                         update_lcdoff_source(VCONFKEY_PM_LCDOFF_BY_TIMEOUT);
1362
1363                 if ((get_pm_cur_state() == S_NORMAL) || (get_pm_cur_state() == S_LCDOFF))
1364                         if (set_custom_lcdon_timeout(0) == true)
1365                                 update_display_time();
1366
1367                 if (check_lcdoff_direct() == true) {
1368                         /* enter next state directly */
1369                         states[get_pm_cur_state()].trans(EVENT_TIMEOUT);
1370                 } else {
1371                         if ((get_pm_cur_state() == S_SLEEP)
1372                         && (is_emulator() == true || timeout_sleep_support == false))
1373                                 return 0;
1374
1375                         st->action(st->timeout);
1376                 }
1377         }
1378
1379         return 0;
1380 }
1381
1382 static gboolean lcd_on_expired(void *data)
1383 {
1384         int lock_state, ret;
1385
1386         if (lock_timeout_id)
1387                 lock_timeout_id = 0;
1388
1389         /* check state of lock */
1390         ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
1391         if (ret > 0 && lock_state == VCONFKEY_IDLE_LOCK)
1392                 return G_SOURCE_REMOVE;
1393         else if (ret < 0)
1394                 _E("Failed to get vconf value for idle lock state: %d", vconf_get_ext_errno());
1395
1396         /* lock screen is not launched yet, but lcd is on */
1397         if (check_lcd_is_on() == false)
1398                 lcd_on_procedure(LCD_NORMAL, NORMAL_MODE);
1399
1400         return G_SOURCE_REMOVE;
1401 }
1402
1403 static inline void stop_lock_timer(void)
1404 {
1405         if (lock_timeout_id) {
1406                 g_source_remove(lock_timeout_id);
1407                 lock_timeout_id = 0;
1408         }
1409 }
1410
1411 static void check_lock_screen(void)
1412 {
1413         int lock_state, ret;
1414
1415         stop_lock_timer();
1416
1417         /* check state of lock */
1418         ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
1419         if (ret < 0 || lock_state == VCONFKEY_IDLE_LOCK)
1420                 return;
1421
1422         /* Use time to check lock is done. */
1423         lock_timeout_id = g_timeout_add(display_conf.lock_wait_time,
1424             lcd_on_expired, NULL);
1425 }
1426
1427 /* default enter action function */
1428 static int default_action(int timeout)
1429 {
1430         int wakeup_count = -1, pm_cur_state;
1431         time_t now;
1432         double diff;
1433         static time_t last_update_time = 0;
1434         static int last_timeout = 0;
1435         struct timeval now_tv;
1436
1437         if (status != DEVICE_OPS_STATUS_START) {
1438                 _E("Display is not started.");
1439                 return -EINVAL;
1440         }
1441
1442         if (get_pm_cur_state() != S_SLEEP) {
1443                 if ((get_pm_cur_state() == S_NORMAL) &&
1444                     lcdon_tv.tv_sec != 0) {
1445                         gettimeofday(&now_tv, NULL);
1446                         timeout -= DIFF_TIMEVAL_MS(now_tv, lcdon_tv);
1447                         lcdon_tv.tv_sec = 0;
1448                 }
1449                 /* set timer with current state timeout */
1450                 reset_timeout(timeout);
1451
1452                 if (get_pm_cur_state() == S_NORMAL) {
1453                         time(&last_update_time);
1454                         last_timeout = timeout;
1455                 } else {
1456                         _I("Timout set: %s state %d ms",
1457                             states[get_pm_cur_state()].name, timeout);
1458                 }
1459         }
1460
1461         if ((get_pm_cur_state() != get_pm_old_state()) && (get_pm_cur_state() != S_SLEEP)) {
1462                 power_request_change_state_strict(DEVICED_POWER_STATE_SLEEP, DEVICED_POWER_STATE_NORMAL,
1463                         power_get_wakeup_reason(), NULL);
1464                 set_setting_pmstate(get_pm_cur_state());
1465                 pm_cur_state = get_pm_cur_state();
1466                 device_notify(DEVICE_NOTIFIER_LCD, (void *)&pm_cur_state);
1467         }
1468
1469         if ((get_pm_old_state() == S_NORMAL) && (get_pm_cur_state() != S_NORMAL)) {
1470                 time(&now);
1471                 diff = difftime(now, last_update_time);
1472                 _I("S_NORMAL is changed to %s (timeout=%d ms diff=%.0f s).",
1473                     states[get_pm_cur_state()].name, last_timeout, diff);
1474         }
1475
1476         switch (get_pm_cur_state()) {
1477         case S_NORMAL:
1478                 /*
1479                  * normal state : backlight on and restore
1480                  * the previous brightness
1481                  */
1482                 if ((get_pm_old_state() == S_LCDOFF) || (get_pm_old_state() == S_SLEEP))
1483                         check_lock_screen();
1484                 else if (get_pm_old_state() == S_LCDDIM)
1485                         backlight_ops->update();
1486
1487                 if (check_lcd_is_on() == false)
1488                         lcd_on_procedure(LCD_NORMAL, NORMAL_MODE);
1489                 break;
1490
1491         case S_LCDDIM:
1492                 if ((get_pm_old_state() == S_NORMAL) &&
1493                     backlight_ops->get_custom_status())
1494                         backlight_ops->save_custom_brightness();
1495                 /* lcd dim state : dim the brightness */
1496                 backlight_ops->dim();
1497
1498                 if ((get_pm_old_state() == S_LCDOFF) || (get_pm_old_state() == S_SLEEP))
1499                         lcd_on_procedure(LCD_DIM, NORMAL_MODE);
1500                 break;
1501
1502         case S_LCDOFF:
1503                 if ((get_pm_old_state() != S_SLEEP) && (get_pm_old_state() != S_LCDOFF)) {
1504                         stop_lock_timer();
1505                         /* lcd off state : turn off the backlight */
1506                         if (backlight_ops->get_lcd_power() == DPMS_ON)
1507                                 lcd_off_procedure(LCD_OFF_BY_TIMEOUT);
1508                 }
1509
1510                 if (backlight_ops->get_lcd_power() == DPMS_ON
1511                     || lcd_paneloff_mode)
1512                         lcd_off_procedure(LCD_OFF_BY_TIMEOUT);
1513                 break;
1514
1515         case S_SLEEP:
1516                 if ((get_pm_old_state() != S_SLEEP) && (get_pm_old_state() != S_LCDOFF))
1517                         stop_lock_timer();
1518
1519                 if (backlight_ops->get_lcd_power() == DPMS_ON)
1520                         lcd_off_procedure(LCD_OFF_BY_TIMEOUT);
1521
1522                 if (!pm_get_power_lock_support()) {
1523                         /* sleep state : set system mode to SUSPEND */
1524                         if (get_wakeup_count(&wakeup_count) < 0)
1525                                 _E("Wakeup count read error.");
1526
1527                         if (wakeup_count < 0) {
1528                                 _I("Wakup Event. Can not enter suspend mode.");
1529                                 goto go_lcd_off;
1530                         }
1531
1532                         if (set_wakeup_count(wakeup_count) < 0) {
1533                                 _E("Wakeup count write error.");
1534                                 goto go_lcd_off;
1535                         }
1536                 }
1537                 goto go_suspend;
1538         }
1539
1540         return 0;
1541
1542 go_suspend:
1543 #ifdef ENABLE_PM_LOG
1544         pm_history_save(PM_LOG_SLEEP, get_pm_cur_state());
1545 #endif
1546         power_request_change_state(DEVICED_POWER_STATE_SLEEP, HAL_DEVICE_POWER_TRANSITION_REASON_DISPLAY_OFF_TIMEOUT);
1547         return 0;
1548
1549 go_lcd_off:
1550         if (!pm_get_power_lock_support()) {
1551                 /* Resume !! */
1552                 states[get_pm_cur_state()].trans(EVENT_DEVICE);
1553         }
1554         return 0;
1555 }
1556
1557 /*
1558  * default check function
1559  *   return
1560  *    0 : can't transit, others : transitable
1561  */
1562 static int default_check(int curr, int next)
1563 {
1564         int trans_cond;
1565
1566         makeup_trans_condition();
1567
1568         trans_cond = get_trans_condition() & MASK_BIT;
1569
1570         if (next == S_NORMAL) /* S_NORMAL is exceptional */
1571                 return 1;
1572
1573         switch (curr) {
1574         case S_NORMAL:
1575                 trans_cond = trans_cond & MASK_NORMAL;
1576                 break;
1577         case S_LCDDIM:
1578                 trans_cond = trans_cond & MASK_DIM;
1579                 break;
1580         case S_LCDOFF:
1581                 trans_cond = trans_cond & MASK_OFF;
1582                 break;
1583         default:
1584                 trans_cond = 0;
1585                 break;
1586         }
1587
1588         if (trans_cond != 0) {
1589                 print_node(curr);
1590                 return 0;
1591         }
1592
1593         return 1;               /* transitable */
1594 }
1595
1596 static void default_saving_mode(int onoff)
1597 {
1598         if (onoff)
1599                 set_pm_status_flag(PWRSV_FLAG);
1600         else
1601                 clear_pm_status_flag(PWRSV_FLAG);
1602
1603         if (get_pm_cur_state() == S_NORMAL)
1604                 backlight_ops->update();
1605 }
1606
1607 int poll_callback(int condition, PMMsg *data)
1608 {
1609         static time_t last_t;
1610         time_t now;
1611
1612         if (status != DEVICE_OPS_STATUS_START) {
1613                 _E("Display logic is not started.");
1614                 return -ECANCELED;
1615         }
1616
1617         if (condition == INPUT_POLL_EVENT) {
1618                 if ((get_pm_cur_state() == S_LCDOFF) || (get_pm_cur_state() == S_SLEEP))
1619                         _I("Input event signal at Display Off");
1620                 time(&now);
1621                 if ((last_t != now) ||
1622                     (get_pm_cur_state() == S_LCDOFF) ||
1623                     (get_pm_cur_state() == S_SLEEP)) {
1624                         states[get_pm_cur_state()].trans(EVENT_INPUT);
1625                         last_t = now;
1626                 }
1627         }
1628
1629         if (condition == PM_CONTROL_EVENT) {
1630                 proc_condition(data);
1631
1632                 if (IS_COND_REQUEST_CHANGE(data->cond))
1633                         proc_change_state(data->cond, data->pid);
1634         }
1635
1636         return 0;
1637 }
1638
1639 static int update_setting(int key_idx, int val)
1640 {
1641         int ret;
1642
1643         switch (key_idx) {
1644         case SETTING_TO_NORMAL:
1645                 update_display_time();
1646                 states[get_pm_cur_state()].trans(EVENT_INPUT);
1647                 break;
1648         case SETTING_HALLIC_OPEN:
1649                 hallic_open = val;
1650                 update_display_time();
1651                 if ((get_pm_cur_state() == S_NORMAL) || (get_pm_cur_state() == S_LCDDIM))
1652                         states[get_pm_cur_state()].trans(EVENT_INPUT);
1653                 else if ((get_pm_cur_state() == S_SLEEP) && hallic_open)
1654                         proc_change_state(S_LCDOFF, INTERNAL_LOCK_HALLIC);
1655                 break;
1656         case SETTING_LOW_BATT:
1657                 if (low_battery_state(val)) {
1658                         if (!(get_pm_status_flag() & CHRGR_FLAG))
1659                                 power_saving_func(true);
1660                         set_pm_status_flag(LOWBT_FLAG);
1661                 } else {
1662                         if (get_pm_status_flag() & PWRSV_FLAG)
1663                                 power_saving_func(false);
1664                         clear_pm_status_flag(LOWBT_FLAG);
1665                         clear_pm_status_flag(BRTCH_FLAG);
1666                         ret = vconf_set_bool(VCONFKEY_PM_BRIGHTNESS_CHANGED_IN_LPM, false);
1667                         if (ret < 0)
1668                                 _E("Failed to set vconf value for brightness changed in lpm: %d", vconf_get_ext_errno());
1669                 }
1670                 break;
1671         case SETTING_CHARGING:
1672                 if (val) {
1673                         if (get_pm_status_flag() & LOWBT_FLAG) {
1674                                 power_saving_func(false);
1675                                 clear_pm_status_flag(LOWBT_FLAG);
1676                         }
1677                         set_pm_status_flag(CHRGR_FLAG);
1678                 } else {
1679                         int bat_state;
1680                         ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW,
1681                                 &bat_state);
1682                         if (ret < 0) {
1683                                 bat_state = VCONFKEY_SYSMAN_BAT_NORMAL;
1684                                 _E("Failed to get vconf value for battery status low: %d", vconf_get_ext_errno());
1685                         }
1686                         if (low_battery_state(bat_state)) {
1687                                 power_saving_func(true);
1688                                 set_pm_status_flag(LOWBT_FLAG);
1689                         }
1690                         clear_pm_status_flag(CHRGR_FLAG);
1691                 }
1692                 break;
1693         case SETTING_BRT_LEVEL:
1694                 if (get_pm_status_flag() & PWRSV_FLAG) {
1695                         set_pm_status_flag(BRTCH_FLAG);
1696                         ret = vconf_set_bool(VCONFKEY_PM_BRIGHTNESS_CHANGED_IN_LPM, true);
1697                         if (ret < 0)
1698                                 _E("Failed to set vconf value for brightness changed in lpm: %d", vconf_get_ext_errno());
1699                         _I("Brightness changed in low battery,"
1700                                 "escape dim state.");
1701                 }
1702                 backlight_ops->set_default_brt(val);
1703                 break;
1704         case SETTING_LOCK_SCREEN:
1705                 set_lock_screen_state(val);
1706                 if (val == VCONFKEY_IDLE_UNLOCK) {
1707                         if (CHECK_OPS(keyfilter_ops, backlight_enable))
1708                                 keyfilter_ops->backlight_enable(false);
1709                 }
1710
1711                 /* LCD on if lock screen show before waiting time */
1712                 if ((get_pm_cur_state() == S_NORMAL) &&
1713                     val == VCONFKEY_IDLE_LOCK &&
1714                     backlight_ops->get_lcd_power() != DPMS_ON &&
1715                         is_lcdon_blocked() == LCDON_BLOCK_NONE)
1716                         lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
1717                 stop_lock_timer();
1718                 update_display_time();
1719                 if (get_pm_cur_state() == S_NORMAL)
1720                         states[get_pm_cur_state()].trans(EVENT_INPUT);
1721                 break;
1722         case SETTING_LOCK_SCREEN_BG:
1723                 set_lock_screen_bg_state(val);
1724                 update_display_time();
1725                 if (get_pm_cur_state() == S_NORMAL)
1726                         states[get_pm_cur_state()].trans(EVENT_INPUT);
1727                 break;
1728         case SETTING_POWER_CUSTOM_BRIGHTNESS:
1729                 if (val == VCONFKEY_PM_CUSTOM_BRIGHTNESS_ON)
1730                         backlight_ops->set_custom_status(true);
1731                 else
1732                         backlight_ops->set_custom_status(false);
1733                 break;
1734
1735         default:
1736                 return -1;
1737         }
1738         return 0;
1739 }
1740
1741 static void check_seed_status(void)
1742 {
1743         int ret = -1;
1744         int tmp = 0;
1745         int bat_state;
1746         int brt = 0;
1747         int lock_state;
1748
1749         /* Charging check */
1750         if (fp_get_charging_status && (fp_get_charging_status(&tmp) == 0) && (tmp > 0))
1751                 set_pm_status_flag(CHRGR_FLAG);
1752
1753         ret = get_setting_brightness(&tmp);
1754         if (ret != 0 || (tmp < PM_MIN_BRIGHTNESS || tmp > PM_MAX_BRIGHTNESS)) {
1755                 _I("Failed to read vconf value for brightness.");
1756                 brt = display_conf.pm_default_brightness;
1757                 if (tmp < PM_MIN_BRIGHTNESS || tmp > PM_MAX_BRIGHTNESS) {
1758                         ret = vconf_set_int(VCONFKEY_SETAPPL_LCD_BRIGHTNESS, brt);
1759                         if (ret < 0)
1760                                 _E("Failed to set vconf value for lcd brightness: %d", vconf_get_ext_errno());
1761                 }
1762                 tmp = brt;
1763         }
1764         _I("Set brightness(%d) from setting app.", tmp);
1765         backlight_ops->set_default_brt(tmp);
1766         backlight_ops->set_brightness(tmp);
1767
1768         ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, &bat_state);
1769         if (ret < 0) {
1770                 bat_state = VCONFKEY_SYSMAN_BAT_NORMAL;
1771                 _E("Failed to get vconf value for battery status low: %d", vconf_get_ext_errno());
1772         }
1773         if (low_battery_state(bat_state)) {
1774                 if (!(get_pm_status_flag() & CHRGR_FLAG)) {
1775                         power_saving_func(true);
1776                         set_pm_status_flag(LOWBT_FLAG);
1777                 }
1778         }
1779
1780         /* lock screen check */
1781         ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
1782         if (ret < 0) {
1783                 lock_state = -1;
1784                 _E("Failed to get vconf value for idle lock state: %d", vconf_get_ext_errno());
1785         }
1786         set_lock_screen_state(lock_state);
1787         if (lock_state == VCONFKEY_IDLE_LOCK) {
1788                 states[S_NORMAL].timeout = lock_screen_timeout;
1789                 _I("LCD NORMAL timeout(%d ms) is set"
1790                         " for lock screen.", lock_screen_timeout);
1791         }
1792
1793         return;
1794 }
1795
1796 static void init_lcd_operation(void)
1797 {
1798         const struct device_ops *ops = NULL;
1799
1800         ops = find_device("display");
1801         if (!check_default(ops))
1802                 SYS_G_LIST_APPEND(lcdon_ops, ops);
1803
1804         ops = find_device("touchkey");
1805         if (!check_default(ops))
1806                 SYS_G_LIST_APPEND(lcdon_ops, ops);
1807
1808         ops = find_device("touchscreen");
1809         if (!check_default(ops))
1810                 SYS_G_LIST_APPEND(lcdon_ops, ops);
1811 }
1812
1813 static void exit_lcd_operation(void)
1814 {
1815         GList *l = NULL;
1816         GList *l_next = NULL;
1817         const struct device_ops *ops = NULL;
1818
1819         SYS_G_LIST_FOREACH_SAFE(lcdon_ops, l, l_next, ops)
1820                 SYS_G_LIST_REMOVE_LIST(lcdon_ops, l);
1821 }
1822
1823 enum {
1824         INIT_SETTING = 0,
1825         INIT_INTERFACE,
1826         INIT_POLL,
1827         INIT_FIFO,
1828         INIT_DBUS,
1829         INIT_END
1830 };
1831
1832 static const char *errMSG[INIT_END] = {
1833         [INIT_SETTING] = "setting init error",
1834         [INIT_INTERFACE] = "lowlevel interface(sysfs or others) init error",
1835         [INIT_POLL] = "input devices poll init error",
1836         [INIT_FIFO] = "FIFO poll init error",
1837         [INIT_DBUS] = "d-bus init error",
1838 };
1839
1840 int set_lcd_timeout(int on, int dim, int holdkey_block, const char *name)
1841 {
1842         if (on == 0 && dim == 0) {
1843                 _I("LCD timeout changed: default setting");
1844                 custom_normal_timeout = custom_dim_timeout = 0;
1845         } else if (on < 0 || dim < 0) {
1846                 _E("Failed to set value(on=%d dim=%d).", on, dim);
1847                 return -EINVAL;
1848         } else {
1849                 _I("LCD timeout changed: on=%ds dim=%ds", on, dim);
1850                 custom_normal_timeout = SEC_TO_MSEC(on);
1851                 custom_dim_timeout = SEC_TO_MSEC(dim);
1852         }
1853         /* Apply new backlight time */
1854         update_display_time();
1855         if (get_pm_cur_state() == S_NORMAL)
1856                 states[get_pm_cur_state()].trans(EVENT_INPUT);
1857
1858         if (holdkey_block) {
1859                 custom_holdkey_block = true;
1860                 _I("Hold key disabled.");
1861         } else {
1862                 custom_holdkey_block = false;
1863                 _I("Hold key enabled.");
1864         }
1865
1866         if (custom_change_name) {
1867                 free(custom_change_name);
1868                 custom_change_name = 0;
1869         }
1870
1871         if (custom_normal_timeout == 0 &&
1872             custom_dim_timeout == 0 &&
1873             !holdkey_block)
1874                 return 0;
1875
1876         custom_change_name = strndup(name, strlen(name));
1877         if (!custom_change_name) {
1878                 _E("Failed to malloc.");
1879                 custom_normal_timeout = custom_dim_timeout = 0;
1880                 custom_holdkey_block = false;
1881                 return -ENOMEM;
1882         }
1883
1884         return 0;
1885 }
1886
1887 void reset_lcd_timeout(GDBusConnection *conn,
1888         const gchar     *sender,
1889         const gchar     *unique_name,
1890         gpointer         data)
1891 {
1892         if (!sender)
1893                 return;
1894
1895         if (!custom_change_name)
1896                 return;
1897
1898         if (strcmp(sender, custom_change_name))
1899                 return;
1900
1901         _I("reset lcd timeout: Set default timeout. sender=%s", sender);
1902
1903         free(custom_change_name);
1904         custom_change_name = 0;
1905         custom_normal_timeout = custom_dim_timeout = 0;
1906         custom_holdkey_block = false;
1907
1908         update_display_time();
1909         if (get_pm_cur_state() == S_NORMAL)
1910                 states[get_pm_cur_state()].trans(EVENT_INPUT);
1911 }
1912
1913 static int delayed_init_done(void *data)
1914 {
1915         static bool done = false;
1916
1917         if (!data)
1918                 return done;
1919
1920         done = *(int*)data;
1921         if (!done)
1922                 return done;
1923
1924         _I("Booting done, release booting lock.");
1925         if (disp_plgn->pm_unlock_internal) {
1926                 disp_plgn->pm_unlock_internal(INTERNAL_LOCK_BOOTING, LCD_NORMAL, PM_SLEEP_MARGIN);
1927                 disp_plgn->pm_unlock_internal(INTERNAL_LOCK_BOOTING, LCD_OFF, PM_SLEEP_MARGIN);
1928         }
1929
1930         return done;
1931 }
1932
1933 static int battery_health_changed(void *data)
1934 {
1935         int health = DATA_VALUE_INT(data);
1936
1937         _I("battery health change %d", health);
1938
1939         if (health == HEALTH_GOOD) {
1940                 clear_pm_status_flag(BATTERY_FLAG);
1941                 clear_pm_status_flag(DIMSTAY_FLAG);
1942         } else if (health == HEALTH_LOW || health == HEALTH_HIGH || health == HEALTH_OVP) {
1943                 set_pm_status_flag(BATTERY_FLAG);
1944                 set_pm_status_flag(DIMSTAY_FLAG);
1945         }
1946
1947         if (backlight_ops->get_lcd_power() == DPMS_ON)
1948                 backlight_ops->update();
1949
1950         return 0;
1951 }
1952
1953 static gboolean delayed_init_done_dpms(gpointer data)
1954 {
1955         int timeout;
1956
1957         if (!init_dpms())
1958                 return G_SOURCE_CONTINUE;
1959
1960         switch (get_pm_cur_state()) {
1961         case S_NORMAL:
1962         case S_LCDDIM:
1963                 lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
1964                 if (display_conf.timeout_enable) {
1965                         timeout = states[S_NORMAL].timeout;
1966                         /* check minimun lcd on time */
1967                         if (timeout < SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT))
1968                                 timeout = SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT);
1969                         reset_timeout(timeout);
1970                 }
1971                 break;
1972         case S_LCDOFF:
1973                 lcd_off_procedure(LCD_OFF_BY_EVENT);
1974                 timeout = display_conf.lcdoff_timeout;
1975                 reset_timeout(timeout);
1976                 break;
1977         default:
1978                 break;
1979         }
1980
1981         return G_SOURCE_REMOVE;
1982 }
1983
1984 static void add_timer_for_init_dpms(void)
1985 {
1986         guint id = g_timeout_add(500/* milliseconds */, delayed_init_done_dpms, NULL);
1987         if (id == 0)
1988                 _E("Failed to add init_dpms timeout.");
1989 }
1990
1991 /**
1992  * Power manager Main
1993  *
1994  */
1995 static int display_probe(void *data)
1996 {
1997         int ret;
1998
1999         /**
2000          * load display service
2001          * if there is no display shared library,
2002          * deviced does not provide any method and function of display.
2003          */
2004         ret = display_service_load();
2005         if (ret)
2006                 return ret;
2007
2008         /* display_plugin instance initialization */
2009         init_pm_internal();
2010         disp_plgn->device_flags_to_string = __device_flags_to_string;
2011
2012         if (battery_plgn->handle) {
2013                 fp_get_charging_status = dlsym(battery_plgn->handle, "get_charging_status");
2014                 if (!fp_get_charging_status)
2015                         _E("Failed to obtain address of get_charging_status");
2016         } else
2017                 _I("There is no battery module.");
2018
2019         return 0;
2020 }
2021
2022 static int input_init_handler(void)
2023 {
2024         if (!display_conf.input_support)
2025                 remove_device_by_devname("input");
2026
2027         return 0;
2028 }
2029
2030 static int power_resume_from_echomem_callback(void *data)
2031 {
2032         system_wakeup_flag = true;
2033         if (check_wakeup_src() == EVENT_DEVICE)
2034                 /* system waked up by devices */
2035                 states[get_pm_cur_state()].trans(EVENT_DEVICE);
2036         else
2037                 /* system waked up by user input */
2038                 states[get_pm_cur_state()].trans(EVENT_INPUT);
2039
2040         return 0;
2041 }
2042
2043 static int poweroff_triggered_callback(void *udata)
2044 {
2045         int val = (int)(intptr_t) udata;
2046
2047         switch (val) {
2048         case VCONFKEY_SYSMAN_POWER_OFF_NONE:
2049                 clear_pm_status_flag(PWROFF_FLAG);
2050                 break;
2051         case VCONFKEY_SYSMAN_POWER_OFF_DIRECT:
2052         case VCONFKEY_SYSMAN_POWER_OFF_RESTART:
2053                 set_pm_status_flag(PWROFF_FLAG);
2054                 break;
2055         }
2056
2057         return 0;
2058 }
2059
2060 static void esd_action(void)
2061 {
2062         const struct device_ops *touchscreen_ops = NULL;
2063
2064         _I("ESD on");
2065
2066         touchscreen_ops = find_device("touchscreen");
2067
2068         if (!check_default(touchscreen_ops))
2069                 touchscreen_ops->stop(NORMAL_MODE);
2070         backlight_ops->off(NORMAL_MODE);
2071         backlight_ops->on(NORMAL_MODE);
2072         if (!check_default(touchscreen_ops))
2073                 touchscreen_ops->start(NORMAL_MODE);
2074 }
2075
2076 static void lcd_uevent_changed(struct udev_device *dev)
2077 {
2078         const char *devpath;
2079         const char *action;
2080
2081         devpath = udev_device_get_devpath(dev);
2082         if (!devpath)
2083                 return;
2084
2085         if (!fnmatch(LCD_ESD_PATH, devpath, 0)) {
2086                 action = udev_device_get_action(dev);
2087                 if (!strcmp(action, UDEV_CHANGE))
2088                         esd_action();
2089         }
2090 }
2091
2092 static const struct uevent_handler lcd_uevent_ops = {
2093         .subsystem      = LCD_EVENT_SUBSYSTEM,
2094         .uevent_func    = lcd_uevent_changed,
2095         .data           = NULL,
2096 };
2097
2098 static void display_init(void *data)
2099 {
2100         int ret, i;
2101         unsigned int flags = (WITHOUT_STARTNOTI | FLAG_X_DPMS);
2102         int timeout = 0;
2103
2104         _I("Start power manager.");
2105
2106         signal(SIGHUP, sig_hup);
2107
2108         power_saving_func = default_saving_mode;
2109
2110         /* load configutation */
2111         ret = config_parse(DISPLAY_CONF_FILE, display_load_config, &display_conf);
2112         if (ret < 0)
2113                 _W("Failed to load '%s', use default value: %d",
2114                     DISPLAY_CONF_FILE, ret);
2115
2116         register_kernel_uevent_control(&lcd_uevent_ops);
2117
2118         register_notifier(DEVICE_NOTIFIER_DELAYED_INIT, delayed_init_done);
2119         register_notifier(DEVICE_NOTIFIER_APPLICATION_BACKGROUND, display_app_background);
2120         register_notifier(DEVICE_NOTIFIER_APPLICATION_FOREGROUND, display_app_foreground);
2121         register_notifier(DEVICE_NOTIFIER_APPLICATION_TERMINATED, display_app_terminated);
2122         register_notifier(DEVICE_NOTIFIER_BATTERY_HEALTH, battery_health_changed);
2123         register_notifier(DEVICE_NOTIFIER_DISPLAY_BRIGHTNESS, display_brightness_changed);
2124         register_notifier(DEVICE_NOTIFIER_LCD_AUTOBRT_SENSING, display_auto_brightness_sensing);
2125         register_notifier(DEVICE_NOTIFIER_POWER_RESUME_FROM_ECHO_MEM, power_resume_from_echomem_callback);
2126         register_notifier(DEVICE_NOTIFIER_POWEROFF_TRIGGERED, poweroff_triggered_callback);
2127
2128         init_save_userlock();
2129
2130         for (i = INIT_SETTING; i < INIT_END; i++) {
2131                 switch (i) {
2132                 case INIT_SETTING:
2133                         ret = init_setting(update_setting);
2134                         break;
2135                 case INIT_INTERFACE:
2136                         if (display_conf.timeout_enable)
2137                                 get_lcd_timeout_from_settings();
2138                         ret = init_sysfs(flags);
2139                         break;
2140                 case INIT_POLL:
2141                         _I("input init");
2142                         ret = input_init_handler();
2143
2144                         pm_lock_detector_init();
2145                         break;
2146                 case INIT_DBUS:
2147                         _I("Dbus init.");
2148                         ret = init_pm_dbus();
2149                         break;
2150                 }
2151                 if (ret != 0) {
2152                         _E("Failed to init: %s", errMSG[i]);
2153                         break;
2154                 }
2155         }
2156
2157         if (i == INIT_END) {
2158                 display_ops_init(NULL);
2159 #ifdef ENABLE_PM_LOG
2160                 pm_history_init();
2161 #endif
2162                 init_lcd_operation();
2163                 check_seed_status();
2164
2165                 /* In smd test, TSP should be turned off if display panel is not existed. */
2166                 if (backlight_ops->get_lcd_power() == -ENOENT) {
2167                         _I("Display panel is not existed.");
2168                         lcd_direct_control(DPMS_OFF, NORMAL_MODE);
2169                         exit_lcd_operation();
2170                 }
2171
2172                 /* wm_ready needs to be checked
2173                  * since display manager can be launched later than deviced.
2174                  * In the case, display cannot be turned on at the first booting */
2175                 // wm_ready = check_wm_ready();
2176                 if (init_dpms()) {
2177                         if (is_lcdon_blocked() != LCDON_BLOCK_NONE)
2178                                 lcd_off_procedure(LCD_OFF_BY_EVENT);
2179                         else
2180                                 lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
2181                 } else {
2182                         add_timer_for_init_dpms();
2183                 }
2184
2185                 if (display_conf.lcd_always_on) {
2186                         _I("LCD always on.");
2187                         trans_table[S_NORMAL][EVENT_TIMEOUT] = S_NORMAL;
2188                 }
2189
2190                 if (flags & WITHOUT_STARTNOTI) {        /* start without noti */
2191                         _I("Start Power managing without noti");
2192                         power_request_change_state_strict(DEVICED_POWER_STATE_SLEEP, DEVICED_POWER_STATE_NORMAL,
2193                                 HAL_DEVICE_POWER_TRANSITION_REASON_UNKNOWN, NULL);
2194                         /*
2195                          * Lock lcd off until booting is done.
2196                          * deviced guarantees all booting script is executing.
2197                          * Last script of booting unlocks this suspend blocking state.
2198                          */
2199                         if (disp_plgn->pm_lock_internal)
2200                                 disp_plgn->pm_lock_internal(INTERNAL_LOCK_BOOTING, LCD_OFF,
2201                                                 STAY_CUR_STATE, DELAYED_INIT_WATING_TIME);
2202
2203                         /* Initial display state right after the booting done */
2204                         if (is_lcdon_blocked())
2205                                 set_pm_cur_state(S_LCDOFF);
2206                         else
2207                                 set_pm_cur_state(S_NORMAL);
2208                         ret = vconf_set_int(VCONFKEY_PM_STATE, get_pm_cur_state());
2209                         if (ret < 0)
2210                                 _E("Failed to set vconf value for pm cur state: %d", vconf_get_ext_errno());
2211
2212                         status = DEVICE_OPS_STATUS_START;
2213                         if (display_conf.timeout_enable) {
2214                                 timeout = states[S_NORMAL].timeout;
2215                                 /* check minimun lcd on time */
2216                                 if (timeout < SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT))
2217                                         timeout = SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT);
2218
2219                                 if (disp_plgn->pm_lock_internal)
2220                                         disp_plgn->pm_lock_internal(INTERNAL_LOCK_BOOTING, LCD_NORMAL,
2221                                                         STAY_CUR_STATE, timeout);
2222                         }
2223
2224                 }
2225
2226                 if (display_conf.input_support)
2227                         if (CHECK_OPS(keyfilter_ops, init))
2228                                 keyfilter_ops->init();
2229
2230                 set_display_init_direction(display_conf.display_init_direction);
2231         }
2232 }
2233
2234 static void display_exit(void *data)
2235 {
2236         int i = INIT_END;
2237
2238         status = DEVICE_OPS_STATUS_STOP;
2239
2240         /* Set current state to S_NORMAL */
2241         set_pm_cur_state(S_NORMAL);
2242         set_setting_pmstate(get_pm_cur_state());
2243         /* timeout is not needed */
2244         reset_timeout(TIMEOUT_NONE);
2245
2246         if (CHECK_OPS(keyfilter_ops, exit))
2247                 keyfilter_ops->exit();
2248
2249         unregister_kernel_uevent_control(&lcd_uevent_ops);
2250
2251         display_ops_exit(NULL);
2252
2253         for (i = i - 1; i >= INIT_SETTING; i--) {
2254                 switch (i) {
2255                 case INIT_SETTING:
2256                         exit_setting();
2257                         break;
2258                 case INIT_INTERFACE:
2259                         exit_sysfs();
2260                         break;
2261                 case INIT_POLL:
2262                         unregister_notifier(DEVICE_NOTIFIER_DELAYED_INIT, delayed_init_done);
2263                         unregister_notifier(DEVICE_NOTIFIER_APPLICATION_BACKGROUND, display_app_background);
2264                         unregister_notifier(DEVICE_NOTIFIER_APPLICATION_FOREGROUND, display_app_foreground);
2265                         unregister_notifier(DEVICE_NOTIFIER_APPLICATION_TERMINATED, display_app_terminated);
2266                         unregister_notifier(DEVICE_NOTIFIER_BATTERY_HEALTH, battery_health_changed);
2267                         unregister_notifier(DEVICE_NOTIFIER_DISPLAY_BRIGHTNESS, display_brightness_changed);
2268                         unregister_notifier(DEVICE_NOTIFIER_POWER_RESUME_FROM_ECHO_MEM, power_resume_from_echomem_callback);
2269
2270                         break;
2271                 }
2272         }
2273
2274         exit_lcd_operation();
2275         free_lock_info_list();
2276
2277         /* free display service */
2278         display_service_free();
2279
2280         _I("Stop power manager.");
2281 }
2282
2283 static int display_start(enum device_flags flags)
2284 {
2285         const struct display_ops *enhance_ops = NULL;
2286         bool on = true;
2287
2288         /* NORMAL MODE */
2289         if (flags & NORMAL_MODE) {
2290                 if (flags & LCD_PANEL_OFF_MODE)
2291                         /* standby on */
2292                         backlight_ops->standby(true);
2293                 else
2294                         /* normal lcd on */
2295                         backlight_ops->on(flags);
2296                 FIND_DISPLAY(enhance_ops, "enhance");
2297                 if (enhance_ops && enhance_ops->func)
2298                         enhance_ops->func(RESTORE_ENHANCE_OUTDOOR, &on);
2299                 return 0;
2300         }
2301
2302         /* CORE LOGIC MODE */
2303         if (!(flags & CORE_LOGIC_MODE))
2304                 return 0;
2305
2306         if (status == DEVICE_OPS_STATUS_START)
2307                 return -EALREADY;
2308
2309         if (display_probe(NULL) < 0)
2310                 return -EPERM;
2311
2312         display_init(NULL);
2313
2314         return 0;
2315 }
2316
2317 static int display_stop(enum device_flags flags)
2318 {
2319         /* NORMAL MODE */
2320         if (flags & NORMAL_MODE || flags & FORCE_OFF_MODE) {
2321                 backlight_ops->off(flags);
2322                 return 0;
2323         }
2324
2325         /* CORE LOGIC MODE */
2326         if (!(flags & CORE_LOGIC_MODE))
2327                 return 0;
2328
2329         if (status == DEVICE_OPS_STATUS_STOP)
2330                 return -EALREADY;
2331
2332         display_exit(NULL);
2333
2334         return 0;
2335 }
2336
2337 static int display_status(void)
2338 {
2339         return status;
2340 }
2341
2342 static const struct device_ops display_device_ops = {
2343         .priority = DEVICE_PRIORITY_HIGH,
2344         DECLARE_NAME_LEN("display"),
2345         .probe    = display_probe,
2346         .init     = display_init,
2347         .exit     = display_exit,
2348         .start    = display_start,
2349         .stop     = display_stop,
2350         .status   = display_status,
2351 };
2352
2353 DEVICE_OPS_REGISTER(&display_device_ops)
2354
2355 static void __CONSTRUCTOR__ initialize(void)
2356 {
2357         disp_plgn = get_var_display_plugin();
2358         if (!disp_plgn)
2359                 _E("Failed to get display plugin variable.");
2360
2361         backlight_ops = get_var_backlight_ops();
2362         if (!backlight_ops)
2363                 _E("Failed to get backlight operator variable.");
2364
2365         battery_plgn = get_var_battery_plugin();
2366         if (!battery_plgn)
2367                 _E("Failed to get battery plugin variable.");
2368 }
2369 /**
2370  * @}
2371  */