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