4 * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 * @brief Power manager main loop.
24 * This file includes Main loop, the FSM, signal processing.
35 #include <sys/types.h>
39 #include <vconf-keys.h>
42 #include "ambient-mode.h"
45 #include "device-node.h"
46 #include "lock-detector.h"
47 #include "display-ops.h"
48 #include "core/devices.h"
49 #include "core/device-notifier.h"
50 #include "core/udev.h"
51 #include "core/list.h"
52 #include "core/common.h"
53 #include "core/config-parser.h"
54 #include "core/launch.h"
55 #include "apps/apps.h"
56 #include "extcon/extcon.h"
57 #include "battery/power-supply.h"
58 #include "power/power-handler.h"
59 #include "power/boot.h"
60 #include "dd-display.h"
61 #include "display/display-dpms.h"
62 #include "proximity.h"
63 #include "display-info.h"
65 #define DISPLAY_CONF_FILE "/etc/deviced/display.conf"
68 * @addtogroup POWER_MANAGER
72 #define LOCK_SCREEN_INPUT_TIMEOUT 10000
73 #define LOCK_SCREEN_CONTROL_TIMEOUT 5000
74 #define ALWAYS_ON_TIMEOUT 360000000
75 #define LATE_LCD_TRANSIT 1
79 #define GESTURE_STR "gesture"
80 #define POWER_KEY_STR "powerkey"
81 #define TOUCH_STR "touch"
82 #define EVENT_STR "event"
83 #define TIMEOUT_STR "timeout"
84 #define PROXI_STR "proximity"
85 #define PALM_STR "palm"
86 #define UNKNOWN_STR "unknown"
88 #define METHOD_APP_STATUS "CheckAppStatus"
93 extern void init_pm_internal();
94 extern int get_charging_status(int *val);
95 extern void init_save_userlock(void);
97 unsigned int pm_status_flag;
98 static int trans_condition;
100 static void (*power_saving_func) (int onoff);
101 static enum device_ops_status status = DEVICE_OPS_STATUS_UNINIT;
105 guint timeout_src_id;
106 int system_wakeup_flag = false;
107 static unsigned int custom_normal_timeout = 0;
108 static unsigned int custom_dim_timeout = 0;
109 static int custom_holdkey_block = false;
110 static int custom_change_pid = -1;
111 static char *custom_change_name;
112 static bool hallic_open = true;
113 static guint lock_timeout_id;
114 static guint transit_timer;
115 static int lock_screen_timeout = LOCK_SCREEN_INPUT_TIMEOUT;
116 static long displayoff_time;
117 static struct timeval lcdon_tv;
118 static int lcd_paneloff_mode = false;
119 static int stay_touchscreen_off = false;
122 * The two variables(lcdon_broadcast, pmstate_suspend) must be set initial
123 * state because it should be sent from previous state at booting time.
125 static bool lcdon_broadcast = true;
126 static int pmstate_suspend = PM_SUSPEND;
128 static bool touch_blocked = false;
130 /* default transition, action fuctions */
131 static int default_trans(int evt);
132 static int default_action(int timeout);
133 static int default_check(int curr, int next);
135 static gboolean del_normal_cond(void *data);
136 static gboolean del_dim_cond(void *data);
137 static gboolean del_off_cond(void *data);
139 static gboolean pmlock_check(void *data);
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;
144 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 },
154 static int trans_table[S_END][EVENT_END] = {
156 { S_START, S_START }, /* S_START */
157 { S_LCDDIM, S_NORMAL }, /* S_NORMAL */
158 { S_LCDOFF, S_NORMAL }, /* S_LCDDIM */
159 { S_SLEEP, S_NORMAL }, /* S_LCDOFF */
160 { S_SLEEP, S_STANDBY }, /* S_STANDBY */
161 { S_LCDOFF, S_NORMAL }, /* S_SLEEP */
162 { S_POWEROFF, S_POWEROFF }, /* S_POWEROFF */
172 static const char *lcdon_sig_lookup[SIGNAL_MAX] = {
173 [SIGNAL_PRE] = "LCDOn",
174 [SIGNAL_POST] = "LCDOnCompleted",
176 static const char *lcdoff_sig_lookup[SIGNAL_MAX] = {
177 [SIGNAL_PRE] = "LCDOff",
178 [SIGNAL_POST] = "LCDOffCompleted",
181 #define SHIFT_UNLOCK 4
182 #define SHIFT_CHANGE_STATE 7
183 #define CHANGE_STATE_BIT 0xF00 /* 1111 0000 0000 */
184 #define SHIFT_LOCK_FLAG 16
185 #define SHIFT_CHANGE_TIMEOUT 20
186 #define CUSTOM_TIMEOUT_BIT 0x1
187 #define CUSTOM_HOLDKEY_BIT 0x2
188 #define HOLD_KEY_BLOCK_BIT 0x1
189 #define TIMEOUT_NONE (-1)
191 #define S_COVER_TIMEOUT 8000
192 #define GET_HOLDKEY_BLOCK_STATE(x) ((x >> SHIFT_LOCK_FLAG) & HOLD_KEY_BLOCK_BIT)
193 #define BOOTING_DONE_WATING_TIME 60000 /* 1 minute */
194 #define LOCK_TIME_WARNING 60 /* 60 seconds */
196 #define ACTIVE_ACT "active"
197 #define INACTIVE_ACT "inactive"
199 #define LOCK_SCREEN_WATING_TIME 300 /* 0.3 second */
200 #define LONG_PRESS_INTERVAL 400 /* 0.4 seconds */
201 #define SAMPLING_INTERVAL 1 /* 1 sec */
202 #define BRIGHTNESS_CHANGE_STEP 10
203 #define LCD_ALWAYS_ON 0
204 #define ACCEL_SENSOR_ON 1
205 #define CONTINUOUS_SAMPLING 1
206 #define LCDOFF_TIMEOUT 500 /* milli second */
208 #define DIFF_TIMEVAL_MS(a, b) \
209 (((a.tv_sec * 1000000 + a.tv_usec) - \
210 (b.tv_sec * 1000000 + b.tv_usec)) \
213 struct display_config display_conf = {
214 .lock_wait_time = LOCK_SCREEN_WATING_TIME,
215 .longpress_interval = LONG_PRESS_INTERVAL,
216 .lightsensor_interval = SAMPLING_INTERVAL,
217 .lcdoff_timeout = LCDOFF_TIMEOUT,
218 .pm_default_brightness = 80,
219 .brightness_change_step = BRIGHTNESS_CHANGE_STEP,
220 .lcd_always_on = LCD_ALWAYS_ON,
222 .framerate_app = {0, 0, 0, 0},
223 .control_display = 0,
224 .powerkey_doublepress = 0,
225 .accel_sensor_on = ACCEL_SENSOR_ON,
226 .continuous_sampling = CONTINUOUS_SAMPLING,
227 .timeout_enable = true,
228 .input_support = true,
229 .lockcheck_timeout = 600,
230 .aod_enter_level = 40,
232 .touch_wakeup = false,
233 .sleep_support = true,
236 struct display_function_info display_info = {
237 .update_auto_brightness = NULL,
238 .set_autobrightness_min = NULL,
239 .reset_autobrightness_min = NULL,
240 .face_detection = NULL,
243 typedef struct _pm_lock_node {
247 GVariant *warning_param;
251 bool broadcast_warning;
254 static dd_list *cond_head[S_END];
256 static void set_process_active(bool flag, pid_t pid)
260 if (pid >= INTERNAL_LOCK_BASE)
263 /* Send dbug to resourced */
264 ret = dbus_handle_emit_dbus_signal(NULL,
265 RESOURCED_PATH_PROCESS,
266 RESOURCED_INTERFACE_PROCESS,
267 RESOURCED_METHOD_ACTIVE,
268 g_variant_new("(si)", (flag ? ACTIVE_ACT : INACTIVE_ACT), pid));
270 _E("Failed to send dbus signal to resourced.");
273 bool check_lock_state(int state)
278 DD_LIST_FOREACH(cond_head[state], elem, t) {
279 if (t->background == false)
286 void change_state_action(enum state_t state, int (*func)(int timeout))
288 _I("[%s] 'action' is changed.", states[state].name);
289 states[state].action = func;
292 void change_state_trans(enum state_t state, int (*func)(int evt))
294 _I("[%s] 'trans' is changed.", states[state].name);
295 states[state].trans = func;
298 void change_state_check(enum state_t state, int (*func)(int curr, int next))
300 _I("[%s] 'check' is changed.", states[state].name);
301 states[state].check = func;
304 void change_state_name(enum state_t state, const char *name)
306 _I("[%s] 'name' is changed.", states[state].name);
307 states[state].name = name;
310 void change_trans_table(enum state_t state, enum state_t next)
312 _I("[%s] 'timeout trans table' is changed.", states[state].name);
313 trans_table[state][EVENT_TIMEOUT] = next;
316 void change_proc_change_state(int (*func)(unsigned int cond, pid_t pid))
318 _I("'proc change state' is changed.");
319 proc_change_state = func;
322 static inline long clock_gettime_to_long(void)
327 ret = clock_gettime(CLOCK_REALTIME, &now);
330 _E("Failed to clock gettime!");
334 return SEC_TO_MSEC(now.tv_sec) + NSEC_TO_MSEC(now.tv_nsec);
337 static int display_brightness_changed(void *data)
341 brt = DATA_VALUE_INT(data);
343 ret = dbus_handle_emit_dbus_signal(NULL,
344 DEVICED_PATH_DISPLAY,
345 DEVICED_INTERFACE_DISPLAY,
347 g_variant_new("(i)", brt));
349 _E("Failed to send dbus signal Brightness.");
354 static int display_auto_brightness_sensing(void *data)
359 g_source_remove(transit_timer);
365 static void broadcast_lcd_on(enum signal_type type, enum device_flags flags)
372 if (type <= SIGNAL_INVALID || type >= SIGNAL_MAX) {
373 _E("Invalid signal type(%d).", type);
377 if (type == SIGNAL_PRE && displayoff_time != 0)
378 diff = clock_gettime_to_long() - displayoff_time;
380 if (flags & LCD_ON_BY_GESTURE)
382 else if (flags & LCD_ON_BY_POWER_KEY)
384 else if (flags & LCD_ON_BY_EVENT)
386 else if (flags & LCD_ON_BY_TOUCH)
391 signal = lcdon_sig_lookup[type];
392 _I("lcdstep : Broadcast signal(%s:%s).", signal, str);
393 ret = dbus_handle_emit_dbus_signal(NULL,
394 DEVICED_PATH_DISPLAY,
395 DEVICED_INTERFACE_DISPLAY,
397 g_variant_new("(si)", str, diff));
399 _E("Failed to send dbus signal(%s)", signal);
402 static void broadcast_lcd_off(enum signal_type type, enum device_flags flags)
408 if (type <= SIGNAL_INVALID || type >= SIGNAL_MAX) {
409 _E("Invalid signal type(%d).", type);
413 if (type == SIGNAL_PRE)
414 displayoff_time = clock_gettime_to_long();
416 signal = lcdoff_sig_lookup[type];
418 if (flags & LCD_OFF_BY_POWER_KEY)
420 else if (flags & LCD_OFF_BY_TIMEOUT)
422 else if (flags & LCD_OFF_BY_EVENT)
424 else if (flags & LCD_OFF_BY_PROXIMITY)
426 else if (flags & LCD_OFF_BY_PALM)
428 else if (flags & LCD_OFF_BY_GESTURE)
433 _I("lcdstep : Broadcast signal(%s).", signal);
434 ret = dbus_handle_emit_dbus_signal(NULL,
435 DEVICED_PATH_DISPLAY,
436 DEVICED_INTERFACE_DISPLAY,
438 g_variant_new("(s)", str));
440 _E("Failed to send dbus signal(%s)", signal);
443 void broadcast_lcd_off_late(enum device_flags flags)
445 static enum device_flags late_flags;
447 if (flags & LCD_OFF_LATE_MODE)
448 broadcast_lcd_off(SIGNAL_POST, late_flags);
453 static unsigned long get_lcd_on_flags(void)
455 unsigned long flags = NORMAL_MODE;
457 if (lcd_paneloff_mode)
458 flags |= LCD_PANEL_OFF_MODE;
460 if (ambient_get_condition() == true) {
461 flags |= AMBIENT_MODE;
462 flags |= LCD_PHASED_TRANSIT_MODE;
468 bool touch_event_blocked(void)
470 return touch_blocked;
473 static gboolean late_transit_on(void *data)
476 return G_SOURCE_REMOVE;
478 g_source_remove(transit_timer);
481 backlight_ops.transit_state(DPMS_ON);
482 return G_SOURCE_REMOVE;
485 void lcd_on_procedure(int state, enum device_flags flag)
488 const struct device_ops *ops = NULL;
489 unsigned long flags = get_lcd_on_flags();
493 * Display on procedure
494 * step 1. broadcast lcd on signal with cause
495 * step 2. set brightness
496 * step 3. set pmstate of vconf
497 * step 4. display on operate
499 * - b. TSP(touch screen) and touchkey enable
500 * step 5. broadcast lcd on complete siganl
501 * step 6. key backlight enable
503 _I("[lcdstep] 0x%lx", flags);
505 if (flags & AMBIENT_MODE) {
506 if (ambient_get_state() == false && backlight_ops.get_lcd_power() == DPMS_ON)
508 ambient_set_state(false);
511 /* send LCDOn dbus signal */
512 if (!lcdon_broadcast)
513 broadcast_lcd_on(SIGNAL_PRE, flags);
515 if (!(flags & LCD_PHASED_TRANSIT_MODE)) {
516 /* Update brightness level */
517 if (state == LCD_DIM)
519 else if (state == LCD_NORMAL)
520 backlight_ops.update();
523 if (state == LCD_NORMAL)
524 set_setting_pmstate(S_NORMAL);
525 else if (state == LCD_DIM)
526 set_setting_pmstate(S_LCDDIM);
528 DD_LIST_FOREACH(lcdon_ops, l, ops)
531 if (!lcdon_broadcast) {
532 broadcast_lcd_on(SIGNAL_POST, flags);
533 if (flags & LCD_PHASED_TRANSIT_MODE)
534 transit_timer = g_timeout_add_seconds(LATE_LCD_TRANSIT,
535 late_transit_on, NULL);
536 lcdon_broadcast = true;
539 if (CHECK_OPS(keyfilter_ops, backlight_enable))
540 keyfilter_ops->backlight_enable(true);
542 touch_blocked = false;
545 static unsigned long get_lcd_off_flags(void)
547 unsigned long flags = NORMAL_MODE;
549 if (ambient_get_condition() == true) {
550 flags |= AMBIENT_MODE;
551 flags |= LCD_PHASED_TRANSIT_MODE;
554 if (stay_touchscreen_off)
555 flags |= TOUCH_SCREEN_OFF_MODE;
560 inline void lcd_off_procedure(enum device_flags flag)
563 const struct device_ops *ops = NULL;
564 unsigned long flags = get_lcd_off_flags();
568 * Display off procedure
569 * step 0. enhance mode off using nofity (e.g mdnie, HBM, LBM)
570 * step 1. broadcast lcd off signal with cause
571 * step 2. set pmstate of vconf
572 * step 3. display off operate
574 * - b. TSP(touch screen) and touchkey disable
575 * step 4. broadcast lcd off complete siganl
577 _I("[lcdstep] 0x%lx", flags);
579 device_notify(DEVICE_NOTIFIER_LCD_OFF, NULL);
581 touch_blocked = true;
583 if (flags & AMBIENT_MODE) {
584 if (ambient_get_state() == true)
586 ambient_set_state(true);
589 if (lcdon_broadcast) {
590 broadcast_lcd_off(SIGNAL_PRE, flags);
591 lcdon_broadcast = false;
593 set_setting_pmstate(S_LCDOFF);
595 if (CHECK_OPS(keyfilter_ops, backlight_enable))
596 keyfilter_ops->backlight_enable(false);
599 g_source_remove(transit_timer);
603 if (flags & LCD_PHASED_TRANSIT_MODE)
604 backlight_ops.transit_state(DPMS_OFF);
606 DD_LIST_FOREACH(lcdon_ops, l, ops)
609 if (flags & AMBIENT_MODE)
610 broadcast_lcd_off_late(flags);
612 broadcast_lcd_off(SIGNAL_POST, flags);
614 device_notify(DEVICE_NOTIFIER_LCD_OFF_COMPLETE, NULL);
617 void set_stay_touchscreen_off(int val)
619 _I("Stay touch screen off: %d", val);
620 stay_touchscreen_off = val;
622 if (disp_plgn.pm_change_internal)
623 disp_plgn.pm_change_internal(INTERNAL_LOCK_PM, LCD_NORMAL);
626 void set_lcd_paneloff_mode(int val)
628 _I("Lcd paneloff mode: %d", val);
629 lcd_paneloff_mode = val;
631 if (disp_plgn.pm_change_internal)
632 disp_plgn.pm_change_internal(INTERNAL_LOCK_PM, LCD_NORMAL);
635 int low_battery_state(int val)
638 case VCONFKEY_SYSMAN_BAT_POWER_OFF:
639 case VCONFKEY_SYSMAN_BAT_CRITICAL_LOW:
640 case VCONFKEY_SYSMAN_BAT_REAL_POWER_OFF:
646 int get_hallic_open(void)
651 static int refresh_app_cond()
655 if (check_lock_state(S_NORMAL))
656 trans_condition = trans_condition | MASK_NORMAL;
657 if (check_lock_state(S_LCDDIM))
658 trans_condition = trans_condition | MASK_DIM;
659 if (check_lock_state(S_LCDOFF))
660 trans_condition = trans_condition | MASK_OFF;
665 static void makeup_trans_condition(void)
667 check_processes(S_NORMAL);
668 check_processes(S_LCDDIM);
669 check_processes(S_LCDOFF);
673 static PmLockNode *find_node(enum state_t s_index, pid_t pid)
676 PmLockNode *t = NULL;
678 DD_LIST_FOREACH(cond_head[s_index], elem, t) {
686 static PmLockNode *add_node(enum state_t s_index, pid_t pid, guint timeout_id,
689 guint warning_id = 0;
694 n = (PmLockNode *) malloc(sizeof(PmLockNode));
696 _E("Not enough memory, add cond. fail");
700 if (pid < INTERNAL_LOCK_BASE) {
701 v = g_variant_new("(ii)", s_index, pid);
703 warning_id = g_timeout_add_seconds(display_conf.lockcheck_timeout,
704 pmlock_check, (void *)v);
706 _E("Failed to make GVariant.");
713 n->timeout_id = timeout_id;
714 n->warning_id = warning_id;
715 n->warning_param = v;
717 n->holdkey_block = holdkey_block;
718 n->background = false;
719 n->broadcast_warning = true;
720 DD_LIST_APPEND(cond_head[s_index], n);
726 static int del_node(enum state_t s_index, PmLockNode *n)
731 DD_LIST_REMOVE(cond_head[s_index], n);
735 g_source_remove(n->timeout_id);
739 g_source_remove(n->warning_id);
742 if (n->warning_param) {
743 g_variant_unref(n->warning_param);
744 n->warning_param = NULL;
752 static void print_node(int next)
761 if (next <= S_START || next >= S_END)
765 DD_LIST_FOREACH(cond_head[next], elem, n) {
766 diff = difftime(now, n->time);
767 ctime_r(&n->time, buf);
768 buf[strlen(buf) - 1] = 0;
770 if (diff > LOCK_TIME_WARNING) {
771 if (diff > LOCK_TIME_WARNING * 60 && n->pid < INTERNAL_LOCK_BASE && n->broadcast_warning) {
772 ret = dbus_handle_emit_dbus_signal(NULL,
773 DEVICED_PATH_DISPLAY,
774 DEVICED_INTERFACE_DISPLAY,
776 g_variant_new("(i)", n->pid));
778 _E("Failed to send dbus signal pmlock_over.");
779 n->broadcast_warning = false;
781 _W("Over(%.0f s) pid( %5d) lock time(%s)", diff, n->pid, buf);
783 _I("Pid(%5d) lock time(%s)", n->pid, buf);
787 void get_pname(pid_t pid, char *pname)
792 if (pid >= INTERNAL_LOCK_BASE)
793 snprintf(buf, PATH_MAX, "/proc/%d/cmdline", getpid());
795 snprintf(buf, PATH_MAX, "/proc/%d/cmdline", pid);
797 cmdline = open(buf, O_RDONLY);
800 _E("Process(%d) does not exist now(may be dead without unlock).", pid);
804 r = read(cmdline, pname, PATH_MAX);
805 if ((r >= 0) && (r < PATH_MAX))
813 static void del_state_cond(void *data, enum state_t state)
815 PmLockNode *tmp = NULL;
821 /* A passed data is a pid_t type data, not a 64bit data. */
822 pid = (pid_t)((intptr_t)data);
823 _I("delete prohibit dim condition by timeout (%d)", pid);
825 if (pid == INTERNAL_LOCK_AMBIENT)
826 ambient_check_invalid_state(pid);
828 tmp = find_node(state, pid);
829 del_node(state, tmp);
830 set_unlock_time(pid, state);
833 states[pm_cur_state].trans(EVENT_TIMEOUT);
835 if (state == S_LCDOFF)
836 set_process_active(false, pid);
839 static gboolean del_normal_cond(void *data)
841 del_state_cond(data, S_NORMAL);
842 return G_SOURCE_REMOVE;
845 static gboolean del_dim_cond(void *data)
847 del_state_cond(data, S_LCDDIM);
848 return G_SOURCE_REMOVE;
851 static gboolean del_off_cond(void *data)
853 del_state_cond(data, S_LCDOFF);
854 return G_SOURCE_REMOVE;
857 static void pmlock_check_cb(GVariant *var, void *user_data, GError *err)
860 int ret, detected = 0;
862 enum state_t state = (enum state_t) user_data;
870 if (!dh_get_param_from_var(var, "(iis)", &pid, &detected, &app_id)) {
871 _E("Failed to get params from gvariant. expected:%s, type:%s", "(iis)", g_variant_get_type_string(var));
875 if (is_app(pid) == 1 && !detected)
878 node = find_node(state, pid);
883 diff = difftime(now, node->time);
885 CRITICAL_LOG("%s(%d) has held %s lock for a long time(%.0f s).",
886 app_id, pid, states[state].name + 2, diff);
888 ret = dbus_handle_emit_dbus_signal(NULL,
889 DEVICED_PATH_DISPLAY,
890 DEVICED_INTERFACE_DISPLAY,
892 g_variant_new("(i)", pid));
894 _E("Failed to send dbus pmlock_expired");
899 g_variant_unref(var);
903 * Any process is possible many time lock, deviced can not know malicious
904 * or good process. so infinity or more then 10 min lock process, deviced
905 * will check it through resoured. And then, it will ask the user whether to quit or not.
907 static gboolean pmlock_check(void *data)
910 char chr_pid[PID_MAX];
918 _E("Invalid parameter.");
919 return G_SOURCE_REMOVE;
923 g_variant_get(v, "(ii)", &state, &pid);
925 if (state == S_LCDOFF && backlight_ops.get_lcd_power() == DPMS_ON) {
926 _D("Lcd state is PM_LCD_POWER_ON");
927 return G_SOURCE_CONTINUE;
930 /* Stop checking lock if process had been terminated */
931 if (kill(pid, 0) == -1) {
932 node = find_node(state, pid);
933 del_node(state, node);
934 _I("Process %d not found. Stop checking lock.", pid);
935 return G_SOURCE_REMOVE;
938 snprintf(chr_pid, sizeof(chr_pid), "%d", pid);
951 _E("Invalid state.");
953 return G_SOURCE_REMOVE;
956 ret = dbus_handle_method_async_with_reply(RESOURCED_BUS_NAME,
957 RESOURCED_PATH_PROCESS,
958 RESOURCED_INTERFACE_PROCESS,
960 "is", arr, pmlock_check_cb, -1, (void *)(intptr_t)state);
962 _E("Failed to call dbus method");
964 return G_SOURCE_CONTINUE;
967 /* timeout handler */
968 gboolean timeout_handler(void *data)
970 _I("Time out state %s", states[pm_cur_state].name);
972 if (timeout_src_id) {
973 g_source_remove(timeout_src_id);
977 states[pm_cur_state].trans(EVENT_TIMEOUT);
978 return G_SOURCE_REMOVE;
981 void reset_timeout(int timeout)
983 if (!display_conf.timeout_enable)
986 if (pm_cur_state == S_LCDOFF
987 && (is_emulator() == true || display_conf.sleep_support == false))
990 _I("Reset timeout(%d ms).", timeout);
991 if (timeout_src_id != 0) {
992 g_source_remove(timeout_src_id);
996 if (trans_table[pm_cur_state][EVENT_TIMEOUT] == pm_cur_state)
1000 timeout_src_id = g_timeout_add(timeout,
1001 timeout_handler, NULL);
1002 else if (timeout == 0)
1003 states[pm_cur_state].trans(EVENT_TIMEOUT);
1006 /* get configurations from setting */
1007 static int get_lcd_timeout_from_settings(void)
1012 for (i = 0; i < S_END; i++) {
1013 switch (states[i].state) {
1015 get_run_timeout(&val);
1018 get_dim_timeout(&val);
1021 val = display_conf.lcdoff_timeout;
1024 /* This state doesn't need to set time out. */
1029 states[i].timeout = val;
1031 _I("State(%s) timeout(%d) ms", states[i].name,
1038 static void update_display_time(void)
1040 int run_timeout, val;
1042 /* first priority : s cover */
1044 states[S_NORMAL].timeout = S_COVER_TIMEOUT;
1045 _I("S cover closed: Timeout(%d ms) is set by normal.",
1050 /* second priority : custom timeout */
1051 if (custom_normal_timeout > 0) {
1052 states[S_NORMAL].timeout = custom_normal_timeout;
1053 states[S_LCDDIM].timeout = custom_dim_timeout;
1054 _I("CUSTOM : timeout is set by normal(%d ms), dim(%d ms)",
1055 custom_normal_timeout, custom_dim_timeout);
1059 /* third priority : lock state */
1060 if ((__get_lock_screen_state() == VCONFKEY_IDLE_LOCK) &&
1061 !get_lock_screen_bg_state()) {
1062 /* timeout is different according to key or event. */
1063 states[S_NORMAL].timeout = lock_screen_timeout;
1064 _I("LOCK: Timeout(%d ms) is set by normal.",
1065 lock_screen_timeout);
1069 /* default setting */
1070 get_run_timeout(&run_timeout);
1073 * if the run_timeout is zero, it regards AlwaysOn state
1075 if (run_timeout == 0 || display_conf.lcd_always_on) {
1076 run_timeout = ALWAYS_ON_TIMEOUT;
1077 _I("LCD always on.");
1080 states[S_NORMAL].timeout = run_timeout;
1082 get_dim_timeout(&val);
1083 states[S_LCDDIM].timeout = val;
1085 _I("Normal: NORMAL timeout is set by %d ms", states[S_NORMAL].timeout);
1086 _I("Normal: DIM timeout is set by %d ms", states[S_LCDDIM].timeout);
1089 static void update_display_locktime(int time)
1091 lock_screen_timeout = time;
1092 update_display_time();
1095 void set_dim_state(bool on)
1097 _I("Dim state is %d.", on);
1098 update_display_time();
1099 states[pm_cur_state].trans(EVENT_INPUT);
1102 static void broadcast_pm_suspend(void)
1107 if (pmstate_suspend)
1110 _D("PM will be changed to sleep.");
1112 pmstate_suspend = PM_SUSPEND;
1113 now = clock_gettime_to_long();
1114 ret = dbus_handle_emit_dbus_signal(NULL,
1115 DEVICED_PATH_DISPLAY,
1116 DEVICED_INTERFACE_DISPLAY,
1118 g_variant_new("(t)", (guint64)now));
1120 _E("Failed to send dbus signal sleep.");
1123 static void broadcast_pm_wakeup(void)
1128 if (!pmstate_suspend)
1131 _D("PM is changed to wakeup.");
1133 pmstate_suspend = PM_WAKEUP;
1134 now = clock_gettime_to_long();
1135 ret = dbus_handle_emit_dbus_signal(NULL,
1136 DEVICED_PATH_DISPLAY,
1137 DEVICED_INTERFACE_DISPLAY,
1139 g_variant_new("(t)", (guint64)now));
1141 _E("Failed to send dbus signal wakeup.");
1145 void lcd_on_direct(enum device_flags flags)
1147 if (power_ops.get_power_lock_support()
1148 && pm_cur_state == S_SLEEP) {
1149 broadcast_pm_wakeup();
1150 power_ops.power_lock();
1153 pm_cur_state = S_NORMAL;
1155 _D("lcd is on directly");
1156 gettimeofday(&lcdon_tv, NULL);
1157 lcd_on_procedure(LCD_NORMAL, flags);
1159 update_display_locktime(LOCK_SCREEN_INPUT_TIMEOUT);
1162 static inline bool check_lcd_is_on(void)
1164 if (backlight_ops.get_lcd_power() != DPMS_ON)
1170 static int check_lock_condition(enum state_t state)
1173 PmLockNode *t = NULL;
1175 pid_t owner = getpid();
1177 _D("check holdkey block : state of %s", states[state].name);
1179 DD_LIST_FOREACH(cond_head[state], elem, t) {
1180 if (t->pid != owner && t->background == false) {
1182 _I("state change was blocked by pid(%d)!", t->pid);
1190 static gboolean timer_refresh_cb(gpointer data)
1194 /* state transition */
1195 pm_old_state = pm_cur_state;
1196 pm_cur_state = S_NORMAL;
1197 st = &states[pm_cur_state];
1200 st->action(st->timeout);
1205 int custom_lcdon(int timeout)
1212 if (check_lcd_is_on() == false)
1213 lcd_on_direct(LCD_ON_BY_GESTURE);
1215 _I("Custom lcd on timeout(%d ms).", timeout);
1216 if (set_custom_lcdon_timeout(timeout) == true)
1217 update_display_time();
1219 /* state transition */
1220 pm_old_state = pm_cur_state;
1221 pm_cur_state = S_NORMAL;
1222 st = &states[pm_cur_state];
1226 st->action(st->timeout);
1228 g_idle_add(timer_refresh_cb, NULL);
1233 int custom_lcdoff(enum device_flags flag)
1237 check_processes(S_NORMAL);
1238 check_processes(S_LCDDIM);
1240 /* check holdkey block flag in lock node */
1241 if (check_lock_condition(S_NORMAL) || check_lock_condition(S_LCDDIM)) {
1243 * When another proccess is normal lock, device is received call then,
1244 * call app can be changed to lcd state by proximity.
1245 * If proximity is near then normal lock will be unlocked.
1247 if (flag & LCD_OFF_BY_PROXIMITY) {
1248 _I("custom lcd off by proximity, delete normal lock");
1249 delete_condition(S_NORMAL);
1251 _I("skip custom lcd off");
1256 _I("custom lcd off by flag(%d)", flag);
1257 if (backlight_ops.get_lcd_power() == DPMS_ON)
1258 lcd_off_procedure(flag);
1260 if (set_custom_lcdon_timeout(0) == true)
1261 update_display_time();
1263 /* state transition */
1264 pm_old_state = pm_cur_state;
1265 pm_cur_state = S_LCDOFF;
1266 st = &states[pm_cur_state];
1270 st->action(st->timeout);
1275 int display_on_by_reason(const char *reason, int timeout)
1281 str_len = strlen(reason);
1283 if (!strncmp(reason, GESTURE_STR, str_len))
1284 flag = LCD_ON_BY_GESTURE;
1285 else if (!strncmp(reason, EVENT_STR, str_len))
1286 flag = LCD_ON_BY_EVENT;
1288 _E("Reason is unkown(%s)", reason);
1293 _E("Cannot setting timeout %d", timeout);
1297 if (check_lcd_is_on() == false)
1298 lcd_on_direct(flag);
1300 _I("platform lcd on by %s (%d ms)", reason, timeout);
1301 if (set_custom_lcdon_timeout(timeout) == true)
1302 update_display_time();
1304 /* state transition */
1305 pm_old_state = pm_cur_state;
1306 pm_cur_state = S_NORMAL;
1307 st = &states[pm_cur_state];
1311 st->action(st->timeout);
1316 int display_off_by_reason(const char *reason)
1322 str_len = strlen(reason);
1324 if (!strncmp(reason, GESTURE_STR, str_len)) {
1325 check_processes(S_NORMAL);
1326 check_processes(S_LCDDIM);
1328 /* check holdkey block flag in lock node */
1329 if (check_lock_condition(S_NORMAL) || check_lock_condition(S_LCDDIM)) {
1330 _I("skip platform lcd off by gesture");
1333 flag = LCD_OFF_BY_GESTURE;
1334 } else if (!strncmp(reason, PALM_STR, str_len)) {
1335 delete_condition(S_NORMAL);
1336 delete_condition(S_LCDDIM);
1338 flag = LCD_OFF_BY_PALM;
1340 _E("Reason is unkown(%s)", reason);
1344 _I("platform lcd off by %s", reason);
1345 if (backlight_ops.get_lcd_power() == DPMS_ON)
1346 lcd_off_procedure(flag);
1348 /* state transition */
1349 pm_old_state = pm_cur_state;
1350 pm_cur_state = S_LCDOFF;
1351 st = &states[pm_cur_state];
1355 st->action(st->timeout);
1360 static void default_proc_change_state_action(enum state_t next, int timeout)
1364 pm_old_state = pm_cur_state;
1365 pm_cur_state = next;
1367 st = &states[pm_cur_state];
1369 if (st && st->action) {
1371 st->action(st->timeout);
1373 st->action(timeout);
1377 static int default_proc_change_state(unsigned int cond, pid_t pid)
1381 next = GET_COND_STATE(cond);
1382 _I("Change process(%d) state to %s.", pid, states[next].name);
1386 if (check_lcd_is_on() == false)
1387 lcd_on_direct(LCD_ON_BY_EVENT);
1388 update_display_locktime(LOCK_SCREEN_CONTROL_TIMEOUT);
1389 default_proc_change_state_action(next, -1);
1392 default_proc_change_state_action(next, -1);
1395 if (backlight_ops.get_lcd_power() == DPMS_ON) {
1396 if (get_proximity_state() == SENSOR_PROXIMITY_NEAR)
1397 lcd_off_procedure(LCD_OFF_BY_PROXIMITY);
1399 lcd_off_procedure(LCD_OFF_BY_EVENT);
1401 if (set_custom_lcdon_timeout(0))
1402 update_display_time();
1403 default_proc_change_state_action(next, -1);
1406 _I("Dangerous requests.");
1407 /* at first LCD_OFF and then goto sleep */
1408 /* state transition */
1409 default_proc_change_state_action(S_LCDOFF, TIMEOUT_NONE);
1410 delete_condition(S_NORMAL);
1411 delete_condition(S_LCDDIM);
1412 delete_condition(S_LCDOFF);
1413 if (lcdon_broadcast) {
1414 _I("broadcast lcd off signal at non-lcd device");
1415 broadcast_lcd_off(SIGNAL_PRE, 0);
1416 broadcast_lcd_off(SIGNAL_POST, 0);
1418 default_proc_change_state_action(S_SLEEP, TIMEOUT_NONE);
1428 /* update transition condition for application requrements */
1429 static void update_lock_timer(PMMsg *data,
1430 PmLockNode *node, guint timeout_id)
1434 if (data->timeout > 0) {
1439 if (node->timeout_id)
1440 g_source_remove(node->timeout_id);
1441 node->timeout_id = timeout_id;
1444 static void proc_condition_lock(PMMsg *data)
1447 guint cond_timeout_id = 0;
1448 char pname[PATH_MAX];
1449 pid_t pid = data->pid;
1451 int holdkey_block,ret;
1456 state = GET_COND_STATE(data->cond);
1457 if (state == S_START)
1460 flags = GET_COND_FLAG(data->cond);
1461 get_pname(pid, pname);
1463 if (state == S_LCDOFF && pm_cur_state == S_SLEEP &&
1464 power_ops.get_power_lock() == POWER_UNLOCK)
1465 proc_change_state(data->cond, INTERNAL_LOCK_PM);
1467 if (data->timeout > 0) {
1468 /* To pass a pid_t data through the timer infrastructure
1469 * without memory allocation, a pid_t data becomes typecast
1470 * to intptr_t and void *(64bit) type. */
1471 cond_timeout_id = g_timeout_add(
1473 states[state].timeout_cb,
1474 (void*)((intptr_t)pid));
1475 if (!cond_timeout_id)
1476 _E("Failed to register display timer.");
1479 holdkey_block = GET_COND_FLAG(data->cond) & PM_FLAG_BLOCK_HOLDKEY;
1481 tmp = find_node(state, pid);
1483 add_node(state, pid, cond_timeout_id, holdkey_block);
1485 update_lock_timer(data, tmp, cond_timeout_id);
1486 tmp->holdkey_block = holdkey_block;
1489 if (state == S_LCDOFF)
1490 set_process_active(true, pid);
1492 _I("[%s] locked by %5d with %u ms", states[state].name, pid, data->timeout);
1494 if (state == S_LCDOFF)
1495 lock_type = PM_LCDOFF_STR;
1496 else if (state == S_LCDDIM)
1497 lock_type = PM_LCDDIM_STR;
1498 else if (state == S_NORMAL)
1499 lock_type = PM_LCDON_STR;
1501 goto skip_broadcast_signal;
1503 /* power lock signal */
1504 ret = dbus_handle_emit_dbus_signal(NULL,
1505 DEVICED_PATH_DISPLAY,
1506 DEVICED_INTERFACE_DISPLAY,
1508 g_variant_new("(sii)", lock_type, pid, (int)data->timeout));
1510 _E("Failed to send dbus signal PowerLock.");
1512 skip_broadcast_signal:
1513 _SD("be requested LOCK info pname(%s), holdkeyblock(%d) flags(%d)",
1514 pname, holdkey_block, flags);
1515 set_lock_time(pid, pname, state);
1517 device_notify(DEVICE_NOTIFIER_DISPLAY_LOCK, (void *)&value);
1520 static void proc_condition_unlock(PMMsg *data)
1522 pid_t pid = data->pid;
1525 char pname[PATH_MAX];
1531 state = GET_COND_STATE(data->cond);
1535 flags = GET_COND_FLAG(data->cond);
1536 get_pname(pid, pname);
1538 tmp = find_node(state, pid);
1539 del_node(state, tmp);
1541 if (state == S_LCDOFF)
1542 set_process_active(false, pid);
1544 _I("[%s] unlocked by %5d", states[state].name, pid);
1546 if (state == S_LCDOFF)
1547 lock_type = PM_LCDOFF_STR;
1548 else if (state == S_LCDDIM)
1549 lock_type = PM_LCDDIM_STR;
1550 else if (state == S_NORMAL)
1551 lock_type = PM_LCDON_STR;
1553 goto skip_broadcast_signal;
1555 /* power unlock signal */
1556 ret = dbus_handle_emit_dbus_signal(NULL,
1557 DEVICED_PATH_DISPLAY,
1558 DEVICED_INTERFACE_DISPLAY,
1560 g_variant_new("(sii)", lock_type, pid, (int)data->timeout));
1562 _E("Failed to send dbus signal PowerUnlock.");
1564 skip_broadcast_signal:
1565 _SD("be requested UNLOCK info pname(%s) flag(%d)", pname, flags);
1566 set_unlock_time(pid, state);
1568 device_notify(DEVICE_NOTIFIER_DISPLAY_LOCK, (void *)&value);
1571 static int proc_condition(PMMsg *data)
1575 if (IS_COND_REQUEST_LOCK(data->cond))
1576 proc_condition_lock(data);
1578 if (IS_COND_REQUEST_UNLOCK(data->cond))
1579 proc_condition_unlock(data);
1581 if (!display_conf.timeout_enable)
1584 flags = GET_COND_FLAG(data->cond);
1586 /* guard time for suspend */
1587 if (pm_cur_state == S_LCDOFF)
1588 reset_timeout(states[S_LCDOFF].timeout);
1590 if (flags & PM_FLAG_RESET_TIMER)
1591 reset_timeout(states[pm_cur_state].timeout);
1594 if (!timeout_src_id)
1595 states[pm_cur_state].trans(EVENT_TIMEOUT);
1600 /* If some changed, return 1 */
1601 int check_processes(enum state_t prohibit_state)
1603 dd_list *elem, *next;
1604 PmLockNode *t = NULL;
1607 DD_LIST_FOREACH_SAFE(cond_head[prohibit_state], elem, next, t) {
1608 if (t->pid < INTERNAL_LOCK_BASE && kill(t->pid, 0) == -1) {
1609 _E("%d process does not exist, delete the REQ"
1610 " - prohibit state %d ",
1611 t->pid, prohibit_state);
1612 if (t->pid == custom_change_pid) {
1613 get_lcd_timeout_from_settings();
1614 custom_normal_timeout = custom_dim_timeout = 0;
1615 custom_change_pid = -1;
1618 set_unlock_time(t->pid, prohibit_state);
1619 del_node(prohibit_state, t);
1626 int check_holdkey_block(enum state_t state)
1629 PmLockNode *t = NULL;
1632 _I("Check holdkey block: state of %s", states[state].name);
1634 if (custom_holdkey_block == true) {
1635 _I("Custom hold key blocked by pid(%d).",
1640 DD_LIST_FOREACH(cond_head[state], elem, t) {
1641 if (t->holdkey_block == true) {
1643 _I("Hold key blocked by pid(%d).", t->pid);
1651 int delete_condition(enum state_t state)
1653 dd_list *elem, *next;
1654 PmLockNode *t = NULL;
1656 _I("delete condition : state of %s", states[state].name);
1658 if (!cond_head[state])
1661 DD_LIST_FOREACH_SAFE(cond_head[state], elem, next, t) {
1662 if (t->timeout_id > 0) {
1663 g_source_remove(t->timeout_id);
1666 if (state == S_LCDOFF)
1667 set_process_active(false, t->pid);
1668 _I("delete node of pid(%d)", t->pid);
1669 set_unlock_time(t->pid, state);
1673 DD_LIST_FREE_LIST(cond_head[state]);
1674 cond_head[state] = NULL;
1679 void update_lcdoff_source(int source)
1684 case VCONFKEY_PM_LCDOFF_BY_TIMEOUT:
1685 _I("LCD OFF by timeout.");
1687 case VCONFKEY_PM_LCDOFF_BY_POWERKEY:
1688 _I("LCD OFF by powerkey.");
1691 _E("Invalid value(%d).", source);
1694 ret = vconf_set_int(VCONFKEY_PM_LCDOFF_SOURCE, source);
1696 _E("Failed to set vconf value for lcd off source: %d", vconf_get_ext_errno());
1699 #ifdef ENABLE_PM_LOG
1701 typedef struct _pm_history {
1703 enum pm_log_type log_type;
1707 static int max_history_count = MAX_LOG_COUNT;
1708 static pm_history pm_history_log[MAX_LOG_COUNT] = {{0, }, };
1709 static int history_count = 0;
1711 static const char history_string[PM_LOG_MAX][15] = {
1712 "PRESS", "LONG PRESS", "RELEASE", "LCD ON", "LCD ON COMPL", "LCD ON FAIL",
1713 "LCD DIM", "LCD DIM FAIL", "LCD OFF", "LCD OFF COMPL", "LCD OFF FAIL",
1714 "LCD FAIL", "SLEEP"};
1716 void pm_history_init()
1718 memset(pm_history_log, 0x0, sizeof(pm_history_log));
1720 max_history_count = MAX_LOG_COUNT;
1723 void pm_history_save(enum pm_log_type log_type, int code)
1728 pm_history_log[history_count].time = now;
1729 pm_history_log[history_count].log_type = log_type;
1730 pm_history_log[history_count].keycode = code;
1733 if (history_count >= max_history_count)
1737 void pm_history_print(int fd, int count)
1739 int start_index, index, i;
1744 if (count <= 0 || count > max_history_count)
1747 start_index = (history_count - count + max_history_count)
1748 % max_history_count;
1750 for (i = 0; i < count; i++) {
1751 index = (start_index + i) % max_history_count;
1753 if (pm_history_log[index].time == 0)
1756 if (pm_history_log[index].log_type < PM_LOG_MIN ||
1757 pm_history_log[index].log_type >= PM_LOG_MAX)
1759 ctime_r(&pm_history_log[index].time, time_buf);
1760 time_buf[strlen(time_buf) - 1] = 0;
1761 snprintf(buf, sizeof(buf), "[%3d] %15s %3d %s\n",
1763 history_string[pm_history_log[index].log_type],
1764 pm_history_log[index].keycode,
1766 ret = write(fd, buf, strlen(buf));
1768 _E("Write() failed: %d", errno);
1773 void print_info(int fd)
1776 char buf[PATH_MAX + 255];
1779 char pname[PATH_MAX];
1787 snprintf(buf, sizeof(buf),
1788 "\n==========================================="
1789 "===========================\n");
1790 ret = write(fd, buf, strlen(buf));
1792 _E("Write() failed: %d", errno);
1793 snprintf(buf, sizeof(buf), "Timeout Info: Run[%dms] Dim[%dms] Off[%dms]\n",
1794 states[S_NORMAL].timeout,
1795 states[S_LCDDIM].timeout, states[S_LCDOFF].timeout);
1796 ret = write(fd, buf, strlen(buf));
1798 _E("Write() failed: %d", errno);
1800 snprintf(buf, sizeof(buf), "Tran. Locked : %s %s %s\n",
1801 (trans_condition & MASK_NORMAL) ? states[S_NORMAL].name : "-",
1802 (trans_condition & MASK_DIM) ? states[S_LCDDIM].name : "-",
1803 (trans_condition & MASK_OFF) ? states[S_LCDOFF].name : "-");
1804 ret = write(fd, buf, strlen(buf));
1806 _E("Write() failed: %d", errno);
1808 snprintf(buf, sizeof(buf), "Current State: %s\n",
1809 states[pm_cur_state].name);
1810 ret = write(fd, buf, strlen(buf));
1812 _E("Write() failed: %d", errno);
1814 snprintf(buf, sizeof(buf), "Current Lock Conditions: \n");
1815 ret = write(fd, buf, strlen(buf));
1817 _E("Write() failed: %d", errno);
1819 for (s_index = S_NORMAL; s_index < S_END; s_index++) {
1820 DD_LIST_FOREACH(cond_head[s_index], elem, t) {
1821 get_pname((pid_t)t->pid, pname);
1822 ctime_r(&t->time, time_buf);
1823 time_buf[strlen(time_buf) - 1] = 0;
1824 snprintf(buf, sizeof(buf),
1825 " %d: [%s] locked by pid %d %s %s\n",
1826 i++, states[s_index].name, t->pid, pname, time_buf);
1827 ret = write(fd, buf, strlen(buf));
1829 _E("Write() failed: %d", errno);
1833 print_lock_info_list(fd);
1835 #ifdef ENABLE_PM_LOG
1836 pm_history_print(fd, 250);
1840 void save_display_log(const char *path)
1847 _D("internal state is saved!");
1850 ctime_r(&now_time, time_buf);
1851 time_buf[strlen(time_buf) - 1] = 0;
1853 fd = open(path, O_CREAT | O_TRUNC | O_WRONLY, 0644);
1855 snprintf(buf, sizeof(buf),
1856 "\npm_state_log now-time : %d(s) %s\n\n",
1857 (int)now_time, time_buf);
1858 ret = write(fd, buf, strlen(buf));
1860 _E("write() failed (%d)", errno);
1862 snprintf(buf, sizeof(buf), "pm_status_flag: %#x\n", pm_status_flag);
1863 ret = write(fd, buf, strlen(buf));
1865 _E("write() failed (%d)", errno);
1867 if (disp_plgn.get_lock_screen_state ) {
1868 snprintf(buf, sizeof(buf), "screen lock status : %d\n",
1869 disp_plgn.get_lock_screen_state());
1870 ret = write(fd, buf, strlen(buf));
1872 _E("write() failed (%d)", errno);
1878 fd = open("/dev/console", O_WRONLY);
1885 /* SIGHUP signal handler
1886 * For debug... print info to syslog
1888 static void sig_hup(int signo)
1890 _I("received sig hub %d", signo);
1895 int check_lcdoff_direct(void)
1897 int ret, lock, cradle;
1900 if (pm_old_state != S_NORMAL)
1903 if (pm_cur_state != S_LCDDIM)
1906 if (!display_conf.dimming)
1909 lock = __get_lock_screen_state();
1910 if (lock != VCONFKEY_IDLE_LOCK && hallic_open)
1913 hdmi_state = extcon_get_status(EXTCON_CABLE_HDMI);
1917 ret = vconf_get_int(VCONFKEY_SYSMAN_CRADLE_STATUS, &cradle);
1918 if (ret >= 0 && cradle == DOCK_SOUND)
1921 _E("Failed to get vconf value for cradle status: %d", vconf_get_ext_errno());
1923 _D("Goto LCDOFF direct: lock(%d) hdmi(%d) cradle(%d).", lock, hdmi_state, cradle);
1928 static int __check_lcdoff_lock_state(void)
1930 if (cond_head[S_LCDOFF] != NULL)
1937 * default transition function
1940 * 3. call enter action function
1942 static int default_trans(int evt)
1944 struct state *st = &states[pm_cur_state];
1947 next_state = (enum state_t)trans_table[pm_cur_state][evt];
1949 /* check conditions */
1950 while (st->check && !st->check(pm_cur_state, next_state)) {
1951 /* There is a condition. */
1952 _I("%s locked. Trans to %s failed.", states[pm_cur_state].name,
1953 states[next_state].name);
1954 if (!check_processes(pm_cur_state)) {
1955 /* This is valid condition
1956 * The application that sent the condition is running now. */
1961 /* state transition */
1962 pm_old_state = pm_cur_state;
1963 pm_cur_state = next_state;
1964 st = &states[pm_cur_state];
1968 if (pm_cur_state == S_LCDOFF)
1969 update_lcdoff_source(VCONFKEY_PM_LCDOFF_BY_TIMEOUT);
1971 if (pm_cur_state == S_NORMAL || pm_cur_state == S_LCDOFF)
1972 if (set_custom_lcdon_timeout(0) == true)
1973 update_display_time();
1975 if (check_lcdoff_direct() == true) {
1976 /* enter next state directly */
1977 states[pm_cur_state].trans(EVENT_TIMEOUT);
1979 if (pm_cur_state == S_SLEEP
1980 && (is_emulator() == true || display_conf.sleep_support == false))
1983 st->action(st->timeout);
1990 static gboolean lcd_on_expired(void *data)
1992 int lock_state, ret;
1994 if (lock_timeout_id)
1995 lock_timeout_id = 0;
1997 /* check state of lock */
1998 ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
1999 if (ret > 0 && lock_state == VCONFKEY_IDLE_LOCK)
2000 return G_SOURCE_REMOVE;
2002 _E("Failed to get vconf value for idle lock state: %d", vconf_get_ext_errno());
2004 /* lock screen is not launched yet, but lcd is on */
2005 if (check_lcd_is_on() == false)
2006 lcd_on_procedure(LCD_NORMAL, NORMAL_MODE);
2008 return G_SOURCE_REMOVE;
2011 static inline void stop_lock_timer(void)
2013 if (lock_timeout_id) {
2014 g_source_remove(lock_timeout_id);
2015 lock_timeout_id = 0;
2019 static void check_lock_screen(void)
2021 int lock_state, ret;
2025 /* check state of lock */
2026 ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
2027 if (ret < 0 || lock_state == VCONFKEY_IDLE_LOCK)
2030 /* Use time to check lock is done. */
2031 lock_timeout_id = g_timeout_add(display_conf.lock_wait_time,
2032 lcd_on_expired, NULL);
2035 /* default enter action function */
2036 static int default_action(int timeout)
2038 int wakeup_count = -1;
2041 static time_t last_update_time = 0;
2042 static int last_timeout = 0;
2043 struct timeval now_tv;
2045 if (status != DEVICE_OPS_STATUS_START) {
2046 _E("Display is not started.");
2050 if (pm_cur_state != S_SLEEP) {
2051 if (pm_cur_state == S_NORMAL &&
2052 lcdon_tv.tv_sec != 0) {
2053 gettimeofday(&now_tv, NULL);
2054 timeout -= DIFF_TIMEVAL_MS(now_tv, lcdon_tv);
2055 lcdon_tv.tv_sec = 0;
2057 /* set timer with current state timeout */
2058 reset_timeout(timeout);
2060 if (pm_cur_state == S_NORMAL) {
2061 time(&last_update_time);
2062 last_timeout = timeout;
2064 _I("Timout set: %s state %d ms",
2065 states[pm_cur_state].name, timeout);
2069 if (pm_cur_state != pm_old_state && pm_cur_state != S_SLEEP) {
2070 if (power_ops.get_power_lock_support()) {
2071 broadcast_pm_wakeup();
2072 power_ops.power_lock();
2074 set_setting_pmstate(pm_cur_state);
2075 device_notify(DEVICE_NOTIFIER_LCD, (void *)&pm_cur_state);
2078 if (pm_old_state == S_NORMAL && pm_cur_state != S_NORMAL) {
2080 diff = difftime(now, last_update_time);
2081 _I("S_NORMAL is changed to %s (timeout=%d ms diff=%.0f s).",
2082 states[pm_cur_state].name, last_timeout, diff);
2085 switch (pm_cur_state) {
2088 * normal state : backlight on and restore
2089 * the previous brightness
2091 if (pm_old_state == S_LCDOFF || pm_old_state == S_SLEEP)
2092 check_lock_screen();
2093 else if (pm_old_state == S_LCDDIM)
2094 backlight_ops.update();
2096 if (check_lcd_is_on() == false)
2097 lcd_on_procedure(LCD_NORMAL, NORMAL_MODE);
2101 if (pm_old_state == S_NORMAL &&
2102 backlight_ops.get_custom_status())
2103 backlight_ops.save_custom_brightness();
2104 /* lcd dim state : dim the brightness */
2105 backlight_ops.dim();
2107 if (pm_old_state == S_LCDOFF || pm_old_state == S_SLEEP)
2108 lcd_on_procedure(LCD_DIM, NORMAL_MODE);
2112 if (pm_old_state != S_SLEEP && pm_old_state != S_LCDOFF) {
2114 /* lcd off state : turn off the backlight */
2115 if (backlight_ops.get_lcd_power() == DPMS_ON)
2116 lcd_off_procedure(LCD_OFF_BY_TIMEOUT);
2119 if (backlight_ops.get_lcd_power() == DPMS_ON
2120 || lcd_paneloff_mode)
2121 lcd_off_procedure(LCD_OFF_BY_TIMEOUT);
2125 if (pm_old_state != S_SLEEP && pm_old_state != S_LCDOFF)
2128 if (backlight_ops.get_lcd_power() == DPMS_ON)
2129 lcd_off_procedure(LCD_OFF_BY_TIMEOUT);
2131 if (!power_ops.get_power_lock_support()) {
2132 /* sleep state : set system mode to SUSPEND */
2133 if (power_ops.get_wakeup_count(&wakeup_count) < 0)
2134 _E("Wakeup count read error.");
2136 if (wakeup_count < 0) {
2137 _I("Wakup Event. Can not enter suspend mode.");
2141 if (power_ops.set_wakeup_count(wakeup_count) < 0) {
2142 _E("Wakeup count write error.");
2152 #ifdef ENABLE_PM_LOG
2153 pm_history_save(PM_LOG_SLEEP, pm_cur_state);
2155 broadcast_pm_suspend();
2156 if (power_ops.get_power_lock_support()) {
2157 if (power_ops.enable_autosleep)
2158 power_ops.enable_autosleep();
2160 if (power_ops.power_unlock() < 0)
2161 _E("Power unlock state error.");
2163 power_ops.suspend();
2164 _I("system wakeup!!");
2165 system_wakeup_flag = true;
2167 if (power_ops.check_wakeup_src() == EVENT_DEVICE)
2168 /* system waked up by devices */
2169 states[pm_cur_state].trans(EVENT_DEVICE);
2171 /* system waked up by user input */
2172 states[pm_cur_state].trans(EVENT_INPUT);
2177 if (!power_ops.get_power_lock_support()) {
2179 states[pm_cur_state].trans(EVENT_DEVICE);
2185 * default check function
2187 * 0 : can't transit, others : transitable
2189 static int default_check(int curr, int next)
2193 makeup_trans_condition();
2195 trans_cond = trans_condition & MASK_BIT;
2197 if (next == S_NORMAL) /* S_NORMAL is exceptional */
2202 trans_cond = trans_cond & MASK_NORMAL;
2205 trans_cond = trans_cond & MASK_DIM;
2208 trans_cond = trans_cond & MASK_OFF;
2215 if (trans_cond != 0) {
2220 return 1; /* transitable */
2223 static void default_saving_mode(int onoff)
2226 pm_status_flag |= PWRSV_FLAG;
2228 pm_status_flag &= ~PWRSV_FLAG;
2230 if (pm_cur_state == S_NORMAL)
2231 backlight_ops.update();
2234 static int poll_callback(int condition, PMMsg *data)
2236 static time_t last_t;
2239 if (status != DEVICE_OPS_STATUS_START) {
2240 _E("Display logic is not started.");
2244 if (condition == INPUT_POLL_EVENT) {
2245 if (pm_cur_state == S_LCDOFF || pm_cur_state == S_SLEEP)
2246 _I("Input event signal at Display Off");
2248 if (last_t != now ||
2249 pm_cur_state == S_LCDOFF ||
2250 pm_cur_state == S_SLEEP) {
2251 states[pm_cur_state].trans(EVENT_INPUT);
2256 if (condition == PM_CONTROL_EVENT) {
2257 proc_condition(data);
2259 if (IS_COND_REQUEST_CHANGE(data->cond))
2260 proc_change_state(data->cond, data->pid);
2266 static int update_setting(int key_idx, int val)
2271 case SETTING_TO_NORMAL:
2272 update_display_time();
2273 states[pm_cur_state].trans(EVENT_INPUT);
2275 case SETTING_HALLIC_OPEN:
2277 update_display_time();
2278 if (pm_cur_state == S_NORMAL || pm_cur_state == S_LCDDIM)
2279 states[pm_cur_state].trans(EVENT_INPUT);
2280 else if (pm_cur_state == S_SLEEP && hallic_open)
2281 proc_change_state(S_LCDOFF, INTERNAL_LOCK_HALLIC);
2283 case SETTING_LOW_BATT:
2284 if (low_battery_state(val)) {
2285 if (!(pm_status_flag & CHRGR_FLAG))
2286 power_saving_func(true);
2287 pm_status_flag |= LOWBT_FLAG;
2289 if (pm_status_flag & PWRSV_FLAG)
2290 power_saving_func(false);
2291 pm_status_flag &= ~LOWBT_FLAG;
2292 pm_status_flag &= ~BRTCH_FLAG;
2293 ret = vconf_set_bool(VCONFKEY_PM_BRIGHTNESS_CHANGED_IN_LPM, false);
2295 _E("Failed to set vconf value for brightness changed in lpm: %d", vconf_get_ext_errno());
2298 case SETTING_CHARGING:
2300 if (pm_status_flag & LOWBT_FLAG) {
2301 power_saving_func(false);
2302 pm_status_flag &= ~LOWBT_FLAG;
2304 pm_status_flag |= CHRGR_FLAG;
2307 ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW,
2310 bat_state = VCONFKEY_SYSMAN_BAT_NORMAL;
2311 _E("Failed to get vconf value for battery status low: %d", vconf_get_ext_errno());
2313 if (low_battery_state(bat_state)) {
2314 power_saving_func(true);
2315 pm_status_flag |= LOWBT_FLAG;
2317 pm_status_flag &= ~CHRGR_FLAG;
2320 case SETTING_BRT_LEVEL:
2321 if (pm_status_flag & PWRSV_FLAG) {
2322 pm_status_flag |= BRTCH_FLAG;
2323 ret = vconf_set_bool(VCONFKEY_PM_BRIGHTNESS_CHANGED_IN_LPM, true);
2325 _E("Failed to set vconf value for brightness changed in lpm: %d", vconf_get_ext_errno());
2326 _I("Brightness changed in low battery,"
2327 "escape dim state.");
2329 backlight_ops.set_default_brt(val);
2331 case SETTING_LOCK_SCREEN:
2332 set_lock_screen_state(val);
2333 if (val == VCONFKEY_IDLE_UNLOCK) {
2334 if (CHECK_OPS(keyfilter_ops, backlight_enable))
2335 keyfilter_ops->backlight_enable(false);
2338 /* LCD on if lock screen show before waiting time */
2339 if (pm_cur_state == S_NORMAL &&
2340 val == VCONFKEY_IDLE_LOCK &&
2341 backlight_ops.get_lcd_power() != DPMS_ON &&
2342 is_lcdon_blocked() == LCDON_BLOCK_NONE)
2343 lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
2345 update_display_time();
2346 if (pm_cur_state == S_NORMAL)
2347 states[pm_cur_state].trans(EVENT_INPUT);
2349 case SETTING_LOCK_SCREEN_BG:
2350 set_lock_screen_bg_state(val);
2351 update_display_time();
2352 if (pm_cur_state == S_NORMAL)
2353 states[pm_cur_state].trans(EVENT_INPUT);
2355 case SETTING_POWEROFF:
2357 case POWEROFF_TYPE_NONE:
2358 pm_status_flag &= ~PWROFF_FLAG;
2360 case POWEROFF_TYPE_DIRECT:
2361 case POWEROFF_TYPE_RESTART:
2362 pm_status_flag |= PWROFF_FLAG;
2366 case SETTING_POWER_CUSTOM_BRIGHTNESS:
2367 if (val == VCONFKEY_PM_CUSTOM_BRIGHTNESS_ON)
2368 backlight_ops.set_custom_status(true);
2370 backlight_ops.set_custom_status(false);
2379 static void check_seed_status(void)
2387 /* Charging check */
2388 if ((get_charging_status(&tmp) == 0) && (tmp > 0))
2389 pm_status_flag |= CHRGR_FLAG;
2391 ret = get_setting_brightness(&tmp);
2392 if (ret != 0 || (tmp < PM_MIN_BRIGHTNESS || tmp > PM_MAX_BRIGHTNESS)) {
2393 _I("Failed to read vconf value for brightness.");
2394 brt = display_conf.pm_default_brightness;
2395 if (tmp < PM_MIN_BRIGHTNESS || tmp > PM_MAX_BRIGHTNESS) {
2396 ret = vconf_set_int(VCONFKEY_SETAPPL_LCD_BRIGHTNESS, brt);
2398 _E("Failed to set vconf value for lcd brightness: %d", vconf_get_ext_errno());
2402 _I("Set brightness(%d) from setting app.", tmp);
2403 backlight_ops.set_default_brt(tmp);
2404 backlight_ops.set_brightness(tmp);
2406 ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, &bat_state);
2408 bat_state = VCONFKEY_SYSMAN_BAT_NORMAL;
2409 _E("Failed to get vconf value for battery status low: %d", vconf_get_ext_errno());
2411 if (low_battery_state(bat_state)) {
2412 if (!(pm_status_flag & CHRGR_FLAG)) {
2413 power_saving_func(true);
2414 pm_status_flag |= LOWBT_FLAG;
2418 /* lock screen check */
2419 ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
2422 _E("Failed to get vconf value for idle lock state: %d", vconf_get_ext_errno());
2424 set_lock_screen_state(lock_state);
2425 if (lock_state == VCONFKEY_IDLE_LOCK) {
2426 states[S_NORMAL].timeout = lock_screen_timeout;
2427 _I("LCD NORMAL timeout(%d ms) is set"
2428 " for lock screen.", lock_screen_timeout);
2434 static void init_lcd_operation(void)
2436 const struct device_ops *ops = NULL;
2438 ops = find_device("display");
2439 if (!check_default(ops))
2440 DD_LIST_APPEND(lcdon_ops, ops);
2442 ops = find_device("touchkey");
2443 if (!check_default(ops))
2444 DD_LIST_APPEND(lcdon_ops, ops);
2446 ops = find_device("touchscreen");
2447 if (!check_default(ops))
2448 DD_LIST_APPEND(lcdon_ops, ops);
2451 static void exit_lcd_operation(void)
2454 dd_list *l_next = NULL;
2455 const struct device_ops *ops = NULL;
2457 DD_LIST_FOREACH_SAFE(lcdon_ops, l, l_next, ops)
2458 DD_LIST_REMOVE_LIST(lcdon_ops, l);
2470 static const char *errMSG[INIT_END] = {
2471 [INIT_SETTING] = "setting init error",
2472 [INIT_INTERFACE] = "lowlevel interface(sysfs or others) init error",
2473 [INIT_POLL] = "input devices poll init error",
2474 [INIT_FIFO] = "FIFO poll init error",
2475 [INIT_DBUS] = "d-bus init error",
2478 int set_lcd_timeout(int on, int dim, int holdkey_block, const char *name)
2480 if (on == 0 && dim == 0) {
2481 _I("LCD timeout changed: default setting");
2482 custom_normal_timeout = custom_dim_timeout = 0;
2483 } else if (on < 0 || dim < 0) {
2484 _E("Failed to set value(on=%d dim=%d).", on, dim);
2487 _I("LCD timeout changed: on=%ds dim=%ds", on, dim);
2488 custom_normal_timeout = SEC_TO_MSEC(on);
2489 custom_dim_timeout = SEC_TO_MSEC(dim);
2491 /* Apply new backlight time */
2492 update_display_time();
2493 if (pm_cur_state == S_NORMAL)
2494 states[pm_cur_state].trans(EVENT_INPUT);
2496 if (holdkey_block) {
2497 custom_holdkey_block = true;
2498 _I("Hold key disabled.");
2500 custom_holdkey_block = false;
2501 _I("Hold key enabled.");
2504 if (custom_change_name) {
2505 free(custom_change_name);
2506 custom_change_name = 0;
2509 if (custom_normal_timeout == 0 &&
2510 custom_dim_timeout == 0 &&
2514 custom_change_name = strndup(name, strlen(name));
2515 if (!custom_change_name) {
2516 _E("Failed to malloc.");
2517 custom_normal_timeout = custom_dim_timeout = 0;
2518 custom_holdkey_block = false;
2525 void reset_lcd_timeout(GDBusConnection *conn,
2526 const gchar *sender,
2527 const gchar *unique_name,
2533 if (!custom_change_name)
2536 if (strcmp(sender, custom_change_name))
2539 _I("reset lcd timeout: Set default timeout. sender=%s", sender);
2541 free(custom_change_name);
2542 custom_change_name = 0;
2543 custom_normal_timeout = custom_dim_timeout = 0;
2544 custom_holdkey_block = false;
2546 update_display_time();
2547 if (pm_cur_state == S_NORMAL)
2548 states[pm_cur_state].trans(EVENT_INPUT);
2551 static int booting_done(void *data)
2553 static bool done = false;
2562 _I("Booting done, release booting lock.");
2563 if (disp_plgn.pm_unlock_internal) {
2564 disp_plgn.pm_unlock_internal(INTERNAL_LOCK_BOOTING, LCD_NORMAL, PM_SLEEP_MARGIN);
2565 disp_plgn.pm_unlock_internal(INTERNAL_LOCK_BOOTING, LCD_OFF, PM_SLEEP_MARGIN);
2571 static int process_background(void *data)
2576 pid = *(pid_t *)data;
2578 node = find_node(S_NORMAL, pid);
2580 node->background = true;
2581 _I("Process(%d) is background, then PM will be unlocked LCD_NORMAL.", pid);
2587 static int process_foreground(void *data)
2592 pid = *(pid_t *)data;
2594 node = find_node(S_NORMAL, pid);
2596 node->background = false;
2597 _I("Process(%d) is foreground, then PM will be locked LCD_NORMAL.", pid);
2603 static int battery_health_changed(void *data)
2605 int health = DATA_VALUE_INT(data);
2607 _I("battery health change %d", health);
2609 if (health == HEALTH_GOOD) {
2610 pm_status_flag &= ~BATTERY_FLAG;
2611 pm_status_flag &= ~DIMSTAY_FLAG;
2612 } else if (health == HEALTH_LOW || health == HEALTH_HIGH || health == HEALTH_OVP) {
2613 pm_status_flag |= BATTERY_FLAG;
2614 pm_status_flag |= DIMSTAY_FLAG;
2617 if (backlight_ops.get_lcd_power() == DPMS_ON)
2618 backlight_ops.update();
2623 static int display_load_config(struct parse_result *result, void *user_data)
2625 struct display_config *c = user_data;
2627 _D("display_load_config: section=%s name=%s value=%s", result->section, result->name, result->value);
2632 if (!MATCH(result->section, "Display"))
2635 if (MATCH(result->name, "LockScreenWaitingTime")) {
2636 SET_CONF(c->lock_wait_time, atof(result->value));
2637 _D("lock wait time is %.3f", c->lock_wait_time);
2638 } else if (MATCH(result->name, "LongPressInterval")) {
2639 SET_CONF(c->longpress_interval, atof(result->value));
2640 _D("long press interval is %.3f", c->longpress_interval);
2641 } else if (MATCH(result->name, "LightSensorSamplingInterval")) {
2642 SET_CONF(c->lightsensor_interval, atof(result->value));
2643 _D("lightsensor interval is %.3f", c->lightsensor_interval);
2644 } else if (MATCH(result->name, "LCDOffTimeout")) {
2645 SET_CONF(c->lcdoff_timeout, atoi(result->value));
2646 _D("lcdoff timeout is %d ms", c->lcdoff_timeout);
2647 } else if (MATCH(result->name, "BrightnessChangeStep")) {
2648 SET_CONF(c->brightness_change_step, atoi(result->value));
2649 _D("brightness change step is %d", c->brightness_change_step);
2650 } else if (MATCH(result->name, "LCDAlwaysOn")) {
2651 c->lcd_always_on = (MATCH(result->value, "yes") ? 1 : 0);
2652 _D("LCD always on is %d", c->lcd_always_on);
2653 } else if (MATCH(result->name, "Dimming")) {
2654 c->dimming = (MATCH(result->value, "yes") ? 1 : 0);
2655 _D("Dimming is %d", c->dimming);
2656 } else if (MATCH(result->name, "ChangedFrameRateAllowed")) {
2657 if (strstr(result->value, "setting")) {
2658 c->framerate_app[REFRESH_SETTING] = 1;
2659 _D("framerate app is Setting");
2661 if (strstr(result->value, "all")) {
2662 memset(c->framerate_app, 1, sizeof(c->framerate_app));
2663 _D("framerate app is All");
2665 } else if (MATCH(result->name, "ControlDisplay")) {
2666 c->control_display = (MATCH(result->value, "yes") ? 1 : 0);
2667 _D("ControlDisplay is %d", c->control_display);
2668 } else if (MATCH(result->name, "PowerKeyDoublePressSupport")) {
2669 c->powerkey_doublepress = (MATCH(result->value, "yes") ? 1 : 0);
2670 _D("PowerKeyDoublePressSupport is %d", c->powerkey_doublepress);
2671 } else if (MATCH(result->name, "AccelSensorOn")) {
2672 c->accel_sensor_on = (MATCH(result->value, "yes") ? 1 : 0);
2673 _D("AccelSensorOn is %d", c->accel_sensor_on);
2674 } else if (MATCH(result->name, "ContinuousSampling")) {
2675 c->continuous_sampling = (MATCH(result->value, "yes") ? 1 : 0);
2676 _D("ContinuousSampling is %d", c->continuous_sampling);
2677 } else if (MATCH(result->name, "TimeoutEnable")) {
2678 c->timeout_enable = (MATCH(result->value, "yes") ? true : false);
2679 _D("Timeout is %s", c->timeout_enable ? "enalbed" : "disabled");
2680 } else if (MATCH(result->name, "InputSupport")) {
2681 c->input_support = (MATCH(result->value, "yes") ? true : false);
2682 _D("Input is %s", c->input_support ? "supported" : "NOT supported");
2683 } else if (MATCH(result->name, "LockCheckTimeout")) {
2684 SET_CONF(c->lockcheck_timeout, atoi(result->value));
2685 _D("LockCheckTimeout is %d", c->lockcheck_timeout);
2686 } else if (MATCH(result->name, "AODTSP")) {
2687 c->aod_tsp = (MATCH(result->value, "yes") ? true : false);
2688 _D("TSP control at is %d at aod", c->aod_tsp);
2689 } else if (MATCH(result->name, "SleepSupport")) {
2690 c->sleep_support = (MATCH(result->value, "yes") ? true : false);
2691 _D("SleepSupport is %d", c->sleep_support);
2697 static gboolean delayed_init_dpms(gpointer data)
2702 return G_SOURCE_CONTINUE;
2704 switch (pm_cur_state) {
2707 lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
2708 if (display_conf.timeout_enable) {
2709 timeout = states[S_NORMAL].timeout;
2710 /* check minimun lcd on time */
2711 if (timeout < SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT))
2712 timeout = SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT);
2713 reset_timeout(timeout);
2717 lcd_off_procedure(LCD_OFF_BY_EVENT);
2718 timeout = display_conf.lcdoff_timeout;
2719 reset_timeout(timeout);
2725 return G_SOURCE_REMOVE;
2728 static void add_timer_for_init_dpms(void)
2730 guint id = g_timeout_add(500/* milliseconds */, delayed_init_dpms, NULL);
2732 _E("Failed to add init_dpms timeout.");
2736 * Power manager Main
2739 static int display_probe(void *data)
2744 * load display service
2745 * if there is no display shared library,
2746 * deviced does not provide any method and function of display.
2748 ret = display_service_load();
2752 /* display_plugin instance initialization */
2754 disp_plgn.check_lcdoff_lock_state = __check_lcdoff_lock_state;
2759 static int input_init_handler(void)
2761 if (!display_conf.input_support)
2764 g_idle_add(init_input, NULL);
2769 static void esd_action(void)
2771 const struct device_ops *touchscreen_ops = NULL;
2775 touchscreen_ops = find_device("touchscreen");
2777 if (!check_default(touchscreen_ops))
2778 touchscreen_ops->stop(NORMAL_MODE);
2779 backlight_ops.off(NORMAL_MODE);
2780 backlight_ops.on(NORMAL_MODE);
2781 if (!check_default(touchscreen_ops))
2782 touchscreen_ops->start(NORMAL_MODE);
2785 static void lcd_uevent_changed(struct udev_device *dev)
2787 const char *devpath;
2790 devpath = udev_device_get_devpath(dev);
2794 if (!fnmatch(LCD_ESD_PATH, devpath, 0)) {
2795 action = udev_device_get_action(dev);
2796 if (!strcmp(action, UDEV_CHANGE))
2801 static const struct uevent_handler lcd_uevent_ops = {
2802 .subsystem = LCD_EVENT_SUBSYSTEM,
2803 .uevent_func = lcd_uevent_changed,
2807 static void display_init(void *data)
2810 unsigned int flags = (WITHOUT_STARTNOTI | FLAG_X_DPMS);
2813 _I("Start power manager.");
2815 signal(SIGHUP, sig_hup);
2817 power_saving_func = default_saving_mode;
2819 /* load configutation */
2820 ret = config_parse(DISPLAY_CONF_FILE, display_load_config, &display_conf);
2822 _W("Failed to load '%s', use default value: %d",
2823 DISPLAY_CONF_FILE, ret);
2825 register_kernel_uevent_control(&lcd_uevent_ops);
2827 register_notifier(DEVICE_NOTIFIER_BOOTING_DONE, booting_done);
2828 register_notifier(DEVICE_NOTIFIER_PROCESS_BACKGROUND, process_background);
2829 register_notifier(DEVICE_NOTIFIER_PROCESS_FOREGROUND, process_foreground);
2830 register_notifier(DEVICE_NOTIFIER_BATTERY_HEALTH, battery_health_changed);
2831 register_notifier(DEVICE_NOTIFIER_DISPLAY_BRIGHTNESS, display_brightness_changed);
2832 register_notifier(DEVICE_NOTIFIER_LCD_AUTOBRT_SENSING, display_auto_brightness_sensing);
2834 init_save_userlock();
2836 for (i = INIT_SETTING; i < INIT_END; i++) {
2839 ret = init_setting(update_setting);
2841 case INIT_INTERFACE:
2842 if (display_conf.timeout_enable)
2843 get_lcd_timeout_from_settings();
2844 ret = init_sysfs(flags);
2848 pm_callback = poll_callback;
2849 ret = input_init_handler();
2851 pm_lock_detector_init();
2855 ret = init_pm_dbus();
2859 _E("Failed to init: %s", errMSG[i]);
2864 if (i == INIT_END) {
2865 display_ops_init(NULL);
2866 #ifdef ENABLE_PM_LOG
2869 init_lcd_operation();
2870 check_seed_status();
2872 /* In smd test, TSP should be turned off if display panel is not existed. */
2873 if (backlight_ops.get_lcd_power() == -ENOENT) {
2874 _I("Display panel is not existed.");
2875 lcd_direct_control(DPMS_OFF, NORMAL_MODE);
2876 exit_lcd_operation();
2879 /* wm_ready needs to be checked
2880 * since display manager can be launched later than deviced.
2881 * In the case, display cannot be turned on at the first booting */
2882 // wm_ready = check_wm_ready();
2884 lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
2885 if (is_lcdon_blocked() != LCDON_BLOCK_NONE)
2886 lcd_off_procedure(LCD_OFF_BY_EVENT);
2888 add_timer_for_init_dpms();
2891 if (display_conf.lcd_always_on) {
2892 _I("LCD always on.");
2893 trans_table[S_NORMAL][EVENT_TIMEOUT] = S_NORMAL;
2896 if (flags & WITHOUT_STARTNOTI) { /* start without noti */
2897 _I("Start Power managing without noti");
2898 if (power_ops.get_power_lock_support()) {
2899 broadcast_pm_wakeup();
2900 power_ops.power_lock();
2903 * Lock lcd off until booting is done.
2904 * deviced guarantees all booting script is executing.
2905 * Last script of booting unlocks this suspend blocking state.
2907 if (disp_plgn.pm_lock_internal)
2908 disp_plgn.pm_lock_internal(INTERNAL_LOCK_BOOTING, LCD_OFF,
2909 STAY_CUR_STATE, BOOTING_DONE_WATING_TIME);
2911 /* Initial display state right after the booting done */
2912 if (is_lcdon_blocked())
2913 pm_cur_state = S_LCDOFF;
2915 pm_cur_state = S_NORMAL;
2916 ret = vconf_set_int(VCONFKEY_PM_STATE, pm_cur_state);
2918 _E("Failed to set vconf value for pm cur state: %d", vconf_get_ext_errno());
2920 status = DEVICE_OPS_STATUS_START;
2921 if (display_conf.timeout_enable) {
2922 timeout = states[S_NORMAL].timeout;
2923 /* check minimun lcd on time */
2924 if (timeout < SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT))
2925 timeout = SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT);
2927 if (disp_plgn.pm_lock_internal)
2928 disp_plgn.pm_lock_internal(INTERNAL_LOCK_BOOTING, LCD_NORMAL,
2929 STAY_CUR_STATE, timeout);
2934 if (display_conf.input_support)
2935 if (CHECK_OPS(keyfilter_ops, init))
2936 keyfilter_ops->init();
2940 static void display_exit(void *data)
2944 status = DEVICE_OPS_STATUS_STOP;
2946 /* Set current state to S_NORMAL */
2947 pm_cur_state = S_NORMAL;
2948 set_setting_pmstate(pm_cur_state);
2949 /* timeout is not needed */
2950 reset_timeout(TIMEOUT_NONE);
2952 if (CHECK_OPS(keyfilter_ops, exit))
2953 keyfilter_ops->exit();
2955 unregister_kernel_uevent_control(&lcd_uevent_ops);
2957 display_ops_exit(NULL);
2959 for (i = i - 1; i >= INIT_SETTING; i--) {
2964 case INIT_INTERFACE:
2968 unregister_notifier(DEVICE_NOTIFIER_BOOTING_DONE, booting_done);
2969 unregister_notifier(DEVICE_NOTIFIER_PROCESS_BACKGROUND, process_background);
2970 unregister_notifier(DEVICE_NOTIFIER_PROCESS_FOREGROUND, process_foreground);
2971 unregister_notifier(DEVICE_NOTIFIER_BATTERY_HEALTH, battery_health_changed);
2972 unregister_notifier(DEVICE_NOTIFIER_DISPLAY_BRIGHTNESS, display_brightness_changed);
2979 exit_lcd_operation();
2980 free_lock_info_list();
2982 /* free display service */
2983 display_service_free();
2985 _I("Stop power manager.");
2988 static int display_start(enum device_flags flags)
2990 const struct display_ops *enhance_ops = NULL;
2994 if (flags & NORMAL_MODE) {
2995 if (flags & LCD_PANEL_OFF_MODE)
2997 backlight_ops.standby(true);
3000 backlight_ops.on(flags);
3001 FIND_DISPLAY(enhance_ops, "enhance");
3002 if (enhance_ops && enhance_ops->func)
3003 enhance_ops->func(RESTORE_ENHANCE_OUTDOOR, &on);
3007 /* CORE LOGIC MODE */
3008 if (!(flags & CORE_LOGIC_MODE))
3011 if (status == DEVICE_OPS_STATUS_START)
3014 if (display_probe(NULL) < 0)
3022 static int display_stop(enum device_flags flags)
3025 if (flags & NORMAL_MODE || flags & FORCE_OFF_MODE) {
3026 backlight_ops.off(flags);
3030 /* CORE LOGIC MODE */
3031 if (!(flags & CORE_LOGIC_MODE))
3034 if (status == DEVICE_OPS_STATUS_STOP)
3042 static int display_status(void)
3047 static const struct device_ops display_device_ops = {
3048 .priority = DEVICE_PRIORITY_HIGH,
3049 DECLARE_NAME_LEN("display"),
3050 .probe = display_probe,
3051 .init = display_init,
3052 .exit = display_exit,
3053 .start = display_start,
3054 .stop = display_stop,
3055 .status = display_status,
3058 DEVICE_OPS_REGISTER(&display_device_ops)