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