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>
38 #include <vconf-keys.h>
43 #include "device-node.h"
44 #include "lock-detector.h"
45 #include "display-ops.h"
46 #include "core/queue.h"
47 #include "core/data.h"
48 #include "core/devices.h"
49 #include "core/device-notifier.h"
50 #include "core/device-handler.h"
51 #include "core/udev.h"
52 #include "core/list.h"
53 #include "core/common.h"
54 #include "core/edbus-handler.h"
55 #include "core/config-parser.h"
56 #include "dd-display.h"
59 #define PM_STATE_LOG_FILE "/var/log/pm_state.log"
60 #define DISPLAY_CONF_FILE "/etc/deviced/display.conf"
63 * @addtogroup POWER_MANAGER
67 #define SET_BRIGHTNESS_IN_BOOTLOADER "/usr/bin/save_blenv SLP_LCD_BRIGHT"
68 #define LOCK_SCREEN_INPUT_TIMEOUT 10000
69 #define LOCK_SCREEN_CONTROL_TIMEOUT 5000
70 #define DD_LCDOFF_INPUT_TIMEOUT 3000
72 unsigned int pm_status_flag;
74 static void (*power_saving_func) (int onoff);
75 static enum device_ops_status status = DEVICE_OPS_STATUS_UNINIT;
79 Ecore_Timer *timeout_src_id;
80 static int pre_suspend_flag = false;
81 int system_wakeup_flag = false;
82 static unsigned int custom_normal_timeout = 0;
83 static unsigned int custom_dim_timeout = 0;
84 static int custom_holdkey_block = false;
85 static int custom_change_pid = -1;
86 static char *custom_change_name;
87 static int standby_mode = false;
88 static int standby_state = false;
89 static Eina_List *standby_mode_list = NULL;
90 static int (*basic_action) (int);
91 static bool hallic_open = true;
92 static Ecore_Timer *lock_timeout_id;
93 static int lock_screen_timeout = LOCK_SCREEN_INPUT_TIMEOUT;
94 static int hdmi_state = 0;
95 static int tts_state = false;
96 static struct timeval lcdon_tv;
98 /* default transition, action fuctions */
99 static int default_trans(int evt);
100 static int default_action(int timeout);
101 static int default_check(int next);
103 struct state states[S_END] = {
104 {S_START, default_trans, default_action, default_check,},
105 {S_NORMAL, default_trans, default_action, default_check,},
106 {S_LCDDIM, default_trans, default_action, default_check,},
107 {S_LCDOFF, default_trans, default_action, default_check,},
108 {S_SLEEP, default_trans, default_action, default_check,}
111 static const char state_string[5][10] =
112 { "S_START", "S_NORMAL", "S_LCDDIM", "S_LCDOFF", "S_SLEEP" };
114 static int trans_table[S_END][EVENT_END] = {
115 /* Timeout , Input */
116 {S_START, S_START}, /* S_START */
117 {S_LCDDIM, S_NORMAL}, /* S_NORMAL */
118 {S_LCDOFF, S_NORMAL}, /* S_LCDDIM */
119 {S_SLEEP, S_NORMAL}, /* S_LCDOFF */
120 {S_LCDOFF, S_NORMAL}, /* S_SLEEP */
123 #define SHIFT_UNLOCK 4
124 #define MASK_RESET_TIMEOUT 0x8 /* 1000 */
125 #define MASK_MARGIN_TIMEOUT (0x1 << 8)
126 #define SHIFT_CHANGE_STATE 7
127 #define CHANGE_STATE_BIT 0xF00 /* 1111 0000 0000 */
128 #define SHIFT_LOCK_FLAG 16
129 #define SHIFT_CHANGE_TIMEOUT 20
130 #define CUSTOM_TIMEOUT_BIT 0x1
131 #define CUSTOM_HOLDKEY_BIT 0x2
132 #define HOLD_KEY_BLOCK_BIT 0x1
133 #define STANDBY_MODE_BIT 0x2
134 #define TIMEOUT_NONE (-1)
136 #define S_COVER_TIMEOUT 8000
137 #define GET_HOLDKEY_BLOCK_STATE(x) ((x >> SHIFT_LOCK_FLAG) & HOLD_KEY_BLOCK_BIT)
138 #define GET_STANDBY_MODE_STATE(x) ((x >> SHIFT_LOCK_FLAG) & STANDBY_MODE_BIT)
139 #define MASK32 0xffffffff
140 #define BOOTING_DONE_WATING_TIME 60000 /* 1 minute */
141 #define LOCK_TIME_ERROR 600 /* 600 seconds */
142 #define LOCK_TIME_WARNING 60 /* 60 seconds */
144 #define ACTIVE_ACT "active"
145 #define INACTIVE_ACT "inactive"
146 #define SIGNAL_LCD_ON "LCDOn"
147 #define SIGNAL_LCD_OFF "LCDOff"
149 #define LOCK_SCREEN_WATING_TIME 0.3 /* 0.3 second */
150 #define LONG_PRESS_INTERVAL 2 /* 2 seconds */
151 #define SAMPLING_INTERVAL 1 /* 1 sec */
152 #define BRIGHTNESS_CHANGE_STEP 10
153 #define HBM_LUX_THRESHOLD 32768 /* lux */
154 #define LCD_ALWAYS_ON 0
155 #define LCDOFF_TIMEOUT 500 /* milli second */
157 #define DIFF_TIMEVAL_MS(a, b) \
158 (((a.tv_sec * 1000000 + a.tv_usec) - \
159 (b.tv_sec * 1000000 + b.tv_usec)) \
162 struct display_config display_conf = {
163 .lock_wait_time = LOCK_SCREEN_WATING_TIME,
164 .longpress_interval = LONG_PRESS_INTERVAL,
165 .lightsensor_interval = SAMPLING_INTERVAL,
166 .lcdoff_timeout = LCDOFF_TIMEOUT,
167 .brightness_change_step = BRIGHTNESS_CHANGE_STEP,
168 .hbm_lux_threshold = HBM_LUX_THRESHOLD,
169 .lcd_always_on = LCD_ALWAYS_ON,
170 .framerate_app = {0,0,0,0},
171 .control_display = 0,
172 .powerkey_doublepress = 0,
176 struct display_function_info display_info = {
177 .update_auto_brightness = NULL,
178 .set_autobrightness_min = NULL,
179 .reset_autobrightness_min = NULL,
180 .face_detection = NULL,
183 typedef struct _pm_lock_node {
185 Ecore_Timer *timeout_id;
188 struct _pm_lock_node *next;
191 static PmLockNode *cond_head[S_END];
193 static void set_process_active(bool flag, pid_t pid)
199 if (pid >= INTERNAL_LOCK_BASE)
202 sprintf(str, "%d", (int)pid);
204 arr[0] = (flag ? ACTIVE_ACT : INACTIVE_ACT);
207 /* Send dbug to resourced */
208 ret = broadcast_edbus_signal(RESOURCED_PATH_PROCESS,
209 RESOURCED_INTERFACE_PROCESS, RESOURCED_METHOD_ACTIVE, "si", arr);
211 _E("Fail to send dbus signal to resourced!!");
214 int get_standby_state(void)
216 return standby_state;
219 static inline void set_standby_state(bool state)
221 if (standby_state != state)
222 standby_state = state;
225 void broadcast_lcd_on(void)
227 broadcast_edbus_signal(DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
228 SIGNAL_LCD_ON, NULL, NULL);
231 void broadcast_lcd_off(void)
233 broadcast_edbus_signal(DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
234 SIGNAL_LCD_OFF, NULL, NULL);
237 void tts_lcd_off(void)
241 ret = dbus_method_sync(POPUP_BUS_NAME, POPUP_PATH_SERVANT,
242 POPUP_IFACE_SERVANT, POPUP_METHOD_SCREENOFF_TTS, NULL, NULL);
245 _E("Failed to tts(%d)", ret);
248 inline void lcd_on_procedure(void)
251 /* AMOLED Low Power Mode off */
252 if (display_conf.alpm_on == true &&
253 alpm_set_state != NULL) {
254 if (alpm_set_state(false) < 0)
255 _E("Failed to ALPM off");
257 backlight_ops.update();
259 touch_ops.screen_on();
262 inline void lcd_off_procedure(void)
265 _D("standby mode! lcd off logic is skipped");
268 /* AMOLED Low Power Mode on */
269 if (display_conf.alpm_on == true &&
270 alpm_set_state != NULL) {
271 if (alpm_set_state(true) < 0)
272 _E("Failed to ALPM on!");
276 touch_ops.screen_off();
282 int low_battery_state(int val)
285 case VCONFKEY_SYSMAN_BAT_POWER_OFF:
286 case VCONFKEY_SYSMAN_BAT_CRITICAL_LOW:
287 case VCONFKEY_SYSMAN_BAT_REAL_POWER_OFF:
293 int get_hallic_open(void)
298 static int refresh_app_cond()
302 if (cond_head[S_LCDDIM] != NULL)
303 trans_condition = trans_condition | MASK_DIM;
304 if (cond_head[S_LCDOFF] != NULL)
305 trans_condition = trans_condition | MASK_OFF;
306 if (cond_head[S_SLEEP] != NULL)
307 trans_condition = trans_condition | MASK_SLP;
312 static PmLockNode *find_node(enum state_t s_index, pid_t pid)
314 PmLockNode *t = cond_head[s_index];
324 static PmLockNode *add_node(enum state_t s_index, pid_t pid, Ecore_Timer *timeout_id,
330 n = (PmLockNode *) malloc(sizeof(PmLockNode));
332 _E("Not enough memory, add cond. fail");
338 n->timeout_id = timeout_id;
340 n->holdkey_block = holdkey_block;
341 n->next = cond_head[s_index];
342 cond_head[s_index] = n;
348 static int del_node(enum state_t s_index, PmLockNode *n)
356 t = cond_head[s_index];
361 prev->next = t->next;
363 cond_head[s_index] = cond_head[s_index]->next;
366 ecore_timer_del(t->timeout_id);
377 static void print_node(int next)
384 if (next <= S_START || next >= S_END)
390 diff = difftime(now, n->time);
391 ctime_r(&n->time, buf);
393 if (diff > LOCK_TIME_ERROR)
394 _E("over %.0f s, pid: %5d, lock time: %s", diff, n->pid, buf);
395 else if (diff > LOCK_TIME_WARNING)
396 _I("over %.0f s, pid: %5d, lock time: %s", diff, n->pid, buf);
398 _I("pid: %5d, lock time: %s", n->pid, buf);
404 void get_pname(pid_t pid, char *pname)
409 if (pid >= INTERNAL_LOCK_BASE)
410 snprintf(buf, PATH_MAX, "/proc/%d/cmdline", getpid());
412 snprintf(buf, PATH_MAX, "/proc/%d/cmdline", pid);
414 cmdline = open(buf, O_RDONLY);
417 _E("%d does not exist now(may be dead without unlock)", pid);
421 r = read(cmdline, pname, PATH_MAX);
422 if ((r >= 0) && (r < PATH_MAX))
430 static Eina_Bool del_dim_cond(void *data)
432 PmLockNode *tmp = NULL;
433 char pname[PATH_MAX];
434 pid_t pid = (pid_t)data;
436 _I("delete prohibit dim condition by timeout\n");
438 tmp = find_node(S_LCDDIM, pid);
439 del_node(S_LCDDIM, tmp);
440 get_pname(pid, pname);
441 set_unlock_time(pname, S_NORMAL);
444 states[pm_cur_state].trans(EVENT_TIMEOUT);
449 static Eina_Bool del_off_cond(void *data)
451 PmLockNode *tmp = NULL;
452 char pname[PATH_MAX];
453 pid_t pid = (pid_t)data;
455 _I("delete prohibit off condition by timeout\n");
457 tmp = find_node(S_LCDOFF, pid);
458 del_node(S_LCDOFF, tmp);
459 get_pname(pid, pname);
460 set_unlock_time(pname, S_LCDDIM);
463 states[pm_cur_state].trans(EVENT_TIMEOUT);
468 static Eina_Bool del_sleep_cond(void *data)
470 PmLockNode *tmp = NULL;
471 char pname[PATH_MAX];
472 pid_t pid = (pid_t)data;
474 _I("delete prohibit sleep condition by timeout\n");
476 tmp = find_node(S_SLEEP, pid);
477 del_node(S_SLEEP, tmp);
478 get_pname(pid, pname);
479 set_unlock_time(pname, S_LCDOFF);
482 states[pm_cur_state].trans(EVENT_TIMEOUT);
484 set_process_active(EINA_FALSE, (pid_t)data);
488 /* timeout handler */
489 Eina_Bool timeout_handler(void *data)
491 _I("Time out state %s\n", state_string[pm_cur_state]);
493 if (timeout_src_id) {
494 ecore_timer_del(timeout_src_id);
495 timeout_src_id = NULL;
498 states[pm_cur_state].trans(EVENT_TIMEOUT);
502 inline static void reset_timeout(int timeout)
504 if (timeout_src_id != 0) {
505 ecore_timer_del(timeout_src_id);
506 timeout_src_id = NULL;
509 timeout_src_id = ecore_timer_add(MSEC_TO_SEC(timeout),
510 (Ecore_Task_Cb)timeout_handler, NULL);
511 else if (timeout == 0)
512 states[pm_cur_state].trans(EVENT_TIMEOUT);
515 /* get configurations from setting */
516 static int get_lcd_timeout_from_settings(void)
523 for (i = 0; i < S_END; i++) {
524 switch (states[i].state) {
526 ret = get_run_timeout(&val);
528 buf = getenv("PM_TO_NORMAL");
529 val = (buf ? atoi(buf) : DEFAULT_NORMAL_TIMEOUT);
533 get_dim_timeout(&val);
536 val = display_conf.lcdoff_timeout;
539 /* This state doesn't need to set time out. */
544 states[i].timeout = val;
546 _I("%s state : %d ms timeout", state_string[i],
553 static void update_display_time(void)
555 int ret, run_timeout, val;
557 /* first priority : s cover */
559 states[S_NORMAL].timeout = S_COVER_TIMEOUT;
560 _I("S cover closed : timeout is set by normal(%d ms)",
565 /* second priority : custom timeout */
566 if (custom_normal_timeout > 0) {
567 states[S_NORMAL].timeout = custom_normal_timeout;
568 states[S_LCDDIM].timeout = custom_dim_timeout;
569 _I("CUSTOM : timeout is set by normal(%d ms), dim(%d ms)",
570 custom_normal_timeout, custom_dim_timeout);
574 /* third priority : lock state */
575 if ((get_lock_screen_state() == VCONFKEY_IDLE_LOCK) &&
576 !get_lock_screen_bg_state()) {
577 if (pm_status_flag & SMAST_FLAG) {
578 /* smart stay is on, timeout is always 5 seconds. */
579 states[S_NORMAL].timeout = LOCK_SCREEN_CONTROL_TIMEOUT;
580 _I("LOCK : timeout is set, smart stay timeout(%d ms)",
581 LOCK_SCREEN_CONTROL_TIMEOUT);
583 /* timeout is different according to key or event. */
584 states[S_NORMAL].timeout = lock_screen_timeout;
585 _I("LOCK : timeout is set by normal(%d ms)",
586 lock_screen_timeout);
591 /* default setting */
592 ret = get_run_timeout(&run_timeout);
593 if (ret < 0 || run_timeout <= 0) {
594 _E("Can not get run timeout. set default %d ms",
595 DEFAULT_NORMAL_TIMEOUT);
596 run_timeout = DEFAULT_NORMAL_TIMEOUT;
598 states[S_NORMAL].timeout = run_timeout;
600 get_dim_timeout(&val);
601 states[S_LCDDIM].timeout = val;
603 _I("Normal: NORMAL timeout is set by %d ms", states[S_NORMAL].timeout);
604 _I("Normal: DIM timeout is set by %d ms", states[S_LCDDIM].timeout);
607 static void update_display_locktime(int time)
609 lock_screen_timeout = time;
610 update_display_time();
613 void lcd_on_direct(void)
617 if (power_ops.get_power_lock_support()
618 && pm_cur_state == S_SLEEP)
619 power_ops.power_lock();
621 if (pre_suspend_flag == true) {
622 power_ops.post_resume();
623 pre_suspend_flag = false;
626 _D("lcd is on directly");
627 gettimeofday(&lcdon_tv, NULL);
628 if (hbm_check_timeout != NULL)
631 reset_timeout(DD_LCDOFF_INPUT_TIMEOUT);
633 ret = vconf_get_int(VCONFKEY_CALL_STATE, &call_state);
634 if ((ret >= 0 && call_state != VCONFKEY_CALL_OFF) ||
635 (get_lock_screen_state() == VCONFKEY_IDLE_LOCK)) {
636 _D("LOCK state, lcd is on directly");
639 reset_timeout(display_conf.lcdoff_timeout);
641 update_display_locktime(LOCK_SCREEN_INPUT_TIMEOUT);
644 int custom_lcdon(int timeout)
651 if (backlight_ops.get_lcd_power() != PM_LCD_POWER_ON)
654 _I("custom lcd on %d ms", timeout);
655 if (set_custom_lcdon_timeout(timeout) == true)
656 update_display_time();
658 /* state transition */
659 pm_old_state = pm_cur_state;
660 pm_cur_state = S_NORMAL;
661 st = &states[pm_cur_state];
665 st->action(st->timeout);
671 static int proc_change_state(unsigned int cond, pid_t pid)
677 for (i = S_NORMAL; i < S_END; i++) {
678 if ((cond >> (SHIFT_CHANGE_STATE + i)) & 0x1) {
683 _I("Change State to %s (%d)", state_string[next_state], pid);
685 if (next_state == S_NORMAL) {
686 if (backlight_ops.get_lcd_power() != PM_LCD_POWER_ON)
688 } else if (next_state == S_LCDOFF) {
689 if (backlight_ops.get_lcd_power() != PM_LCD_POWER_OFF)
693 if (next_state == S_LCDOFF)
694 if (set_custom_lcdon_timeout(0) == true)
695 update_display_time();
697 switch (next_state) {
699 update_display_locktime(LOCK_SCREEN_CONTROL_TIMEOUT);
704 /* state transition */
705 pm_old_state = pm_cur_state;
706 pm_cur_state = next_state;
707 st = &states[pm_cur_state];
709 /* pm state is updated to dim because of standby mode */
710 if (standby_mode && (pm_cur_state == S_LCDOFF))
711 set_setting_pmstate(S_LCDDIM);
715 st->action(st->timeout);
719 _I("Dangerous requests.");
720 /* at first LCD_OFF and then goto sleep */
721 /* state transition */
722 pm_old_state = pm_cur_state;
723 pm_cur_state = S_LCDOFF;
724 st = &states[pm_cur_state];
726 st->action(TIMEOUT_NONE);
728 delete_condition(S_SLEEP);
729 pm_old_state = pm_cur_state;
730 pm_cur_state = S_SLEEP;
731 st = &states[pm_cur_state];
733 st->action(TIMEOUT_NONE);
744 static int standby_action(int timeout)
746 if (backlight_ops.standby() < 0) {
747 _E("Fail to start standby mode!");
750 if (CHECK_OPS(keyfilter_ops, backlight_enable))
751 keyfilter_ops->backlight_enable(false);
753 touch_ops.screen_off();
755 set_standby_state(true);
757 _I("standby mode (only LCD OFF, But phone is working normal)");
758 reset_timeout(timeout);
763 static void set_standby_mode(pid_t pid, int enable)
766 Eina_List *l_next = NULL;
770 EINA_LIST_FOREACH(standby_mode_list, l, data)
771 if (pid == (int) data) {
772 _E("%d already acquired standby mode", pid);
775 EINA_LIST_APPEND(standby_mode_list, (void *)pid);
776 _I("%d acquire standby mode", pid);
780 basic_action = states[S_LCDOFF].action;
781 states[S_LCDOFF].action = standby_action;
782 trans_table[S_LCDOFF][EVENT_TIMEOUT] = S_LCDOFF;
783 _I("Standby mode is enabled!");
787 EINA_LIST_FOREACH_SAFE(standby_mode_list, l, l_next, data)
788 if (pid == (int) data) {
789 standby_mode_list = eina_list_remove_list(
790 standby_mode_list, l);
791 _I("%d release standby mode", pid);
793 if (standby_mode_list != NULL)
795 set_standby_state(false);
796 standby_mode = false;
797 if (basic_action != NULL) {
798 states[S_LCDOFF].action = basic_action;
800 trans_table[S_LCDOFF][EVENT_TIMEOUT] = S_SLEEP;
801 proc_change_state(S_NORMAL << (SHIFT_CHANGE_STATE + S_NORMAL),
803 _I("Standby mode is disabled!");
807 /* update transition condition for application requrements */
808 static int proc_condition(PMMsg *data)
810 PmLockNode *tmp = NULL;
811 unsigned int val = data->cond;
812 pid_t pid = data->pid;
813 Ecore_Timer *cond_timeout_id = NULL;
814 bool holdkey_block = 0;
820 char pname[PATH_MAX];
823 get_pname(pid, pname);
824 val_timeout = val >> SHIFT_CHANGE_TIMEOUT;
825 if (val_timeout & (CUSTOM_TIMEOUT_BIT | CUSTOM_HOLDKEY_BIT)) {
826 if (data->timeout == 0 && data->timeout2 == 0) {
827 _I("LCD timeout changed : default setting");
828 get_lcd_timeout_from_settings();
829 if (get_lock_screen_state() == VCONFKEY_IDLE_LOCK) {
830 _I("LOCK state : setting lock timeout!");
831 states[S_NORMAL].timeout = lock_screen_timeout;
833 custom_normal_timeout = custom_dim_timeout = 0;
834 if (!(val_timeout & CUSTOM_HOLDKEY_BIT))
835 custom_change_pid = -1;
837 _I("LCD timeout changed : normal(%d s), dim(%d s)",
838 data->timeout, data->timeout2);
839 custom_normal_timeout = SEC_TO_MSEC(data->timeout);
840 states[S_NORMAL].timeout = custom_normal_timeout;
841 custom_dim_timeout = SEC_TO_MSEC(data->timeout2);
842 states[S_LCDDIM].timeout = custom_dim_timeout;
843 custom_change_pid = pid;
846 if (val_timeout & CUSTOM_HOLDKEY_BIT) {
847 custom_holdkey_block = true;
848 custom_change_pid = pid;
849 _I("hold key disabled !");
851 custom_holdkey_block = false;
852 _I("hold key enabled !");
856 if (val & MASK_DIM) {
857 if (data->timeout > 0) {
859 ecore_timer_add(MSEC_TO_SEC(data->timeout),
860 (Ecore_Task_Cb)del_dim_cond, (void*)pid);
862 holdkey_block = GET_HOLDKEY_BLOCK_STATE(val);
863 tmp = find_node(S_LCDDIM, pid);
865 add_node(S_LCDDIM, pid, cond_timeout_id, holdkey_block);
867 if (data->timeout > 0) {
871 if (tmp->timeout_id) {
872 ecore_timer_del(tmp->timeout_id);
873 tmp->timeout_id = cond_timeout_id;
875 tmp->holdkey_block = holdkey_block;
878 _SD("[%s] locked by pid %d - process %s holdkeyblock %d\n",
879 "S_NORMAL", pid, pname, holdkey_block);
880 set_lock_time(pname, S_NORMAL);
882 if (val & MASK_OFF) {
883 if (data->timeout > 0) {
885 ecore_timer_add(MSEC_TO_SEC(data->timeout),
886 (Ecore_Task_Cb)del_off_cond, (void*)pid);
888 holdkey_block = GET_HOLDKEY_BLOCK_STATE(val);
889 tmp = find_node(S_LCDOFF, pid);
891 add_node(S_LCDOFF, pid, cond_timeout_id, holdkey_block);
893 if (data->timeout > 0) {
897 if (tmp->timeout_id) {
898 ecore_timer_del(tmp->timeout_id);
899 tmp->timeout_id = cond_timeout_id;
901 tmp->holdkey_block = holdkey_block;
904 _SD("[%s] locked by pid %d - process %s holdkeyblock %d\n",
905 "S_LCDDIM", pid, pname, holdkey_block);
906 set_lock_time(pname, S_LCDDIM);
908 if (val & MASK_SLP) {
910 * pm-state must be changed to LCDOFF,
911 * to guarantee of LCDOFF-lock
912 * when system resumes from suspend state.
914 if (pm_cur_state == S_SLEEP)
915 proc_change_state(S_LCDOFF <<
916 (SHIFT_CHANGE_STATE + S_LCDOFF), getpid());
917 if (data->timeout > 0) {
919 ecore_timer_add(MSEC_TO_SEC(data->timeout),
920 (Ecore_Task_Cb)del_sleep_cond, (void*)pid);
922 if (GET_STANDBY_MODE_STATE(val))
923 set_standby_mode(pid, true);
924 tmp = find_node(S_SLEEP, pid);
926 add_node(S_SLEEP, pid, cond_timeout_id, 0);
928 if (data->timeout > 0) {
932 if (tmp->timeout_id) {
933 ecore_timer_del(tmp->timeout_id);
934 tmp->timeout_id = cond_timeout_id;
936 tmp->holdkey_block = 0;
938 set_process_active(EINA_TRUE, pid);
941 _SD("[%s] locked by pid %d - process %s\n", "S_LCDOFF", pid,
943 set_lock_time(pname, S_LCDOFF);
946 /* UNLOCK(GRANT) condition processing */
947 val = val >> SHIFT_UNLOCK;
948 if (val & MASK_DIM) {
949 tmp = find_node(S_LCDDIM, pid);
950 del_node(S_LCDDIM, tmp);
951 _SD("[%s] unlocked by pid %d - process %s\n", "S_NORMAL",
953 set_unlock_time(pname, S_NORMAL);
955 if (val & MASK_OFF) {
956 tmp = find_node(S_LCDOFF, pid);
957 del_node(S_LCDOFF, tmp);
958 _SD("[%s] unlocked by pid %d - process %s\n", "S_LCDDIM",
960 set_unlock_time(pname, S_LCDDIM);
962 if (val & MASK_SLP) {
963 tmp = find_node(S_SLEEP, pid);
964 del_node(S_SLEEP, tmp);
966 set_standby_mode(pid, false);
967 set_process_active(EINA_FALSE, pid);
969 _SD("[%s] unlocked by pid %d - process %s\n", "S_LCDOFF",
971 set_unlock_time(pname, S_LCDOFF);
976 reset_timeout(states[pm_cur_state].timeout);
977 _I("reset timeout (%d ms)",
978 states[pm_cur_state].timeout);
981 /* guard time for suspend */
982 if (pm_cur_state == S_LCDOFF) {
983 reset_timeout(states[S_LCDOFF].timeout);
984 _I("margin timeout (%d ms)",
985 states[S_LCDOFF].timeout);
989 if (timeout_src_id == 0)
990 states[pm_cur_state].trans(EVENT_TIMEOUT);
995 /* If some changed, return 1 */
996 int check_processes(enum state_t prohibit_state)
998 PmLockNode *t = cond_head[prohibit_state];
999 PmLockNode *tmp = NULL;
1003 if (t->pid < INTERNAL_LOCK_BASE && kill(t->pid, 0) == -1) {
1004 _E("%d process does not exist, delete the REQ"
1005 " - prohibit state %d ",
1006 t->pid, prohibit_state);
1007 if (t->pid == custom_change_pid) {
1008 get_lcd_timeout_from_settings();
1009 custom_normal_timeout = custom_dim_timeout = 0;
1010 custom_change_pid = -1;
1013 set_standby_mode(t->pid, false);
1020 del_node(prohibit_state, tmp);
1028 int check_holdkey_block(enum state_t state)
1030 PmLockNode *t = cond_head[state];
1033 _I("check holdkey block : state of %s", state_string[state]);
1035 if (custom_holdkey_block == true) {
1036 _I("custom hold key blocked by pid(%d)",
1042 if (t->holdkey_block == true) {
1044 _I("Hold key blocked by pid(%d)!", t->pid);
1053 int delete_condition(enum state_t state)
1055 PmLockNode *t = cond_head[state];
1057 PmLockNode *tmp = NULL;
1059 char pname[PATH_MAX];
1061 _I("delete condition : state of %s", state_string[state]);
1064 if (t->timeout_id > 0) {
1065 ecore_timer_del(t->timeout_id);
1066 t->timeout_id = NULL;
1071 if (state == S_SLEEP)
1072 set_process_active(EINA_FALSE, pid);
1073 _I("delete node of pid(%d)", pid);
1074 del_node(state, tmp);
1075 get_pname(pid, pname);
1076 set_unlock_time(pname, state-1);
1082 void update_lcdoff_source(int source)
1088 case VCONFKEY_PM_LCDOFF_BY_TIMEOUT:
1089 _I("LCD OFF by timeout");
1091 case VCONFKEY_PM_LCDOFF_BY_POWERKEY:
1092 _I("LCD OFF by powerkey");
1095 _E("Invalid value(%d)", source);
1098 vconf_set_int(VCONFKEY_PM_LCDOFF_SOURCE, source);
1101 #ifdef ENABLE_PM_LOG
1103 typedef struct _pm_history {
1105 enum pm_log_type log_type;
1109 static int max_history_count = MAX_LOG_COUNT;
1110 static pm_history pm_history_log[MAX_LOG_COUNT] = {0,};
1111 static int history_count = 0;
1113 static const char history_string[PM_LOG_MAX][15] =
1114 {"PRESS", "LONG PRESS", "RELEASE", "LCD ON", "LCD ON FAIL",
1115 "LCD DIM", "LCD DIM FAIL", "LCD OFF", "LCD OFF FAIL", "SLEEP"};
1117 void pm_history_init()
1119 memset(pm_history_log, 0x0, sizeof(pm_history_log));
1121 max_history_count = MAX_LOG_COUNT;
1124 void pm_history_save(enum pm_log_type log_type, int code)
1129 pm_history_log[history_count].time = now;
1130 pm_history_log[history_count].log_type = log_type;
1131 pm_history_log[history_count].keycode = code;
1134 if (history_count >= max_history_count)
1138 void pm_history_print(int fd, int count)
1140 int start_index, index, i;
1144 if (count <= 0 || count > max_history_count)
1147 start_index = (history_count - count + max_history_count)
1148 % max_history_count;
1150 for (i = 0; i < count; i++) {
1151 index = (start_index + i) % max_history_count;
1153 if (pm_history_log[index].time == 0)
1156 if (pm_history_log[index].log_type < PM_LOG_MIN ||
1157 pm_history_log[index].log_type >= PM_LOG_MAX)
1159 ctime_r(&pm_history_log[index].time, time_buf);
1160 snprintf(buf, sizeof(buf), "[%3d] %15s %3d %s",
1162 history_string[pm_history_log[index].log_type],
1163 pm_history_log[index].keycode,
1165 write(fd, buf, strlen(buf));
1170 /* logging indev_list for debug */
1171 void print_dev_list(int fd)
1174 unsigned int total = 0;
1177 total = eina_list_count(indev_list);
1178 _I("***** total list : %d *****", total);
1179 for (i = 0; i < total; i++) {
1180 tmp = (indev*)eina_list_nth(indev_list, i);
1181 _I("* %d | path:%s, fd:%d, dev_fd:%d",
1182 i, tmp->dev_path, tmp->fd, tmp->dev_fd);
1185 snprintf(buf, sizeof(buf), " %2d| path:%s, fd:%d, dev_fd:%d\n",
1186 i, tmp->dev_path, tmp->fd, tmp->dev_fd);
1187 write(fd, buf, strlen(buf));
1190 _I("***************************\n");
1193 void print_info(int fd)
1198 Eina_List *l = NULL;
1200 char pname[PATH_MAX];
1205 snprintf(buf, sizeof(buf),
1206 "\n==========================================="
1207 "===========================\n");
1208 write(fd, buf, strlen(buf));
1209 snprintf(buf, sizeof(buf),"Timeout Info: Run[%dms] Dim[%dms] Off[%dms]\n",
1210 states[S_NORMAL].timeout,
1211 states[S_LCDDIM].timeout, states[S_LCDOFF].timeout);
1212 write(fd, buf, strlen(buf));
1214 snprintf(buf, sizeof(buf), "Tran. Locked : %s %s %s\n",
1215 (trans_condition & MASK_DIM) ? state_string[S_NORMAL] : "-",
1216 (trans_condition & MASK_OFF) ? state_string[S_LCDDIM] : "-",
1217 (trans_condition & MASK_SLP) ? state_string[S_LCDOFF] : "-");
1218 write(fd, buf, strlen(buf));
1220 snprintf(buf, sizeof(buf), "Current State: %s\n",
1221 state_string[pm_cur_state]);
1222 write(fd, buf, strlen(buf));
1224 snprintf(buf, sizeof(buf), "Current Lock Conditions: \n");
1225 write(fd, buf, strlen(buf));
1227 for (s_index = S_NORMAL; s_index < S_END; s_index++) {
1230 t = cond_head[s_index];
1233 get_pname((pid_t)t->pid, pname);
1234 ctime_r(&t->time, time_buf);
1235 snprintf(buf, sizeof(buf),
1236 " %d: [%s] locked by pid %d %s %s",
1237 i++, state_string[s_index - 1], t->pid, pname, time_buf);
1238 write(fd, buf, strlen(buf));
1246 snprintf(buf, sizeof(buf), "\n\nstandby mode is on\n");
1247 write(fd, buf, strlen(buf));
1249 EINA_LIST_FOREACH(standby_mode_list, l, data) {
1250 get_pname((pid_t)data, pname);
1251 snprintf(buf, sizeof(buf),
1252 " standby mode acquired by pid %d"
1253 " - process %s\n", data, pname);
1254 write(fd, buf, strlen(buf));
1257 print_lock_info_list(fd);
1259 #ifdef ENABLE_PM_LOG
1260 pm_history_print(fd, 250);
1264 void save_display_log(void)
1271 _D("internal state is saved!");
1274 ctime_r(&now_time, time_buf);
1276 fd = open(PM_STATE_LOG_FILE, O_CREAT | O_TRUNC | O_WRONLY, 0644);
1278 snprintf(buf, sizeof(buf),
1279 "\npm_state_log now-time : %d(s) %s\n\n",
1280 (int)now_time, time_buf);
1281 write(fd, buf, strlen(buf));
1283 snprintf(buf, sizeof(buf), "pm_status_flag: %x\n", pm_status_flag);
1284 write(fd, buf, strlen(buf));
1286 snprintf(buf, sizeof(buf), "screen lock status : %d\n",
1287 get_lock_screen_state());
1288 write(fd, buf, strlen(buf));
1294 fd = open("/dev/console", O_WRONLY);
1301 /* SIGHUP signal handler
1302 * For debug... print info to syslog
1304 static void sig_hup(int signo)
1309 static void sig_usr(int signo)
1311 pm_status_flag |= VCALL_FLAG;
1314 int check_lcdoff_direct(void)
1316 int ret, lock, cradle;
1321 lock = get_lock_screen_state();
1322 if (lock != VCONFKEY_IDLE_LOCK && hallic_open)
1328 ret = vconf_get_int(VCONFKEY_SYSMAN_CRADLE_STATUS, &cradle);
1329 if (ret >= 0 && cradle == DOCK_SOUND)
1332 if (pm_old_state != S_NORMAL)
1335 if (pm_cur_state != S_LCDDIM)
1339 * goto lcd dim state when battery health is bad
1340 * and abnormal popup shows
1342 if ((pm_status_flag & DIMSTAY_FLAG) &&
1343 (check_abnormal_popup() == HEALTH_BAD))
1346 _D("Goto LCDOFF direct(%d,%d,%d)", lock, hdmi_state, cradle);
1351 int check_lcdoff_lock_state(void)
1353 if (cond_head[S_SLEEP] != NULL)
1360 * default transition function
1363 * 3. call enter action function
1365 static int default_trans(int evt)
1367 struct state *st = &states[pm_cur_state];
1370 next_state = (enum state_t)trans_table[pm_cur_state][evt];
1372 /* check conditions */
1373 while (st->check && !st->check(next_state)) {
1374 /* There is a condition. */
1376 _D("standby mode, goto next_state %s",
1377 state_string[next_state]);
1380 _I("%s -> %s : check fail", state_string[pm_cur_state],
1381 state_string[next_state]);
1382 if (!check_processes(next_state)) {
1383 /* this is valid condition - the application that sent the condition is running now. */
1389 if (display_info.face_detection &&
1390 (pm_status_flag & SMAST_FLAG) && hallic_open) {
1391 if (display_info.face_detection(evt, pm_cur_state, next_state))
1395 /* state transition */
1396 pm_old_state = pm_cur_state;
1397 pm_cur_state = next_state;
1398 st = &states[pm_cur_state];
1402 if (pm_cur_state == S_LCDOFF)
1403 update_lcdoff_source(VCONFKEY_PM_LCDOFF_BY_TIMEOUT);
1405 if (pm_cur_state == S_NORMAL || pm_cur_state == S_LCDOFF)
1406 if (set_custom_lcdon_timeout(0) == true)
1407 update_display_time();
1409 if (check_lcdoff_direct() == true) {
1410 /* enter next state directly */
1411 states[pm_cur_state].trans(EVENT_TIMEOUT);
1414 st->action(st->timeout);
1421 static Eina_Bool lcd_on_expired(void *data)
1423 int lock_state, ret;
1425 if (lock_timeout_id)
1426 lock_timeout_id = NULL;
1428 /* check state of lock */
1429 ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
1431 if (ret > 0 && lock_state == VCONFKEY_IDLE_LOCK)
1434 if (backlight_ops.get_lcd_power() == PM_LCD_POWER_ON)
1437 /* lock screen is not launched yet, but lcd is on */
1438 if (backlight_ops.get_lcd_power() != PM_LCD_POWER_ON)
1444 static inline void stop_lock_timer(void)
1446 if (lock_timeout_id) {
1447 ecore_timer_del(lock_timeout_id);
1448 lock_timeout_id = NULL;
1452 static void check_lock_screen(void)
1454 int lock_setting, lock_state, app_state, ret;
1458 ret = vconf_get_int(VCONFKEY_CALL_STATE, &app_state);
1459 if (ret >= 0 && app_state != VCONFKEY_CALL_OFF)
1462 /* check setting of lock screen is enabled. */
1463 ret = vconf_get_int(VCONFKEY_SETAPPL_SCREEN_LOCK_TYPE_INT,
1466 if (ret < 0 || lock_setting == SETTING_SCREEN_LOCK_TYPE_NONE)
1469 /* check state of lock */
1470 ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
1472 if (ret < 0 || lock_state == VCONFKEY_IDLE_LOCK)
1475 /* Use time to check lock is done. */
1476 lock_timeout_id = ecore_timer_add(display_conf.lock_wait_time,
1477 (Ecore_Task_Cb)lcd_on_expired, (void*)NULL);
1482 if (backlight_ops.get_lcd_power() != PM_LCD_POWER_ON)
1486 /* default enter action function */
1487 static int default_action(int timeout)
1490 int wakeup_count = -1;
1492 char *pkgname = NULL;
1494 int lock_state = -1;
1498 static time_t last_update_time = 0;
1499 static int last_timeout = 0;
1500 struct timeval now_tv;
1502 if (status != DEVICE_OPS_STATUS_START) {
1503 _E("display is not started!");
1507 if (pm_cur_state != S_SLEEP) {
1508 if (pm_cur_state == S_NORMAL &&
1509 lcdon_tv.tv_sec != 0) {
1510 gettimeofday(&now_tv, NULL);
1511 timeout -= DIFF_TIMEVAL_MS(now_tv, lcdon_tv);
1512 lcdon_tv.tv_sec = 0;
1514 /* set timer with current state timeout */
1515 reset_timeout(timeout);
1517 if (pm_cur_state == S_NORMAL) {
1518 time(&last_update_time);
1519 last_timeout = timeout;
1521 _I("timout set: %s state %d ms",
1522 state_string[pm_cur_state], timeout);
1526 if (pm_cur_state != pm_old_state && pm_cur_state != S_SLEEP) {
1527 if (power_ops.get_power_lock_support())
1528 power_ops.power_lock();
1529 if (pm_cur_state != S_LCDOFF)
1530 set_setting_pmstate(pm_cur_state);
1531 device_notify(DEVICE_NOTIFIER_LCD, (void *)pm_cur_state);
1534 if (pm_old_state == S_NORMAL && pm_cur_state != S_NORMAL) {
1536 diff = difftime(now, last_update_time);
1537 _I("S_NORMAL is changed to %s [%d ms, %.0f s]",
1538 state_string[pm_cur_state], last_timeout, diff);
1541 switch (pm_cur_state) {
1544 * normal state : backlight on and restore
1545 * the previous brightness
1547 if (pm_old_state == S_LCDOFF || pm_old_state == S_SLEEP) {
1548 if (pre_suspend_flag == true) {
1549 power_ops.post_resume();
1550 pre_suspend_flag = false;
1552 check_lock_screen();
1553 } else if (pm_old_state == S_LCDDIM)
1554 backlight_ops.update();
1555 set_standby_state(false);
1559 if (pm_old_state == S_NORMAL &&
1560 backlight_ops.get_custom_status())
1561 backlight_ops.save_custom_brightness();
1562 /* lcd dim state : dim the brightness */
1563 backlight_ops.dim();
1564 if (pm_old_state == S_LCDOFF || pm_old_state == S_SLEEP) {
1567 touch_ops.screen_on();
1570 set_standby_state(false);
1574 if (pm_old_state != S_SLEEP && pm_old_state != S_LCDOFF) {
1576 /* lcd off state : turn off the backlight */
1577 if (backlight_ops.get_lcd_power() != PM_LCD_POWER_OFF)
1578 lcd_off_procedure();
1579 set_setting_pmstate(pm_cur_state);
1581 if (pre_suspend_flag == false) {
1582 pre_suspend_flag = true;
1583 power_ops.pre_suspend();
1587 if (backlight_ops.get_lcd_power() != PM_LCD_POWER_OFF)
1588 lcd_off_procedure();
1592 if (pm_old_state != S_SLEEP && pm_old_state != S_LCDOFF)
1595 if (backlight_ops.get_lcd_power() != PM_LCD_POWER_OFF)
1596 lcd_off_procedure();
1598 if (!power_ops.get_power_lock_support()) {
1599 /* sleep state : set system mode to SUSPEND */
1600 if (device_get_property(DEVICE_TYPE_POWER,
1601 PROP_POWER_WAKEUP_COUNT, &wakeup_count) < 0)
1602 _E("wakeup count read error");
1604 if (wakeup_count < 0) {
1605 _I("Wakup Event! Can not enter suspend mode.");
1609 if (device_set_property(DEVICE_TYPE_POWER,
1610 PROP_POWER_WAKEUP_COUNT, wakeup_count) < 0) {
1611 _E("wakeup count write error");
1621 #ifdef ENABLE_PM_LOG
1622 pm_history_save(PM_LOG_SLEEP, pm_cur_state);
1624 if (power_ops.get_power_lock_support()) {
1625 if (power_ops.power_unlock() < 0)
1626 _E("power unlock state error!");
1628 power_ops.suspend();
1629 _I("system wakeup!!");
1630 system_wakeup_flag = true;
1632 if (power_ops.check_wakeup_src() == EVENT_DEVICE)
1633 /* system waked up by devices */
1634 states[pm_cur_state].trans(EVENT_DEVICE);
1636 /* system waked up by user input */
1637 states[pm_cur_state].trans(EVENT_INPUT);
1642 if (!power_ops.get_power_lock_support()) {
1644 states[pm_cur_state].trans(EVENT_DEVICE);
1650 * default check function
1652 * 0 : can't transit, others : transitable
1654 static int default_check(int next)
1656 int trans_cond = trans_condition & MASK_BIT;
1657 int lock_state = -1;
1660 vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
1661 if (lock_state==VCONFKEY_IDLE_LOCK && next != S_SLEEP) {
1663 vconf_get_int(VCONFKEY_CALL_STATE, &app_state);
1664 if (app_state != VCONFKEY_CALL_OFF)
1666 vconf_get_bool(VCONFKEY_ALARM_RINGING, &app_state);
1667 if (app_state == EINA_TRUE)
1669 _I("default_check:LOCK STATE, it's transitable");
1676 trans_cond = trans_cond & MASK_DIM;
1679 trans_cond = trans_cond & MASK_OFF;
1682 trans_cond = trans_cond & MASK_SLP;
1684 default: /* S_NORMAL is exceptional */
1689 if (trans_cond != 0) {
1694 return 1; /* transitable */
1697 static void default_saving_mode(int onoff)
1700 pm_status_flag |= PWRSV_FLAG;
1701 /* off hbm state, it's power saving mode */
1702 if (hbm_get_state != NULL &&
1703 hbm_get_state() == true)
1704 hbm_set_state_with_timeout(false, 0);
1706 pm_status_flag &= ~PWRSV_FLAG;
1708 if (pm_cur_state == S_NORMAL)
1709 backlight_ops.update();
1712 static int poll_callback(int condition, PMMsg *data)
1714 static time_t last_t;
1717 if (status != DEVICE_OPS_STATUS_START) {
1718 _E("display logic is not started!");
1722 if (condition == INPUT_POLL_EVENT) {
1723 if (pm_cur_state == S_LCDOFF || pm_cur_state == S_SLEEP)
1724 _I("Power key input");
1726 if (last_t != now) {
1727 states[pm_cur_state].trans(EVENT_INPUT);
1730 } else if (condition == PM_CONTROL_EVENT) {
1731 if (data->cond & MASK_BIT
1732 || ((data->cond >> SHIFT_UNLOCK) & MASK_BIT)
1733 || (data->cond >> SHIFT_CHANGE_TIMEOUT))
1734 proc_condition(data);
1736 if (data->cond & CHANGE_STATE_BIT)
1737 proc_change_state(data->cond, data->pid);
1743 static int update_setting(int key_idx, int val)
1747 int run_timeout = -1;
1748 int power_saving_stat = -1;
1749 int power_saving_display_stat = -1;
1752 case SETTING_TO_NORMAL:
1753 ret = get_run_timeout(&run_timeout);
1754 if (ret < 0 || run_timeout <= 0) {
1755 _E("Can not get run timeout. set default %.2f ms",
1756 DEFAULT_NORMAL_TIMEOUT);
1757 run_timeout = DEFAULT_NORMAL_TIMEOUT;
1759 states[S_NORMAL].timeout = run_timeout;
1760 states[pm_cur_state].trans(EVENT_INPUT);
1762 case SETTING_HALLIC_OPEN:
1764 update_display_time();
1765 if (pm_cur_state == S_NORMAL || pm_cur_state == S_LCDDIM)
1766 states[pm_cur_state].trans(EVENT_INPUT);
1767 else if (pm_cur_state == S_SLEEP && hallic_open)
1768 proc_change_state(S_LCDOFF <<
1769 (SHIFT_CHANGE_STATE + S_LCDOFF), getpid());
1771 case SETTING_LOW_BATT:
1772 if (low_battery_state(val)) {
1773 if (!(pm_status_flag & CHRGR_FLAG))
1774 power_saving_func(true);
1775 pm_status_flag |= LOWBT_FLAG;
1777 if (pm_status_flag & PWRSV_FLAG)
1778 power_saving_func(false);
1779 pm_status_flag &= ~LOWBT_FLAG;
1780 pm_status_flag &= ~BRTCH_FLAG;
1781 vconf_set_bool(VCONFKEY_PM_BRIGHTNESS_CHANGED_IN_LPM,
1785 case SETTING_CHARGING:
1787 if (pm_status_flag & LOWBT_FLAG) {
1788 power_saving_func(false);
1789 pm_status_flag &= ~LOWBT_FLAG;
1791 pm_status_flag |= CHRGR_FLAG;
1793 int bat_state = VCONFKEY_SYSMAN_BAT_NORMAL;
1794 vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW,
1796 if (low_battery_state(bat_state)) {
1797 power_saving_func(true);
1798 pm_status_flag |= LOWBT_FLAG;
1800 pm_status_flag &= ~CHRGR_FLAG;
1803 case SETTING_BRT_LEVEL:
1804 if (pm_status_flag & PWRSV_FLAG) {
1805 pm_status_flag |= BRTCH_FLAG;
1806 vconf_set_bool(VCONFKEY_PM_BRIGHTNESS_CHANGED_IN_LPM,
1808 _I("brightness changed in low battery,"
1809 "escape dim state");
1811 backlight_ops.set_default_brt(val);
1812 snprintf(buf, sizeof(buf), "%d", val);
1813 _D("Brightness set in bl : %d",val);
1814 launch_evenif_exist(SET_BRIGHTNESS_IN_BOOTLOADER, buf);
1816 case SETTING_LOCK_SCREEN:
1817 set_lock_screen_state(val);
1818 if (val == VCONFKEY_IDLE_UNLOCK) {
1819 if (CHECK_OPS(keyfilter_ops, backlight_enable))
1820 keyfilter_ops->backlight_enable(false);
1823 /* LCD on if lock screen show before waiting time */
1824 if (pm_cur_state == S_NORMAL &&
1825 val == VCONFKEY_IDLE_LOCK &&
1826 backlight_ops.get_lcd_power() != PM_LCD_POWER_ON)
1829 update_display_time();
1830 if (pm_cur_state == S_NORMAL) {
1831 states[pm_cur_state].trans(EVENT_INPUT);
1834 case SETTING_LOCK_SCREEN_BG:
1835 set_lock_screen_bg_state(val);
1836 update_display_time();
1837 if (pm_cur_state == S_NORMAL) {
1838 states[pm_cur_state].trans(EVENT_INPUT);
1841 case SETTING_POWER_SAVING:
1843 vconf_get_bool(VCONFKEY_SETAPPL_PWRSV_CUSTMODE_DISPLAY,
1844 &power_saving_display_stat);
1845 if (power_saving_display_stat != 1)
1846 power_saving_display_stat = 0;
1847 if (device_set_property(DEVICE_TYPE_DISPLAY, PROP_DISPLAY_FRAME_RATE,
1848 power_saving_display_stat) < 0) {
1849 _E("Fail to set display frame rate!");
1851 backlight_ops.update();
1853 case SETTING_POWER_SAVING_DISPLAY:
1854 vconf_get_bool(VCONFKEY_SETAPPL_PWRSV_SYSMODE_STATUS,
1855 &power_saving_stat);
1856 if (power_saving_stat == 1) {
1858 power_saving_display_stat = 1;
1860 power_saving_display_stat = 0;
1861 if (device_set_property(DEVICE_TYPE_DISPLAY,
1862 PROP_DISPLAY_FRAME_RATE, power_saving_display_stat) < 0) {
1863 _E("Fail to set display frame rate!");
1865 backlight_ops.update();
1868 case SETTING_SMART_STAY:
1870 pm_status_flag &= ~SMAST_FLAG;
1871 _I("Smart Stay Feature off");
1873 pm_status_flag |= SMAST_FLAG;
1874 _I("Smart Stay Feature on");
1877 case SETTING_POWEROFF:
1879 case VCONFKEY_SYSMAN_POWER_OFF_NONE:
1880 case VCONFKEY_SYSMAN_POWER_OFF_POPUP:
1881 pm_status_flag &= ~PWROFF_FLAG;
1883 case VCONFKEY_SYSMAN_POWER_OFF_DIRECT:
1884 case VCONFKEY_SYSMAN_POWER_OFF_RESTART:
1885 pm_status_flag |= PWROFF_FLAG;
1889 case SETTING_BOOT_POWER_ON_STATUS:
1891 * Unlock lcd off after booting is done.
1892 * deviced guarantees all booting script is executing.
1893 * Last script of booting unlocks this suspend blocking state.
1895 if (val == VCONFKEY_DEVICED_BOOT_POWER_ON_DONE) {
1897 pm_unlock_internal(INTERNAL_LOCK_BOOTING, LCD_OFF, PM_SLEEP_MARGIN);
1900 case SETTING_POWER_CUSTOM_BRIGHTNESS:
1901 if (val == VCONFKEY_PM_CUSTOM_BRIGHTNESS_ON)
1902 backlight_ops.set_custom_status(true);
1904 backlight_ops.set_custom_status(false);
1906 case SETTING_ACCESSIBILITY_TTS:
1908 _I("TTS is %s", (val ? "ON" : "OFF"));
1917 static void check_seed_status(void)
1921 int bat_state = VCONFKEY_SYSMAN_BAT_NORMAL;
1924 int lock_state = -1;
1925 int power_saving_stat = -1;
1926 int power_saving_display_stat = -1;
1927 int smart_stay_on = 0;
1929 /* Charging check */
1930 if ((get_charging_status(&tmp) == 0) && (tmp > 0)) {
1931 pm_status_flag |= CHRGR_FLAG;
1934 ret = get_setting_brightness(&tmp);
1935 if (ret != 0 || (tmp < PM_MIN_BRIGHTNESS || tmp > PM_MAX_BRIGHTNESS)) {
1936 _I("fail to read vconf value for brightness");
1937 brt = PM_DEFAULT_BRIGHTNESS;
1938 if (tmp < PM_MIN_BRIGHTNESS || tmp > PM_MAX_BRIGHTNESS)
1939 vconf_set_int(VCONFKEY_SETAPPL_LCD_BRIGHTNESS, brt);
1942 _I("Set brightness from Setting App. %d", tmp);
1943 backlight_ops.set_default_brt(tmp);
1945 vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, &bat_state);
1946 if (low_battery_state(bat_state)) {
1947 if (!(pm_status_flag & CHRGR_FLAG)) {
1948 power_saving_func(true);
1949 pm_status_flag |= LOWBT_FLAG;
1952 backlight_ops.update();
1954 touch_ops.screen_on();
1957 /* lock screen check */
1958 ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
1959 set_lock_screen_state(lock_state);
1960 if (lock_state == VCONFKEY_IDLE_LOCK) {
1961 states[S_NORMAL].timeout = lock_screen_timeout;
1962 _I("LCD NORMAL timeout is set by %d ms"
1963 " for lock screen", lock_screen_timeout);
1966 /* power saving display stat */
1967 vconf_get_bool(VCONFKEY_SETAPPL_PWRSV_SYSMODE_STATUS,
1968 &power_saving_stat);
1969 if (power_saving_stat <= 0) {
1970 power_saving_display_stat = 0;
1972 vconf_get_bool(VCONFKEY_SETAPPL_PWRSV_CUSTMODE_DISPLAY,
1973 &power_saving_display_stat);
1975 if (power_saving_display_stat < 0) {
1976 _E("failed to read power saving display stat!");
1978 _I("power saving display stat : %d",
1979 power_saving_display_stat);
1982 /* Smart stay status */
1983 vconf_get_int(VCONFKEY_SETAPPL_SMARTSCREEN_SMARTSTAY_STATUS, &smart_stay_on);
1984 if (!smart_stay_on) {
1985 _I("Smart Stay Feature off");
1987 _I("Smart Stay Feature on");
1988 pm_status_flag |= SMAST_FLAG;
1992 ret = vconf_get_bool(VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, &tts_state);
1994 _E("Failed to get TTS setting! (%d)", ret);
1995 _I("TTS is %s", (tts_state ? "ON" : "OFF"));
2009 static const char *errMSG[INIT_END] = {
2010 [INIT_SETTING] = "setting init error",
2011 [INIT_INTERFACE] = "lowlevel interface(sysfs or others) init error",
2012 [INIT_POLL] = "input devices poll init error",
2013 [INIT_FIFO] = "FIFO poll init error",
2014 [INIT_DBUS] = "d-bus init error",
2017 static int input_action(char* input_act, char* input_path)
2020 Eina_List *list_node = NULL;
2021 Eina_List *l = NULL;
2022 Eina_List *l_next = NULL;
2024 PmLockNode *tmp = NULL;
2026 if (!strcmp("add", input_act)) {
2027 _I("add input path : %s", input_path);
2028 ret = init_pm_poll_input(poll_callback, input_path);
2029 } else if (!strcmp("remove", input_act)) {
2030 EINA_LIST_FOREACH_SAFE(indev_list, l, l_next, data)
2031 if(!strcmp(input_path, data->dev_path)) {
2032 _I("remove %s", input_path);
2033 ecore_main_fd_handler_del(data->dev_fd);
2035 free(data->dev_path);
2037 indev_list = eina_list_remove_list(indev_list, l);
2040 } else if (!strcmp("change", input_act)) {
2041 if (!strcmp("ESD", input_path)) {
2043 if (pm_cur_state == S_NORMAL) {
2044 backlight_ops.off();
2046 } else if (pm_cur_state == S_LCDDIM) {
2047 backlight_ops.off();
2048 backlight_ops.dim();
2056 int set_lcd_timeout(int on, int dim, int holdkey_block, char *name)
2058 if (on == 0 && dim == 0) {
2059 _I("LCD timeout changed : default setting");
2060 custom_normal_timeout = custom_dim_timeout = 0;
2061 } else if (on < 0 || dim < 0) {
2062 _E("fail to set value (%d,%d)", on, dim);
2065 _I("LCD timeout changed : on(%ds), dim(%ds)", on, dim);
2066 custom_normal_timeout = SEC_TO_MSEC(on);
2067 custom_dim_timeout = SEC_TO_MSEC(dim);
2069 /* Apply new backlight time */
2070 update_display_time();
2072 if (holdkey_block) {
2073 custom_holdkey_block = true;
2074 _I("hold key disabled !");
2076 custom_holdkey_block = false;
2077 _I("hold key enabled !");
2080 if (custom_change_name) {
2081 free(custom_change_name);
2082 custom_change_name = 0;
2085 if (custom_normal_timeout == 0 &&
2086 custom_dim_timeout == 0 &&
2090 custom_change_name = strndup(name, strlen(name));
2091 if (!custom_change_name) {
2092 _E("Malloc falied!");
2093 custom_normal_timeout = custom_dim_timeout = 0;
2094 custom_holdkey_block = false;
2101 int reset_lcd_timeout(char *name, enum watch_id id)
2106 if (!custom_change_name)
2109 if (strcmp(name, custom_change_name))
2112 _I("reset lcd timeout %s: set default timeout", name);
2114 free(custom_change_name);
2115 custom_change_name = 0;
2116 custom_normal_timeout = custom_dim_timeout = 0;
2117 custom_holdkey_block = false;
2119 update_display_time();
2120 if (pm_cur_state == S_NORMAL) {
2121 states[pm_cur_state].trans(EVENT_INPUT);
2127 int get_hdmi_state(void)
2132 static int hdmi_changed(void *data)
2134 hdmi_state = (int)data;
2139 static int hall_ic_open(void *data)
2141 int open = (int)data;
2143 update_pm_setting(SETTING_HALLIC_OPEN, open);
2148 static int input_device_add(void *data)
2150 char *path = (char *)data;
2155 input_action(UDEV_ADD, path);
2160 static int input_device_remove(void *data)
2162 char *path = (char *)data;
2167 input_action(UDEV_REMOVE, path);
2172 static int booting_done(void *data)
2174 static bool done = false;
2179 _I("booting done, unlock LCD_OFF");
2180 pm_unlock_internal(INTERNAL_LOCK_BOOTING, LCD_OFF, PM_SLEEP_MARGIN);
2186 static int lcd_esd(void *data)
2193 input_action(UDEV_CHANGE, path);
2198 static int battery_health_changed(void *data)
2200 int health = (int)data;
2202 if (health == HEALTH_GOOD) {
2203 _D("battery health good");
2204 pm_status_flag &= ~DIMSTAY_FLAG;
2206 } else if (health == HEALTH_BAD) {
2207 _D("battery health bad");
2208 pm_status_flag |= DIMSTAY_FLAG;
2214 static int display_load_config(struct parse_result *result, void *user_data)
2216 struct display_config *c = user_data;
2218 _D("%s,%s,%s", result->section, result->name, result->value);
2223 if (!MATCH(result->section, "Display"))
2226 if (MATCH(result->name, "LockScreenWaitingTime")) {
2227 SET_CONF(c->lock_wait_time, atof(result->value));
2228 _D("lock wait time is %.3f", c->lock_wait_time);
2229 } else if (MATCH(result->name, "LongPressInterval")) {
2230 SET_CONF(c->longpress_interval, atof(result->value));
2231 _D("long press interval is %.3f", c->longpress_interval);
2232 } else if (MATCH(result->name, "LightSensorSamplingInterval")) {
2233 SET_CONF(c->lightsensor_interval, atof(result->value));
2234 _D("lightsensor interval is %.3f", c->lightsensor_interval);
2235 } else if (MATCH(result->name, "LCDOffTimeout")) {
2236 SET_CONF(c->lcdoff_timeout, atoi(result->value));
2237 _D("lcdoff timeout is %d ms", c->lcdoff_timeout);
2238 } else if (MATCH(result->name, "BrightnessChangeStep")) {
2239 SET_CONF(c->brightness_change_step, atoi(result->value));
2240 _D("brightness change step is %d", c->brightness_change_step);
2241 } else if (MATCH(result->name, "HBMLuxThreshold")) {
2242 SET_CONF(c->hbm_lux_threshold, atoi(result->value));
2243 _D("HBM lux threshold is %d", c->hbm_lux_threshold);
2244 } else if (MATCH(result->name, "LCDAlwaysOn")) {
2245 c->lcd_always_on = (MATCH(result->value, "yes") ? 1 : 0);
2246 _D("LCD always on is %d", c->lcd_always_on);
2247 } else if (MATCH(result->name, "ChangedFrameRateAllowed")) {
2248 if (strstr(result->value, "setting")) {
2249 c->framerate_app[REFRESH_SETTING] = 1;
2250 _D("framerate app is Setting");
2252 if (strstr(result->value, "all")) {
2253 memset(c->framerate_app, 1, sizeof(c->framerate_app));
2254 _D("framerate app is All");
2256 } else if (MATCH(result->name, "ControlDisplay")) {
2257 c->control_display = (MATCH(result->value, "yes") ? 1 : 0);
2258 _D("ControlDisplay is %d", c->control_display);
2259 } else if (MATCH(result->name, "PowerKeyDoublePressSupport")) {
2260 c->powerkey_doublepress = (MATCH(result->value, "yes") ? 1 : 0);
2261 _D("PowerKeyDoublePressSupport is %d", c->powerkey_doublepress);
2262 } else if (MATCH(result->name, "UseALPM")) {
2263 c->alpm_on = (MATCH(result->value, "yes") ? 1 : 0);
2264 _D("UseALPM is %d", c->alpm_on);
2271 * Power manager Main
2274 static void display_init(void *data)
2277 unsigned int flags = (WITHOUT_STARTNOTI | FLAG_X_DPMS);
2280 _I("Start power manager");
2282 signal(SIGHUP, sig_hup);
2284 power_saving_func = default_saving_mode;
2285 /* noti init for new input device like bt mouse */
2288 /* load configutation */
2289 ret = config_parse(DISPLAY_CONF_FILE, display_load_config, &display_conf);
2291 _W("Failed to load %s, %s Use default value!",
2292 DISPLAY_CONF_FILE, ret);
2294 register_notifier(DEVICE_NOTIFIER_HALLIC_OPEN, hall_ic_open);
2295 register_notifier(DEVICE_NOTIFIER_INPUT_ADD, input_device_add);
2296 register_notifier(DEVICE_NOTIFIER_INPUT_REMOVE, input_device_remove);
2297 register_notifier(DEVICE_NOTIFIER_BOOTING_DONE, booting_done);
2298 register_notifier(DEVICE_NOTIFIER_LCD_ESD, lcd_esd);
2299 register_notifier(DEVICE_NOTIFIER_HDMI, hdmi_changed);
2300 register_notifier(DEVICE_NOTIFIER_BATTERY_HEALTH, battery_health_changed);
2302 for (i = INIT_SETTING; i < INIT_END; i++) {
2305 ret = init_setting(update_setting);
2307 case INIT_INTERFACE:
2308 get_lcd_timeout_from_settings();
2309 ret = init_sysfs(flags);
2313 ret = init_pm_poll(poll_callback);
2317 ret = init_pm_dbus();
2321 _E("%s", errMSG[i]);
2326 if (i == INIT_END) {
2327 display_ops_init(NULL);
2328 #ifdef ENABLE_PM_LOG
2331 check_seed_status();
2333 if (display_conf.lcd_always_on) {
2334 _D("LCD always on!");
2335 trans_table[S_NORMAL][EVENT_TIMEOUT] = S_NORMAL;
2338 if (flags & WITHOUT_STARTNOTI) { /* start without noti */
2339 _I("Start Power managing without noti");
2340 pm_cur_state = S_NORMAL;
2341 set_setting_pmstate(pm_cur_state);
2343 timeout = states[S_NORMAL].timeout;
2344 /* check minimun lcd on time */
2345 if (timeout < DEFAULT_NORMAL_TIMEOUT)
2346 timeout = DEFAULT_NORMAL_TIMEOUT;
2348 reset_timeout(timeout);
2351 * Lock lcd off until booting is done.
2352 * deviced guarantees all booting script is executing.
2353 * Last script of booting unlocks this suspend blocking state.
2355 pm_lock_internal(INTERNAL_LOCK_BOOTING, LCD_OFF,
2356 STAY_CUR_STATE, BOOTING_DONE_WATING_TIME);
2358 if (CHECK_OPS(keyfilter_ops, init))
2359 keyfilter_ops->init();
2361 status = DEVICE_OPS_STATUS_START;
2364 static void display_exit(void *data)
2368 status = DEVICE_OPS_STATUS_STOP;
2370 /* Set current state to S_NORMAL */
2371 pm_cur_state = S_NORMAL;
2372 set_setting_pmstate(pm_cur_state);
2373 /* timeout is not needed */
2376 if (CHECK_OPS(keyfilter_ops, exit))
2377 keyfilter_ops->exit();
2379 display_ops_exit(NULL);
2381 for (i = i - 1; i >= INIT_SETTING; i--) {
2386 case INIT_INTERFACE:
2390 unregister_notifier(DEVICE_NOTIFIER_HALLIC_OPEN, hall_ic_open);
2391 unregister_notifier(DEVICE_NOTIFIER_INPUT_ADD,
2393 unregister_notifier(DEVICE_NOTIFIER_INPUT_REMOVE,
2394 input_device_remove);
2395 unregister_notifier(DEVICE_NOTIFIER_BOOTING_DONE,
2397 unregister_notifier(DEVICE_NOTIFIER_LCD_ESD, lcd_esd);
2398 unregister_notifier(DEVICE_NOTIFIER_HDMI, hdmi_changed);
2399 unregister_notifier(DEVICE_NOTIFIER_BATTERY_HEALTH,
2400 battery_health_changed);
2406 free_lock_info_list();
2408 _I("Stop power manager");
2411 static int display_start(void)
2413 if (status == DEVICE_OPS_STATUS_START)
2421 static int display_stop(void)
2423 if (status == DEVICE_OPS_STATUS_STOP)
2431 static int display_status(void)
2436 static const struct device_ops display_device_ops = {
2437 .priority = DEVICE_PRIORITY_HIGH,
2439 .init = display_init,
2440 .exit = display_exit,
2441 .start = display_start,
2442 .stop = display_stop,
2443 .status = display_status,
2446 DEVICE_OPS_REGISTER(&display_device_ops)