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>
40 #include <vconf-keys.h>
42 #include <libsyscommon/list.h>
43 #include <hal/device/hal-device-power.h>
45 #include "ambient-mode.h"
48 #include "lock-detector.h"
49 #include "display-ops.h"
50 #include "shared/devices.h"
51 #include "shared/device-notifier.h"
52 #include "core/udev.h"
53 #include "shared/common.h"
54 #include "shared/apps.h"
55 #include "extcon/extcon.h"
56 #include "battery/power-supply.h"
57 #include "power/power.h"
58 #include "power/power-off.h"
59 #include "power/power-suspend.h"
60 #include "power/power-boot.h"
61 #include "power/power-doze.h"
62 #include "display/display-dpms.h"
63 #include "proximity.h"
64 #include "display-info.h"
65 #include "display-signal.h"
66 #include "display-lock.h"
67 #include "shared/plugin.h"
69 #define DISPLAY_CONF_FILE "/etc/deviced/display.conf"
72 * @addtogroup POWER_MANAGER
76 #define LOCK_SCREEN_INPUT_TIMEOUT 10000
77 #define LOCK_SCREEN_CONTROL_TIMEOUT 5000
78 #define ALWAYS_ON_TIMEOUT 360000000
79 #define LATE_LCD_TRANSIT 1
81 #define GESTURE_STR "gesture"
82 #define POWER_KEY_STR "powerkey"
83 #define TOUCH_STR "touch"
84 #define EVENT_STR "event"
85 #define TIMEOUT_STR "timeout"
86 #define PROXI_STR "proximity"
87 #define PALM_STR "palm"
88 #define UNKNOWN_STR "unknown"
90 extern void init_pm_internal();
91 extern void init_save_userlock(void);
93 static struct display_plugin *disp_plgn;
94 static struct _backlight_ops *backlight_ops;
95 static struct battery_plugin *battery_plgn;
96 static int (*fp_get_charging_status) (int *val);
98 static void (*power_saving_func) (int onoff);
99 static enum device_ops_status status = DEVICE_OPS_STATUS_UNINIT;
101 static guint timeout_src_id;
102 static int system_wakeup_flag = false;
103 static unsigned int custom_normal_timeout = 0;
104 static unsigned int custom_dim_timeout = 0;
105 int custom_holdkey_block = false;
106 static char *custom_change_name;
107 static bool hallic_open = true;
108 static guint lock_timeout_id;
109 static guint transit_timer;
110 static int lock_screen_timeout = LOCK_SCREEN_INPUT_TIMEOUT;
111 static struct timeval lcdon_tv;
112 static int lcd_paneloff_mode = false;
113 static int stay_touchscreen_off = false;
116 * The two variables(lcdon_broadcast, pmstate_suspend) must be set initial
117 * state because it should be sent from previous state at booting time.
119 static bool lcdon_broadcast = true;
121 static bool touch_blocked = false;
123 /* default transition, action fuctions */
124 static int default_trans(int evt);
125 static int default_action(int timeout);
126 static int default_check(int curr, int next);
128 static gboolean del_normal_cond(void *data);
129 static gboolean del_dim_cond(void *data);
130 static gboolean del_off_cond(void *data);
132 static int default_proc_change_state(unsigned int cond, pid_t pid);
133 static int (*proc_change_state)(unsigned int cond, pid_t pid) = default_proc_change_state;
135 static struct state states[S_END] = {
136 { S_START, "S_START", NULL, NULL, NULL, NULL },
137 { S_NORMAL, "S_NORMAL", default_trans, default_action, default_check, del_normal_cond },
138 { S_LCDDIM, "S_LCDDIM", default_trans, default_action, default_check, del_dim_cond },
139 { S_LCDOFF, "S_LCDOFF", default_trans, default_action, default_check, del_off_cond },
140 { S_STANDBY, "S_STANDBY", NULL, NULL, NULL, NULL },
141 { S_SLEEP, "S_SLEEP", default_trans, default_action, default_check, NULL },
142 { S_POWEROFF, "S_POWEROFF", NULL, NULL, NULL, NULL },
145 static int trans_table[S_END][EVENT_END] = {
147 { S_START, S_START }, /* S_START */
148 { S_LCDDIM, S_NORMAL }, /* S_NORMAL */
149 { S_LCDOFF, S_NORMAL }, /* S_LCDDIM */
150 { S_SLEEP, S_NORMAL }, /* S_LCDOFF */
151 { S_SLEEP, S_STANDBY }, /* S_STANDBY */
152 { S_LCDOFF, S_NORMAL }, /* S_SLEEP */
153 { S_POWEROFF, S_POWEROFF }, /* S_POWEROFF */
156 #define SHIFT_UNLOCK 4
157 #define SHIFT_CHANGE_STATE 7
158 #define CHANGE_STATE_BIT 0xF00 /* 1111 0000 0000 */
159 #define SHIFT_LOCK_FLAG 16
160 #define SHIFT_CHANGE_TIMEOUT 20
161 #define CUSTOM_TIMEOUT_BIT 0x1
162 #define CUSTOM_HOLDKEY_BIT 0x2
163 #define HOLD_KEY_BLOCK_BIT 0x1
164 #define TIMEOUT_NONE (-1)
166 #define S_COVER_TIMEOUT 8000
167 #define GET_HOLDKEY_BLOCK_STATE(x) ((x >> SHIFT_LOCK_FLAG) & HOLD_KEY_BLOCK_BIT)
168 #define DELAYED_INIT_WATING_TIME 60000 /* 1 minute */
170 #define LOCK_SCREEN_WATING_TIME 300 /* 0.3 second */
171 #define LONG_PRESS_INTERVAL 400 /* 0.4 seconds */
172 #define SAMPLING_INTERVAL 1 /* 1 sec */
173 #define BRIGHTNESS_CHANGE_STEP 10
174 #define LCD_ALWAYS_ON 0
175 #define ACCEL_SENSOR_ON 1
176 #define CONTINUOUS_SAMPLING 1
177 #define LCDOFF_TIMEOUT 300 /* milli second */
179 #define DIFF_TIMEVAL_MS(a, b) \
180 (((a.tv_sec * 1000000 + a.tv_usec) - \
181 (b.tv_sec * 1000000 + b.tv_usec)) \
184 static struct display_config display_conf = {
185 .lock_wait_time = LOCK_SCREEN_WATING_TIME,
186 .longpress_interval = LONG_PRESS_INTERVAL,
187 .lightsensor_interval = SAMPLING_INTERVAL,
188 .lcdoff_timeout = LCDOFF_TIMEOUT,
189 .pm_default_brightness = 80,
190 .brightness_change_step = BRIGHTNESS_CHANGE_STEP,
191 .lcd_always_on = LCD_ALWAYS_ON,
193 .framerate_app = {0, 0, 0, 0},
194 .control_display = 0,
195 .powerkey_doublepress = 0,
196 .accel_sensor_on = ACCEL_SENSOR_ON,
197 .continuous_sampling = CONTINUOUS_SAMPLING,
198 .timeout_enable = true,
199 .input_support = true,
200 .lockcheck_timeout = 600,
201 .display_init_direction = DISPLAY_INIT_DIRECTION_HORIZONTAL,
202 .aod_enter_level = 40,
204 .touch_wakeup = false,
205 .display_on_usb_conn_changed = true,
208 struct display_function_info display_info = {
209 .update_auto_brightness = NULL,
210 .set_autobrightness_min = NULL,
211 .reset_autobrightness_min = NULL,
212 .face_detection = NULL,
215 inline const struct display_config* get_var_display_config()
217 return &display_conf;
220 inline struct state* state_st(enum state_t state)
222 return &states[state];
225 guint get_transition_timer(void)
227 return timeout_src_id;
230 void change_state_action(enum state_t state, int (*func)(int timeout))
232 _I("[%s] 'action' is changed.", states[state].name);
233 states[state].action = func;
236 void change_state_trans(enum state_t state, int (*func)(int evt))
238 _I("[%s] 'trans' is changed.", states[state].name);
239 states[state].trans = func;
242 void change_state_check(enum state_t state, int (*func)(int curr, int next))
244 _I("[%s] 'check' is changed.", states[state].name);
245 states[state].check = func;
248 void change_state_name(enum state_t state, const char *name)
250 _I("[%s] 'name' is changed.", states[state].name);
251 states[state].name = name;
254 void change_trans_table(enum state_t state, enum state_t next)
256 _I("[%s] 'timeout trans table' is changed.", states[state].name);
257 trans_table[state][EVENT_TIMEOUT] = next;
260 void change_proc_change_state(int (*func)(unsigned int cond, pid_t pid))
262 _I("'proc change state' is changed.");
263 proc_change_state = func;
266 static int display_brightness_changed(void *data)
270 brt = DATA_VALUE_INT(data);
272 ret = gdbus_signal_emit(NULL,
273 DEVICED_PATH_DISPLAY,
274 DEVICED_INTERFACE_DISPLAY,
276 g_variant_new("(i)", brt));
278 _E("Failed to send dbus signal Brightness.");
283 static int display_auto_brightness_sensing(void *data)
288 g_source_remove(transit_timer);
294 static const char* __device_flags_to_string(enum device_flags flags)
297 if (flags & (LCD_ON_BY_GESTURE | LCD_OFF_BY_GESTURE))
299 else if (flags & (LCD_ON_BY_POWER_KEY | LCD_OFF_BY_POWER_KEY))
300 return POWER_KEY_STR;
301 else if (flags & (LCD_ON_BY_EVENT | LCD_OFF_BY_EVENT))
303 else if (flags & LCD_ON_BY_TOUCH)
305 else if (flags & LCD_OFF_BY_TIMEOUT)
307 else if (flags & LCD_OFF_BY_PROXIMITY)
309 else if (flags & LCD_OFF_BY_PALM)
315 static unsigned long get_lcd_on_flags(void)
317 unsigned long flags = NORMAL_MODE;
319 if (lcd_paneloff_mode)
320 flags |= LCD_PANEL_OFF_MODE;
322 if (ambient_get_condition() == true) {
323 flags |= AMBIENT_MODE;
324 flags |= LCD_PHASED_TRANSIT_MODE;
330 bool touch_event_blocked(void)
332 return touch_blocked;
335 static gboolean late_transit_on(void *data)
338 return G_SOURCE_REMOVE;
340 g_source_remove(transit_timer);
343 backlight_ops->transit_state(DPMS_ON);
344 return G_SOURCE_REMOVE;
347 void lcd_on_procedure(int state, enum device_flags flag)
350 const struct device_ops *ops = NULL;
351 unsigned long flags = get_lcd_on_flags();
355 * Display on procedure
357 * step 2. broadcast lcd on signal with cause
358 * step 3. set brightness
359 * step 4. set pmstate of vconf
360 * step 5. display on operate
362 * - b. TSP(touch screen) and touchkey enable
363 * step 6. broadcast lcd on complete signal
364 * step 7. key backlight enable
368 _I("[lcdstep] 0x%lx", flags);
370 if (flags & AMBIENT_MODE) {
371 if (ambient_get_state() == false && backlight_ops->get_lcd_power() == DPMS_ON)
373 ambient_set_state(false);
376 /* send LCDOn dbus signal */
377 if (!lcdon_broadcast)
378 broadcast_lcd_on(SIGNAL_PRE, flags);
380 if (!(flags & LCD_PHASED_TRANSIT_MODE)) {
381 /* Update brightness level */
382 if (state == LCD_DIM)
383 backlight_ops->dim();
384 else if (state == LCD_NORMAL)
385 backlight_ops->update();
388 if (state == LCD_NORMAL)
389 set_setting_pmstate(S_NORMAL);
390 else if (state == LCD_DIM)
391 set_setting_pmstate(S_LCDDIM);
393 SYS_G_LIST_FOREACH(lcdon_ops, l, ops)
396 if (!lcdon_broadcast) {
397 broadcast_lcd_on(SIGNAL_POST, flags);
398 if (flags & LCD_PHASED_TRANSIT_MODE)
399 transit_timer = g_timeout_add_seconds(LATE_LCD_TRANSIT,
400 late_transit_on, NULL);
401 lcdon_broadcast = true;
404 if (CHECK_OPS(keyfilter_ops, backlight_enable))
405 keyfilter_ops->backlight_enable(true);
407 touch_blocked = false;
410 static unsigned long get_lcd_off_flags(void)
412 unsigned long flags = NORMAL_MODE;
414 if (ambient_get_condition() == true) {
415 flags |= AMBIENT_MODE;
416 flags |= LCD_PHASED_TRANSIT_MODE;
419 if (stay_touchscreen_off)
420 flags |= TOUCH_SCREEN_OFF_MODE;
425 inline void lcd_off_procedure(enum device_flags flag)
428 const struct device_ops *ops = NULL;
429 unsigned long flags = get_lcd_off_flags();
433 * Display off procedure
434 * step 0. enhance mode off using nofity (e.g mdnie, HBM, LBM)
435 * step 1. broadcast lcd off signal with cause
436 * step 2. set pmstate of vconf
437 * step 3. display off operate
439 * - b. TSP(touch screen) and touchkey disable
440 * step 4. broadcast lcd off complete siganl
441 * step 5. enter doze mode if it is enabled
443 _I("[lcdstep] 0x%lx", flags);
447 device_notify(DEVICE_NOTIFIER_LCD_OFF, NULL);
449 if (lcdon_broadcast) {
450 broadcast_lcd_off(SIGNAL_PRE, flags);
451 lcdon_broadcast = false;
456 touch_blocked = true;
458 set_setting_pmstate(S_LCDOFF);
460 if (CHECK_OPS(keyfilter_ops, backlight_enable))
461 keyfilter_ops->backlight_enable(false);
464 g_source_remove(transit_timer);
468 if (flags & LCD_PHASED_TRANSIT_MODE)
469 backlight_ops->transit_state(DPMS_OFF);
471 SYS_G_LIST_FOREACH(lcdon_ops, l, ops)
474 if (flags & AMBIENT_MODE) {
475 broadcast_lcd_off_late(flags);
477 broadcast_lcd_off(SIGNAL_POST, flags);
478 device_notify(DEVICE_NOTIFIER_LCD_OFF_COMPLETE, NULL);
484 void set_stay_touchscreen_off(int val)
486 _I("Stay touch screen off: %d", val);
487 stay_touchscreen_off = val;
489 if (disp_plgn->pm_change_internal)
490 disp_plgn->pm_change_internal(INTERNAL_LOCK_PM, LCD_NORMAL);
493 void set_lcd_paneloff_mode(int val)
495 _I("Lcd paneloff mode: %d", val);
496 lcd_paneloff_mode = val;
498 if (disp_plgn->pm_change_internal)
499 disp_plgn->pm_change_internal(INTERNAL_LOCK_PM, LCD_NORMAL);
502 int low_battery_state(int val)
505 case VCONFKEY_SYSMAN_BAT_POWER_OFF:
506 case VCONFKEY_SYSMAN_BAT_CRITICAL_LOW:
507 case VCONFKEY_SYSMAN_BAT_REAL_POWER_OFF:
513 int get_hallic_open(void)
518 void get_pname(pid_t pid, char *pname)
523 if (pid >= INTERNAL_LOCK_BASE)
524 snprintf(buf, PATH_MAX, "/proc/%d/cmdline", getpid());
526 snprintf(buf, PATH_MAX, "/proc/%d/cmdline", pid);
528 cmdline = open(buf, O_RDONLY);
531 _E("Process(%d) does not exist now(may be dead without unlock).", pid);
535 r = read(cmdline, pname, PATH_MAX);
536 if ((r >= 0) && (r < PATH_MAX))
544 static void del_state_cond(void *data, enum state_t state)
546 PmLockNode *tmp = NULL;
552 /* A passed data is a pid_t type data, not a 64bit data. */
553 pid = (pid_t)((intptr_t)data);
554 _I("delete prohibit %s condition by timeout (%d)", states[state].name, pid);
556 if (pid == INTERNAL_LOCK_AMBIENT)
557 ambient_check_invalid_state(pid);
559 tmp = find_node(state, pid);
560 del_node(state, tmp);
561 set_unlock_time(pid, state);
563 /* Change state only when the two conditions below are satisfied.
564 * 1. There should be no running state-transition timer
565 * 2. Released lock is one of the pm_cur_state's lock
566 * This emulates already expired transition timer */
567 if (!timeout_src_id && get_pm_cur_state() == state)
568 states[get_pm_cur_state()].trans(EVENT_TIMEOUT);
570 if (state == S_LCDOFF)
571 set_process_active(false, pid);
574 static gboolean del_normal_cond(void *data)
576 del_state_cond(data, S_NORMAL);
577 return G_SOURCE_REMOVE;
580 static gboolean del_dim_cond(void *data)
582 del_state_cond(data, S_LCDDIM);
583 return G_SOURCE_REMOVE;
586 static gboolean del_off_cond(void *data)
588 del_state_cond(data, S_LCDOFF);
589 return G_SOURCE_REMOVE;
592 /* timeout handler */
593 gboolean timeout_handler(void *data)
595 _I("Time out state %s", states[get_pm_cur_state()].name);
597 if (timeout_src_id) {
598 g_source_remove(timeout_src_id);
602 states[get_pm_cur_state()].trans(EVENT_TIMEOUT);
603 return G_SOURCE_REMOVE;
606 void reset_timeout(int timeout)
608 if (!display_conf.timeout_enable)
611 if ((get_pm_cur_state() == S_LCDOFF)
612 && (is_emulator() == true || timeout_sleep_support == false))
615 _I("Reset timeout(%d ms).", timeout);
616 if (timeout_src_id != 0) {
617 g_source_remove(timeout_src_id);
621 if (trans_table[get_pm_cur_state()][EVENT_TIMEOUT] == get_pm_cur_state())
625 timeout_src_id = g_timeout_add(timeout,
626 timeout_handler, NULL);
627 else if (timeout == 0)
628 states[get_pm_cur_state()].trans(EVENT_TIMEOUT);
631 /* get configurations from setting */
632 static int get_lcd_timeout_from_settings(void)
637 for (i = 0; i < S_END; i++) {
638 switch (states[i].state) {
640 get_run_timeout(&val);
643 get_dim_timeout(&val);
646 val = display_conf.lcdoff_timeout;
649 /* This state doesn't need to set time out. */
654 states[i].timeout = val;
656 _I("State(%s) timeout(%d) ms", states[i].name,
663 static void update_display_time(void)
665 int run_timeout, val;
667 /* first priority : s cover */
669 states[S_NORMAL].timeout = S_COVER_TIMEOUT;
670 _I("S cover closed: Timeout(%d ms) is set by normal.",
675 /* second priority : custom timeout */
676 if (custom_normal_timeout > 0) {
677 states[S_NORMAL].timeout = custom_normal_timeout;
678 states[S_LCDDIM].timeout = custom_dim_timeout;
679 _I("CUSTOM : timeout is set by normal(%d ms), dim(%d ms)",
680 custom_normal_timeout, custom_dim_timeout);
684 /* third priority : lock state */
685 if ((__get_lock_screen_state() == VCONFKEY_IDLE_LOCK) &&
686 !get_lock_screen_bg_state()) {
687 /* timeout is different according to key or event. */
688 states[S_NORMAL].timeout = lock_screen_timeout;
689 _I("LOCK: Timeout(%d ms) is set by normal.",
690 lock_screen_timeout);
694 /* default setting */
695 get_run_timeout(&run_timeout);
698 * if the run_timeout is zero, it regards AlwaysOn state
700 if (run_timeout == 0 || display_conf.lcd_always_on) {
701 run_timeout = ALWAYS_ON_TIMEOUT;
702 _I("LCD always on.");
705 states[S_NORMAL].timeout = run_timeout;
707 get_dim_timeout(&val);
708 states[S_LCDDIM].timeout = val;
710 _I("Normal: NORMAL timeout is set by %d ms", states[S_NORMAL].timeout);
711 _I("Normal: DIM timeout is set by %d ms", states[S_LCDDIM].timeout);
714 static void update_display_locktime(int time)
716 lock_screen_timeout = time;
717 update_display_time();
720 void set_dim_state(bool on)
722 _I("Dim state is %d.", on);
723 update_display_time();
724 states[get_pm_cur_state()].trans(EVENT_INPUT);
727 void lcd_on_direct(enum device_flags flags)
729 enum hal_device_power_transition_reason reason;
731 if (flags & LCD_ON_BY_POWER_KEY)
732 reason = HAL_DEVICE_POWER_TRANSITION_REASON_POWER_KEY;
733 else if (flags & LCD_ON_BY_TOUCH)
734 reason = HAL_DEVICE_POWER_TRANSITION_REASON_TOUCH_SCREEN;
736 reason = HAL_DEVICE_POWER_TRANSITION_REASON_UNKNOWN;
738 power_request_change_state_strict(DEVICED_POWER_STATE_SLEEP, DEVICED_POWER_STATE_NORMAL, reason, NULL);
739 set_pm_cur_state(S_NORMAL);
741 _D("lcd is on directly");
742 gettimeofday(&lcdon_tv, NULL);
743 lcd_on_procedure(LCD_NORMAL, flags);
745 update_display_locktime(LOCK_SCREEN_INPUT_TIMEOUT);
748 static inline bool check_lcd_is_on(void)
750 if (backlight_ops->get_lcd_power() != DPMS_ON)
756 static gboolean timer_refresh_cb(gpointer data)
760 /* state transition */
761 set_pm_old_state(get_pm_cur_state());
762 set_pm_cur_state(S_NORMAL);
763 st = &states[get_pm_cur_state()];
766 st->action(st->timeout);
771 int custom_lcdon(int timeout)
778 if (check_lcd_is_on() == false)
779 lcd_on_direct(LCD_ON_BY_GESTURE);
781 _I("Custom lcd on timeout(%d ms).", timeout);
782 if (set_custom_lcdon_timeout(timeout) == true)
783 update_display_time();
785 /* state transition */
786 set_pm_old_state(get_pm_cur_state());
787 set_pm_cur_state(S_NORMAL);
788 st = &states[get_pm_cur_state()];
792 st->action(st->timeout);
794 g_idle_add(timer_refresh_cb, NULL);
799 int custom_lcdoff(enum device_flags flag)
803 check_processes(S_NORMAL);
804 check_processes(S_LCDDIM);
806 /* check holdkey block flag in lock node */
807 if (check_lock_condition(S_NORMAL) || check_lock_condition(S_LCDDIM)) {
809 * When another proccess is normal lock, device is received call then,
810 * call app can be changed to lcd state by proximity.
811 * If proximity is near then normal lock will be unlocked.
813 if (flag & LCD_OFF_BY_PROXIMITY) {
814 _I("custom lcd off by proximity, delete normal lock");
815 delete_condition(S_NORMAL);
817 _I("skip custom lcd off");
822 _I("custom lcd off by flag(%d)", flag);
823 if (backlight_ops->get_lcd_power() == DPMS_ON)
824 lcd_off_procedure(flag);
826 if (set_custom_lcdon_timeout(0) == true)
827 update_display_time();
829 /* state transition */
830 set_pm_old_state(get_pm_cur_state());
831 set_pm_cur_state(S_LCDOFF);
832 st = &states[get_pm_cur_state()];
836 st->action(st->timeout);
841 int display_on_by_reason(const char *reason, int timeout)
847 str_len = strlen(reason);
849 if (!strncmp(reason, GESTURE_STR, str_len))
850 flag = LCD_ON_BY_GESTURE;
851 else if (!strncmp(reason, EVENT_STR, str_len))
852 flag = LCD_ON_BY_EVENT;
854 _E("Reason is unknown(%s)", reason);
859 _E("Cannot setting timeout %d", timeout);
863 if (check_lcd_is_on() == false)
866 _I("platform lcd on by %s (%d ms)", reason, timeout);
867 if (set_custom_lcdon_timeout(timeout) == true)
868 update_display_time();
870 /* state transition */
871 set_pm_old_state(get_pm_cur_state());
872 set_pm_cur_state(S_NORMAL);
873 st = &states[get_pm_cur_state()];
877 st->action(st->timeout);
882 int display_off_by_reason(const char *reason)
888 str_len = strlen(reason);
890 if (!strncmp(reason, GESTURE_STR, str_len)) {
891 check_processes(S_NORMAL);
892 check_processes(S_LCDDIM);
894 /* check holdkey block flag in lock node */
895 if (check_lock_condition(S_NORMAL) || check_lock_condition(S_LCDDIM)) {
896 _I("skip platform lcd off by gesture");
899 flag = LCD_OFF_BY_GESTURE;
900 } else if (!strncmp(reason, PALM_STR, str_len)) {
901 delete_condition(S_NORMAL);
902 delete_condition(S_LCDDIM);
904 flag = LCD_OFF_BY_PALM;
906 _E("Reason is unknown(%s)", reason);
910 _I("platform lcd off by %s", reason);
911 if (backlight_ops->get_lcd_power() == DPMS_ON)
912 lcd_off_procedure(flag);
914 /* state transition */
915 set_pm_old_state(get_pm_cur_state());
916 set_pm_cur_state(S_LCDOFF);
917 st = &states[get_pm_cur_state()];
921 st->action(st->timeout);
926 static void default_proc_change_state_action(enum state_t next, int timeout)
930 set_pm_old_state(get_pm_cur_state());
931 set_pm_cur_state(next);
933 st = &states[get_pm_cur_state()];
935 if (st && st->action) {
937 st->action(st->timeout);
943 static int default_proc_change_state(unsigned int cond, pid_t pid)
947 next = GET_COND_STATE(cond);
948 _I("Change process(%d) state to %s.", pid, states[next].name);
952 if (check_lcd_is_on() == false)
953 lcd_on_direct(LCD_ON_BY_EVENT);
954 update_display_locktime(LOCK_SCREEN_CONTROL_TIMEOUT);
955 default_proc_change_state_action(next, -1);
958 default_proc_change_state_action(next, -1);
961 if (backlight_ops->get_lcd_power() == DPMS_ON) {
962 if (get_proximity_state() == SENSOR_PROXIMITY_NEAR)
963 lcd_off_procedure(LCD_OFF_BY_PROXIMITY);
965 lcd_off_procedure(LCD_OFF_BY_EVENT);
967 if (set_custom_lcdon_timeout(0))
968 update_display_time();
969 default_proc_change_state_action(next, -1);
972 _I("Dangerous requests.");
973 /* at first LCD_OFF and then goto sleep */
974 /* state transition */
975 default_proc_change_state_action(S_LCDOFF, TIMEOUT_NONE);
976 delete_condition(S_NORMAL);
977 delete_condition(S_LCDDIM);
978 delete_condition(S_LCDOFF);
979 if (lcdon_broadcast) {
980 _I("broadcast lcd off signal at non-lcd device");
981 broadcast_lcd_off(SIGNAL_PRE, 0);
982 broadcast_lcd_off(SIGNAL_POST, 0);
984 default_proc_change_state_action(S_SLEEP, TIMEOUT_NONE);
994 static void proc_condition_lock(PMMsg *data)
997 guint cond_timeout_id = 0;
998 char pname[PATH_MAX];
999 pid_t pid = data->pid;
1001 int holdkey_block, ret;
1004 const char *lock_type = NULL;
1006 state = GET_COND_STATE(data->cond);
1007 if (state == S_START)
1010 flags = GET_COND_FLAG(data->cond);
1011 get_pname(pid, pname);
1013 if ((state == S_LCDOFF) && (get_pm_cur_state() == S_SLEEP) &&
1014 (pm_get_power_lock() == POWER_UNLOCK))
1015 proc_change_state(data->cond, INTERNAL_LOCK_PM);
1017 if (data->timeout > 0) {
1018 /* To pass a pid_t data through the timer infrastructure
1019 * without memory allocation, a pid_t data becomes typecast
1020 * to intptr_t and void *(64bit) type. */
1021 cond_timeout_id = g_timeout_add(
1023 states[state].timeout_cb,
1024 (void*)((intptr_t)pid));
1025 if (!cond_timeout_id)
1026 _E("Failed to register display timer.");
1029 holdkey_block = GET_COND_FLAG(data->cond) & PM_FLAG_BLOCK_HOLDKEY;
1031 tmp = find_node(state, pid);
1033 tmp = add_node(state, pid, cond_timeout_id, holdkey_block);
1035 _E("Failed to acquire lock, state: %d, pid: %d.", state, pid);
1039 update_lock_timer(data, tmp, cond_timeout_id);
1040 tmp->holdkey_block = holdkey_block;
1043 if (state == S_LCDOFF)
1044 set_process_active(true, pid);
1046 _I("[%s] locked by %5d with %u ms", states[state].name, pid, data->timeout);
1048 if (pid < INTERNAL_LOCK_BASE) {
1050 if (state == S_LCDOFF)
1051 lock_type = PM_LCDOFF_STR;
1052 else if (state == S_LCDDIM)
1053 lock_type = PM_LCDDIM_STR;
1054 else if (state == S_NORMAL)
1055 lock_type = PM_LCDON_STR;
1058 /* power lock signal */
1059 ret = gdbus_signal_emit(NULL,
1060 DEVICED_PATH_DISPLAY,
1061 DEVICED_INTERFACE_DISPLAY,
1063 g_variant_new("(sii)", lock_type, pid, (int)data->timeout));
1065 _E("Failed to send dbus signal PowerLock.");
1068 _SD("be requested LOCK info pname(%s), holdkeyblock(%d) flags(%d)",
1069 pname, holdkey_block, flags);
1070 set_lock_time(pid, pname, state);
1072 device_notify(DEVICE_NOTIFIER_DISPLAY_LOCK, (void *)&value);
1075 static void proc_condition_unlock(PMMsg *data)
1077 pid_t pid = data->pid;
1080 char pname[PATH_MAX];
1084 const char *lock_type = NULL;
1086 state = GET_COND_STATE(data->cond);
1090 flags = GET_COND_FLAG(data->cond);
1091 get_pname(pid, pname);
1093 tmp = find_node(state, pid);
1094 del_node(state, tmp);
1096 if (state == S_LCDOFF)
1097 set_process_active(false, pid);
1099 _I("[%s] unlocked by %5d", states[state].name, pid);
1101 if (pid < INTERNAL_LOCK_BASE) {
1103 if (state == S_LCDOFF)
1104 lock_type = PM_LCDOFF_STR;
1105 else if (state == S_LCDDIM)
1106 lock_type = PM_LCDDIM_STR;
1107 else if (state == S_NORMAL)
1108 lock_type = PM_LCDON_STR;
1111 /* power unlock signal */
1112 ret = gdbus_signal_emit(NULL,
1113 DEVICED_PATH_DISPLAY,
1114 DEVICED_INTERFACE_DISPLAY,
1116 g_variant_new("(sii)", lock_type, pid, (int)data->timeout));
1118 _E("Failed to send dbus signal PowerUnlock.");
1122 _SD("be requested UNLOCK info pname(%s) flag(%d)", pname, flags);
1123 set_unlock_time(pid, state);
1125 device_notify(DEVICE_NOTIFIER_DISPLAY_LOCK, (void *)&value);
1128 static int proc_condition(PMMsg *data)
1132 if (IS_COND_REQUEST_LOCK(data->cond))
1133 proc_condition_lock(data);
1135 if (IS_COND_REQUEST_UNLOCK(data->cond))
1136 proc_condition_unlock(data);
1138 if (!display_conf.timeout_enable)
1141 flags = GET_COND_FLAG(data->cond);
1143 /* guard time for suspend */
1144 if (get_pm_cur_state() == S_LCDOFF)
1145 reset_timeout(states[S_LCDOFF].timeout);
1147 if (flags & PM_FLAG_RESET_TIMER)
1148 reset_timeout(states[get_pm_cur_state()].timeout);
1151 if (!timeout_src_id)
1152 states[get_pm_cur_state()].trans(EVENT_TIMEOUT);
1157 void update_lcdoff_source(int source)
1162 case VCONFKEY_PM_LCDOFF_BY_TIMEOUT:
1163 _I("LCD OFF by timeout.");
1165 case VCONFKEY_PM_LCDOFF_BY_POWERKEY:
1166 _I("LCD OFF by powerkey.");
1169 _E("Invalid value(%d).", source);
1172 ret = vconf_set_int(VCONFKEY_PM_LCDOFF_SOURCE, source);
1174 _E("Failed to set vconf value for lcd off source: %d", vconf_get_ext_errno());
1177 void print_info(int fd)
1180 char buf[PATH_MAX + 255];
1183 char pname[PATH_MAX];
1191 snprintf(buf, sizeof(buf),
1192 "\n==========================================="
1193 "===========================\n");
1194 ret = write(fd, buf, strlen(buf));
1196 _E("Write() failed: %d", errno);
1197 snprintf(buf, sizeof(buf), "Timeout Info: Run[%dms] Dim[%dms] Off[%dms]\n",
1198 states[S_NORMAL].timeout,
1199 states[S_LCDDIM].timeout, states[S_LCDOFF].timeout);
1200 ret = write(fd, buf, strlen(buf));
1202 _E("Write() failed: %d", errno);
1204 snprintf(buf, sizeof(buf), "Tran. Locked : %s %s %s\n",
1205 (get_trans_condition() & MASK_NORMAL) ? states[S_NORMAL].name : "-",
1206 (get_trans_condition() & MASK_DIM) ? states[S_LCDDIM].name : "-",
1207 (get_trans_condition() & MASK_OFF) ? states[S_LCDOFF].name : "-");
1208 ret = write(fd, buf, strlen(buf));
1210 _E("Write() failed: %d", errno);
1212 snprintf(buf, sizeof(buf), "Current State: %s\n",
1213 states[get_pm_cur_state()].name);
1214 ret = write(fd, buf, strlen(buf));
1216 _E("Write() failed: %d", errno);
1218 snprintf(buf, sizeof(buf), "Current Lock Conditions: \n");
1219 ret = write(fd, buf, strlen(buf));
1221 _E("Write() failed: %d", errno);
1223 for (s_index = S_NORMAL; s_index < S_END; s_index++) {
1224 SYS_G_LIST_FOREACH(get_cond_head(s_index), elem, t) {
1225 get_pname((pid_t)t->pid, pname);
1226 ctime_r(&t->time, time_buf);
1227 time_buf[strlen(time_buf) - 1] = 0;
1228 snprintf(buf, sizeof(buf),
1229 " %d: [%s] locked by pid %d %s %s\n",
1230 i++, states[s_index].name, t->pid, pname, time_buf);
1231 ret = write(fd, buf, strlen(buf));
1233 _E("Write() failed: %d", errno);
1237 print_lock_info_list(fd);
1239 #ifdef ENABLE_PM_LOG
1240 pm_history_print(fd, 250);
1244 void save_display_log(const char *path)
1251 _D("internal state is saved!");
1254 ctime_r(&now_time, time_buf);
1255 time_buf[strlen(time_buf) - 1] = 0;
1257 fd = open(path, O_CREAT | O_TRUNC | O_WRONLY, 0644);
1259 snprintf(buf, sizeof(buf),
1260 "\npm_state_log now-time : %d(s) %s\n\n",
1261 (int)now_time, time_buf);
1262 ret = write(fd, buf, strlen(buf));
1264 _E("write() failed (%d)", errno);
1266 snprintf(buf, sizeof(buf), "pm_status_flag: %#x\n", get_pm_status_flag());
1267 ret = write(fd, buf, strlen(buf));
1269 _E("write() failed (%d)", errno);
1271 if (disp_plgn->get_lock_screen_state ) {
1272 snprintf(buf, sizeof(buf), "screen lock status : %d\n",
1273 disp_plgn->get_lock_screen_state());
1274 ret = write(fd, buf, strlen(buf));
1276 _E("write() failed (%d)", errno);
1282 fd = open("/dev/console", O_WRONLY);
1289 /* SIGHUP signal handler
1290 * For debug... print info to syslog
1292 static void sig_hup(int signo)
1294 _I("received sig hub %d", signo);
1299 int check_lcdoff_direct(void)
1301 int ret, lock, cradle;
1304 if (get_pm_old_state() != S_NORMAL)
1307 if (get_pm_cur_state() != S_LCDDIM)
1310 if (!display_conf.dimming)
1313 lock = __get_lock_screen_state();
1314 if (lock != VCONFKEY_IDLE_LOCK && hallic_open)
1317 hdmi_state = extcon_get_status(EXTCON_CABLE_HDMI);
1321 ret = vconf_get_int(VCONFKEY_SYSMAN_CRADLE_STATUS, &cradle);
1322 if (ret >= 0 && cradle == DOCK_SOUND)
1325 _E("Failed to get vconf value for cradle status: %d", vconf_get_ext_errno());
1327 _D("Goto LCDOFF direct: lock(%d) hdmi(%d) cradle(%d).", lock, hdmi_state, cradle);
1333 * default transition function
1336 * 3. call enter action function
1338 static int default_trans(int evt)
1340 struct state *st = &states[get_pm_cur_state()];
1343 next_state = (enum state_t)trans_table[get_pm_cur_state()][evt];
1345 /* check conditions */
1346 if (st->check && !st->check(get_pm_cur_state(), next_state)) {
1347 /* There is a condition. */
1348 _I("%s locked. Trans to %s failed.", states[get_pm_cur_state()].name,
1349 states[next_state].name);
1353 /* state transition */
1354 set_pm_old_state(get_pm_cur_state());
1355 set_pm_cur_state(next_state);
1356 st = &states[get_pm_cur_state()];
1360 if (get_pm_cur_state() == S_LCDOFF)
1361 update_lcdoff_source(VCONFKEY_PM_LCDOFF_BY_TIMEOUT);
1363 if ((get_pm_cur_state() == S_NORMAL) || (get_pm_cur_state() == S_LCDOFF))
1364 if (set_custom_lcdon_timeout(0) == true)
1365 update_display_time();
1367 if (check_lcdoff_direct() == true) {
1368 /* enter next state directly */
1369 states[get_pm_cur_state()].trans(EVENT_TIMEOUT);
1371 if ((get_pm_cur_state() == S_SLEEP)
1372 && (is_emulator() == true || timeout_sleep_support == false))
1375 st->action(st->timeout);
1382 static gboolean lcd_on_expired(void *data)
1384 int lock_state, ret;
1386 if (lock_timeout_id)
1387 lock_timeout_id = 0;
1389 /* check state of lock */
1390 ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
1391 if (ret > 0 && lock_state == VCONFKEY_IDLE_LOCK)
1392 return G_SOURCE_REMOVE;
1394 _E("Failed to get vconf value for idle lock state: %d", vconf_get_ext_errno());
1396 /* lock screen is not launched yet, but lcd is on */
1397 if (check_lcd_is_on() == false)
1398 lcd_on_procedure(LCD_NORMAL, NORMAL_MODE);
1400 return G_SOURCE_REMOVE;
1403 static inline void stop_lock_timer(void)
1405 if (lock_timeout_id) {
1406 g_source_remove(lock_timeout_id);
1407 lock_timeout_id = 0;
1411 static void check_lock_screen(void)
1413 int lock_state, ret;
1417 /* check state of lock */
1418 ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
1419 if (ret < 0 || lock_state == VCONFKEY_IDLE_LOCK)
1422 /* Use time to check lock is done. */
1423 lock_timeout_id = g_timeout_add(display_conf.lock_wait_time,
1424 lcd_on_expired, NULL);
1427 /* default enter action function */
1428 static int default_action(int timeout)
1430 int wakeup_count = -1, pm_cur_state;
1433 static time_t last_update_time = 0;
1434 static int last_timeout = 0;
1435 struct timeval now_tv;
1437 if (status != DEVICE_OPS_STATUS_START) {
1438 _E("Display is not started.");
1442 if (get_pm_cur_state() != S_SLEEP) {
1443 if ((get_pm_cur_state() == S_NORMAL) &&
1444 lcdon_tv.tv_sec != 0) {
1445 gettimeofday(&now_tv, NULL);
1446 timeout -= DIFF_TIMEVAL_MS(now_tv, lcdon_tv);
1447 lcdon_tv.tv_sec = 0;
1449 /* set timer with current state timeout */
1450 reset_timeout(timeout);
1452 if (get_pm_cur_state() == S_NORMAL) {
1453 time(&last_update_time);
1454 last_timeout = timeout;
1456 _I("Timout set: %s state %d ms",
1457 states[get_pm_cur_state()].name, timeout);
1461 if ((get_pm_cur_state() != get_pm_old_state()) && (get_pm_cur_state() != S_SLEEP)) {
1462 power_request_change_state_strict(DEVICED_POWER_STATE_SLEEP, DEVICED_POWER_STATE_NORMAL,
1463 power_get_wakeup_reason(), NULL);
1464 set_setting_pmstate(get_pm_cur_state());
1465 pm_cur_state = get_pm_cur_state();
1466 device_notify(DEVICE_NOTIFIER_LCD, (void *)&pm_cur_state);
1469 if ((get_pm_old_state() == S_NORMAL) && (get_pm_cur_state() != S_NORMAL)) {
1471 diff = difftime(now, last_update_time);
1472 _I("S_NORMAL is changed to %s (timeout=%d ms diff=%.0f s).",
1473 states[get_pm_cur_state()].name, last_timeout, diff);
1476 switch (get_pm_cur_state()) {
1479 * normal state : backlight on and restore
1480 * the previous brightness
1482 if ((get_pm_old_state() == S_LCDOFF) || (get_pm_old_state() == S_SLEEP))
1483 check_lock_screen();
1484 else if (get_pm_old_state() == S_LCDDIM)
1485 backlight_ops->update();
1487 if (check_lcd_is_on() == false)
1488 lcd_on_procedure(LCD_NORMAL, NORMAL_MODE);
1492 if ((get_pm_old_state() == S_NORMAL) &&
1493 backlight_ops->get_custom_status())
1494 backlight_ops->save_custom_brightness();
1495 /* lcd dim state : dim the brightness */
1496 backlight_ops->dim();
1498 if ((get_pm_old_state() == S_LCDOFF) || (get_pm_old_state() == S_SLEEP))
1499 lcd_on_procedure(LCD_DIM, NORMAL_MODE);
1503 if ((get_pm_old_state() != S_SLEEP) && (get_pm_old_state() != S_LCDOFF)) {
1505 /* lcd off state : turn off the backlight */
1506 if (backlight_ops->get_lcd_power() == DPMS_ON)
1507 lcd_off_procedure(LCD_OFF_BY_TIMEOUT);
1510 if (backlight_ops->get_lcd_power() == DPMS_ON
1511 || lcd_paneloff_mode)
1512 lcd_off_procedure(LCD_OFF_BY_TIMEOUT);
1516 if ((get_pm_old_state() != S_SLEEP) && (get_pm_old_state() != S_LCDOFF))
1519 if (backlight_ops->get_lcd_power() == DPMS_ON)
1520 lcd_off_procedure(LCD_OFF_BY_TIMEOUT);
1522 if (!pm_get_power_lock_support()) {
1523 /* sleep state : set system mode to SUSPEND */
1524 if (get_wakeup_count(&wakeup_count) < 0)
1525 _E("Wakeup count read error.");
1527 if (wakeup_count < 0) {
1528 _I("Wakup Event. Can not enter suspend mode.");
1532 if (set_wakeup_count(wakeup_count) < 0) {
1533 _E("Wakeup count write error.");
1543 #ifdef ENABLE_PM_LOG
1544 pm_history_save(PM_LOG_SLEEP, get_pm_cur_state());
1546 power_request_change_state(DEVICED_POWER_STATE_SLEEP, HAL_DEVICE_POWER_TRANSITION_REASON_DISPLAY_OFF_TIMEOUT);
1550 if (!pm_get_power_lock_support()) {
1552 states[get_pm_cur_state()].trans(EVENT_DEVICE);
1558 * default check function
1560 * 0 : can't transit, others : transitable
1562 static int default_check(int curr, int next)
1566 makeup_trans_condition();
1568 trans_cond = get_trans_condition() & MASK_BIT;
1570 if (next == S_NORMAL) /* S_NORMAL is exceptional */
1575 trans_cond = trans_cond & MASK_NORMAL;
1578 trans_cond = trans_cond & MASK_DIM;
1581 trans_cond = trans_cond & MASK_OFF;
1588 if (trans_cond != 0) {
1593 return 1; /* transitable */
1596 static void default_saving_mode(int onoff)
1599 set_pm_status_flag(PWRSV_FLAG);
1601 clear_pm_status_flag(PWRSV_FLAG);
1603 if (get_pm_cur_state() == S_NORMAL)
1604 backlight_ops->update();
1607 int poll_callback(int condition, PMMsg *data)
1609 static time_t last_t;
1612 if (status != DEVICE_OPS_STATUS_START) {
1613 _E("Display logic is not started.");
1617 if (condition == INPUT_POLL_EVENT) {
1618 if ((get_pm_cur_state() == S_LCDOFF) || (get_pm_cur_state() == S_SLEEP))
1619 _I("Input event signal at Display Off");
1621 if ((last_t != now) ||
1622 (get_pm_cur_state() == S_LCDOFF) ||
1623 (get_pm_cur_state() == S_SLEEP)) {
1624 states[get_pm_cur_state()].trans(EVENT_INPUT);
1629 if (condition == PM_CONTROL_EVENT) {
1630 proc_condition(data);
1632 if (IS_COND_REQUEST_CHANGE(data->cond))
1633 proc_change_state(data->cond, data->pid);
1639 static int update_setting(int key_idx, int val)
1644 case SETTING_TO_NORMAL:
1645 update_display_time();
1646 states[get_pm_cur_state()].trans(EVENT_INPUT);
1648 case SETTING_HALLIC_OPEN:
1650 update_display_time();
1651 if ((get_pm_cur_state() == S_NORMAL) || (get_pm_cur_state() == S_LCDDIM))
1652 states[get_pm_cur_state()].trans(EVENT_INPUT);
1653 else if ((get_pm_cur_state() == S_SLEEP) && hallic_open)
1654 proc_change_state(S_LCDOFF, INTERNAL_LOCK_HALLIC);
1656 case SETTING_LOW_BATT:
1657 if (low_battery_state(val)) {
1658 if (!(get_pm_status_flag() & CHRGR_FLAG))
1659 power_saving_func(true);
1660 set_pm_status_flag(LOWBT_FLAG);
1662 if (get_pm_status_flag() & PWRSV_FLAG)
1663 power_saving_func(false);
1664 clear_pm_status_flag(LOWBT_FLAG);
1665 clear_pm_status_flag(BRTCH_FLAG);
1666 ret = vconf_set_bool(VCONFKEY_PM_BRIGHTNESS_CHANGED_IN_LPM, false);
1668 _E("Failed to set vconf value for brightness changed in lpm: %d", vconf_get_ext_errno());
1671 case SETTING_CHARGING:
1673 if (get_pm_status_flag() & LOWBT_FLAG) {
1674 power_saving_func(false);
1675 clear_pm_status_flag(LOWBT_FLAG);
1677 set_pm_status_flag(CHRGR_FLAG);
1680 ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW,
1683 bat_state = VCONFKEY_SYSMAN_BAT_NORMAL;
1684 _E("Failed to get vconf value for battery status low: %d", vconf_get_ext_errno());
1686 if (low_battery_state(bat_state)) {
1687 power_saving_func(true);
1688 set_pm_status_flag(LOWBT_FLAG);
1690 clear_pm_status_flag(CHRGR_FLAG);
1693 case SETTING_BRT_LEVEL:
1694 if (get_pm_status_flag() & PWRSV_FLAG) {
1695 set_pm_status_flag(BRTCH_FLAG);
1696 ret = vconf_set_bool(VCONFKEY_PM_BRIGHTNESS_CHANGED_IN_LPM, true);
1698 _E("Failed to set vconf value for brightness changed in lpm: %d", vconf_get_ext_errno());
1699 _I("Brightness changed in low battery,"
1700 "escape dim state.");
1702 backlight_ops->set_default_brt(val);
1704 case SETTING_LOCK_SCREEN:
1705 set_lock_screen_state(val);
1706 if (val == VCONFKEY_IDLE_UNLOCK) {
1707 if (CHECK_OPS(keyfilter_ops, backlight_enable))
1708 keyfilter_ops->backlight_enable(false);
1711 /* LCD on if lock screen show before waiting time */
1712 if ((get_pm_cur_state() == S_NORMAL) &&
1713 val == VCONFKEY_IDLE_LOCK &&
1714 backlight_ops->get_lcd_power() != DPMS_ON &&
1715 is_lcdon_blocked() == LCDON_BLOCK_NONE)
1716 lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
1718 update_display_time();
1719 if (get_pm_cur_state() == S_NORMAL)
1720 states[get_pm_cur_state()].trans(EVENT_INPUT);
1722 case SETTING_LOCK_SCREEN_BG:
1723 set_lock_screen_bg_state(val);
1724 update_display_time();
1725 if (get_pm_cur_state() == S_NORMAL)
1726 states[get_pm_cur_state()].trans(EVENT_INPUT);
1728 case SETTING_POWER_CUSTOM_BRIGHTNESS:
1729 if (val == VCONFKEY_PM_CUSTOM_BRIGHTNESS_ON)
1730 backlight_ops->set_custom_status(true);
1732 backlight_ops->set_custom_status(false);
1741 static void check_seed_status(void)
1749 /* Charging check */
1750 if (fp_get_charging_status && (fp_get_charging_status(&tmp) == 0) && (tmp > 0))
1751 set_pm_status_flag(CHRGR_FLAG);
1753 ret = get_setting_brightness(&tmp);
1754 if (ret != 0 || (tmp < PM_MIN_BRIGHTNESS || tmp > PM_MAX_BRIGHTNESS)) {
1755 _I("Failed to read vconf value for brightness.");
1756 brt = display_conf.pm_default_brightness;
1757 if (tmp < PM_MIN_BRIGHTNESS || tmp > PM_MAX_BRIGHTNESS) {
1758 ret = vconf_set_int(VCONFKEY_SETAPPL_LCD_BRIGHTNESS, brt);
1760 _E("Failed to set vconf value for lcd brightness: %d", vconf_get_ext_errno());
1764 _I("Set brightness(%d) from setting app.", tmp);
1765 backlight_ops->set_default_brt(tmp);
1766 backlight_ops->set_brightness(tmp);
1768 ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, &bat_state);
1770 bat_state = VCONFKEY_SYSMAN_BAT_NORMAL;
1771 _E("Failed to get vconf value for battery status low: %d", vconf_get_ext_errno());
1773 if (low_battery_state(bat_state)) {
1774 if (!(get_pm_status_flag() & CHRGR_FLAG)) {
1775 power_saving_func(true);
1776 set_pm_status_flag(LOWBT_FLAG);
1780 /* lock screen check */
1781 ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
1784 _E("Failed to get vconf value for idle lock state: %d", vconf_get_ext_errno());
1786 set_lock_screen_state(lock_state);
1787 if (lock_state == VCONFKEY_IDLE_LOCK) {
1788 states[S_NORMAL].timeout = lock_screen_timeout;
1789 _I("LCD NORMAL timeout(%d ms) is set"
1790 " for lock screen.", lock_screen_timeout);
1796 static void init_lcd_operation(void)
1798 const struct device_ops *ops = NULL;
1800 ops = find_device("display");
1801 if (!check_default(ops))
1802 SYS_G_LIST_APPEND(lcdon_ops, ops);
1804 ops = find_device("touchkey");
1805 if (!check_default(ops))
1806 SYS_G_LIST_APPEND(lcdon_ops, ops);
1808 ops = find_device("touchscreen");
1809 if (!check_default(ops))
1810 SYS_G_LIST_APPEND(lcdon_ops, ops);
1813 static void exit_lcd_operation(void)
1816 GList *l_next = NULL;
1817 const struct device_ops *ops = NULL;
1819 SYS_G_LIST_FOREACH_SAFE(lcdon_ops, l, l_next, ops)
1820 SYS_G_LIST_REMOVE_LIST(lcdon_ops, l);
1832 static const char *errMSG[INIT_END] = {
1833 [INIT_SETTING] = "setting init error",
1834 [INIT_INTERFACE] = "lowlevel interface(sysfs or others) init error",
1835 [INIT_POLL] = "input devices poll init error",
1836 [INIT_FIFO] = "FIFO poll init error",
1837 [INIT_DBUS] = "d-bus init error",
1840 int set_lcd_timeout(int on, int dim, int holdkey_block, const char *name)
1842 if (on == 0 && dim == 0) {
1843 _I("LCD timeout changed: default setting");
1844 custom_normal_timeout = custom_dim_timeout = 0;
1845 } else if (on < 0 || dim < 0) {
1846 _E("Failed to set value(on=%d dim=%d).", on, dim);
1849 _I("LCD timeout changed: on=%ds dim=%ds", on, dim);
1850 custom_normal_timeout = SEC_TO_MSEC(on);
1851 custom_dim_timeout = SEC_TO_MSEC(dim);
1853 /* Apply new backlight time */
1854 update_display_time();
1855 if (get_pm_cur_state() == S_NORMAL)
1856 states[get_pm_cur_state()].trans(EVENT_INPUT);
1858 if (holdkey_block) {
1859 custom_holdkey_block = true;
1860 _I("Hold key disabled.");
1862 custom_holdkey_block = false;
1863 _I("Hold key enabled.");
1866 if (custom_change_name) {
1867 free(custom_change_name);
1868 custom_change_name = 0;
1871 if (custom_normal_timeout == 0 &&
1872 custom_dim_timeout == 0 &&
1876 custom_change_name = strndup(name, strlen(name));
1877 if (!custom_change_name) {
1878 _E("Failed to malloc.");
1879 custom_normal_timeout = custom_dim_timeout = 0;
1880 custom_holdkey_block = false;
1887 void reset_lcd_timeout(GDBusConnection *conn,
1888 const gchar *sender,
1889 const gchar *unique_name,
1895 if (!custom_change_name)
1898 if (strcmp(sender, custom_change_name))
1901 _I("reset lcd timeout: Set default timeout. sender=%s", sender);
1903 free(custom_change_name);
1904 custom_change_name = 0;
1905 custom_normal_timeout = custom_dim_timeout = 0;
1906 custom_holdkey_block = false;
1908 update_display_time();
1909 if (get_pm_cur_state() == S_NORMAL)
1910 states[get_pm_cur_state()].trans(EVENT_INPUT);
1913 static int delayed_init_done(void *data)
1915 static bool done = false;
1924 _I("Booting done, release booting lock.");
1925 if (disp_plgn->pm_unlock_internal) {
1926 disp_plgn->pm_unlock_internal(INTERNAL_LOCK_BOOTING, LCD_NORMAL, PM_SLEEP_MARGIN);
1927 disp_plgn->pm_unlock_internal(INTERNAL_LOCK_BOOTING, LCD_OFF, PM_SLEEP_MARGIN);
1933 static int battery_health_changed(void *data)
1935 int health = DATA_VALUE_INT(data);
1937 _I("battery health change %d", health);
1939 if (health == HEALTH_GOOD) {
1940 clear_pm_status_flag(BATTERY_FLAG);
1941 clear_pm_status_flag(DIMSTAY_FLAG);
1942 } else if (health == HEALTH_LOW || health == HEALTH_HIGH || health == HEALTH_OVP) {
1943 set_pm_status_flag(BATTERY_FLAG);
1944 set_pm_status_flag(DIMSTAY_FLAG);
1947 if (backlight_ops->get_lcd_power() == DPMS_ON)
1948 backlight_ops->update();
1953 static gboolean delayed_init_done_dpms(gpointer data)
1958 return G_SOURCE_CONTINUE;
1960 switch (get_pm_cur_state()) {
1963 lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
1964 if (display_conf.timeout_enable) {
1965 timeout = states[S_NORMAL].timeout;
1966 /* check minimun lcd on time */
1967 if (timeout < SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT))
1968 timeout = SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT);
1969 reset_timeout(timeout);
1973 lcd_off_procedure(LCD_OFF_BY_EVENT);
1974 timeout = display_conf.lcdoff_timeout;
1975 reset_timeout(timeout);
1981 return G_SOURCE_REMOVE;
1984 static void add_timer_for_init_dpms(void)
1986 guint id = g_timeout_add(500/* milliseconds */, delayed_init_done_dpms, NULL);
1988 _E("Failed to add init_dpms timeout.");
1992 * Power manager Main
1995 static int display_probe(void *data)
2000 * load display service
2001 * if there is no display shared library,
2002 * deviced does not provide any method and function of display.
2004 ret = display_service_load();
2008 /* display_plugin instance initialization */
2010 disp_plgn->device_flags_to_string = __device_flags_to_string;
2012 if (battery_plgn->handle) {
2013 fp_get_charging_status = dlsym(battery_plgn->handle, "get_charging_status");
2014 if (!fp_get_charging_status)
2015 _E("Failed to obtain address of get_charging_status");
2017 _I("There is no battery module.");
2022 static int input_init_handler(void)
2024 if (!display_conf.input_support)
2025 remove_device_by_devname("input");
2030 static int power_resume_from_echomem_callback(void *data)
2032 system_wakeup_flag = true;
2033 if (check_wakeup_src() == EVENT_DEVICE)
2034 /* system waked up by devices */
2035 states[get_pm_cur_state()].trans(EVENT_DEVICE);
2037 /* system waked up by user input */
2038 states[get_pm_cur_state()].trans(EVENT_INPUT);
2043 static int poweroff_triggered_callback(void *udata)
2045 int val = (int)(intptr_t) udata;
2048 case VCONFKEY_SYSMAN_POWER_OFF_NONE:
2049 clear_pm_status_flag(PWROFF_FLAG);
2051 case VCONFKEY_SYSMAN_POWER_OFF_DIRECT:
2052 case VCONFKEY_SYSMAN_POWER_OFF_RESTART:
2053 set_pm_status_flag(PWROFF_FLAG);
2060 static void esd_action(void)
2062 const struct device_ops *touchscreen_ops = NULL;
2066 touchscreen_ops = find_device("touchscreen");
2068 if (!check_default(touchscreen_ops))
2069 touchscreen_ops->stop(NORMAL_MODE);
2070 backlight_ops->off(NORMAL_MODE);
2071 backlight_ops->on(NORMAL_MODE);
2072 if (!check_default(touchscreen_ops))
2073 touchscreen_ops->start(NORMAL_MODE);
2076 static void lcd_uevent_changed(struct udev_device *dev)
2078 const char *devpath;
2081 devpath = udev_device_get_devpath(dev);
2085 if (!fnmatch(LCD_ESD_PATH, devpath, 0)) {
2086 action = udev_device_get_action(dev);
2087 if (!strcmp(action, UDEV_CHANGE))
2092 static const struct uevent_handler lcd_uevent_ops = {
2093 .subsystem = LCD_EVENT_SUBSYSTEM,
2094 .uevent_func = lcd_uevent_changed,
2098 static void display_init(void *data)
2101 unsigned int flags = (WITHOUT_STARTNOTI | FLAG_X_DPMS);
2104 _I("Start power manager.");
2106 signal(SIGHUP, sig_hup);
2108 power_saving_func = default_saving_mode;
2110 /* load configutation */
2111 ret = config_parse(DISPLAY_CONF_FILE, display_load_config, &display_conf);
2113 _W("Failed to load '%s', use default value: %d",
2114 DISPLAY_CONF_FILE, ret);
2116 register_kernel_uevent_control(&lcd_uevent_ops);
2118 register_notifier(DEVICE_NOTIFIER_DELAYED_INIT, delayed_init_done);
2119 register_notifier(DEVICE_NOTIFIER_APPLICATION_BACKGROUND, display_app_background);
2120 register_notifier(DEVICE_NOTIFIER_APPLICATION_FOREGROUND, display_app_foreground);
2121 register_notifier(DEVICE_NOTIFIER_APPLICATION_TERMINATED, display_app_terminated);
2122 register_notifier(DEVICE_NOTIFIER_BATTERY_HEALTH, battery_health_changed);
2123 register_notifier(DEVICE_NOTIFIER_DISPLAY_BRIGHTNESS, display_brightness_changed);
2124 register_notifier(DEVICE_NOTIFIER_LCD_AUTOBRT_SENSING, display_auto_brightness_sensing);
2125 register_notifier(DEVICE_NOTIFIER_POWER_RESUME_FROM_ECHO_MEM, power_resume_from_echomem_callback);
2126 register_notifier(DEVICE_NOTIFIER_POWEROFF_TRIGGERED, poweroff_triggered_callback);
2128 init_save_userlock();
2130 for (i = INIT_SETTING; i < INIT_END; i++) {
2133 ret = init_setting(update_setting);
2135 case INIT_INTERFACE:
2136 if (display_conf.timeout_enable)
2137 get_lcd_timeout_from_settings();
2138 ret = init_sysfs(flags);
2142 ret = input_init_handler();
2144 pm_lock_detector_init();
2148 ret = init_pm_dbus();
2152 _E("Failed to init: %s", errMSG[i]);
2157 if (i == INIT_END) {
2158 display_ops_init(NULL);
2159 #ifdef ENABLE_PM_LOG
2162 init_lcd_operation();
2163 check_seed_status();
2165 /* In smd test, TSP should be turned off if display panel is not existed. */
2166 if (backlight_ops->get_lcd_power() == -ENOENT) {
2167 _I("Display panel is not existed.");
2168 lcd_direct_control(DPMS_OFF, NORMAL_MODE);
2169 exit_lcd_operation();
2172 /* wm_ready needs to be checked
2173 * since display manager can be launched later than deviced.
2174 * In the case, display cannot be turned on at the first booting */
2175 // wm_ready = check_wm_ready();
2177 if (is_lcdon_blocked() != LCDON_BLOCK_NONE)
2178 lcd_off_procedure(LCD_OFF_BY_EVENT);
2180 lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
2182 add_timer_for_init_dpms();
2185 if (display_conf.lcd_always_on) {
2186 _I("LCD always on.");
2187 trans_table[S_NORMAL][EVENT_TIMEOUT] = S_NORMAL;
2190 if (flags & WITHOUT_STARTNOTI) { /* start without noti */
2191 _I("Start Power managing without noti");
2192 power_request_change_state_strict(DEVICED_POWER_STATE_SLEEP, DEVICED_POWER_STATE_NORMAL,
2193 HAL_DEVICE_POWER_TRANSITION_REASON_UNKNOWN, NULL);
2195 * Lock lcd off until booting is done.
2196 * deviced guarantees all booting script is executing.
2197 * Last script of booting unlocks this suspend blocking state.
2199 if (disp_plgn->pm_lock_internal)
2200 disp_plgn->pm_lock_internal(INTERNAL_LOCK_BOOTING, LCD_OFF,
2201 STAY_CUR_STATE, DELAYED_INIT_WATING_TIME);
2203 /* Initial display state right after the booting done */
2204 if (is_lcdon_blocked())
2205 set_pm_cur_state(S_LCDOFF);
2207 set_pm_cur_state(S_NORMAL);
2208 ret = vconf_set_int(VCONFKEY_PM_STATE, get_pm_cur_state());
2210 _E("Failed to set vconf value for pm cur state: %d", vconf_get_ext_errno());
2212 status = DEVICE_OPS_STATUS_START;
2213 if (display_conf.timeout_enable) {
2214 timeout = states[S_NORMAL].timeout;
2215 /* check minimun lcd on time */
2216 if (timeout < SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT))
2217 timeout = SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT);
2219 if (disp_plgn->pm_lock_internal)
2220 disp_plgn->pm_lock_internal(INTERNAL_LOCK_BOOTING, LCD_NORMAL,
2221 STAY_CUR_STATE, timeout);
2226 if (display_conf.input_support)
2227 if (CHECK_OPS(keyfilter_ops, init))
2228 keyfilter_ops->init();
2230 set_display_init_direction(display_conf.display_init_direction);
2234 static void display_exit(void *data)
2238 status = DEVICE_OPS_STATUS_STOP;
2240 /* Set current state to S_NORMAL */
2241 set_pm_cur_state(S_NORMAL);
2242 set_setting_pmstate(get_pm_cur_state());
2243 /* timeout is not needed */
2244 reset_timeout(TIMEOUT_NONE);
2246 if (CHECK_OPS(keyfilter_ops, exit))
2247 keyfilter_ops->exit();
2249 unregister_kernel_uevent_control(&lcd_uevent_ops);
2251 display_ops_exit(NULL);
2253 for (i = i - 1; i >= INIT_SETTING; i--) {
2258 case INIT_INTERFACE:
2262 unregister_notifier(DEVICE_NOTIFIER_DELAYED_INIT, delayed_init_done);
2263 unregister_notifier(DEVICE_NOTIFIER_APPLICATION_BACKGROUND, display_app_background);
2264 unregister_notifier(DEVICE_NOTIFIER_APPLICATION_FOREGROUND, display_app_foreground);
2265 unregister_notifier(DEVICE_NOTIFIER_APPLICATION_TERMINATED, display_app_terminated);
2266 unregister_notifier(DEVICE_NOTIFIER_BATTERY_HEALTH, battery_health_changed);
2267 unregister_notifier(DEVICE_NOTIFIER_DISPLAY_BRIGHTNESS, display_brightness_changed);
2268 unregister_notifier(DEVICE_NOTIFIER_POWER_RESUME_FROM_ECHO_MEM, power_resume_from_echomem_callback);
2274 exit_lcd_operation();
2275 free_lock_info_list();
2277 /* free display service */
2278 display_service_free();
2280 _I("Stop power manager.");
2283 static int display_start(enum device_flags flags)
2285 const struct display_ops *enhance_ops = NULL;
2289 if (flags & NORMAL_MODE) {
2290 if (flags & LCD_PANEL_OFF_MODE)
2292 backlight_ops->standby(true);
2295 backlight_ops->on(flags);
2296 FIND_DISPLAY(enhance_ops, "enhance");
2297 if (enhance_ops && enhance_ops->func)
2298 enhance_ops->func(RESTORE_ENHANCE_OUTDOOR, &on);
2302 /* CORE LOGIC MODE */
2303 if (!(flags & CORE_LOGIC_MODE))
2306 if (status == DEVICE_OPS_STATUS_START)
2309 if (display_probe(NULL) < 0)
2317 static int display_stop(enum device_flags flags)
2320 if (flags & NORMAL_MODE || flags & FORCE_OFF_MODE) {
2321 backlight_ops->off(flags);
2325 /* CORE LOGIC MODE */
2326 if (!(flags & CORE_LOGIC_MODE))
2329 if (status == DEVICE_OPS_STATUS_STOP)
2337 static int display_status(void)
2342 static const struct device_ops display_device_ops = {
2343 .priority = DEVICE_PRIORITY_HIGH,
2344 DECLARE_NAME_LEN("display"),
2345 .probe = display_probe,
2346 .init = display_init,
2347 .exit = display_exit,
2348 .start = display_start,
2349 .stop = display_stop,
2350 .status = display_status,
2353 DEVICE_OPS_REGISTER(&display_device_ops)
2355 static void __CONSTRUCTOR__ initialize(void)
2357 disp_plgn = get_var_display_plugin();
2359 _E("Failed to get display plugin variable.");
2361 backlight_ops = get_var_backlight_ops();
2363 _E("Failed to get backlight operator variable.");
2365 battery_plgn = get_var_battery_plugin();
2367 _E("Failed to get battery plugin variable.");