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 <device/display-internal.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 "apps/apps.h"
55 #include "extcon/extcon.h"
56 #include "battery/power-supply.h"
57 #include "power/power-off.h"
58 #include "power/power-suspend.h"
59 #include "power/power-boot.h"
60 #include "power/power-doze.h"
61 #include "display-dpms.h"
62 #include "display-signal.h"
63 #include "display-lock.h"
64 #include "shared/plugin.h"
66 #define DISPLAY_CONF_FILE "/etc/deviced/display.conf"
69 * @addtogroup POWER_MANAGER
73 #define LOCK_SCREEN_INPUT_TIMEOUT 10000
74 #define LOCK_SCREEN_CONTROL_TIMEOUT 5000
75 #define ALWAYS_ON_TIMEOUT 360000000
76 #define LATE_LCD_TRANSIT 1
78 #define GESTURE_STR "gesture"
79 #define POWER_KEY_STR "powerkey"
80 #define TOUCH_STR "touch"
81 #define EVENT_STR "event"
82 #define TIMEOUT_STR "timeout"
83 #define PROXI_STR "proximity"
84 #define PALM_STR "palm"
85 #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);
97 static void (*power_saving_func) (int onoff);
98 static enum device_ops_status status = DEVICE_OPS_STATUS_UNINIT;
100 static guint timeout_src_id;
101 static int system_wakeup_flag = false;
102 static unsigned int custom_normal_timeout = 0;
103 static unsigned int custom_dim_timeout = 0;
104 int custom_holdkey_block = false;
105 static char *custom_change_name;
106 static bool hallic_open = true;
107 static guint lock_timeout_id;
108 static guint transit_timer;
109 static int lock_screen_timeout = LOCK_SCREEN_INPUT_TIMEOUT;
110 static struct timeval lcdon_tv;
111 static int lcd_paneloff_mode = false;
112 static int stay_touchscreen_off = false;
115 * The two variables(lcdon_broadcast, pmstate_suspend) must be set initial
116 * state because it should be sent from previous state at booting time.
118 static bool lcdon_broadcast = true;
120 static bool touch_blocked = false;
122 /* default transition, action fuctions */
123 static int default_trans(int evt);
124 static int default_action(int timeout);
125 static int default_check(int curr, int next);
127 static gboolean del_normal_cond(void *data);
128 static gboolean del_dim_cond(void *data);
129 static gboolean del_off_cond(void *data);
131 static int default_proc_change_state(unsigned int cond, pid_t pid);
132 static int (*proc_change_state)(unsigned int cond, pid_t pid) = default_proc_change_state;
134 static struct state states[S_END] = {
135 { S_START, "S_START", NULL, NULL, NULL, NULL },
136 { S_NORMAL, "S_NORMAL", default_trans, default_action, default_check, del_normal_cond },
137 { S_LCDDIM, "S_LCDDIM", default_trans, default_action, default_check, del_dim_cond },
138 { S_LCDOFF, "S_LCDOFF", default_trans, default_action, default_check, del_off_cond },
139 { S_STANDBY, "S_STANDBY", NULL, NULL, NULL, NULL },
140 { S_SLEEP, "S_SLEEP", default_trans, default_action, default_check, NULL },
141 { S_POWEROFF, "S_POWEROFF", NULL, NULL, NULL, NULL },
144 static int trans_table[S_END][EVENT_END] = {
146 { S_START, S_START }, /* S_START */
147 { S_LCDDIM, S_NORMAL }, /* S_NORMAL */
148 { S_LCDOFF, S_NORMAL }, /* S_LCDDIM */
149 { S_SLEEP, S_NORMAL }, /* S_LCDOFF */
150 { S_SLEEP, S_STANDBY }, /* S_STANDBY */
151 { S_LCDOFF, S_NORMAL }, /* S_SLEEP */
152 { S_POWEROFF, S_POWEROFF }, /* S_POWEROFF */
155 #define SHIFT_UNLOCK 4
156 #define SHIFT_CHANGE_STATE 7
157 #define CHANGE_STATE_BIT 0xF00 /* 1111 0000 0000 */
158 #define SHIFT_LOCK_FLAG 16
159 #define SHIFT_CHANGE_TIMEOUT 20
160 #define CUSTOM_TIMEOUT_BIT 0x1
161 #define CUSTOM_HOLDKEY_BIT 0x2
162 #define HOLD_KEY_BLOCK_BIT 0x1
163 #define TIMEOUT_NONE (-1)
165 #define S_COVER_TIMEOUT 8000
166 #define GET_HOLDKEY_BLOCK_STATE(x) ((x >> SHIFT_LOCK_FLAG) & HOLD_KEY_BLOCK_BIT)
167 #define DELAYED_INIT_WATING_TIME 60000 /* 1 minute */
169 #define LOCK_SCREEN_WATING_TIME 300 /* 0.3 second */
170 #define LONG_PRESS_INTERVAL 2 /* 2 seconds */
171 #define SAMPLING_INTERVAL 1 /* 1 sec */
172 #define BRIGHTNESS_CHANGE_STEP 10
173 #define LCD_ALWAYS_ON 0
174 #define ACCEL_SENSOR_ON 1
175 #define CONTINUOUS_SAMPLING 1
176 #define LCDOFF_TIMEOUT 300 /* milli second */
178 #define DIFF_TIMEVAL_MS(a, b) \
179 (((a.tv_sec * 1000000 + a.tv_usec) - \
180 (b.tv_sec * 1000000 + b.tv_usec)) \
183 static struct display_config display_conf = {
184 .lock_wait_time = LOCK_SCREEN_WATING_TIME,
185 .longpress_interval = LONG_PRESS_INTERVAL,
186 .lightsensor_interval = SAMPLING_INTERVAL,
187 .lcdoff_timeout = LCDOFF_TIMEOUT,
188 .pm_default_brightness = 80,
189 .brightness_change_step = BRIGHTNESS_CHANGE_STEP,
190 .lcd_always_on = LCD_ALWAYS_ON,
192 .framerate_app = {0, 0, 0, 0},
193 .control_display = 0,
194 .powerkey_doublepress = 0,
195 .accel_sensor_on = ACCEL_SENSOR_ON,
196 .continuous_sampling = CONTINUOUS_SAMPLING,
197 .timeout_enable = true,
198 .input_support = true,
199 .lockcheck_timeout = 600,
200 .aod_enter_level = 40,
202 .touch_wakeup = false,
203 .display_on_usb_conn_changed = true,
206 struct display_function_info display_info = {
207 .update_auto_brightness = NULL,
208 .set_autobrightness_min = NULL,
209 .reset_autobrightness_min = NULL,
210 .face_detection = NULL,
213 inline struct display_config* get_var_display_config()
215 return &display_conf;
218 inline struct state* state_st(enum state_t state)
220 return &states[state];
223 guint get_transition_timer(void)
225 return timeout_src_id;
228 void change_state_action(enum state_t state, int (*func)(int timeout))
230 _I("[%s] 'action' is changed.", states[state].name);
231 states[state].action = func;
234 void change_state_trans(enum state_t state, int (*func)(int evt))
236 _I("[%s] 'trans' is changed.", states[state].name);
237 states[state].trans = func;
240 void change_state_check(enum state_t state, int (*func)(int curr, int next))
242 _I("[%s] 'check' is changed.", states[state].name);
243 states[state].check = func;
246 void change_state_name(enum state_t state, const char *name)
248 _I("[%s] 'name' is changed.", states[state].name);
249 states[state].name = name;
252 void change_trans_table(enum state_t state, enum state_t next)
254 _I("[%s] 'timeout trans table' is changed.", states[state].name);
255 trans_table[state][EVENT_TIMEOUT] = next;
258 void change_proc_change_state(int (*func)(unsigned int cond, pid_t pid))
260 _I("'proc change state' is changed.");
261 proc_change_state = func;
264 static int display_brightness_changed(void *data)
268 brt = DATA_VALUE_INT(data);
270 ret = gdbus_signal_emit(NULL,
271 DEVICED_PATH_DISPLAY,
272 DEVICED_INTERFACE_DISPLAY,
274 g_variant_new("(i)", brt));
276 _E("Failed to send dbus signal Brightness.");
281 static int display_auto_brightness_sensing(void *data)
286 g_source_remove(transit_timer);
292 static const char* __device_flags_to_string(enum device_flags flags)
294 if (flags & LCD_ON_BY_GESTURE)
296 else if (flags & (LCD_ON_BY_POWER_KEY | LCD_OFF_BY_POWER_KEY))
297 return POWER_KEY_STR;
298 else if (flags & (LCD_ON_BY_EVENT | LCD_OFF_BY_EVENT))
300 else if (flags & LCD_ON_BY_TOUCH)
302 else if (flags & LCD_OFF_BY_TIMEOUT)
308 static unsigned long get_lcd_on_flags(void)
310 unsigned long flags = NORMAL_MODE;
312 if (lcd_paneloff_mode)
313 flags |= LCD_PANEL_OFF_MODE;
315 if (ambient_get_condition() == true) {
316 flags |= AMBIENT_MODE;
317 flags |= LCD_PHASED_TRANSIT_MODE;
323 bool touch_event_blocked(void)
325 return touch_blocked;
328 static gboolean late_transit_on(void *data)
331 return G_SOURCE_REMOVE;
333 g_source_remove(transit_timer);
336 backlight_ops->transit_state(DPMS_ON);
337 return G_SOURCE_REMOVE;
340 void lcd_on_procedure(int state, enum device_flags flag)
343 const struct device_ops *ops = NULL;
344 unsigned long flags = get_lcd_on_flags();
348 * Display on procedure
350 * step 2. broadcast lcd on signal with cause
351 * step 3. set brightness
352 * step 4. set pmstate of vconf
353 * step 5. display on operate
355 * - b. TSP(touch screen) and touchkey enable
356 * step 6. broadcast lcd on complete signal
357 * step 7. key backlight enable
361 _I("[lcdstep] 0x%lx", flags);
363 if (flags & AMBIENT_MODE) {
364 if (ambient_get_state() == false && backlight_ops->get_lcd_power() == DPMS_ON)
366 ambient_set_state(false);
369 /* send LCDOn dbus signal */
370 if (!lcdon_broadcast)
371 broadcast_lcd_on(SIGNAL_PRE, flags);
373 if (!(flags & LCD_PHASED_TRANSIT_MODE)) {
374 /* Update brightness level */
375 if (state == LCD_DIM)
376 backlight_ops->dim();
377 else if (state == LCD_NORMAL)
378 backlight_ops->update();
381 if (state == LCD_NORMAL)
382 set_setting_pmstate(S_NORMAL);
383 else if (state == LCD_DIM)
384 set_setting_pmstate(S_LCDDIM);
386 SYS_G_LIST_FOREACH(lcdon_ops, l, ops)
389 if (!lcdon_broadcast) {
390 broadcast_lcd_on(SIGNAL_POST, flags);
391 if (flags & LCD_PHASED_TRANSIT_MODE)
392 transit_timer = g_timeout_add_seconds(LATE_LCD_TRANSIT,
393 late_transit_on, NULL);
394 lcdon_broadcast = true;
397 if (CHECK_OPS(keyfilter_ops, backlight_enable))
398 keyfilter_ops->backlight_enable(true);
400 touch_blocked = false;
403 static unsigned long get_lcd_off_flags(void)
405 unsigned long flags = NORMAL_MODE;
407 if (ambient_get_condition() == true) {
408 flags |= AMBIENT_MODE;
409 flags |= LCD_PHASED_TRANSIT_MODE;
412 if (stay_touchscreen_off)
413 flags |= TOUCH_SCREEN_OFF_MODE;
418 inline void lcd_off_procedure(enum device_flags flag)
421 const struct device_ops *ops = NULL;
422 unsigned long flags = get_lcd_off_flags();
426 * Display off procedure
427 * step 0. enhance mode off using nofity (e.g mdnie, HBM, LBM)
428 * step 1. broadcast lcd off signal with cause
429 * step 2. set pmstate of vconf
430 * step 3. display off operate
432 * - b. TSP(touch screen) and touchkey disable
433 * step 4. broadcast lcd off complete siganl
434 * step 5. enter doze mode if it is enabled
436 _I("[lcdstep] 0x%lx", flags);
440 device_notify(DEVICE_NOTIFIER_LCD_OFF, NULL);
442 if (lcdon_broadcast) {
443 broadcast_lcd_off(SIGNAL_PRE, flags);
444 lcdon_broadcast = false;
449 touch_blocked = true;
451 set_setting_pmstate(S_LCDOFF);
453 if (CHECK_OPS(keyfilter_ops, backlight_enable))
454 keyfilter_ops->backlight_enable(false);
457 g_source_remove(transit_timer);
461 if (flags & LCD_PHASED_TRANSIT_MODE)
462 backlight_ops->transit_state(DPMS_OFF);
464 SYS_G_LIST_FOREACH(lcdon_ops, l, ops)
467 if (flags & AMBIENT_MODE) {
468 broadcast_lcd_off_late(flags);
470 broadcast_lcd_off(SIGNAL_POST, flags);
471 device_notify(DEVICE_NOTIFIER_LCD_OFF_COMPLETE, NULL);
477 void set_stay_touchscreen_off(int val)
479 _I("Stay touch screen off: %d", val);
480 stay_touchscreen_off = val;
482 if (disp_plgn->pm_change_internal)
483 disp_plgn->pm_change_internal(INTERNAL_LOCK_PM, LCD_NORMAL);
486 void set_lcd_paneloff_mode(int val)
488 _I("Lcd paneloff mode: %d", val);
489 lcd_paneloff_mode = val;
491 if (disp_plgn->pm_change_internal)
492 disp_plgn->pm_change_internal(INTERNAL_LOCK_PM, LCD_NORMAL);
495 int low_battery_state(int val)
498 case VCONFKEY_SYSMAN_BAT_POWER_OFF:
499 case VCONFKEY_SYSMAN_BAT_CRITICAL_LOW:
500 case VCONFKEY_SYSMAN_BAT_REAL_POWER_OFF:
506 int get_hallic_open(void)
511 void get_pname(pid_t pid, char *pname)
516 if (pid >= INTERNAL_LOCK_BASE)
517 snprintf(buf, PATH_MAX, "/proc/%d/cmdline", getpid());
519 snprintf(buf, PATH_MAX, "/proc/%d/cmdline", pid);
521 cmdline = open(buf, O_RDONLY);
524 _E("Process(%d) does not exist now(may be dead without unlock).", pid);
528 r = read(cmdline, pname, PATH_MAX);
529 if ((r >= 0) && (r < PATH_MAX))
537 static void del_state_cond(void *data, enum state_t state)
539 PmLockNode *tmp = NULL;
545 /* A passed data is a pid_t type data, not a 64bit data. */
546 pid = (pid_t)((intptr_t)data);
547 _I("delete prohibit %s condition by timeout (%d)", states[state].name, pid);
549 if (pid == INTERNAL_LOCK_AMBIENT)
550 ambient_check_invalid_state(pid);
552 tmp = find_node(state, pid);
553 del_node(state, tmp);
554 set_unlock_time(pid, state);
556 /* Change state only when the two conditions below are satisfied.
557 * 1. There should be no running state-transition timer
558 * 2. Released lock is one of the pm_cur_state's lock
559 * This emulates already expired transition timer */
560 if (!timeout_src_id && get_pm_cur_state() == state)
561 states[get_pm_cur_state()].trans(EVENT_TIMEOUT);
563 if (state == S_LCDOFF)
564 set_process_active(false, pid);
567 static gboolean del_normal_cond(void *data)
569 del_state_cond(data, S_NORMAL);
570 return G_SOURCE_REMOVE;
573 static gboolean del_dim_cond(void *data)
575 del_state_cond(data, S_LCDDIM);
576 return G_SOURCE_REMOVE;
579 static gboolean del_off_cond(void *data)
581 del_state_cond(data, S_LCDOFF);
582 return G_SOURCE_REMOVE;
585 /* timeout handler */
586 gboolean timeout_handler(void *data)
588 _I("Time out state %s", states[get_pm_cur_state()].name);
590 if (timeout_src_id) {
591 g_source_remove(timeout_src_id);
595 states[get_pm_cur_state()].trans(EVENT_TIMEOUT);
596 return G_SOURCE_REMOVE;
599 void reset_timeout(int timeout)
601 if (!display_conf.timeout_enable)
604 if ((get_pm_cur_state() == S_LCDOFF)
605 && (is_emulator() == true || timeout_sleep_support == false))
608 _I("Reset timeout(%d ms).", timeout);
609 if (timeout_src_id != 0) {
610 g_source_remove(timeout_src_id);
614 if (trans_table[get_pm_cur_state()][EVENT_TIMEOUT] == get_pm_cur_state())
618 timeout_src_id = g_timeout_add(timeout,
619 timeout_handler, NULL);
620 else if (timeout == 0)
621 states[get_pm_cur_state()].trans(EVENT_TIMEOUT);
624 /* get configurations from setting */
625 static int get_lcd_timeout_from_settings(void)
630 for (i = 0; i < S_END; i++) {
631 switch (states[i].state) {
633 get_run_timeout(&val);
636 get_dim_timeout(&val);
639 val = display_conf.lcdoff_timeout;
642 /* This state doesn't need to set time out. */
647 states[i].timeout = val;
649 _I("State(%s) timeout(%d) ms", states[i].name,
656 static void update_display_time(void)
658 int run_timeout, val;
660 /* first priority : s cover */
662 states[S_NORMAL].timeout = S_COVER_TIMEOUT;
663 _I("S cover closed: Timeout(%d ms) is set by normal.",
668 /* second priority : custom timeout */
669 if (custom_normal_timeout > 0) {
670 states[S_NORMAL].timeout = custom_normal_timeout;
671 states[S_LCDDIM].timeout = custom_dim_timeout;
672 _I("CUSTOM : timeout is set by normal(%d ms), dim(%d ms)",
673 custom_normal_timeout, custom_dim_timeout);
677 /* third priority : lock state */
678 if ((__get_lock_screen_state() == VCONFKEY_IDLE_LOCK) &&
679 !get_lock_screen_bg_state()) {
680 /* timeout is different according to key or event. */
681 states[S_NORMAL].timeout = lock_screen_timeout;
682 _I("LOCK: Timeout(%d ms) is set by normal.",
683 lock_screen_timeout);
687 /* default setting */
688 get_run_timeout(&run_timeout);
691 * if the run_timeout is zero, it regards AlwaysOn state
693 if (run_timeout == 0 || display_conf.lcd_always_on) {
694 run_timeout = ALWAYS_ON_TIMEOUT;
695 _I("LCD always on.");
698 states[S_NORMAL].timeout = run_timeout;
700 get_dim_timeout(&val);
701 states[S_LCDDIM].timeout = val;
703 _I("Normal: NORMAL timeout is set by %d ms", states[S_NORMAL].timeout);
704 _I("Normal: DIM timeout is set by %d ms", states[S_LCDDIM].timeout);
707 static void update_display_locktime(int time)
709 lock_screen_timeout = time;
710 update_display_time();
713 void set_dim_state(bool on)
715 _I("Dim state is %d.", on);
716 update_display_time();
717 states[get_pm_cur_state()].trans(EVENT_INPUT);
720 void lcd_on_direct(enum device_flags flags)
722 if (pm_get_power_lock_support()
723 && (get_pm_cur_state() == S_SLEEP)) {
724 broadcast_pm_wakeup();
725 power_acquire_wakelock();
726 set_pm_cur_state(S_NORMAL);
729 _D("lcd is on directly");
730 gettimeofday(&lcdon_tv, NULL);
731 lcd_on_procedure(LCD_NORMAL, flags);
733 update_display_locktime(LOCK_SCREEN_INPUT_TIMEOUT);
736 static inline bool check_lcd_is_on(void)
738 if (backlight_ops->get_lcd_power() != DPMS_ON)
744 static gboolean timer_refresh_cb(gpointer data)
748 /* state transition */
749 set_pm_old_state(get_pm_cur_state());
750 set_pm_cur_state(S_NORMAL);
751 st = &states[get_pm_cur_state()];
754 st->action(st->timeout);
759 int custom_lcdon(int timeout)
766 if (check_lcd_is_on() == false)
767 lcd_on_direct(LCD_ON_BY_GESTURE);
769 _I("Custom lcd on timeout(%d ms).", timeout);
770 if (set_custom_lcdon_timeout(timeout) == true)
771 update_display_time();
773 /* state transition */
774 set_pm_old_state(get_pm_cur_state());
775 set_pm_cur_state(S_NORMAL);
776 st = &states[get_pm_cur_state()];
780 st->action(st->timeout);
782 g_idle_add(timer_refresh_cb, NULL);
787 int custom_lcdoff(enum device_flags flag)
791 check_processes(S_NORMAL);
792 check_processes(S_LCDDIM);
794 /* check holdkey block flag in lock node */
795 if (check_lock_condition(S_NORMAL) || check_lock_condition(S_LCDDIM)) {
797 * When another proccess is normal lock, device is received call then,
798 * call app can be changed to lcd state by proximity.
799 * If proximity is near then normal lock will be unlocked.
801 if (flag & LCD_OFF_BY_PROXIMITY) {
802 _I("custom lcd off by proximity, delete normal lock");
803 delete_condition(S_NORMAL);
805 _I("skip custom lcd off");
810 _I("custom lcd off by flag(%d)", flag);
811 if (backlight_ops->get_lcd_power() == DPMS_ON)
812 lcd_off_procedure(flag);
814 if (set_custom_lcdon_timeout(0) == true)
815 update_display_time();
817 /* state transition */
818 set_pm_old_state(get_pm_cur_state());
819 set_pm_cur_state(S_LCDOFF);
820 st = &states[get_pm_cur_state()];
824 st->action(st->timeout);
829 int display_on_by_reason(const char *reason, int timeout)
835 str_len = strlen(reason);
837 if (!strncmp(reason, GESTURE_STR, str_len))
838 flag = LCD_ON_BY_GESTURE;
839 else if (!strncmp(reason, EVENT_STR, str_len))
840 flag = LCD_ON_BY_EVENT;
842 _E("Reason is unknown(%s)", reason);
847 _E("Cannot setting timeout %d", timeout);
851 if (check_lcd_is_on() == false)
854 _I("platform lcd on by %s (%d ms)", reason, timeout);
855 if (set_custom_lcdon_timeout(timeout) == true)
856 update_display_time();
858 /* state transition */
859 set_pm_old_state(get_pm_cur_state());
860 set_pm_cur_state(S_NORMAL);
861 st = &states[get_pm_cur_state()];
865 st->action(st->timeout);
870 int display_off_by_reason(const char *reason)
876 str_len = strlen(reason);
878 if (!strncmp(reason, GESTURE_STR, str_len)) {
879 check_processes(S_NORMAL);
880 check_processes(S_LCDDIM);
882 /* check holdkey block flag in lock node */
883 if (check_lock_condition(S_NORMAL) || check_lock_condition(S_LCDDIM)) {
884 _I("skip platform lcd off by gesture");
887 flag = LCD_OFF_BY_GESTURE;
888 } else if (!strncmp(reason, PALM_STR, str_len)) {
889 delete_condition(S_NORMAL);
890 delete_condition(S_LCDDIM);
892 flag = LCD_OFF_BY_PALM;
894 _E("Reason is unknown(%s)", reason);
898 _I("platform lcd off by %s", reason);
899 if (backlight_ops->get_lcd_power() == DPMS_ON)
900 lcd_off_procedure(flag);
902 /* state transition */
903 set_pm_old_state(get_pm_cur_state());
904 set_pm_cur_state(S_LCDOFF);
905 st = &states[get_pm_cur_state()];
909 st->action(st->timeout);
914 static void default_proc_change_state_action(enum state_t next, int timeout)
918 set_pm_old_state(get_pm_cur_state());
919 set_pm_cur_state(next);
921 st = &states[get_pm_cur_state()];
923 if (st && st->action) {
925 st->action(st->timeout);
931 static int default_proc_change_state(unsigned int cond, pid_t pid)
935 next = GET_COND_STATE(cond);
936 _I("Change process(%d) state to %s.", pid, states[next].name);
940 if (check_lcd_is_on() == false)
941 lcd_on_direct(LCD_ON_BY_EVENT);
942 update_display_locktime(LOCK_SCREEN_CONTROL_TIMEOUT);
943 default_proc_change_state_action(next, -1);
946 default_proc_change_state_action(next, -1);
949 if (backlight_ops->get_lcd_power() == DPMS_ON)
950 lcd_off_procedure(LCD_OFF_BY_EVENT);
951 if (set_custom_lcdon_timeout(0))
952 update_display_time();
953 default_proc_change_state_action(next, -1);
956 _I("Dangerous requests.");
957 /* at first LCD_OFF and then goto sleep */
958 /* state transition */
959 default_proc_change_state_action(S_LCDOFF, TIMEOUT_NONE);
960 delete_condition(S_NORMAL);
961 delete_condition(S_LCDDIM);
962 delete_condition(S_LCDOFF);
963 if (lcdon_broadcast) {
964 _I("broadcast lcd off signal at non-lcd device");
965 broadcast_lcd_off(SIGNAL_PRE, 0);
966 broadcast_lcd_off(SIGNAL_POST, 0);
968 default_proc_change_state_action(S_SLEEP, TIMEOUT_NONE);
978 static void proc_condition_lock(PMMsg *data)
981 guint cond_timeout_id = 0;
982 char pname[PATH_MAX];
983 pid_t pid = data->pid;
985 int holdkey_block, ret;
988 const char *lock_type = NULL;
990 state = GET_COND_STATE(data->cond);
991 if (state == S_START)
994 flags = GET_COND_FLAG(data->cond);
995 get_pname(pid, pname);
997 if ((state == S_LCDOFF) && (get_pm_cur_state() == S_SLEEP) &&
998 (pm_get_power_lock() == POWER_UNLOCK))
999 proc_change_state(data->cond, INTERNAL_LOCK_PM);
1001 if (data->timeout > 0) {
1002 /* To pass a pid_t data through the timer infrastructure
1003 * without memory allocation, a pid_t data becomes typecast
1004 * to intptr_t and void *(64bit) type. */
1005 cond_timeout_id = g_timeout_add(
1007 states[state].timeout_cb,
1008 (void*)((intptr_t)pid));
1009 if (!cond_timeout_id)
1010 _E("Failed to register display timer.");
1013 holdkey_block = GET_COND_FLAG(data->cond) & PM_FLAG_BLOCK_HOLDKEY;
1015 tmp = find_node(state, pid);
1017 tmp = add_node(state, pid, cond_timeout_id, holdkey_block);
1019 _E("Failed to acquire lock, state: %d, pid: %d.", state, pid);
1023 update_lock_timer(data, tmp, cond_timeout_id);
1024 tmp->holdkey_block = holdkey_block;
1027 if (state == S_LCDOFF)
1028 set_process_active(true, pid);
1030 _I("[%s] locked by %5d with %u ms", states[state].name, pid, data->timeout);
1032 if (pid < INTERNAL_LOCK_BASE) {
1034 if (state == S_LCDOFF)
1035 lock_type = PM_LCDOFF_STR;
1036 else if (state == S_LCDDIM)
1037 lock_type = PM_LCDDIM_STR;
1038 else if (state == S_NORMAL)
1039 lock_type = PM_LCDON_STR;
1042 /* power lock signal */
1043 ret = gdbus_signal_emit(NULL,
1044 DEVICED_PATH_DISPLAY,
1045 DEVICED_INTERFACE_DISPLAY,
1047 g_variant_new("(sii)", lock_type, pid, (int)data->timeout));
1049 _E("Failed to send dbus signal PowerLock.");
1053 _SD("be requested LOCK info pname(%s), holdkeyblock(%d) flags(%d)",
1054 pname, holdkey_block, flags);
1055 set_lock_time(pid, pname, state);
1057 device_notify(DEVICE_NOTIFIER_DISPLAY_LOCK, (void *)&value);
1060 static void proc_condition_unlock(PMMsg *data)
1062 pid_t pid = data->pid;
1065 char pname[PATH_MAX];
1069 const char *lock_type = NULL;
1071 state = GET_COND_STATE(data->cond);
1075 flags = GET_COND_FLAG(data->cond);
1076 get_pname(pid, pname);
1078 tmp = find_node(state, pid);
1079 del_node(state, tmp);
1081 if (state == S_LCDOFF)
1082 set_process_active(false, pid);
1084 _I("[%s] unlocked by %5d", states[state].name, pid);
1086 if (pid < INTERNAL_LOCK_BASE) {
1088 if (state == S_LCDOFF)
1089 lock_type = PM_LCDOFF_STR;
1090 else if (state == S_LCDDIM)
1091 lock_type = PM_LCDDIM_STR;
1092 else if (state == S_NORMAL)
1093 lock_type = PM_LCDON_STR;
1096 /* power unlock signal */
1097 ret = gdbus_signal_emit(NULL,
1098 DEVICED_PATH_DISPLAY,
1099 DEVICED_INTERFACE_DISPLAY,
1101 g_variant_new("(sii)", lock_type, pid, (int)data->timeout));
1103 _E("Failed to send dbus signal PowerUnlock.");
1107 _SD("be requested UNLOCK info pname(%s) flag(%d)", pname, flags);
1108 set_unlock_time(pid, state);
1110 device_notify(DEVICE_NOTIFIER_DISPLAY_LOCK, (void *)&value);
1113 static int proc_condition(PMMsg *data)
1117 if (IS_COND_REQUEST_LOCK(data->cond))
1118 proc_condition_lock(data);
1120 if (IS_COND_REQUEST_UNLOCK(data->cond))
1121 proc_condition_unlock(data);
1123 if (!display_conf.timeout_enable)
1126 flags = GET_COND_FLAG(data->cond);
1128 /* guard time for suspend */
1129 if (get_pm_cur_state() == S_LCDOFF)
1130 reset_timeout(states[S_LCDOFF].timeout);
1132 if (flags & PM_FLAG_RESET_TIMER)
1133 reset_timeout(states[get_pm_cur_state()].timeout);
1136 if (!timeout_src_id)
1137 states[get_pm_cur_state()].trans(EVENT_TIMEOUT);
1142 void update_lcdoff_source(int source)
1147 case VCONFKEY_PM_LCDOFF_BY_TIMEOUT:
1148 _I("LCD OFF by timeout.");
1150 case VCONFKEY_PM_LCDOFF_BY_POWERKEY:
1151 _I("LCD OFF by powerkey.");
1154 _E("Invalid value(%d).", source);
1157 ret = vconf_set_int(VCONFKEY_PM_LCDOFF_SOURCE, source);
1159 _E("Failed to set vconf value for lcd off source: %d", vconf_get_ext_errno());
1162 void print_info(int fd)
1165 char buf[PATH_MAX + 255];
1168 char pname[PATH_MAX];
1176 snprintf(buf, sizeof(buf),
1177 "\n==========================================="
1178 "===========================\n");
1179 ret = write(fd, buf, strlen(buf));
1181 _E("Write() failed: %d", errno);
1182 snprintf(buf, sizeof(buf), "Timeout Info: Run[%dms] Dim[%dms] Off[%dms]\n",
1183 states[S_NORMAL].timeout,
1184 states[S_LCDDIM].timeout, states[S_LCDOFF].timeout);
1185 ret = write(fd, buf, strlen(buf));
1187 _E("Write() failed: %d", errno);
1189 snprintf(buf, sizeof(buf), "Tran. Locked : %s %s %s\n",
1190 (get_trans_condition() & MASK_NORMAL) ? states[S_NORMAL].name : "-",
1191 (get_trans_condition() & MASK_DIM) ? states[S_LCDDIM].name : "-",
1192 (get_trans_condition() & MASK_OFF) ? states[S_LCDOFF].name : "-");
1193 ret = write(fd, buf, strlen(buf));
1195 _E("Write() failed: %d", errno);
1197 snprintf(buf, sizeof(buf), "Current State: %s\n",
1198 states[get_pm_cur_state()].name);
1199 ret = write(fd, buf, strlen(buf));
1201 _E("Write() failed: %d", errno);
1203 snprintf(buf, sizeof(buf), "Current Lock Conditions: \n");
1204 ret = write(fd, buf, strlen(buf));
1206 _E("Write() failed: %d", errno);
1208 for (s_index = S_NORMAL; s_index < S_END; s_index++) {
1209 SYS_G_LIST_FOREACH(get_cond_head(s_index), elem, t) {
1210 get_pname((pid_t)t->pid, pname);
1211 ctime_r(&t->time, time_buf);
1212 time_buf[strlen(time_buf) - 1] = 0;
1213 snprintf(buf, sizeof(buf),
1214 " %d: [%s] locked by pid %d %s %s\n",
1215 i++, states[s_index].name, t->pid, pname, time_buf);
1216 ret = write(fd, buf, strlen(buf));
1218 _E("Write() failed: %d", errno);
1222 print_lock_info_list(fd);
1224 #ifdef ENABLE_PM_LOG
1225 pm_history_print(fd, 250);
1229 void save_display_log(const char *path)
1236 _D("internal state is saved!");
1239 ctime_r(&now_time, time_buf);
1240 time_buf[strlen(time_buf) - 1] = 0;
1242 fd = open(path, O_CREAT | O_TRUNC | O_WRONLY, 0644);
1244 snprintf(buf, sizeof(buf),
1245 "\npm_state_log now-time : %d(s) %s\n\n",
1246 (int)now_time, time_buf);
1247 ret = write(fd, buf, strlen(buf));
1249 _E("write() failed (%d)", errno);
1251 snprintf(buf, sizeof(buf), "pm_status_flag: %#x\n", get_pm_status_flag());
1252 ret = write(fd, buf, strlen(buf));
1254 _E("write() failed (%d)", errno);
1256 if (disp_plgn->get_lock_screen_state ) {
1257 snprintf(buf, sizeof(buf), "screen lock status : %d\n",
1258 disp_plgn->get_lock_screen_state());
1259 ret = write(fd, buf, strlen(buf));
1261 _E("write() failed (%d)", errno);
1267 fd = open("/dev/console", O_WRONLY);
1274 /* SIGHUP signal handler
1275 * For debug... print info to syslog
1277 static void sig_hup(int signo)
1279 _I("received sig hub %d", signo);
1284 int check_lcdoff_direct(void)
1286 int ret, lock, cradle;
1289 if (get_pm_old_state() != S_NORMAL)
1292 if (get_pm_cur_state() != S_LCDDIM)
1295 if (!display_conf.dimming)
1298 lock = __get_lock_screen_state();
1299 if (lock != VCONFKEY_IDLE_LOCK && hallic_open)
1302 hdmi_state = extcon_get_status(EXTCON_CABLE_HDMI);
1306 ret = vconf_get_int(VCONFKEY_SYSMAN_CRADLE_STATUS, &cradle);
1307 if (ret >= 0 && cradle == DOCK_SOUND)
1310 _E("Failed to get vconf value for cradle status: %d", vconf_get_ext_errno());
1312 _D("Goto LCDOFF direct: lock(%d) hdmi(%d) cradle(%d).", lock, hdmi_state, cradle);
1318 * default transition function
1321 * 3. call enter action function
1323 static int default_trans(int evt)
1325 struct state *st = &states[get_pm_cur_state()];
1328 next_state = (enum state_t)trans_table[get_pm_cur_state()][evt];
1330 /* check conditions */
1331 if (st->check && !st->check(get_pm_cur_state(), next_state)) {
1332 /* There is a condition. */
1333 _I("%s locked. Trans to %s failed.", states[get_pm_cur_state()].name,
1334 states[next_state].name);
1338 /* state transition */
1339 set_pm_old_state(get_pm_cur_state());
1340 set_pm_cur_state(next_state);
1341 st = &states[get_pm_cur_state()];
1345 if (get_pm_cur_state() == S_LCDOFF)
1346 update_lcdoff_source(VCONFKEY_PM_LCDOFF_BY_TIMEOUT);
1348 if ((get_pm_cur_state() == S_NORMAL) || (get_pm_cur_state() == S_LCDOFF))
1349 if (set_custom_lcdon_timeout(0) == true)
1350 update_display_time();
1352 if (check_lcdoff_direct() == true) {
1353 /* enter next state directly */
1354 states[get_pm_cur_state()].trans(EVENT_TIMEOUT);
1356 if ((get_pm_cur_state() == S_SLEEP)
1357 && (is_emulator() == true || timeout_sleep_support == false))
1360 st->action(st->timeout);
1367 static gboolean lcd_on_expired(void *data)
1369 int lock_state, ret;
1371 if (lock_timeout_id)
1372 lock_timeout_id = 0;
1374 /* check state of lock */
1375 ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
1376 if (ret > 0 && lock_state == VCONFKEY_IDLE_LOCK)
1377 return G_SOURCE_REMOVE;
1379 _E("Failed to get vconf value for idle lock state: %d", vconf_get_ext_errno());
1381 /* lock screen is not launched yet, but lcd is on */
1382 if (check_lcd_is_on() == false)
1383 lcd_on_procedure(LCD_NORMAL, NORMAL_MODE);
1385 return G_SOURCE_REMOVE;
1388 static inline void stop_lock_timer(void)
1390 if (lock_timeout_id) {
1391 g_source_remove(lock_timeout_id);
1392 lock_timeout_id = 0;
1396 static void check_lock_screen(void)
1398 int lock_state, ret;
1402 /* check state of lock */
1403 ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
1404 if (ret < 0 || lock_state == VCONFKEY_IDLE_LOCK)
1407 /* Use time to check lock is done. */
1408 lock_timeout_id = g_timeout_add(display_conf.lock_wait_time,
1409 lcd_on_expired, NULL);
1412 /* default enter action function */
1413 static int default_action(int timeout)
1415 int wakeup_count = -1, pm_cur_state;
1418 static time_t last_update_time = 0;
1419 static int last_timeout = 0;
1420 struct timeval now_tv;
1422 if (status != DEVICE_OPS_STATUS_START) {
1423 _E("Display is not started.");
1427 if (get_pm_cur_state() != S_SLEEP) {
1428 if ((get_pm_cur_state() == S_NORMAL) &&
1429 lcdon_tv.tv_sec != 0) {
1430 gettimeofday(&now_tv, NULL);
1431 timeout -= DIFF_TIMEVAL_MS(now_tv, lcdon_tv);
1432 lcdon_tv.tv_sec = 0;
1434 /* set timer with current state timeout */
1435 reset_timeout(timeout);
1437 if (get_pm_cur_state() == S_NORMAL) {
1438 time(&last_update_time);
1439 last_timeout = timeout;
1441 _I("Timout set: %s state %d ms",
1442 states[get_pm_cur_state()].name, timeout);
1446 if ((get_pm_cur_state() != get_pm_old_state()) && (get_pm_cur_state() != S_SLEEP)) {
1447 if (pm_get_power_lock_support()) {
1448 broadcast_pm_wakeup();
1449 power_acquire_wakelock();
1451 set_setting_pmstate(get_pm_cur_state());
1452 pm_cur_state = get_pm_cur_state();
1453 device_notify(DEVICE_NOTIFIER_LCD, (void *)&pm_cur_state);
1456 if ((get_pm_old_state() == S_NORMAL) && (get_pm_cur_state() != S_NORMAL)) {
1458 diff = difftime(now, last_update_time);
1459 _I("S_NORMAL is changed to %s (timeout=%d ms diff=%.0f s).",
1460 states[get_pm_cur_state()].name, last_timeout, diff);
1463 switch (get_pm_cur_state()) {
1466 * normal state : backlight on and restore
1467 * the previous brightness
1469 if ((get_pm_old_state() == S_LCDOFF) || (get_pm_old_state() == S_SLEEP))
1470 check_lock_screen();
1471 else if (get_pm_old_state() == S_LCDDIM)
1472 backlight_ops->update();
1474 if (check_lcd_is_on() == false)
1475 lcd_on_procedure(LCD_NORMAL, NORMAL_MODE);
1479 if ((get_pm_old_state() == S_NORMAL) &&
1480 backlight_ops->get_custom_status())
1481 backlight_ops->save_custom_brightness();
1482 /* lcd dim state : dim the brightness */
1483 backlight_ops->dim();
1485 if ((get_pm_old_state() == S_LCDOFF) || (get_pm_old_state() == S_SLEEP))
1486 lcd_on_procedure(LCD_DIM, NORMAL_MODE);
1490 if ((get_pm_old_state() != S_SLEEP) && (get_pm_old_state() != S_LCDOFF)) {
1492 /* lcd off state : turn off the backlight */
1493 if (backlight_ops->get_lcd_power() == DPMS_ON)
1494 lcd_off_procedure(LCD_OFF_BY_TIMEOUT);
1497 if (backlight_ops->get_lcd_power() == DPMS_ON
1498 || lcd_paneloff_mode)
1499 lcd_off_procedure(LCD_OFF_BY_TIMEOUT);
1503 if ((get_pm_old_state() != S_SLEEP) && (get_pm_old_state() != S_LCDOFF))
1506 if (backlight_ops->get_lcd_power() == DPMS_ON)
1507 lcd_off_procedure(LCD_OFF_BY_TIMEOUT);
1509 if (!pm_get_power_lock_support()) {
1510 /* sleep state : set system mode to SUSPEND */
1511 if (get_wakeup_count(&wakeup_count) < 0)
1512 _E("Wakeup count read error.");
1514 if (wakeup_count < 0) {
1515 _I("Wakup Event. Can not enter suspend mode.");
1519 if (set_wakeup_count(wakeup_count) < 0) {
1520 _E("Wakeup count write error.");
1530 #ifdef ENABLE_PM_LOG
1531 pm_history_save(PM_LOG_SLEEP, get_pm_cur_state());
1533 broadcast_pm_suspend();
1534 if (pm_get_power_lock_support()) {
1535 power_enable_autosleep();
1537 if (power_release_wakelock() < 0)
1538 _E("Power unlock state error.");
1541 _I("system wakeup!!");
1542 system_wakeup_flag = true;
1544 if (check_wakeup_src() == EVENT_DEVICE)
1545 /* system waked up by devices */
1546 states[get_pm_cur_state()].trans(EVENT_DEVICE);
1548 /* system waked up by user input */
1549 states[get_pm_cur_state()].trans(EVENT_INPUT);
1554 if (!pm_get_power_lock_support()) {
1556 states[get_pm_cur_state()].trans(EVENT_DEVICE);
1562 * default check function
1564 * 0 : can't transit, others : transitable
1566 static int default_check(int curr, int next)
1570 makeup_trans_condition();
1572 trans_cond = get_trans_condition() & MASK_BIT;
1574 if (next == S_NORMAL) /* S_NORMAL is exceptional */
1579 trans_cond = trans_cond & MASK_NORMAL;
1582 trans_cond = trans_cond & MASK_DIM;
1585 trans_cond = trans_cond & MASK_OFF;
1592 if (trans_cond != 0) {
1597 return 1; /* transitable */
1600 static void default_saving_mode(int onoff)
1603 set_pm_status_flag(PWRSV_FLAG);
1605 clear_pm_status_flag(PWRSV_FLAG);
1607 if (get_pm_cur_state() == S_NORMAL)
1608 backlight_ops->update();
1611 int poll_callback(int condition, PMMsg *data)
1613 static time_t last_t;
1616 if (status != DEVICE_OPS_STATUS_START) {
1617 _E("Display logic is not started.");
1621 if (condition == INPUT_POLL_EVENT) {
1622 if ((get_pm_cur_state() == S_LCDOFF) || (get_pm_cur_state() == S_SLEEP))
1623 _I("Input event signal at Display Off");
1625 if ((last_t != now) ||
1626 (get_pm_cur_state() == S_LCDOFF) ||
1627 (get_pm_cur_state() == S_SLEEP)) {
1628 states[get_pm_cur_state()].trans(EVENT_INPUT);
1633 if (condition == PM_CONTROL_EVENT) {
1634 proc_condition(data);
1636 if (IS_COND_REQUEST_CHANGE(data->cond))
1637 proc_change_state(data->cond, data->pid);
1643 static int update_setting(int key_idx, int val)
1648 case SETTING_TO_NORMAL:
1649 update_display_time();
1650 states[get_pm_cur_state()].trans(EVENT_INPUT);
1652 case SETTING_HALLIC_OPEN:
1654 update_display_time();
1655 if ((get_pm_cur_state() == S_NORMAL) || (get_pm_cur_state() == S_LCDDIM))
1656 states[get_pm_cur_state()].trans(EVENT_INPUT);
1657 else if ((get_pm_cur_state() == S_SLEEP) && hallic_open)
1658 proc_change_state(S_LCDOFF, INTERNAL_LOCK_HALLIC);
1660 case SETTING_LOW_BATT:
1661 if (low_battery_state(val)) {
1662 if (!(get_pm_status_flag() & CHRGR_FLAG))
1663 power_saving_func(true);
1664 set_pm_status_flag(LOWBT_FLAG);
1666 if (get_pm_status_flag() & PWRSV_FLAG)
1667 power_saving_func(false);
1668 clear_pm_status_flag(LOWBT_FLAG);
1669 clear_pm_status_flag(BRTCH_FLAG);
1670 ret = vconf_set_bool(VCONFKEY_PM_BRIGHTNESS_CHANGED_IN_LPM, false);
1672 _E("Failed to set vconf value for brightness changed in lpm: %d", vconf_get_ext_errno());
1675 case SETTING_CHARGING:
1677 if (get_pm_status_flag() & LOWBT_FLAG) {
1678 power_saving_func(false);
1679 clear_pm_status_flag(LOWBT_FLAG);
1681 set_pm_status_flag(CHRGR_FLAG);
1684 ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW,
1687 bat_state = VCONFKEY_SYSMAN_BAT_NORMAL;
1688 _E("Failed to get vconf value for battery status low: %d", vconf_get_ext_errno());
1690 if (low_battery_state(bat_state)) {
1691 power_saving_func(true);
1692 set_pm_status_flag(LOWBT_FLAG);
1694 clear_pm_status_flag(CHRGR_FLAG);
1697 case SETTING_BRT_LEVEL:
1698 if (get_pm_status_flag() & PWRSV_FLAG) {
1699 set_pm_status_flag(BRTCH_FLAG);
1700 ret = vconf_set_bool(VCONFKEY_PM_BRIGHTNESS_CHANGED_IN_LPM, true);
1702 _E("Failed to set vconf value for brightness changed in lpm: %d", vconf_get_ext_errno());
1703 _I("Brightness changed in low battery,"
1704 "escape dim state.");
1706 backlight_ops->set_default_brt(val);
1708 case SETTING_LOCK_SCREEN:
1709 set_lock_screen_state(val);
1710 if (val == VCONFKEY_IDLE_UNLOCK) {
1711 if (CHECK_OPS(keyfilter_ops, backlight_enable))
1712 keyfilter_ops->backlight_enable(false);
1715 /* LCD on if lock screen show before waiting time */
1716 if ((get_pm_cur_state() == S_NORMAL) &&
1717 val == VCONFKEY_IDLE_LOCK &&
1718 backlight_ops->get_lcd_power() != DPMS_ON &&
1719 is_lcdon_blocked() == LCDON_BLOCK_NONE)
1720 lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
1722 update_display_time();
1723 if (get_pm_cur_state() == S_NORMAL)
1724 states[get_pm_cur_state()].trans(EVENT_INPUT);
1726 case SETTING_LOCK_SCREEN_BG:
1727 set_lock_screen_bg_state(val);
1728 update_display_time();
1729 if (get_pm_cur_state() == S_NORMAL)
1730 states[get_pm_cur_state()].trans(EVENT_INPUT);
1732 case SETTING_POWEROFF:
1734 case POWEROFF_TYPE_NONE:
1735 clear_pm_status_flag(PWROFF_FLAG);
1737 case POWEROFF_TYPE_DIRECT:
1738 case POWEROFF_TYPE_RESTART:
1739 set_pm_status_flag(PWROFF_FLAG);
1743 case SETTING_POWER_CUSTOM_BRIGHTNESS:
1744 if (val == VCONFKEY_PM_CUSTOM_BRIGHTNESS_ON)
1745 backlight_ops->set_custom_status(true);
1747 backlight_ops->set_custom_status(false);
1756 static void check_seed_status(void)
1764 /* Charging check */
1765 if (fp_get_charging_status && (fp_get_charging_status(&tmp) == 0) && (tmp > 0))
1766 set_pm_status_flag(CHRGR_FLAG);
1768 ret = get_setting_brightness(&tmp);
1769 if (ret != 0 || (tmp < PM_MIN_BRIGHTNESS || tmp > PM_MAX_BRIGHTNESS)) {
1770 _I("Failed to read vconf value for brightness.");
1771 brt = display_conf.pm_default_brightness;
1772 if (tmp < PM_MIN_BRIGHTNESS || tmp > PM_MAX_BRIGHTNESS) {
1773 ret = vconf_set_int(VCONFKEY_SETAPPL_LCD_BRIGHTNESS, brt);
1775 _E("Failed to set vconf value for lcd brightness: %d", vconf_get_ext_errno());
1779 _I("Set brightness(%d) from setting app.", tmp);
1780 backlight_ops->set_default_brt(tmp);
1781 backlight_ops->set_brightness(tmp);
1783 ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, &bat_state);
1785 bat_state = VCONFKEY_SYSMAN_BAT_NORMAL;
1786 _E("Failed to get vconf value for battery status low: %d", vconf_get_ext_errno());
1788 if (low_battery_state(bat_state)) {
1789 if (!(get_pm_status_flag() & CHRGR_FLAG)) {
1790 power_saving_func(true);
1791 set_pm_status_flag(LOWBT_FLAG);
1795 /* lock screen check */
1796 ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
1799 _E("Failed to get vconf value for idle lock state: %d", vconf_get_ext_errno());
1801 set_lock_screen_state(lock_state);
1802 if (lock_state == VCONFKEY_IDLE_LOCK) {
1803 states[S_NORMAL].timeout = lock_screen_timeout;
1804 _I("LCD NORMAL timeout(%d ms) is set"
1805 " for lock screen.", lock_screen_timeout);
1811 static void init_lcd_operation(void)
1813 const struct device_ops *ops = NULL;
1815 ops = find_device("display");
1816 if (!check_default(ops))
1817 SYS_G_LIST_APPEND(lcdon_ops, ops);
1819 ops = find_device("touchkey");
1820 if (!check_default(ops))
1821 SYS_G_LIST_APPEND(lcdon_ops, ops);
1823 ops = find_device("touchscreen");
1824 if (!check_default(ops))
1825 SYS_G_LIST_APPEND(lcdon_ops, ops);
1828 static void exit_lcd_operation(void)
1831 GList *l_next = NULL;
1832 const struct device_ops *ops = NULL;
1834 SYS_G_LIST_FOREACH_SAFE(lcdon_ops, l, l_next, ops)
1835 SYS_G_LIST_REMOVE_LIST(lcdon_ops, l);
1847 static const char *errMSG[INIT_END] = {
1848 [INIT_SETTING] = "setting init error",
1849 [INIT_INTERFACE] = "lowlevel interface(sysfs or others) init error",
1850 [INIT_POLL] = "input devices poll init error",
1851 [INIT_FIFO] = "FIFO poll init error",
1852 [INIT_DBUS] = "d-bus init error",
1855 int set_lcd_timeout(int on, int dim, int holdkey_block, const char *name)
1857 if (on == 0 && dim == 0) {
1858 _I("LCD timeout changed: default setting");
1859 custom_normal_timeout = custom_dim_timeout = 0;
1860 } else if (on < 0 || dim < 0) {
1861 _E("Failed to set value(on=%d dim=%d).", on, dim);
1864 _I("LCD timeout changed: on=%ds dim=%ds", on, dim);
1865 custom_normal_timeout = SEC_TO_MSEC(on);
1866 custom_dim_timeout = SEC_TO_MSEC(dim);
1868 /* Apply new backlight time */
1869 update_display_time();
1870 if (get_pm_cur_state() == S_NORMAL)
1871 states[get_pm_cur_state()].trans(EVENT_INPUT);
1873 if (holdkey_block) {
1874 custom_holdkey_block = true;
1875 _I("Hold key disabled.");
1877 custom_holdkey_block = false;
1878 _I("Hold key enabled.");
1881 if (custom_change_name) {
1882 free(custom_change_name);
1883 custom_change_name = 0;
1886 if (custom_normal_timeout == 0 &&
1887 custom_dim_timeout == 0 &&
1891 custom_change_name = strndup(name, strlen(name));
1892 if (!custom_change_name) {
1893 _E("Failed to malloc.");
1894 custom_normal_timeout = custom_dim_timeout = 0;
1895 custom_holdkey_block = false;
1902 void reset_lcd_timeout(GDBusConnection *conn,
1903 const gchar *sender,
1904 const gchar *unique_name,
1910 if (!custom_change_name)
1913 if (strcmp(sender, custom_change_name))
1916 _I("reset lcd timeout: Set default timeout. sender=%s", sender);
1918 free(custom_change_name);
1919 custom_change_name = 0;
1920 custom_normal_timeout = custom_dim_timeout = 0;
1921 custom_holdkey_block = false;
1923 update_display_time();
1924 if (get_pm_cur_state() == S_NORMAL)
1925 states[get_pm_cur_state()].trans(EVENT_INPUT);
1928 static int delayed_init_done(void *data)
1930 static bool done = false;
1939 _I("Booting done, release booting lock.");
1940 if (disp_plgn->pm_unlock_internal) {
1941 disp_plgn->pm_unlock_internal(INTERNAL_LOCK_BOOTING, LCD_NORMAL, PM_SLEEP_MARGIN);
1942 disp_plgn->pm_unlock_internal(INTERNAL_LOCK_BOOTING, LCD_OFF, PM_SLEEP_MARGIN);
1948 static int battery_health_changed(void *data)
1950 int health = DATA_VALUE_INT(data);
1952 _I("battery health change %d", health);
1954 if (health == HEALTH_GOOD) {
1955 clear_pm_status_flag(BATTERY_FLAG);
1956 clear_pm_status_flag(DIMSTAY_FLAG);
1957 } else if (health == HEALTH_LOW || health == HEALTH_HIGH || health == HEALTH_OVP) {
1958 set_pm_status_flag(BATTERY_FLAG);
1959 set_pm_status_flag(DIMSTAY_FLAG);
1962 if (backlight_ops->get_lcd_power() == DPMS_ON)
1963 backlight_ops->update();
1968 static gboolean delayed_init_done_dpms(gpointer data)
1973 return G_SOURCE_CONTINUE;
1975 switch (get_pm_cur_state()) {
1978 lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
1979 if (display_conf.timeout_enable) {
1980 timeout = states[S_NORMAL].timeout;
1981 /* check minimun lcd on time */
1982 if (timeout < SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT))
1983 timeout = SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT);
1984 reset_timeout(timeout);
1988 lcd_off_procedure(LCD_OFF_BY_EVENT);
1989 timeout = display_conf.lcdoff_timeout;
1990 reset_timeout(timeout);
1996 return G_SOURCE_REMOVE;
1999 static void add_timer_for_init_dpms(void)
2001 guint id = g_timeout_add(500/* milliseconds */, delayed_init_done_dpms, NULL);
2003 _E("Failed to add init_dpms timeout.");
2007 * Power manager Main
2010 static int display_probe(void *data)
2014 /* check display feature */
2015 if (!is_feature_display_supported())
2019 * load display service
2020 * if there is no display shared library,
2021 * deviced does not provide any method and function of display.
2023 ret = display_service_load();
2027 /* display_plugin instance initialization */
2029 disp_plgn->device_flags_to_string = __device_flags_to_string;
2031 if (battery_plgn->handle) {
2032 fp_get_charging_status = dlsym(battery_plgn->handle, "get_charging_status");
2033 if (!fp_get_charging_status)
2034 _E("Failed to obtain address of get_charging_status");
2036 _I("There is no battery module.");
2041 static int input_init_handler(void)
2043 if (!display_conf.input_support)
2044 remove_device_by_devname("input");
2049 static void esd_action(void)
2051 const struct device_ops *touchscreen_ops = NULL;
2055 touchscreen_ops = find_device("touchscreen");
2057 if (!check_default(touchscreen_ops))
2058 touchscreen_ops->stop(NORMAL_MODE);
2059 backlight_ops->off(NORMAL_MODE);
2060 backlight_ops->on(NORMAL_MODE);
2061 if (!check_default(touchscreen_ops))
2062 touchscreen_ops->start(NORMAL_MODE);
2065 static void lcd_uevent_changed(struct udev_device *dev)
2067 const char *devpath;
2070 devpath = udev_device_get_devpath(dev);
2074 if (!fnmatch(LCD_ESD_PATH, devpath, 0)) {
2075 action = udev_device_get_action(dev);
2076 if (!strcmp(action, UDEV_CHANGE))
2081 static const struct uevent_handler lcd_uevent_ops = {
2082 .subsystem = LCD_EVENT_SUBSYSTEM,
2083 .uevent_func = lcd_uevent_changed,
2087 static void display_init(void *data)
2090 unsigned int flags = (WITHOUT_STARTNOTI | FLAG_X_DPMS);
2093 _I("Start power manager.");
2095 signal(SIGHUP, sig_hup);
2097 power_saving_func = default_saving_mode;
2099 /* load configutation */
2100 ret = config_parse(DISPLAY_CONF_FILE, display_load_config, &display_conf);
2102 _W("Failed to load '%s', use default value: %d",
2103 DISPLAY_CONF_FILE, ret);
2105 register_kernel_uevent_control(&lcd_uevent_ops);
2107 register_notifier(DEVICE_NOTIFIER_DELAYED_INIT, delayed_init_done);
2108 register_notifier(DEVICE_NOTIFIER_APPLICATION_BACKGROUND, display_app_background);
2109 register_notifier(DEVICE_NOTIFIER_APPLICATION_FOREGROUND, display_app_foreground);
2110 register_notifier(DEVICE_NOTIFIER_APPLICATION_TERMINATED, display_app_terminated);
2111 register_notifier(DEVICE_NOTIFIER_BATTERY_HEALTH, battery_health_changed);
2112 register_notifier(DEVICE_NOTIFIER_DISPLAY_BRIGHTNESS, display_brightness_changed);
2113 register_notifier(DEVICE_NOTIFIER_LCD_AUTOBRT_SENSING, display_auto_brightness_sensing);
2115 init_save_userlock();
2117 for (i = INIT_SETTING; i < INIT_END; i++) {
2120 ret = init_setting(update_setting);
2122 case INIT_INTERFACE:
2123 if (display_conf.timeout_enable)
2124 get_lcd_timeout_from_settings();
2125 ret = init_sysfs(flags);
2129 ret = input_init_handler();
2131 pm_lock_detector_init();
2135 ret = init_pm_dbus();
2139 _E("Failed to init: %s", errMSG[i]);
2144 if (i == INIT_END) {
2145 display_ops_init(NULL);
2146 #ifdef ENABLE_PM_LOG
2149 init_lcd_operation();
2150 check_seed_status();
2152 /* In smd test, TSP should be turned off if display panel is not existed. */
2153 if (backlight_ops->get_lcd_power() == -ENOENT) {
2154 _I("Display panel is not existed.");
2155 lcd_direct_control(DPMS_OFF, NORMAL_MODE);
2156 exit_lcd_operation();
2159 /* wm_ready needs to be checked
2160 * since display manager can be launched later than deviced.
2161 * In the case, display cannot be turned on at the first booting */
2162 // wm_ready = check_wm_ready();
2164 if (is_lcdon_blocked() != LCDON_BLOCK_NONE)
2165 lcd_off_procedure(LCD_OFF_BY_EVENT);
2167 lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
2169 add_timer_for_init_dpms();
2172 if (display_conf.lcd_always_on) {
2173 _I("LCD always on.");
2174 trans_table[S_NORMAL][EVENT_TIMEOUT] = S_NORMAL;
2177 if (flags & WITHOUT_STARTNOTI) { /* start without noti */
2178 _I("Start Power managing without noti");
2179 if (pm_get_power_lock_support()) {
2180 broadcast_pm_wakeup();
2181 power_acquire_wakelock();
2184 * Lock lcd off until booting is done.
2185 * deviced guarantees all booting script is executing.
2186 * Last script of booting unlocks this suspend blocking state.
2188 if (disp_plgn->pm_lock_internal)
2189 disp_plgn->pm_lock_internal(INTERNAL_LOCK_BOOTING, LCD_OFF,
2190 STAY_CUR_STATE, DELAYED_INIT_WATING_TIME);
2192 /* Initial display state right after the booting done */
2193 if (is_lcdon_blocked())
2194 set_pm_cur_state(S_LCDOFF);
2196 set_pm_cur_state(S_NORMAL);
2197 ret = vconf_set_int(VCONFKEY_PM_STATE, get_pm_cur_state());
2199 _E("Failed to set vconf value for pm cur state: %d", vconf_get_ext_errno());
2201 status = DEVICE_OPS_STATUS_START;
2202 if (display_conf.timeout_enable) {
2203 timeout = states[S_NORMAL].timeout;
2204 /* check minimun lcd on time */
2205 if (timeout < SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT))
2206 timeout = SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT);
2208 if (disp_plgn->pm_lock_internal)
2209 disp_plgn->pm_lock_internal(INTERNAL_LOCK_BOOTING, LCD_NORMAL,
2210 STAY_CUR_STATE, timeout);
2215 if (display_conf.input_support)
2216 if (CHECK_OPS(keyfilter_ops, init))
2217 keyfilter_ops->init();
2221 static void display_exit(void *data)
2225 status = DEVICE_OPS_STATUS_STOP;
2227 /* Set current state to S_NORMAL */
2228 set_pm_cur_state(S_NORMAL);
2229 set_setting_pmstate(get_pm_cur_state());
2230 /* timeout is not needed */
2231 reset_timeout(TIMEOUT_NONE);
2233 if (CHECK_OPS(keyfilter_ops, exit))
2234 keyfilter_ops->exit();
2236 unregister_kernel_uevent_control(&lcd_uevent_ops);
2238 display_ops_exit(NULL);
2240 for (i = i - 1; i >= INIT_SETTING; i--) {
2245 case INIT_INTERFACE:
2249 unregister_notifier(DEVICE_NOTIFIER_DELAYED_INIT, delayed_init_done);
2250 unregister_notifier(DEVICE_NOTIFIER_APPLICATION_BACKGROUND, display_app_background);
2251 unregister_notifier(DEVICE_NOTIFIER_APPLICATION_FOREGROUND, display_app_foreground);
2252 unregister_notifier(DEVICE_NOTIFIER_APPLICATION_TERMINATED, display_app_terminated);
2253 unregister_notifier(DEVICE_NOTIFIER_BATTERY_HEALTH, battery_health_changed);
2254 unregister_notifier(DEVICE_NOTIFIER_DISPLAY_BRIGHTNESS, display_brightness_changed);
2260 exit_lcd_operation();
2261 free_lock_info_list();
2263 /* free display service */
2264 display_service_free();
2266 _I("Stop power manager.");
2269 static int display_start(enum device_flags flags)
2272 if (flags & NORMAL_MODE) {
2273 if (flags & LCD_PANEL_OFF_MODE)
2275 backlight_ops->standby(true);
2278 backlight_ops->on(flags);
2283 /* CORE LOGIC MODE */
2284 if (!(flags & CORE_LOGIC_MODE))
2287 if (status == DEVICE_OPS_STATUS_START)
2290 if (display_probe(NULL) < 0)
2298 static int display_stop(enum device_flags flags)
2301 if (flags & NORMAL_MODE || flags & FORCE_OFF_MODE) {
2302 backlight_ops->off(flags);
2306 /* CORE LOGIC MODE */
2307 if (!(flags & CORE_LOGIC_MODE))
2310 if (status == DEVICE_OPS_STATUS_STOP)
2318 static int display_status(void)
2323 static const struct device_ops display_device_ops = {
2324 .priority = DEVICE_PRIORITY_HIGH,
2325 DECLARE_NAME_LEN("display"),
2326 .probe = display_probe,
2327 .init = display_init,
2328 .exit = display_exit,
2329 .start = display_start,
2330 .stop = display_stop,
2331 .status = display_status,
2334 DEVICE_OPS_REGISTER(&display_device_ops)
2336 static void __CONSTRUCTOR__ initialize(void)
2338 disp_plgn = get_var_display_plugin();
2340 _E("Failed to get display plugin variable.");
2342 backlight_ops = get_var_backlight_ops();
2344 _E("Failed to get backlight operator variable.");
2346 battery_plgn = get_var_battery_plugin();
2348 _E("Failed to get battery plugin variable.");