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