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,
206 .display_dpms_type = DISPLAY_DPMS_TYPE_WINDOW_MANAGER,
209 struct display_function_info display_info = {
210 .update_auto_brightness = NULL,
211 .set_autobrightness_min = NULL,
212 .reset_autobrightness_min = NULL,
213 .face_detection = NULL,
216 inline const struct display_config* get_var_display_config()
218 return &display_conf;
221 inline struct state* state_st(enum state_t state)
223 return &states[state];
226 guint get_transition_timer(void)
228 return timeout_src_id;
231 void change_state_action(enum state_t state, int (*func)(int timeout))
233 _I("[%s] 'action' is changed.", states[state].name);
234 states[state].action = func;
237 void change_state_trans(enum state_t state, int (*func)(int evt))
239 _I("[%s] 'trans' is changed.", states[state].name);
240 states[state].trans = func;
243 void change_state_check(enum state_t state, int (*func)(int curr, int next))
245 _I("[%s] 'check' is changed.", states[state].name);
246 states[state].check = func;
249 void change_state_name(enum state_t state, const char *name)
251 _I("[%s] 'name' is changed.", states[state].name);
252 states[state].name = name;
255 void change_trans_table(enum state_t state, enum state_t next)
257 _I("[%s] 'timeout trans table' is changed.", states[state].name);
258 trans_table[state][EVENT_TIMEOUT] = next;
261 void change_proc_change_state(int (*func)(unsigned int cond, pid_t pid))
263 _I("'proc change state' is changed.");
264 proc_change_state = func;
267 static int display_brightness_changed(void *data)
271 brt = DATA_VALUE_INT(data);
273 ret = gdbus_signal_emit(NULL,
274 DEVICED_PATH_DISPLAY,
275 DEVICED_INTERFACE_DISPLAY,
277 g_variant_new("(i)", brt));
279 _E("Failed to send dbus signal Brightness.");
284 static int display_auto_brightness_sensing(void *data)
289 g_source_remove(transit_timer);
295 static const char* __device_flags_to_string(enum device_flags flags)
298 if (flags & (LCD_ON_BY_GESTURE | LCD_OFF_BY_GESTURE))
300 else if (flags & (LCD_ON_BY_POWER_KEY | LCD_OFF_BY_POWER_KEY))
301 return POWER_KEY_STR;
302 else if (flags & (LCD_ON_BY_EVENT | LCD_OFF_BY_EVENT))
304 else if (flags & LCD_ON_BY_TOUCH)
306 else if (flags & LCD_OFF_BY_TIMEOUT)
308 else if (flags & LCD_OFF_BY_PROXIMITY)
310 else if (flags & LCD_OFF_BY_PALM)
316 static unsigned long get_lcd_on_flags(void)
318 unsigned long flags = NORMAL_MODE;
320 if (lcd_paneloff_mode)
321 flags |= LCD_PANEL_OFF_MODE;
323 if (ambient_get_condition() == true) {
324 flags |= AMBIENT_MODE;
325 flags |= LCD_PHASED_TRANSIT_MODE;
331 bool touch_event_blocked(void)
333 return touch_blocked;
336 static gboolean late_transit_on(void *data)
339 return G_SOURCE_REMOVE;
341 g_source_remove(transit_timer);
344 backlight_ops->transit_state(DPMS_ON);
345 return G_SOURCE_REMOVE;
348 void lcd_on_procedure(int state, enum device_flags flag)
351 const struct device_ops *ops = NULL;
352 unsigned long flags = get_lcd_on_flags();
353 enum hal_device_power_transition_reason reason;
357 * Display on procedure
358 * step 1. change power state to normal
360 * step 3. broadcast lcd on signal with cause
361 * step 4. set brightness
362 * step 5. set pmstate of vconf
363 * step 6. display on operate
365 * - b. TSP(touch screen) and touchkey enable
366 * step 7. broadcast lcd on complete signal
367 * step 8. key backlight enable
370 if (flags & LCD_ON_BY_POWER_KEY)
371 reason = HAL_DEVICE_POWER_TRANSITION_REASON_POWER_KEY;
372 else if (flags & LCD_ON_BY_TOUCH)
373 reason = HAL_DEVICE_POWER_TRANSITION_REASON_TOUCH_SCREEN;
375 reason = HAL_DEVICE_POWER_TRANSITION_REASON_UNKNOWN;
377 power_request_change_state_strict(DEVICED_POWER_STATE_SLEEP, DEVICED_POWER_STATE_NORMAL, reason, NULL);
380 _I("[lcdstep] 0x%lx", flags);
382 if (flags & AMBIENT_MODE) {
383 if (ambient_get_state() == false && backlight_ops->get_lcd_power() == DPMS_ON)
385 ambient_set_state(false);
388 /* send LCDOn dbus signal */
389 if (!lcdon_broadcast)
390 broadcast_lcd_on(SIGNAL_PRE, flags);
392 if (!(flags & LCD_PHASED_TRANSIT_MODE)) {
393 /* Update brightness level */
394 if (state == LCD_DIM)
395 backlight_ops->dim();
396 else if (state == LCD_NORMAL)
397 backlight_ops->update();
400 if (state == LCD_NORMAL)
401 set_setting_pmstate(S_NORMAL);
402 else if (state == LCD_DIM)
403 set_setting_pmstate(S_LCDDIM);
405 SYS_G_LIST_FOREACH(lcdon_ops, l, ops)
408 if (!lcdon_broadcast) {
409 broadcast_lcd_on(SIGNAL_POST, flags);
410 if (flags & LCD_PHASED_TRANSIT_MODE)
411 transit_timer = g_timeout_add_seconds(LATE_LCD_TRANSIT,
412 late_transit_on, NULL);
413 lcdon_broadcast = true;
416 if (CHECK_OPS(keyfilter_ops, backlight_enable))
417 keyfilter_ops->backlight_enable(true);
419 touch_blocked = false;
422 static unsigned long get_lcd_off_flags(void)
424 unsigned long flags = NORMAL_MODE;
426 if (ambient_get_condition() == true) {
427 flags |= AMBIENT_MODE;
428 flags |= LCD_PHASED_TRANSIT_MODE;
431 if (stay_touchscreen_off)
432 flags |= TOUCH_SCREEN_OFF_MODE;
437 inline void lcd_off_procedure(enum device_flags flag)
440 const struct device_ops *ops = NULL;
441 unsigned long flags = get_lcd_off_flags();
445 * Display off procedure
446 * step 0. enhance mode off using nofity (e.g mdnie, HBM, LBM)
447 * step 1. broadcast lcd off signal with cause
448 * step 2. set pmstate of vconf
449 * step 3. display off operate
451 * - b. TSP(touch screen) and touchkey disable
452 * step 4. broadcast lcd off complete siganl
453 * step 5. enter doze mode if it is enabled
455 _I("[lcdstep] 0x%lx", flags);
459 device_notify(DEVICE_NOTIFIER_LCD_OFF, NULL);
461 if (lcdon_broadcast) {
462 broadcast_lcd_off(SIGNAL_PRE, flags);
463 lcdon_broadcast = false;
468 touch_blocked = true;
470 set_setting_pmstate(S_LCDOFF);
472 if (CHECK_OPS(keyfilter_ops, backlight_enable))
473 keyfilter_ops->backlight_enable(false);
476 g_source_remove(transit_timer);
480 if (flags & LCD_PHASED_TRANSIT_MODE)
481 backlight_ops->transit_state(DPMS_OFF);
483 SYS_G_LIST_FOREACH(lcdon_ops, l, ops)
486 if (flags & AMBIENT_MODE) {
487 broadcast_lcd_off_late(flags);
489 broadcast_lcd_off(SIGNAL_POST, flags);
490 device_notify(DEVICE_NOTIFIER_LCD_OFF_COMPLETE, NULL);
496 void set_stay_touchscreen_off(int val)
498 _I("Stay touch screen off: %d", val);
499 stay_touchscreen_off = val;
501 if (disp_plgn->pm_change_internal)
502 disp_plgn->pm_change_internal(INTERNAL_LOCK_PM, LCD_NORMAL);
505 void set_lcd_paneloff_mode(int val)
507 _I("Lcd paneloff mode: %d", val);
508 lcd_paneloff_mode = val;
510 if (disp_plgn->pm_change_internal)
511 disp_plgn->pm_change_internal(INTERNAL_LOCK_PM, LCD_NORMAL);
514 int low_battery_state(int val)
517 case VCONFKEY_SYSMAN_BAT_POWER_OFF:
518 case VCONFKEY_SYSMAN_BAT_CRITICAL_LOW:
519 case VCONFKEY_SYSMAN_BAT_REAL_POWER_OFF:
525 int get_hallic_open(void)
530 void get_pname(pid_t pid, char *pname)
535 if (pid >= INTERNAL_LOCK_BASE)
536 snprintf(buf, PATH_MAX, "/proc/%d/cmdline", getpid());
538 snprintf(buf, PATH_MAX, "/proc/%d/cmdline", pid);
540 cmdline = open(buf, O_RDONLY);
543 _E("Process(%d) does not exist now(may be dead without unlock).", pid);
547 r = read(cmdline, pname, PATH_MAX);
548 if ((r >= 0) && (r < PATH_MAX))
556 static void del_state_cond(void *data, enum state_t state)
558 PmLockNode *tmp = NULL;
564 /* A passed data is a pid_t type data, not a 64bit data. */
565 pid = (pid_t)((intptr_t)data);
566 _I("delete prohibit %s condition by timeout (%d)", states[state].name, pid);
568 if (pid == INTERNAL_LOCK_AMBIENT)
569 ambient_check_invalid_state(pid);
571 tmp = find_node(state, pid);
572 del_node(state, tmp);
573 set_unlock_time(pid, state);
575 /* Change state only when the two conditions below are satisfied.
576 * 1. There should be no running state-transition timer
577 * 2. Released lock is one of the pm_cur_state's lock
578 * This emulates already expired transition timer */
579 if (!timeout_src_id && get_pm_cur_state() == state)
580 states[get_pm_cur_state()].trans(EVENT_TIMEOUT);
582 if (state == S_LCDOFF)
583 set_process_active(false, pid);
586 static gboolean del_normal_cond(void *data)
588 del_state_cond(data, S_NORMAL);
589 return G_SOURCE_REMOVE;
592 static gboolean del_dim_cond(void *data)
594 del_state_cond(data, S_LCDDIM);
595 return G_SOURCE_REMOVE;
598 static gboolean del_off_cond(void *data)
600 del_state_cond(data, S_LCDOFF);
601 return G_SOURCE_REMOVE;
604 /* timeout handler */
605 gboolean timeout_handler(void *data)
607 _I("Time out state %s", states[get_pm_cur_state()].name);
609 if (timeout_src_id) {
610 g_source_remove(timeout_src_id);
614 states[get_pm_cur_state()].trans(EVENT_TIMEOUT);
615 return G_SOURCE_REMOVE;
618 void reset_timeout(int timeout)
620 if (!display_conf.timeout_enable)
623 if ((get_pm_cur_state() == S_LCDOFF)
624 && (is_emulator() == true || timeout_sleep_support == false))
627 _I("Reset timeout(%d ms).", timeout);
628 if (timeout_src_id != 0) {
629 g_source_remove(timeout_src_id);
633 if (trans_table[get_pm_cur_state()][EVENT_TIMEOUT] == get_pm_cur_state())
637 timeout_src_id = g_timeout_add(timeout,
638 timeout_handler, NULL);
639 else if (timeout == 0)
640 states[get_pm_cur_state()].trans(EVENT_TIMEOUT);
643 /* get configurations from setting */
644 static int get_lcd_timeout_from_settings(void)
649 for (i = 0; i < S_END; i++) {
650 switch (states[i].state) {
652 get_run_timeout(&val);
655 get_dim_timeout(&val);
658 val = display_conf.lcdoff_timeout;
661 /* This state doesn't need to set time out. */
666 states[i].timeout = val;
668 _I("State(%s) timeout(%d) ms", states[i].name,
675 static void update_display_time(void)
677 int run_timeout, val;
679 /* first priority : s cover */
681 states[S_NORMAL].timeout = S_COVER_TIMEOUT;
682 _I("S cover closed: Timeout(%d ms) is set by normal.",
687 /* second priority : custom timeout */
688 if (custom_normal_timeout > 0) {
689 states[S_NORMAL].timeout = custom_normal_timeout;
690 states[S_LCDDIM].timeout = custom_dim_timeout;
691 _I("CUSTOM : timeout is set by normal(%d ms), dim(%d ms)",
692 custom_normal_timeout, custom_dim_timeout);
696 /* third priority : lock state */
697 if ((__get_lock_screen_state() == VCONFKEY_IDLE_LOCK) &&
698 !get_lock_screen_bg_state()) {
699 /* timeout is different according to key or event. */
700 states[S_NORMAL].timeout = lock_screen_timeout;
701 _I("LOCK: Timeout(%d ms) is set by normal.",
702 lock_screen_timeout);
706 /* default setting */
707 get_run_timeout(&run_timeout);
710 * if the run_timeout is zero, it regards AlwaysOn state
712 if (run_timeout == 0 || display_conf.lcd_always_on) {
713 run_timeout = ALWAYS_ON_TIMEOUT;
714 _I("LCD always on.");
717 states[S_NORMAL].timeout = run_timeout;
719 get_dim_timeout(&val);
720 states[S_LCDDIM].timeout = val;
722 _I("Normal: NORMAL timeout is set by %d ms", states[S_NORMAL].timeout);
723 _I("Normal: DIM timeout is set by %d ms", states[S_LCDDIM].timeout);
726 static void update_display_locktime(int time)
728 lock_screen_timeout = time;
729 update_display_time();
732 void set_dim_state(bool on)
734 _I("Dim state is %d.", on);
735 update_display_time();
736 states[get_pm_cur_state()].trans(EVENT_INPUT);
739 void lcd_on_direct(enum device_flags flags)
741 set_pm_cur_state(S_NORMAL);
743 _D("lcd is on directly");
744 gettimeofday(&lcdon_tv, NULL);
745 lcd_on_procedure(LCD_NORMAL, flags);
747 update_display_locktime(LOCK_SCREEN_INPUT_TIMEOUT);
750 static inline bool check_lcd_is_on(void)
752 if (backlight_ops->get_lcd_power() != DPMS_ON)
758 static gboolean timer_refresh_cb(gpointer data)
762 /* state transition */
763 set_pm_old_state(get_pm_cur_state());
764 set_pm_cur_state(S_NORMAL);
765 st = &states[get_pm_cur_state()];
768 st->action(st->timeout);
773 int custom_lcdon(int timeout)
780 if (check_lcd_is_on() == false)
781 lcd_on_direct(LCD_ON_BY_GESTURE);
783 _I("Custom lcd on timeout(%d ms).", timeout);
784 if (set_custom_lcdon_timeout(timeout) == true)
785 update_display_time();
787 /* state transition */
788 set_pm_old_state(get_pm_cur_state());
789 set_pm_cur_state(S_NORMAL);
790 st = &states[get_pm_cur_state()];
794 st->action(st->timeout);
796 g_idle_add(timer_refresh_cb, NULL);
801 int custom_lcdoff(enum device_flags flag)
805 check_processes(S_NORMAL);
806 check_processes(S_LCDDIM);
808 /* check holdkey block flag in lock node */
809 if (check_lock_condition(S_NORMAL) || check_lock_condition(S_LCDDIM)) {
811 * When another proccess is normal lock, device is received call then,
812 * call app can be changed to lcd state by proximity.
813 * If proximity is near then normal lock will be unlocked.
815 if (flag & LCD_OFF_BY_PROXIMITY) {
816 _I("custom lcd off by proximity, delete normal lock");
817 delete_condition(S_NORMAL);
819 _I("skip custom lcd off");
824 _I("custom lcd off by flag(%d)", flag);
825 if (backlight_ops->get_lcd_power() == DPMS_ON)
826 lcd_off_procedure(flag);
828 if (set_custom_lcdon_timeout(0) == true)
829 update_display_time();
831 /* state transition */
832 set_pm_old_state(get_pm_cur_state());
833 set_pm_cur_state(S_LCDOFF);
834 st = &states[get_pm_cur_state()];
838 st->action(st->timeout);
843 int display_on_by_reason(const char *reason, int timeout)
849 str_len = strlen(reason);
851 if (!strncmp(reason, GESTURE_STR, str_len))
852 flag = LCD_ON_BY_GESTURE;
853 else if (!strncmp(reason, EVENT_STR, str_len))
854 flag = LCD_ON_BY_EVENT;
856 _E("Reason is unknown(%s)", reason);
861 _E("Cannot setting timeout %d", timeout);
865 if (check_lcd_is_on() == false)
868 _I("platform lcd on by %s (%d ms)", reason, timeout);
869 if (set_custom_lcdon_timeout(timeout) == true)
870 update_display_time();
872 /* state transition */
873 set_pm_old_state(get_pm_cur_state());
874 set_pm_cur_state(S_NORMAL);
875 st = &states[get_pm_cur_state()];
879 st->action(st->timeout);
884 int display_off_by_reason(const char *reason)
890 str_len = strlen(reason);
892 if (!strncmp(reason, GESTURE_STR, str_len)) {
893 check_processes(S_NORMAL);
894 check_processes(S_LCDDIM);
896 /* check holdkey block flag in lock node */
897 if (check_lock_condition(S_NORMAL) || check_lock_condition(S_LCDDIM)) {
898 _I("skip platform lcd off by gesture");
901 flag = LCD_OFF_BY_GESTURE;
902 } else if (!strncmp(reason, PALM_STR, str_len)) {
903 delete_condition(S_NORMAL);
904 delete_condition(S_LCDDIM);
906 flag = LCD_OFF_BY_PALM;
908 _E("Reason is unknown(%s)", reason);
912 _I("platform lcd off by %s", reason);
913 if (backlight_ops->get_lcd_power() == DPMS_ON)
914 lcd_off_procedure(flag);
916 /* state transition */
917 set_pm_old_state(get_pm_cur_state());
918 set_pm_cur_state(S_LCDOFF);
919 st = &states[get_pm_cur_state()];
923 st->action(st->timeout);
928 static void default_proc_change_state_action(enum state_t next, int timeout)
932 set_pm_old_state(get_pm_cur_state());
933 set_pm_cur_state(next);
935 st = &states[get_pm_cur_state()];
937 if (st && st->action) {
939 st->action(st->timeout);
945 static int default_proc_change_state(unsigned int cond, pid_t pid)
949 next = GET_COND_STATE(cond);
950 _I("Change process(%d) state to %s.", pid, states[next].name);
954 if (check_lcd_is_on() == false)
955 lcd_on_direct(LCD_ON_BY_EVENT);
956 update_display_locktime(LOCK_SCREEN_CONTROL_TIMEOUT);
957 default_proc_change_state_action(next, -1);
960 default_proc_change_state_action(next, -1);
963 if (backlight_ops->get_lcd_power() == DPMS_ON) {
964 if (get_proximity_state() == SENSOR_PROXIMITY_NEAR)
965 lcd_off_procedure(LCD_OFF_BY_PROXIMITY);
967 lcd_off_procedure(LCD_OFF_BY_EVENT);
969 if (set_custom_lcdon_timeout(0))
970 update_display_time();
971 default_proc_change_state_action(next, -1);
974 _I("Dangerous requests.");
975 /* at first LCD_OFF and then goto sleep */
976 /* state transition */
977 default_proc_change_state_action(S_LCDOFF, TIMEOUT_NONE);
978 delete_condition(S_NORMAL);
979 delete_condition(S_LCDDIM);
980 delete_condition(S_LCDOFF);
981 if (lcdon_broadcast) {
982 _I("broadcast lcd off signal at non-lcd device");
983 broadcast_lcd_off(SIGNAL_PRE, 0);
984 broadcast_lcd_off(SIGNAL_POST, 0);
986 default_proc_change_state_action(S_SLEEP, TIMEOUT_NONE);
996 static void proc_condition_lock(PMMsg *data)
999 guint cond_timeout_id = 0;
1000 char pname[PATH_MAX];
1001 pid_t pid = data->pid;
1003 int holdkey_block, ret;
1006 const char *lock_type = NULL;
1008 state = GET_COND_STATE(data->cond);
1009 if (state == S_START)
1012 flags = GET_COND_FLAG(data->cond);
1013 get_pname(pid, pname);
1015 if ((state == S_LCDOFF) && (get_pm_cur_state() == S_SLEEP) &&
1016 (pm_get_power_lock() == POWER_UNLOCK)) {
1018 * To escape from display state S_SLEEP,
1019 * it must precede that change power state from SLEEP to NORAML
1021 power_request_change_state_strict(DEVICED_POWER_STATE_SLEEP, DEVICED_POWER_STATE_NORMAL, 0, NULL);
1022 proc_change_state(data->cond, INTERNAL_LOCK_PM);
1025 if (data->timeout > 0) {
1026 /* To pass a pid_t data through the timer infrastructure
1027 * without memory allocation, a pid_t data becomes typecast
1028 * to intptr_t and void *(64bit) type. */
1029 cond_timeout_id = g_timeout_add(
1031 states[state].timeout_cb,
1032 (void*)((intptr_t)pid));
1033 if (!cond_timeout_id)
1034 _E("Failed to register display timer.");
1037 holdkey_block = GET_COND_FLAG(data->cond) & PM_FLAG_BLOCK_HOLDKEY;
1039 tmp = find_node(state, pid);
1041 tmp = add_node(state, pid, cond_timeout_id, holdkey_block);
1043 _E("Failed to acquire lock, state: %d, pid: %d.", state, pid);
1047 update_lock_timer(data, tmp, cond_timeout_id);
1048 tmp->holdkey_block = holdkey_block;
1051 if (state == S_LCDOFF)
1052 set_process_active(true, pid);
1054 _I("[%s] locked by %5d with %u ms", states[state].name, pid, data->timeout);
1056 if (pid < INTERNAL_LOCK_BASE) {
1058 if (state == S_LCDOFF)
1059 lock_type = PM_LCDOFF_STR;
1060 else if (state == S_LCDDIM)
1061 lock_type = PM_LCDDIM_STR;
1062 else if (state == S_NORMAL)
1063 lock_type = PM_LCDON_STR;
1066 /* power lock signal */
1067 ret = gdbus_signal_emit(NULL,
1068 DEVICED_PATH_DISPLAY,
1069 DEVICED_INTERFACE_DISPLAY,
1071 g_variant_new("(sii)", lock_type, pid, (int)data->timeout));
1073 _E("Failed to send dbus signal PowerLock.");
1076 _SD("be requested LOCK info pname(%s), holdkeyblock(%d) flags(%d)",
1077 pname, holdkey_block, flags);
1078 set_lock_time(pid, pname, state);
1080 device_notify(DEVICE_NOTIFIER_DISPLAY_LOCK, (void *)&value);
1083 static void proc_condition_unlock(PMMsg *data)
1085 pid_t pid = data->pid;
1088 char pname[PATH_MAX];
1092 const char *lock_type = NULL;
1094 state = GET_COND_STATE(data->cond);
1098 flags = GET_COND_FLAG(data->cond);
1099 get_pname(pid, pname);
1101 tmp = find_node(state, pid);
1102 del_node(state, tmp);
1104 if (state == S_LCDOFF)
1105 set_process_active(false, pid);
1107 _I("[%s] unlocked by %5d", states[state].name, pid);
1109 if (pid < INTERNAL_LOCK_BASE) {
1111 if (state == S_LCDOFF)
1112 lock_type = PM_LCDOFF_STR;
1113 else if (state == S_LCDDIM)
1114 lock_type = PM_LCDDIM_STR;
1115 else if (state == S_NORMAL)
1116 lock_type = PM_LCDON_STR;
1119 /* power unlock signal */
1120 ret = gdbus_signal_emit(NULL,
1121 DEVICED_PATH_DISPLAY,
1122 DEVICED_INTERFACE_DISPLAY,
1124 g_variant_new("(sii)", lock_type, pid, (int)data->timeout));
1126 _E("Failed to send dbus signal PowerUnlock.");
1130 _SD("be requested UNLOCK info pname(%s) flag(%d)", pname, flags);
1131 set_unlock_time(pid, state);
1133 device_notify(DEVICE_NOTIFIER_DISPLAY_LOCK, (void *)&value);
1136 static int proc_condition(PMMsg *data)
1140 if (IS_COND_REQUEST_LOCK(data->cond))
1141 proc_condition_lock(data);
1143 if (IS_COND_REQUEST_UNLOCK(data->cond))
1144 proc_condition_unlock(data);
1146 if (!display_conf.timeout_enable)
1149 flags = GET_COND_FLAG(data->cond);
1151 /* guard time for suspend */
1152 if (get_pm_cur_state() == S_LCDOFF)
1153 reset_timeout(states[S_LCDOFF].timeout);
1155 if (flags & PM_FLAG_RESET_TIMER)
1156 reset_timeout(states[get_pm_cur_state()].timeout);
1159 if (!timeout_src_id)
1160 states[get_pm_cur_state()].trans(EVENT_TIMEOUT);
1165 void update_lcdoff_source(int source)
1170 case VCONFKEY_PM_LCDOFF_BY_TIMEOUT:
1171 _I("LCD OFF by timeout.");
1173 case VCONFKEY_PM_LCDOFF_BY_POWERKEY:
1174 _I("LCD OFF by powerkey.");
1177 _E("Invalid value(%d).", source);
1180 ret = vconf_set_int(VCONFKEY_PM_LCDOFF_SOURCE, source);
1182 _E("Failed to set vconf value for lcd off source: %d", vconf_get_ext_errno());
1185 void print_info(int fd)
1188 char buf[PATH_MAX + 255];
1191 char pname[PATH_MAX];
1199 snprintf(buf, sizeof(buf),
1200 "\n==========================================="
1201 "===========================\n");
1202 ret = write(fd, buf, strlen(buf));
1204 _E("Write() failed: %d", errno);
1205 snprintf(buf, sizeof(buf), "Timeout Info: Run[%dms] Dim[%dms] Off[%dms]\n",
1206 states[S_NORMAL].timeout,
1207 states[S_LCDDIM].timeout, states[S_LCDOFF].timeout);
1208 ret = write(fd, buf, strlen(buf));
1210 _E("Write() failed: %d", errno);
1212 snprintf(buf, sizeof(buf), "Tran. Locked : %s %s %s\n",
1213 (get_trans_condition() & MASK_NORMAL) ? states[S_NORMAL].name : "-",
1214 (get_trans_condition() & MASK_DIM) ? states[S_LCDDIM].name : "-",
1215 (get_trans_condition() & MASK_OFF) ? states[S_LCDOFF].name : "-");
1216 ret = write(fd, buf, strlen(buf));
1218 _E("Write() failed: %d", errno);
1220 snprintf(buf, sizeof(buf), "Current State: %s\n",
1221 states[get_pm_cur_state()].name);
1222 ret = write(fd, buf, strlen(buf));
1224 _E("Write() failed: %d", errno);
1226 snprintf(buf, sizeof(buf), "Current Lock Conditions: \n");
1227 ret = write(fd, buf, strlen(buf));
1229 _E("Write() failed: %d", errno);
1231 for (s_index = S_NORMAL; s_index < S_END; s_index++) {
1232 SYS_G_LIST_FOREACH(get_cond_head(s_index), elem, t) {
1233 get_pname((pid_t)t->pid, pname);
1234 ctime_r(&t->time, time_buf);
1235 time_buf[strlen(time_buf) - 1] = 0;
1236 snprintf(buf, sizeof(buf),
1237 " %d: [%s] locked by pid %d %s %s\n",
1238 i++, states[s_index].name, t->pid, pname, time_buf);
1239 ret = write(fd, buf, strlen(buf));
1241 _E("Write() failed: %d", errno);
1245 print_lock_info_list(fd);
1247 #ifdef ENABLE_PM_LOG
1248 pm_history_print(fd, 250);
1252 void save_display_log(const char *path)
1259 _D("internal state is saved!");
1262 ctime_r(&now_time, time_buf);
1263 time_buf[strlen(time_buf) - 1] = 0;
1265 fd = open(path, O_CREAT | O_TRUNC | O_WRONLY, 0644);
1267 snprintf(buf, sizeof(buf),
1268 "\npm_state_log now-time : %d(s) %s\n\n",
1269 (int)now_time, time_buf);
1270 ret = write(fd, buf, strlen(buf));
1272 _E("write() failed (%d)", errno);
1274 snprintf(buf, sizeof(buf), "pm_status_flag: %#x\n", get_pm_status_flag());
1275 ret = write(fd, buf, strlen(buf));
1277 _E("write() failed (%d)", errno);
1279 if (disp_plgn->get_lock_screen_state ) {
1280 snprintf(buf, sizeof(buf), "screen lock status : %d\n",
1281 disp_plgn->get_lock_screen_state());
1282 ret = write(fd, buf, strlen(buf));
1284 _E("write() failed (%d)", errno);
1290 fd = open("/dev/console", O_WRONLY);
1297 /* SIGHUP signal handler
1298 * For debug... print info to syslog
1300 static void sig_hup(int signo)
1302 _I("received sig hub %d", signo);
1307 int check_lcdoff_direct(void)
1309 int ret, lock, cradle;
1312 if (get_pm_old_state() != S_NORMAL)
1315 if (get_pm_cur_state() != S_LCDDIM)
1318 if (!display_conf.dimming)
1321 lock = __get_lock_screen_state();
1322 if (lock != VCONFKEY_IDLE_LOCK && hallic_open)
1325 hdmi_state = extcon_get_status(EXTCON_CABLE_HDMI);
1329 ret = vconf_get_int(VCONFKEY_SYSMAN_CRADLE_STATUS, &cradle);
1330 if (ret >= 0 && cradle == DOCK_SOUND)
1333 _E("Failed to get vconf value for cradle status: %d", vconf_get_ext_errno());
1335 _D("Goto LCDOFF direct: lock(%d) hdmi(%d) cradle(%d).", lock, hdmi_state, cradle);
1341 * default transition function
1344 * 3. call enter action function
1346 static int default_trans(int evt)
1348 struct state *st = &states[get_pm_cur_state()];
1351 next_state = (enum state_t)trans_table[get_pm_cur_state()][evt];
1353 /* check conditions */
1354 if (st->check && !st->check(get_pm_cur_state(), next_state)) {
1355 /* There is a condition. */
1356 _I("%s locked. Trans to %s failed.", states[get_pm_cur_state()].name,
1357 states[next_state].name);
1361 /* state transition */
1362 set_pm_old_state(get_pm_cur_state());
1363 set_pm_cur_state(next_state);
1364 st = &states[get_pm_cur_state()];
1368 if (get_pm_cur_state() == S_LCDOFF)
1369 update_lcdoff_source(VCONFKEY_PM_LCDOFF_BY_TIMEOUT);
1371 if ((get_pm_cur_state() == S_NORMAL) || (get_pm_cur_state() == S_LCDOFF))
1372 if (set_custom_lcdon_timeout(0) == true)
1373 update_display_time();
1375 if (check_lcdoff_direct() == true) {
1376 /* enter next state directly */
1377 states[get_pm_cur_state()].trans(EVENT_TIMEOUT);
1379 if ((get_pm_cur_state() == S_SLEEP)
1380 && (is_emulator() == true || timeout_sleep_support == false))
1383 st->action(st->timeout);
1390 static gboolean lcd_on_expired(void *data)
1392 int lock_state, ret;
1394 if (lock_timeout_id)
1395 lock_timeout_id = 0;
1397 /* check state of lock */
1398 ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
1399 if (ret > 0 && lock_state == VCONFKEY_IDLE_LOCK)
1400 return G_SOURCE_REMOVE;
1402 _E("Failed to get vconf value for idle lock state: %d", vconf_get_ext_errno());
1404 /* lock screen is not launched yet, but lcd is on */
1405 if (check_lcd_is_on() == false)
1406 lcd_on_procedure(LCD_NORMAL, NORMAL_MODE);
1408 return G_SOURCE_REMOVE;
1411 static inline void stop_lock_timer(void)
1413 if (lock_timeout_id) {
1414 g_source_remove(lock_timeout_id);
1415 lock_timeout_id = 0;
1419 static void check_lock_screen(void)
1421 int lock_state, ret;
1425 /* check state of lock */
1426 ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
1427 if (ret < 0 || lock_state == VCONFKEY_IDLE_LOCK)
1430 /* Use time to check lock is done. */
1431 lock_timeout_id = g_timeout_add(display_conf.lock_wait_time,
1432 lcd_on_expired, NULL);
1435 /* default enter action function */
1436 static int default_action(int timeout)
1438 int wakeup_count = -1, pm_cur_state;
1441 static time_t last_update_time = 0;
1442 static int last_timeout = 0;
1443 struct timeval now_tv;
1445 if (status != DEVICE_OPS_STATUS_START) {
1446 _E("Display is not started.");
1450 if (get_pm_cur_state() != S_SLEEP) {
1451 if ((get_pm_cur_state() == S_NORMAL) &&
1452 lcdon_tv.tv_sec != 0) {
1453 gettimeofday(&now_tv, NULL);
1454 timeout -= DIFF_TIMEVAL_MS(now_tv, lcdon_tv);
1455 lcdon_tv.tv_sec = 0;
1457 /* set timer with current state timeout */
1458 reset_timeout(timeout);
1460 if (get_pm_cur_state() == S_NORMAL) {
1461 time(&last_update_time);
1462 last_timeout = timeout;
1464 _I("Timout set: %s state %d ms",
1465 states[get_pm_cur_state()].name, timeout);
1469 if ((get_pm_cur_state() != get_pm_old_state()) && (get_pm_cur_state() != S_SLEEP)) {
1470 set_setting_pmstate(get_pm_cur_state());
1471 pm_cur_state = get_pm_cur_state();
1472 device_notify(DEVICE_NOTIFIER_LCD, (void *)&pm_cur_state);
1475 if ((get_pm_old_state() == S_NORMAL) && (get_pm_cur_state() != S_NORMAL)) {
1477 diff = difftime(now, last_update_time);
1478 _I("S_NORMAL is changed to %s (timeout=%d ms diff=%.0f s).",
1479 states[get_pm_cur_state()].name, last_timeout, diff);
1482 switch (get_pm_cur_state()) {
1485 * normal state : backlight on and restore
1486 * the previous brightness
1488 if ((get_pm_old_state() == S_LCDOFF) || (get_pm_old_state() == S_SLEEP))
1489 check_lock_screen();
1490 else if (get_pm_old_state() == S_LCDDIM)
1491 backlight_ops->update();
1493 if (check_lcd_is_on() == false)
1494 lcd_on_procedure(LCD_NORMAL, NORMAL_MODE);
1498 if ((get_pm_old_state() == S_NORMAL) &&
1499 backlight_ops->get_custom_status())
1500 backlight_ops->save_custom_brightness();
1501 /* lcd dim state : dim the brightness */
1502 backlight_ops->dim();
1504 if ((get_pm_old_state() == S_LCDOFF) || (get_pm_old_state() == S_SLEEP))
1505 lcd_on_procedure(LCD_DIM, NORMAL_MODE);
1509 if ((get_pm_old_state() != S_SLEEP) && (get_pm_old_state() != S_LCDOFF)) {
1511 /* lcd off state : turn off the backlight */
1512 if (backlight_ops->get_lcd_power() == DPMS_ON)
1513 lcd_off_procedure(LCD_OFF_BY_TIMEOUT);
1516 if (backlight_ops->get_lcd_power() == DPMS_ON
1517 || lcd_paneloff_mode)
1518 lcd_off_procedure(LCD_OFF_BY_TIMEOUT);
1522 if ((get_pm_old_state() != S_SLEEP) && (get_pm_old_state() != S_LCDOFF))
1525 if (backlight_ops->get_lcd_power() == DPMS_ON)
1526 lcd_off_procedure(LCD_OFF_BY_TIMEOUT);
1528 if (!pm_get_power_lock_support()) {
1529 /* sleep state : set system mode to SUSPEND */
1530 if (get_wakeup_count(&wakeup_count) < 0)
1531 _E("Wakeup count read error.");
1533 if (wakeup_count < 0) {
1534 _I("Wakup Event. Can not enter suspend mode.");
1538 if (set_wakeup_count(wakeup_count) < 0) {
1539 _E("Wakeup count write error.");
1549 #ifdef ENABLE_PM_LOG
1550 pm_history_save(PM_LOG_SLEEP, get_pm_cur_state());
1552 power_request_change_state(DEVICED_POWER_STATE_SLEEP, HAL_DEVICE_POWER_TRANSITION_REASON_DISPLAY_OFF_TIMEOUT);
1556 if (!pm_get_power_lock_support()) {
1558 states[get_pm_cur_state()].trans(EVENT_DEVICE);
1564 * default check function
1566 * 0 : can't transit, others : transitable
1568 static int default_check(int curr, int next)
1572 makeup_trans_condition();
1574 trans_cond = get_trans_condition() & MASK_BIT;
1576 if (next == S_NORMAL) /* S_NORMAL is exceptional */
1581 trans_cond = trans_cond & MASK_NORMAL;
1584 trans_cond = trans_cond & MASK_DIM;
1587 trans_cond = trans_cond & MASK_OFF;
1594 if (trans_cond != 0) {
1599 return 1; /* transitable */
1602 static void default_saving_mode(int onoff)
1605 set_pm_status_flag(PWRSV_FLAG);
1607 clear_pm_status_flag(PWRSV_FLAG);
1609 if (get_pm_cur_state() == S_NORMAL)
1610 backlight_ops->update();
1613 int poll_callback(int condition, PMMsg *data)
1615 static time_t last_t;
1618 if (status != DEVICE_OPS_STATUS_START) {
1619 _E("Display logic is not started.");
1623 if (condition == INPUT_POLL_EVENT) {
1624 if ((get_pm_cur_state() == S_LCDOFF) || (get_pm_cur_state() == S_SLEEP))
1625 _I("Input event signal at Display Off");
1627 if ((last_t != now) ||
1628 (get_pm_cur_state() == S_LCDOFF) ||
1629 (get_pm_cur_state() == S_SLEEP)) {
1630 states[get_pm_cur_state()].trans(EVENT_INPUT);
1635 if (condition == PM_CONTROL_EVENT) {
1636 proc_condition(data);
1638 if (IS_COND_REQUEST_CHANGE(data->cond))
1639 proc_change_state(data->cond, data->pid);
1645 static int update_setting(int key_idx, int val)
1650 case SETTING_TO_NORMAL:
1651 update_display_time();
1652 states[get_pm_cur_state()].trans(EVENT_INPUT);
1654 case SETTING_HALLIC_OPEN:
1656 update_display_time();
1657 if ((get_pm_cur_state() == S_NORMAL) || (get_pm_cur_state() == S_LCDDIM))
1658 states[get_pm_cur_state()].trans(EVENT_INPUT);
1659 else if ((get_pm_cur_state() == S_SLEEP) && hallic_open)
1660 proc_change_state(S_LCDOFF, INTERNAL_LOCK_HALLIC);
1662 case SETTING_LOW_BATT:
1663 if (low_battery_state(val)) {
1664 if (!(get_pm_status_flag() & CHRGR_FLAG))
1665 power_saving_func(true);
1666 set_pm_status_flag(LOWBT_FLAG);
1668 if (get_pm_status_flag() & PWRSV_FLAG)
1669 power_saving_func(false);
1670 clear_pm_status_flag(LOWBT_FLAG);
1671 clear_pm_status_flag(BRTCH_FLAG);
1672 ret = vconf_set_bool(VCONFKEY_PM_BRIGHTNESS_CHANGED_IN_LPM, false);
1674 _E("Failed to set vconf value for brightness changed in lpm: %d", vconf_get_ext_errno());
1677 case SETTING_CHARGING:
1679 if (get_pm_status_flag() & LOWBT_FLAG) {
1680 power_saving_func(false);
1681 clear_pm_status_flag(LOWBT_FLAG);
1683 set_pm_status_flag(CHRGR_FLAG);
1686 ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW,
1689 bat_state = VCONFKEY_SYSMAN_BAT_NORMAL;
1690 _E("Failed to get vconf value for battery status low: %d", vconf_get_ext_errno());
1692 if (low_battery_state(bat_state)) {
1693 power_saving_func(true);
1694 set_pm_status_flag(LOWBT_FLAG);
1696 clear_pm_status_flag(CHRGR_FLAG);
1699 case SETTING_BRT_LEVEL:
1700 if (get_pm_status_flag() & PWRSV_FLAG) {
1701 set_pm_status_flag(BRTCH_FLAG);
1702 ret = vconf_set_bool(VCONFKEY_PM_BRIGHTNESS_CHANGED_IN_LPM, true);
1704 _E("Failed to set vconf value for brightness changed in lpm: %d", vconf_get_ext_errno());
1705 _I("Brightness changed in low battery,"
1706 "escape dim state.");
1708 backlight_ops->set_default_brt(val);
1710 case SETTING_LOCK_SCREEN:
1711 set_lock_screen_state(val);
1712 if (val == VCONFKEY_IDLE_UNLOCK) {
1713 if (CHECK_OPS(keyfilter_ops, backlight_enable))
1714 keyfilter_ops->backlight_enable(false);
1717 /* LCD on if lock screen show before waiting time */
1718 if ((get_pm_cur_state() == S_NORMAL) &&
1719 val == VCONFKEY_IDLE_LOCK &&
1720 backlight_ops->get_lcd_power() != DPMS_ON &&
1721 is_lcdon_blocked() == LCDON_BLOCK_NONE)
1722 lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
1724 update_display_time();
1725 if (get_pm_cur_state() == S_NORMAL)
1726 states[get_pm_cur_state()].trans(EVENT_INPUT);
1728 case SETTING_LOCK_SCREEN_BG:
1729 set_lock_screen_bg_state(val);
1730 update_display_time();
1731 if (get_pm_cur_state() == S_NORMAL)
1732 states[get_pm_cur_state()].trans(EVENT_INPUT);
1734 case SETTING_POWER_CUSTOM_BRIGHTNESS:
1735 if (val == VCONFKEY_PM_CUSTOM_BRIGHTNESS_ON)
1736 backlight_ops->set_custom_status(true);
1738 backlight_ops->set_custom_status(false);
1747 static void check_seed_status(void)
1755 /* Charging check */
1756 if (fp_get_charging_status && (fp_get_charging_status(&tmp) == 0) && (tmp > 0))
1757 set_pm_status_flag(CHRGR_FLAG);
1759 ret = get_setting_brightness(&tmp);
1760 if (ret != 0 || (tmp < PM_MIN_BRIGHTNESS || tmp > PM_MAX_BRIGHTNESS)) {
1761 _I("Failed to read vconf value for brightness.");
1762 brt = display_conf.pm_default_brightness;
1763 if (tmp < PM_MIN_BRIGHTNESS || tmp > PM_MAX_BRIGHTNESS) {
1764 ret = vconf_set_int(VCONFKEY_SETAPPL_LCD_BRIGHTNESS, brt);
1766 _E("Failed to set vconf value for lcd brightness: %d", vconf_get_ext_errno());
1770 _I("Set brightness(%d) from setting app.", tmp);
1771 backlight_ops->set_default_brt(tmp);
1772 backlight_ops->set_brightness(tmp);
1774 ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, &bat_state);
1776 bat_state = VCONFKEY_SYSMAN_BAT_NORMAL;
1777 _E("Failed to get vconf value for battery status low: %d", vconf_get_ext_errno());
1779 if (low_battery_state(bat_state)) {
1780 if (!(get_pm_status_flag() & CHRGR_FLAG)) {
1781 power_saving_func(true);
1782 set_pm_status_flag(LOWBT_FLAG);
1786 /* lock screen check */
1787 ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
1790 _E("Failed to get vconf value for idle lock state: %d", vconf_get_ext_errno());
1792 set_lock_screen_state(lock_state);
1793 if (lock_state == VCONFKEY_IDLE_LOCK) {
1794 states[S_NORMAL].timeout = lock_screen_timeout;
1795 _I("LCD NORMAL timeout(%d ms) is set"
1796 " for lock screen.", lock_screen_timeout);
1802 static void init_lcd_operation(void)
1804 const struct device_ops *ops = NULL;
1806 ops = find_device("display");
1807 if (!check_default(ops))
1808 SYS_G_LIST_APPEND(lcdon_ops, ops);
1810 ops = find_device("touchkey");
1811 if (!check_default(ops))
1812 SYS_G_LIST_APPEND(lcdon_ops, ops);
1814 ops = find_device("touchscreen");
1815 if (!check_default(ops))
1816 SYS_G_LIST_APPEND(lcdon_ops, ops);
1819 static void exit_lcd_operation(void)
1822 GList *l_next = NULL;
1823 const struct device_ops *ops = NULL;
1825 SYS_G_LIST_FOREACH_SAFE(lcdon_ops, l, l_next, ops)
1826 SYS_G_LIST_REMOVE_LIST(lcdon_ops, l);
1838 static const char *errMSG[INIT_END] = {
1839 [INIT_SETTING] = "setting init error",
1840 [INIT_INTERFACE] = "lowlevel interface(sysfs or others) init error",
1841 [INIT_POLL] = "input devices poll init error",
1842 [INIT_FIFO] = "FIFO poll init error",
1843 [INIT_DBUS] = "d-bus init error",
1846 int set_lcd_timeout(int on, int dim, int holdkey_block, const char *name)
1848 if (on == 0 && dim == 0) {
1849 _I("LCD timeout changed: default setting");
1850 custom_normal_timeout = custom_dim_timeout = 0;
1851 } else if (on < 0 || dim < 0) {
1852 _E("Failed to set value(on=%d dim=%d).", on, dim);
1855 _I("LCD timeout changed: on=%ds dim=%ds", on, dim);
1856 custom_normal_timeout = SEC_TO_MSEC(on);
1857 custom_dim_timeout = SEC_TO_MSEC(dim);
1859 /* Apply new backlight time */
1860 update_display_time();
1861 if (get_pm_cur_state() == S_NORMAL)
1862 states[get_pm_cur_state()].trans(EVENT_INPUT);
1864 if (holdkey_block) {
1865 custom_holdkey_block = true;
1866 _I("Hold key disabled.");
1868 custom_holdkey_block = false;
1869 _I("Hold key enabled.");
1872 if (custom_change_name) {
1873 free(custom_change_name);
1874 custom_change_name = 0;
1877 if (custom_normal_timeout == 0 &&
1878 custom_dim_timeout == 0 &&
1882 custom_change_name = strndup(name, strlen(name));
1883 if (!custom_change_name) {
1884 _E("Failed to malloc.");
1885 custom_normal_timeout = custom_dim_timeout = 0;
1886 custom_holdkey_block = false;
1893 void reset_lcd_timeout(GDBusConnection *conn,
1894 const gchar *sender,
1895 const gchar *unique_name,
1901 if (!custom_change_name)
1904 if (strcmp(sender, custom_change_name))
1907 _I("reset lcd timeout: Set default timeout. sender=%s", sender);
1909 free(custom_change_name);
1910 custom_change_name = 0;
1911 custom_normal_timeout = custom_dim_timeout = 0;
1912 custom_holdkey_block = false;
1914 update_display_time();
1915 if (get_pm_cur_state() == S_NORMAL)
1916 states[get_pm_cur_state()].trans(EVENT_INPUT);
1919 static int delayed_init_done(void *data)
1921 static bool done = false;
1930 _I("Booting done, release booting lock.");
1931 if (disp_plgn->pm_unlock_internal) {
1932 disp_plgn->pm_unlock_internal(INTERNAL_LOCK_BOOTING, LCD_NORMAL, PM_SLEEP_MARGIN);
1933 disp_plgn->pm_unlock_internal(INTERNAL_LOCK_BOOTING, LCD_OFF, PM_SLEEP_MARGIN);
1939 static int battery_health_changed(void *data)
1941 int health = DATA_VALUE_INT(data);
1943 _I("battery health change %d", health);
1945 if (health == HEALTH_GOOD) {
1946 clear_pm_status_flag(BATTERY_FLAG);
1947 clear_pm_status_flag(DIMSTAY_FLAG);
1948 } else if (health == HEALTH_LOW || health == HEALTH_HIGH || health == HEALTH_OVP) {
1949 set_pm_status_flag(BATTERY_FLAG);
1950 set_pm_status_flag(DIMSTAY_FLAG);
1953 if (backlight_ops->get_lcd_power() == DPMS_ON)
1954 backlight_ops->update();
1959 static gboolean delayed_dpms_init_done(gpointer data)
1964 return G_SOURCE_CONTINUE;
1966 switch (get_pm_cur_state()) {
1969 lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
1970 if (display_conf.timeout_enable) {
1971 timeout = states[S_NORMAL].timeout;
1972 /* check minimun lcd on time */
1973 if (timeout < SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT))
1974 timeout = SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT);
1975 reset_timeout(timeout);
1979 lcd_off_procedure(LCD_OFF_BY_EVENT);
1980 timeout = display_conf.lcdoff_timeout;
1981 reset_timeout(timeout);
1987 return G_SOURCE_REMOVE;
1990 static void add_timer_for_dpms_init(void)
1992 guint id = g_timeout_add(500/* milliseconds */, delayed_dpms_init_done, NULL);
1994 _E("Failed to add dpms_init timeout.");
1998 * Power manager Main
2001 static int display_probe(void *data)
2006 * load display service
2007 * if there is no display shared library,
2008 * deviced does not provide any method and function of display.
2010 ret = display_service_load();
2014 /* display_plugin instance initialization */
2016 disp_plgn->device_flags_to_string = __device_flags_to_string;
2018 if (battery_plgn->handle) {
2019 fp_get_charging_status = dlsym(battery_plgn->handle, "get_charging_status");
2020 if (!fp_get_charging_status)
2021 _E("Failed to obtain address of get_charging_status");
2023 _I("There is no battery module.");
2028 static int input_init_handler(void)
2030 if (!display_conf.input_support)
2031 remove_device_by_devname("input");
2036 static int power_resume_from_echomem_callback(void *data)
2038 system_wakeup_flag = true;
2039 if (check_wakeup_src() == EVENT_DEVICE)
2040 /* system waked up by devices */
2041 states[get_pm_cur_state()].trans(EVENT_DEVICE);
2043 /* system waked up by user input */
2044 states[get_pm_cur_state()].trans(EVENT_INPUT);
2049 static int poweroff_triggered_callback(void *udata)
2051 int val = (int)(intptr_t) udata;
2054 case VCONFKEY_SYSMAN_POWER_OFF_NONE:
2055 clear_pm_status_flag(PWROFF_FLAG);
2057 case VCONFKEY_SYSMAN_POWER_OFF_DIRECT:
2058 case VCONFKEY_SYSMAN_POWER_OFF_RESTART:
2059 set_pm_status_flag(PWROFF_FLAG);
2066 static void esd_action(void)
2068 const struct device_ops *touchscreen_ops = NULL;
2072 touchscreen_ops = find_device("touchscreen");
2074 if (!check_default(touchscreen_ops))
2075 touchscreen_ops->stop(NORMAL_MODE);
2076 backlight_ops->off(NORMAL_MODE);
2077 backlight_ops->on(NORMAL_MODE);
2078 if (!check_default(touchscreen_ops))
2079 touchscreen_ops->start(NORMAL_MODE);
2082 static void lcd_uevent_changed(struct udev_device *dev)
2084 const char *devpath;
2087 devpath = udev_device_get_devpath(dev);
2091 if (!fnmatch(LCD_ESD_PATH, devpath, 0)) {
2092 action = udev_device_get_action(dev);
2093 if (!strcmp(action, UDEV_CHANGE))
2098 static const struct uevent_handler lcd_uevent_ops = {
2099 .subsystem = LCD_EVENT_SUBSYSTEM,
2100 .uevent_func = lcd_uevent_changed,
2104 static void display_init(void *data)
2107 unsigned int flags = (WITHOUT_STARTNOTI | FLAG_X_DPMS);
2110 _I("Start power manager.");
2112 signal(SIGHUP, sig_hup);
2114 power_saving_func = default_saving_mode;
2116 /* load configutation */
2117 ret = config_parse(DISPLAY_CONF_FILE, display_load_config, &display_conf);
2119 _W("Failed to load '%s', use default value: %d",
2120 DISPLAY_CONF_FILE, ret);
2122 register_kernel_uevent_control(&lcd_uevent_ops);
2124 register_notifier(DEVICE_NOTIFIER_DELAYED_INIT, delayed_init_done);
2125 register_notifier(DEVICE_NOTIFIER_APPLICATION_BACKGROUND, display_app_background);
2126 register_notifier(DEVICE_NOTIFIER_APPLICATION_FOREGROUND, display_app_foreground);
2127 register_notifier(DEVICE_NOTIFIER_APPLICATION_TERMINATED, display_app_terminated);
2128 register_notifier(DEVICE_NOTIFIER_BATTERY_HEALTH, battery_health_changed);
2129 register_notifier(DEVICE_NOTIFIER_DISPLAY_BRIGHTNESS, display_brightness_changed);
2130 register_notifier(DEVICE_NOTIFIER_LCD_AUTOBRT_SENSING, display_auto_brightness_sensing);
2131 register_notifier(DEVICE_NOTIFIER_POWER_RESUME_FROM_ECHO_MEM, power_resume_from_echomem_callback);
2132 register_notifier(DEVICE_NOTIFIER_POWEROFF_TRIGGERED, poweroff_triggered_callback);
2134 init_save_userlock();
2136 for (i = INIT_SETTING; i < INIT_END; i++) {
2139 ret = init_setting(update_setting);
2141 case INIT_INTERFACE:
2142 if (display_conf.timeout_enable)
2143 get_lcd_timeout_from_settings();
2144 ret = init_sysfs(flags);
2148 ret = input_init_handler();
2150 pm_lock_detector_init();
2154 ret = init_pm_dbus();
2158 _E("Failed to init: %s", errMSG[i]);
2163 if (i == INIT_END) {
2164 display_ops_init(NULL);
2165 #ifdef ENABLE_PM_LOG
2168 init_lcd_operation();
2169 check_seed_status();
2171 /* In smd test, TSP should be turned off if display panel is not existed. */
2172 if (backlight_ops->get_lcd_power() == -ENOENT) {
2173 _I("Display panel is not existed.");
2174 lcd_direct_control(DPMS_OFF, NORMAL_MODE);
2175 exit_lcd_operation();
2178 /* wm_ready needs to be checked
2179 * since display manager can be launched later than deviced.
2180 * In the case, display cannot be turned on at the first booting */
2181 // wm_ready = check_wm_ready();
2183 if (is_lcdon_blocked() != LCDON_BLOCK_NONE)
2184 lcd_off_procedure(LCD_OFF_BY_EVENT);
2186 lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
2188 add_timer_for_dpms_init();
2191 if (display_conf.lcd_always_on) {
2192 _I("LCD always on.");
2193 trans_table[S_NORMAL][EVENT_TIMEOUT] = S_NORMAL;
2196 if (flags & WITHOUT_STARTNOTI) { /* start without noti */
2197 _I("Start Power managing without noti");
2199 * Lock lcd off until booting is done.
2200 * deviced guarantees all booting script is executing.
2201 * Last script of booting unlocks this suspend blocking state.
2203 if (disp_plgn->pm_lock_internal)
2204 disp_plgn->pm_lock_internal(INTERNAL_LOCK_BOOTING, LCD_OFF,
2205 STAY_CUR_STATE, DELAYED_INIT_WATING_TIME);
2207 /* Initial display state right after the booting done */
2208 if (is_lcdon_blocked())
2209 set_pm_cur_state(S_LCDOFF);
2211 set_pm_cur_state(S_NORMAL);
2212 ret = vconf_set_int(VCONFKEY_PM_STATE, get_pm_cur_state());
2214 _E("Failed to set vconf value for pm cur state: %d", vconf_get_ext_errno());
2216 status = DEVICE_OPS_STATUS_START;
2217 if (display_conf.timeout_enable) {
2218 timeout = states[S_NORMAL].timeout;
2219 /* check minimun lcd on time */
2220 if (timeout < SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT))
2221 timeout = SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT);
2223 if (disp_plgn->pm_lock_internal)
2224 disp_plgn->pm_lock_internal(INTERNAL_LOCK_BOOTING, LCD_NORMAL,
2225 STAY_CUR_STATE, timeout);
2230 if (display_conf.input_support)
2231 if (CHECK_OPS(keyfilter_ops, init))
2232 keyfilter_ops->init();
2234 set_display_init_direction(display_conf.display_init_direction);
2238 static void display_exit(void *data)
2242 status = DEVICE_OPS_STATUS_STOP;
2244 /* Set current state to S_NORMAL */
2245 set_pm_cur_state(S_NORMAL);
2246 set_setting_pmstate(get_pm_cur_state());
2247 /* timeout is not needed */
2248 reset_timeout(TIMEOUT_NONE);
2250 if (CHECK_OPS(keyfilter_ops, exit))
2251 keyfilter_ops->exit();
2253 unregister_kernel_uevent_control(&lcd_uevent_ops);
2255 display_ops_exit(NULL);
2257 for (i = i - 1; i >= INIT_SETTING; i--) {
2262 case INIT_INTERFACE:
2266 unregister_notifier(DEVICE_NOTIFIER_DELAYED_INIT, delayed_init_done);
2267 unregister_notifier(DEVICE_NOTIFIER_APPLICATION_BACKGROUND, display_app_background);
2268 unregister_notifier(DEVICE_NOTIFIER_APPLICATION_FOREGROUND, display_app_foreground);
2269 unregister_notifier(DEVICE_NOTIFIER_APPLICATION_TERMINATED, display_app_terminated);
2270 unregister_notifier(DEVICE_NOTIFIER_BATTERY_HEALTH, battery_health_changed);
2271 unregister_notifier(DEVICE_NOTIFIER_DISPLAY_BRIGHTNESS, display_brightness_changed);
2272 unregister_notifier(DEVICE_NOTIFIER_POWER_RESUME_FROM_ECHO_MEM, power_resume_from_echomem_callback);
2278 exit_lcd_operation();
2279 free_lock_info_list();
2281 /* free display service */
2282 display_service_free();
2284 _I("Stop power manager.");
2287 static int display_start(enum device_flags flags)
2289 const struct display_ops *enhance_ops = NULL;
2293 if (flags & NORMAL_MODE) {
2294 if (flags & LCD_PANEL_OFF_MODE)
2296 backlight_ops->standby(true);
2299 backlight_ops->on(flags);
2300 FIND_DISPLAY(enhance_ops, "enhance");
2301 if (enhance_ops && enhance_ops->func)
2302 enhance_ops->func(RESTORE_ENHANCE_OUTDOOR, &on);
2306 /* CORE LOGIC MODE */
2307 if (!(flags & CORE_LOGIC_MODE))
2310 if (status == DEVICE_OPS_STATUS_START)
2313 if (display_probe(NULL) < 0)
2321 static int display_stop(enum device_flags flags)
2324 if (flags & NORMAL_MODE || flags & FORCE_OFF_MODE) {
2325 backlight_ops->off(flags);
2329 /* CORE LOGIC MODE */
2330 if (!(flags & CORE_LOGIC_MODE))
2333 if (status == DEVICE_OPS_STATUS_STOP)
2341 static int display_status(void)
2346 static const struct device_ops display_device_ops = {
2347 .priority = DEVICE_PRIORITY_HIGH,
2348 DECLARE_NAME_LEN("display"),
2349 .probe = display_probe,
2350 .init = display_init,
2351 .exit = display_exit,
2352 .start = display_start,
2353 .stop = display_stop,
2354 .status = display_status,
2357 DEVICE_OPS_REGISTER(&display_device_ops)
2359 static void __CONSTRUCTOR__ initialize(void)
2361 disp_plgn = get_var_display_plugin();
2363 _E("Failed to get display plugin variable.");
2365 backlight_ops = get_var_backlight_ops();
2367 _E("Failed to get backlight operator variable.");
2369 battery_plgn = get_var_battery_plugin();
2371 _E("Failed to get battery plugin variable.");