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