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