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 "auto-brightness-sensorhub.h"
46 #include "ambient-mode.h"
50 #include "lock-detector.h"
51 #include "display-ops.h"
52 #include "shared/devices.h"
53 #include "shared/device-notifier.h"
54 #include "core/udev.h"
55 #include "shared/common.h"
56 #include "shared/apps.h"
57 #include "extcon/extcon.h"
58 #include "battery/power-supply.h"
59 #include "power/power.h"
60 #include "power/power-off.h"
61 #include "power/power-suspend.h"
62 #include "power/power-boot.h"
63 #include "power/power-doze.h"
64 #include "device-interface.h"
65 #include "display-plugin.h"
66 #include "display-info.h"
67 #include "battery-monitor.h"
68 #include "display-signal.h"
69 #include "display-lock.h"
70 #include "display-backlight.h"
71 #include "display-misc.h"
72 #include "display-panel.h"
73 #include "display-config.h"
74 #include "display-state-transition.h"
75 #include "shared/plugin.h"
77 #define POWERLOCK_CONF_FILE "/etc/deviced/powerlock.conf"
79 #ifndef VCONFKEY_HOMESCREEN_TUTORIAL_OOBE_ENABLED
80 #define VCONFKEY_HOMESCREEN_TUTORIAL_OOBE_ENABLED "db/private/com.samsung.w-home/tutorial_oobe_enabled"
84 * @addtogroup POWER_MANAGER
88 #define LOCK_SCREEN_INPUT_TIMEOUT 10000
89 #define LOCK_SCREEN_CONTROL_TIMEOUT 5000
90 #define ALWAYS_ON_TIMEOUT 360000000
91 #define LATE_LCD_TRANSIT 1
93 #define GESTURE_STR "gesture"
94 #define POWER_KEY_STR "powerkey"
95 #define BACK_KEY_STR "backkey"
96 #define TOUCH_STR "touch"
97 #define EVENT_STR "event"
98 #define BEZEL_STR "bezel"
99 #define TIMEOUT_STR "timeout"
100 #define PROXI_STR "proximity"
101 #define PALM_STR "palm"
102 #define DISPLAY_DETACH_STR "display_detach"
103 #define UNKNOWN_STR "unknown"
105 extern void init_save_userlock(void);
107 static struct display_plugin *disp_plgn;
108 static struct display_backlight_ops *backlight_ops;
109 static struct battery_plugin *battery_plgn;
110 static int (*fp_get_charging_status) (int *val);
112 static void (*power_saving_func) (int onoff);
113 static enum device_ops_status status = DEVICE_OPS_STATUS_UNINIT;
115 static int system_wakeup_flag = false;
116 static unsigned int custom_normal_timeout = 0;
117 static unsigned int custom_dim_timeout = 0;
118 static char *custom_change_name;
119 static guint lock_timeout_id;
120 static guint transit_timer;
121 static int lock_screen_timeout = LOCK_SCREEN_INPUT_TIMEOUT;
122 static struct timeval lcdon_tv;
124 * The two variables(lcdon_broadcast, pmstate_suspend) must be set initial
125 * state because it should be sent from previous state at booting time.
127 static bool lcdon_broadcast = true;
129 static bool touch_blocked = false;
131 /* default transition, action fuctions */
132 static int default_trans(int evt);
133 static int default_action(int timeout);
134 static int default_check(int curr, int next);
136 static gboolean del_normal_cond(void *data);
137 static gboolean del_dim_cond(void *data);
138 static gboolean del_off_cond(void *data);
140 static int default_proc_change_state(unsigned int cond, pid_t pid);
141 static int (*proc_change_state)(unsigned int cond, pid_t pid) = default_proc_change_state;
143 static struct state states[S_END] = {
144 { S_START, "S_START", NULL, NULL, NULL, NULL },
145 { S_NORMAL, "S_NORMAL", default_trans, default_action, default_check, del_normal_cond },
146 { S_LCDDIM, "S_LCDDIM", default_trans, default_action, default_check, del_dim_cond },
147 { S_LCDOFF, "S_LCDOFF", default_trans, default_action, default_check, del_off_cond },
148 { S_STANDBY, "S_STANDBY", NULL, NULL, NULL, NULL },
149 { S_SLEEP, "S_SLEEP", default_trans, default_action, default_check, NULL },
150 { S_POWEROFF, "S_POWEROFF", NULL, NULL, NULL, NULL },
153 #define SHIFT_UNLOCK 4
154 #define SHIFT_CHANGE_STATE 7
155 #define CHANGE_STATE_BIT 0xF00 /* 1111 0000 0000 */
156 #define SHIFT_LOCK_FLAG 16
157 #define SHIFT_CHANGE_TIMEOUT 20
158 #define CUSTOM_TIMEOUT_BIT 0x1
159 #define CUSTOM_HOLDKEY_BIT 0x2
160 #define HOLD_KEY_BLOCK_BIT 0x1
161 #define TIMEOUT_NONE (-1)
163 #define S_COVER_TIMEOUT 8000
164 #define GET_HOLDKEY_BLOCK_STATE(x) ((x >> SHIFT_LOCK_FLAG) & HOLD_KEY_BLOCK_BIT)
165 #define DELAYED_INIT_WATING_TIME 60000 /* 1 minute */
167 #define LOCK_SCREEN_WATING_TIME 300 /* 0.3 second */
168 #define LONG_PRESS_INTERVAL 500 /* 0.5 seconds */
169 #define SAMPLING_INTERVAL 1 /* 1 sec */
170 #define BRIGHTNESS_CHANGE_STEP 10
171 #define LCD_ALWAYS_ON 0
172 #define ACCEL_SENSOR_ON 1
173 #define CONTINUOUS_SAMPLING 1
174 #define LCDOFF_TIMEOUT 300 /* milli second */
176 #define DIFF_TIMEVAL_MS(a, b) \
177 (((a.tv_sec * 1000000 + a.tv_usec) - \
178 (b.tv_sec * 1000000 + b.tv_usec)) \
181 #define KILLABLE_DAEMON_LOCK_LIMIT 1800 /* seconds, 30min */
182 #define FORCE_RELEASE_LOCK_INTERVAL 5 /* seconds */
184 static void get_comm(pid_t pid, char *comm);
185 static bool is_killable_daemon(pid_t pid);
186 static gboolean pmlock_terminate_daemon_to_release_lock(gpointer data);
187 static int pmlock_check(void *data);
188 static int powerlock_load_config(struct parse_result *result, void *user_data);
189 static void free_killable_daemon_list(void);
191 static GList *display_lock_killable_daemon;
192 static bool initialized_killable_daemon_list;
194 static struct display_config display_conf = {
195 .lock_wait_time = LOCK_SCREEN_WATING_TIME,
196 .longpress_interval = LONG_PRESS_INTERVAL,
197 .lightsensor_interval = SAMPLING_INTERVAL,
198 .lcdoff_timeout = LCDOFF_TIMEOUT,
199 .pm_default_brightness = 70,
200 .brightness_change_step = BRIGHTNESS_CHANGE_STEP,
201 .lcd_always_on = LCD_ALWAYS_ON,
203 .framerate_app = {0, 0, 0, 0},
204 .control_display = 0,
205 .powerkey_doublepress = 0,
206 .accel_sensor_on = ACCEL_SENSOR_ON,
207 .continuous_sampling = CONTINUOUS_SAMPLING,
208 .timeout_enable = true,
209 .input_support = true,
210 .lockcheck_timeout = 600,
211 .display_init_direction = DISPLAY_INIT_DIRECTION_HORIZONTAL,
212 .pmlock_check = pmlock_check,
213 .aod_enter_level = 40,
215 .touch_wakeup = false,
216 .display_on_usb_conn_changed = true,
217 .display_dpms_type = DISPLAY_DPMS_TYPE_WINDOW_MANAGER,
220 struct display_function_info display_info = {
221 .update_auto_brightness = NULL,
222 .set_autobrightness_min = NULL,
223 .reset_autobrightness_min = NULL,
224 .face_detection = NULL,
227 inline const struct display_config *get_var_display_config()
229 return &display_conf;
232 inline struct state *state_st(enum state_t state)
234 return &states[state];
237 static int display_auto_brightness_sensing(void *data)
242 g_source_remove(transit_timer);
248 static const char* __device_flags_to_string(enum device_flags flags)
250 if (flags & (LCD_ON_BY_GESTURE | LCD_OFF_BY_GESTURE))
252 else if (flags & (LCD_ON_BY_POWER_KEY | LCD_OFF_BY_POWER_KEY))
253 return POWER_KEY_STR;
254 else if (flags & (LCD_ON_BY_EVENT | LCD_OFF_BY_EVENT))
256 else if (flags & LCD_ON_BY_BACK_KEY)
258 else if (flags & LCD_ON_BY_TOUCH)
260 else if (flags & LCD_ON_BY_BEZEL)
262 else if (flags & LCD_OFF_BY_TIMEOUT)
264 else if (flags & LCD_OFF_BY_PROXIMITY)
266 else if (flags & LCD_OFF_BY_PALM)
268 else if (flags & LCD_OFF_BY_DISPLAY_DETACH)
269 return DISPLAY_DETACH_STR;
274 static void get_comm(pid_t pid, char *comm)
279 if (pid >= INTERNAL_LOCK_BASE)
280 snprintf(buf, PATH_MAX, "/proc/%d/comm", getpid());
282 snprintf(buf, PATH_MAX, "/proc/%d/comm", pid);
284 fd = open(buf, O_RDONLY);
287 _E("Process(%d) does not exist now(may be dead without unlock).", pid);
291 r = read(fd, comm, PATH_MAX);
292 if ((r > 0) && (r < PATH_MAX)) {
293 if (comm[r - 1] == '\n')
303 static bool is_killable_daemon(pid_t pid)
305 char pname[PATH_MAX] = {0, };
306 const char *blacklist;
309 get_comm(pid, pname);
313 SYS_G_LIST_FOREACH(display_lock_killable_daemon, l, blacklist) {
314 if (MATCH(pname, blacklist))
321 static gboolean pmlock_terminate_daemon_to_release_lock(gpointer data)
328 char pname[PATH_MAX] = {0, };
331 _E("Invalid parameter.");
332 return G_SOURCE_REMOVE;
335 node = (PmLockNode *) data;
340 _E("Invalid lock pid.");
341 del_node(state, node);
342 return G_SOURCE_REMOVE;
345 if (!node->killable_daemon) {
346 _E("Incorrect checker, this is not a killable daemon. Stop checking lock.");
347 return G_SOURCE_REMOVE;
350 pid_exist = (kill(pid, 0) == 0);
352 get_comm(pid, pname);
354 if (node->force_release == false) {
355 /* Stop checking lock if process had been terminated */
357 del_node(state, node);
358 _I("Process %d not found. Stop checking lock.", pid);
359 return G_SOURCE_REMOVE;
362 /* KILLABLE_DAEMON_LOCK_LIMIT is expired. Kill the daemon */
363 CRITICAL_LOG("%s(%d) holds %s lock for %ds. kill SIGTERM.",
364 *pname ? pname : "Unknown", pid, states[state].name, KILLABLE_DAEMON_LOCK_LIMIT);
365 ret = kill(pid, SIGTERM);
367 CRITICAL_LOG_E("Failed to send SIGTERM to process %s(%d), %d.",
368 *pname ? pname : "Unknown", pid, errno);
370 node->force_release = true;
371 node->warning_id = g_timeout_add_seconds(FORCE_RELEASE_LOCK_INTERVAL,
372 pmlock_terminate_daemon_to_release_lock, (gpointer)node);
373 } else if (node->force_release == true) {
374 /* kill confirmation */
376 CRITICAL_LOG("%s(%d) is still alive, kill SIGKILL.",
377 *pname ? pname : "Unknown", pid);
379 ret = kill(pid, SIGKILL);
381 CRITICAL_LOG_E("Failed to kill process %s(%d), %d.",
382 *pname ? pname : "Unknown", pid, errno);
386 CRITICAL_LOG("Release %s lock occupied by PID %d.", states[state].name, pid);
387 del_node(state, node);
388 set_unlock_time(pid, state);
390 if (!display_state_transition_is_there_state_transition_timer())
391 states[get_pm_cur_state()].trans(EVENT_TIMEOUT);
394 return G_SOURCE_REMOVE;
397 static int pmlock_check(void *data)
403 node = (PmLockNode *) data;
405 if (!initialized_killable_daemon_list) {
406 ret = config_parse(POWERLOCK_CONF_FILE, powerlock_load_config, NULL);
407 /* config file may not exist */
408 if (ret < 0 && ret != -ENOENT)
409 _W("Failed to load %s, %d.", POWERLOCK_CONF_FILE, ret);
411 if (status == DEVICE_OPS_STATUS_UNINIT) {
412 _W("Lock request before display init. Preloaded killable list.");
413 initialized_killable_daemon_list = true;
414 } else if (status == DEVICE_OPS_STATUS_STOP) {
415 _W("Lock request after display stop. Loaded list will be freed immediately.");
416 node->killable_daemon = is_killable_daemon(node->pid);
417 free_killable_daemon_list();
418 goto killable_marked;
422 node->killable_daemon = is_killable_daemon(node->pid);
425 /* use default lock checker */
426 if (!node->killable_daemon)
429 return g_timeout_add_seconds(KILLABLE_DAEMON_LOCK_LIMIT,
430 pmlock_terminate_daemon_to_release_lock, (gpointer)node);
433 static void free_killable_daemon_list(void)
438 if (!display_lock_killable_daemon)
441 SYS_G_LIST_FOREACH_SAFE(display_lock_killable_daemon, l, l_next, blacklist) {
442 SYS_G_LIST_REMOVE(display_lock_killable_daemon, blacklist);
445 display_lock_killable_daemon = NULL;
446 initialized_killable_daemon_list = false;
449 static unsigned long get_lcd_on_flags(void)
451 unsigned long flags = NORMAL_MODE;
452 bool lcd_paneloff_mode = false;
454 display_panel_get_lcd_paneloff_mode(&lcd_paneloff_mode);
455 if (lcd_paneloff_mode)
456 flags |= LCD_PANEL_OFF_MODE;
458 if (ambient_get_state()) {
459 flags |= AMBIENT_MODE;
460 flags |= LCD_PHASED_TRANSIT_MODE;
466 bool touch_event_blocked(void)
468 return touch_blocked;
471 static gboolean late_transit_on(void *data)
474 return G_SOURCE_REMOVE;
476 g_source_remove(transit_timer);
479 display_backlight_change_brightness_by_dpms_state(DPMS_ON);
480 return G_SOURCE_REMOVE;
483 void lcd_on_procedure(int state, enum device_flags flag)
485 unsigned long flags = get_lcd_on_flags();
490 * Display on procedure
492 * step 2. check if display is detached (only for factory mode)
493 * step 3. broadcast lcd on signal with cause
494 * step 4. set brightness
495 * step 5. set pmstate of vconf
496 * step 6. display on operate
498 * - b. TSP(touch screen) enable
499 * step 7. broadcast lcd on complete signal
500 * step 8. key backlight enable
504 ret = is_lcdon_blocked();
505 if (ret != LCDON_BLOCK_NONE) {
506 _W("LCDON is blocked, %d.", ret);
510 _I("[lcdstep] 0x%lx", flags);
512 if (flags & AMBIENT_MODE) {
513 if (ambient_get_state() == false && display_panel_get_dpms_cached_state() == DPMS_ON)
515 ambient_set_state(false);
518 /* send LCDOn dbus signal */
519 if (!lcdon_broadcast)
520 broadcast_lcd_on(SIGNAL_PRE, flags);
522 if (!(flags & LCD_PHASED_TRANSIT_MODE)) {
523 /* Update brightness level */
524 if (state == LCD_DIM)
525 display_backlight_set_brightness_by_dim_brightness();
526 else if (state == LCD_NORMAL)
527 display_backlight_update_by_default_brightness();
530 if (state == LCD_NORMAL)
531 set_setting_pmstate(S_NORMAL);
532 else if (state == LCD_DIM)
533 set_setting_pmstate(S_LCDDIM);
535 display_start_dependent_device(flags);
537 if (!lcdon_broadcast) {
538 broadcast_lcd_on(SIGNAL_POST, flags);
539 if (flags & LCD_PHASED_TRANSIT_MODE)
540 transit_timer = g_timeout_add_seconds(LATE_LCD_TRANSIT,
541 late_transit_on, NULL);
542 lcdon_broadcast = true;
545 touch_blocked = false;
548 static unsigned long get_lcd_off_flags(void)
550 unsigned long flags = NORMAL_MODE;
551 bool stay_touchscreen_off = false;
553 if (ambient_get_condition() == true) {
554 flags |= AMBIENT_MODE;
555 flags |= LCD_PHASED_TRANSIT_MODE;
558 display_misc_get_stay_touchscreen_off(&stay_touchscreen_off);
559 if (stay_touchscreen_off)
560 flags |= TOUCH_SCREEN_OFF_MODE;
565 inline void lcd_off_procedure(enum device_flags flag)
567 unsigned long flags = get_lcd_off_flags();
571 * Display off procedure
572 * step 0. enhance mode off using nofity (e.g mdnie, HBM, LBM)
573 * step 1. broadcast lcd off signal with cause
574 * step 2. set pmstate of vconf
575 * step 3. display off operate
577 * - b. TSP(touch screen) disable
578 * step 4. broadcast lcd off complete siganl
579 * step 5. enter doze mode if it is enabled
581 _I("[lcdstep] 0x%lx", flags);
585 device_notify(DEVICE_NOTIFIER_LCD_OFF, NULL);
587 if (lcdon_broadcast) {
588 broadcast_lcd_off(SIGNAL_PRE, flags);
589 lcdon_broadcast = false;
594 touch_blocked = true;
596 if (flags & AMBIENT_MODE) {
597 if (ambient_get_state() == true)
599 ambient_set_state(true);
602 set_setting_pmstate(S_LCDOFF);
605 g_source_remove(transit_timer);
609 if (flags & LCD_PHASED_TRANSIT_MODE)
610 display_backlight_change_brightness_by_dpms_state(DPMS_OFF);
612 display_stop_dependent_device(flags);
614 if (flags & AMBIENT_MODE) {
615 broadcast_lcd_off_late(flags);
617 broadcast_lcd_off(SIGNAL_POST, flags);
618 device_notify(DEVICE_NOTIFIER_LCD_OFF_COMPLETE, NULL);
624 static void del_state_cond(void *data, enum state_t state)
626 PmLockNode *tmp = NULL;
632 /* A passed data is a pid_t type data, not a 64bit data. */
633 pid = (pid_t)((intptr_t)data);
634 _I("delete prohibit %s condition by timeout (%d)", states[state].name, pid);
636 if (pid == INTERNAL_LOCK_AMBIENT)
637 ambient_check_invalid_state(pid);
639 tmp = find_node(state, pid);
640 del_node(state, tmp);
641 set_unlock_time(pid, state);
643 /* Change state only when the two conditions below are satisfied.
644 * 1. There should be no running state-transition timer
645 * 2. Released lock is one of the pm_cur_state's lock
646 * This emulates already expired transition timer */
647 if (!display_state_transition_is_there_state_transition_timer() && (get_pm_cur_state() == state))
648 states[get_pm_cur_state()].trans(EVENT_TIMEOUT);
650 if (state == S_LCDOFF)
651 set_process_active(false, pid);
654 static gboolean del_normal_cond(void *data)
656 del_state_cond(data, S_NORMAL);
657 return G_SOURCE_REMOVE;
660 static gboolean del_dim_cond(void *data)
662 del_state_cond(data, S_LCDDIM);
663 return G_SOURCE_REMOVE;
666 static gboolean del_off_cond(void *data)
668 del_state_cond(data, S_LCDOFF);
669 return G_SOURCE_REMOVE;
672 /* get configurations from setting */
673 static int get_lcd_timeout_from_settings(void)
678 for (i = 0; i < S_END; i++) {
679 switch (states[i].state) {
681 get_run_timeout(&val);
684 get_dim_timeout(&val);
687 val = display_conf.lcdoff_timeout;
690 /* This state doesn't need to set time out. */
695 states[i].timeout = val;
697 _I("State(%s) timeout(%d) ms", states[i].name,
704 static void update_display_time(void)
706 int run_timeout, val;
708 /* first priority : custom timeout */
709 if (custom_normal_timeout > 0) {
710 states[S_NORMAL].timeout = custom_normal_timeout;
711 states[S_LCDDIM].timeout = custom_dim_timeout;
712 _I("CUSTOM : timeout is set by normal(%d ms), dim(%d ms)",
713 custom_normal_timeout, custom_dim_timeout);
717 /* second priority : lock state */
718 if ((__get_lock_screen_state() == VCONFKEY_IDLE_LOCK) &&
719 !get_lock_screen_bg_state()) {
720 /* timeout is different according to key or event. */
721 states[S_NORMAL].timeout = lock_screen_timeout;
722 _I("LOCK: Timeout(%d ms) is set by normal.",
723 lock_screen_timeout);
727 /* default setting */
728 get_run_timeout(&run_timeout);
731 * if the run_timeout is zero, it regards AlwaysOn state
733 if (run_timeout == 0 || display_conf.lcd_always_on) {
734 run_timeout = ALWAYS_ON_TIMEOUT;
735 _I("LCD always on.");
738 states[S_NORMAL].timeout = run_timeout;
740 get_dim_timeout(&val);
741 states[S_LCDDIM].timeout = val;
743 _I("Normal: NORMAL timeout is set by %d ms", states[S_NORMAL].timeout);
744 _I("Normal: DIM timeout is set by %d ms", states[S_LCDDIM].timeout);
747 static void update_display_locktime(int time)
749 lock_screen_timeout = time;
750 update_display_time();
753 void set_dim_state(bool on)
755 _I("Dim state is %d.", on);
756 update_display_time();
757 states[get_pm_cur_state()].trans(EVENT_INPUT);
760 void lcd_on_direct(enum device_flags flags)
762 enum hal_device_power_transition_reason reason;
764 if (flags & LCD_ON_BY_POWER_KEY)
765 reason = HAL_DEVICE_POWER_TRANSITION_REASON_POWER_KEY;
766 else if (flags & LCD_ON_BY_TOUCH)
767 reason = HAL_DEVICE_POWER_TRANSITION_REASON_TOUCH_SCREEN;
769 reason = HAL_DEVICE_POWER_TRANSITION_REASON_UNKNOWN;
771 power_request_change_state_strict(DEVICED_POWER_STATE_SLEEP, DEVICED_POWER_STATE_NORMAL, reason, NULL);
772 set_pm_cur_state(S_NORMAL);
774 _D("lcd is on directly");
775 gettimeofday(&lcdon_tv, NULL);
776 lcd_on_procedure(LCD_NORMAL, flags);
778 update_display_locktime(LOCK_SCREEN_INPUT_TIMEOUT);
781 static inline bool check_lcd_is_on(void)
783 if (display_panel_get_dpms_cached_state() != DPMS_ON)
789 static gboolean timer_refresh_cb(gpointer data)
794 ret = vconf_get_int(VCONFKEY_HOMESCREEN_WATCHFACE_VISIBILITY, &v);
796 _E("Failed to get homescreen watchface visibility");
802 * In watchface, it will be applied at 5 seconds for reduce power-supply.
803 * When the device's screen is another app, it will do turn off after 7 seconds.
805 if (set_custom_lcdon_timeout(5000) == true)
806 update_display_time();
808 /* state transition */
809 set_pm_old_state(get_pm_cur_state());
810 set_pm_cur_state(S_NORMAL);
811 st = &states[get_pm_cur_state()];
814 st->action(st->timeout);
819 int custom_lcdon(int timeout)
828 if (check_lcd_is_on() == false)
829 lcd_on_direct(LCD_ON_BY_GESTURE);
832 * During tutorial, reset timeout by default timeout, not the given timeout */
833 ret = vconf_get_int(VCONFKEY_HOMESCREEN_TUTORIAL_OOBE_ENABLED, &tutorial);
834 if (ret == 0 && tutorial) {
835 _D("During tutorial, reset timeout to default timeout.");
836 update = set_custom_lcdon_timeout(0);
838 _D("Custom lcd on timeout %dms.", timeout);
839 update = set_custom_lcdon_timeout(timeout);
843 update_display_time();
845 /* state transition */
846 set_pm_old_state(get_pm_cur_state());
847 set_pm_cur_state(S_NORMAL);
848 st = &states[get_pm_cur_state()];
852 st->action(st->timeout);
855 g_idle_add(timer_refresh_cb, NULL);
860 int custom_lcdoff(enum device_flags flag)
864 check_processes(S_NORMAL);
865 check_processes(S_LCDDIM);
867 /* check holdkey block flag in lock node */
868 if (check_lock_condition(S_NORMAL) || check_lock_condition(S_LCDDIM)) {
870 * When another proccess is normal lock, device is received call then,
871 * call app can be changed to lcd state by proximity.
872 * If proximity is near then normal lock will be unlocked.
874 if (flag & LCD_OFF_BY_PROXIMITY) {
875 _I("custom lcd off by proximity, delete normal lock");
876 delete_condition(S_NORMAL);
878 _I("skip custom lcd off");
883 _I("custom lcd off by flag(%d)", flag);
884 if (display_panel_get_dpms_cached_state() == DPMS_ON)
885 lcd_off_procedure(flag);
887 if (set_custom_lcdon_timeout(0) == true)
888 update_display_time();
890 /* state transition */
891 set_pm_old_state(get_pm_cur_state());
892 set_pm_cur_state(S_LCDOFF);
893 st = &states[get_pm_cur_state()];
897 st->action(st->timeout);
902 int display_on_by_reason(const char *reason, int timeout)
908 str_len = strlen(reason);
910 if (!strncmp(reason, GESTURE_STR, str_len))
911 flag = LCD_ON_BY_GESTURE;
912 else if (!strncmp(reason, EVENT_STR, str_len))
913 flag = LCD_ON_BY_EVENT;
915 _E("Reason is unknown(%s)", reason);
920 _E("Cannot setting timeout %d", timeout);
924 if (check_lcd_is_on() == false)
927 _I("platform lcd on by %s (%d ms)", reason, timeout);
928 if (set_custom_lcdon_timeout(timeout) == true)
929 update_display_time();
931 /* state transition */
932 set_pm_old_state(get_pm_cur_state());
933 set_pm_cur_state(S_NORMAL);
934 st = &states[get_pm_cur_state()];
938 st->action(st->timeout);
943 int display_off_by_reason(const char *reason)
949 str_len = strlen(reason);
951 if (!strncmp(reason, GESTURE_STR, str_len)) {
952 check_processes(S_NORMAL);
953 check_processes(S_LCDDIM);
955 /* check holdkey block flag in lock node */
956 if (check_lock_condition(S_NORMAL) || check_lock_condition(S_LCDDIM)) {
957 _I("skip platform lcd off by gesture");
960 flag = LCD_OFF_BY_GESTURE;
961 } else if (!strncmp(reason, PALM_STR, str_len)) {
962 delete_condition(S_NORMAL);
963 delete_condition(S_LCDDIM);
965 flag = LCD_OFF_BY_PALM;
966 } else if (!strncmp(reason, DISPLAY_DETACH_STR, str_len)) {
967 delete_condition(S_NORMAL);
968 delete_condition(S_LCDDIM);
970 flag = LCD_OFF_BY_DISPLAY_DETACH;
972 _E("Reason is unknown(%s)", reason);
976 _I("platform lcd off by %s", reason);
977 if (display_panel_get_dpms_cached_state() == DPMS_ON)
978 lcd_off_procedure(flag);
980 /* state transition */
981 set_pm_old_state(get_pm_cur_state());
982 set_pm_cur_state(S_LCDOFF);
983 st = &states[get_pm_cur_state()];
987 st->action(st->timeout);
992 static void default_proc_change_state_action(enum state_t next, int timeout)
996 set_pm_old_state(get_pm_cur_state());
997 set_pm_cur_state(next);
999 st = &states[get_pm_cur_state()];
1001 if (st && st->action) {
1003 st->action(st->timeout);
1005 st->action(timeout);
1009 static int default_proc_change_state(unsigned int cond, pid_t pid)
1013 next = GET_COND_STATE(cond);
1014 _I("Change process(%d) state to %s.", pid, states[next].name);
1018 if (check_lcd_is_on() == false)
1019 lcd_on_direct(LCD_ON_BY_EVENT);
1020 update_display_locktime(LOCK_SCREEN_CONTROL_TIMEOUT);
1021 default_proc_change_state_action(next, -1);
1024 default_proc_change_state_action(next, -1);
1027 if (display_panel_get_dpms_cached_state() == DPMS_ON)
1028 lcd_off_procedure(LCD_OFF_BY_EVENT);
1029 if (set_custom_lcdon_timeout(0))
1030 update_display_time();
1031 default_proc_change_state_action(next, -1);
1034 _I("Dangerous requests.");
1035 /* at first LCD_OFF and then goto sleep */
1036 /* state transition */
1037 default_proc_change_state_action(S_LCDOFF, TIMEOUT_NONE);
1038 delete_condition(S_NORMAL);
1039 delete_condition(S_LCDDIM);
1040 delete_condition(S_LCDOFF);
1041 if (lcdon_broadcast) {
1042 _I("broadcast lcd off signal at non-lcd device");
1043 broadcast_lcd_off(SIGNAL_PRE, 0);
1044 broadcast_lcd_off(SIGNAL_POST, 0);
1046 default_proc_change_state_action(S_SLEEP, TIMEOUT_NONE);
1056 static void proc_condition_lock(PMMsg *data)
1059 guint cond_timeout_id = 0;
1060 char pname[PATH_MAX];
1061 pid_t pid = data->pid;
1063 int holdkey_block, ret;
1066 const char *lock_type = NULL;
1068 state = GET_COND_STATE(data->cond);
1069 if (state == S_START)
1072 flags = GET_COND_FLAG(data->cond);
1073 display_misc_get_process_name(pid, pname);
1075 if ((state == S_LCDOFF) && (get_pm_cur_state() == S_SLEEP) &&
1076 (pm_get_power_lock() == POWER_UNLOCK))
1077 proc_change_state(data->cond, INTERNAL_LOCK_PM);
1079 if (data->timeout > 0) {
1080 /* To pass a pid_t data through the timer infrastructure
1081 * without memory allocation, a pid_t data becomes typecast
1082 * to intptr_t and void *(64bit) type. */
1083 cond_timeout_id = g_timeout_add(
1085 states[state].timeout_cb,
1086 (void*)((intptr_t)pid));
1087 if (!cond_timeout_id)
1088 _E("Failed to register display timer.");
1091 holdkey_block = GET_COND_FLAG(data->cond) & PM_FLAG_BLOCK_HOLDKEY;
1093 tmp = find_node(state, pid);
1095 tmp = add_node(state, pid, cond_timeout_id, holdkey_block);
1097 _E("Failed to acquire lock, state: %d, pid: %d.", state, pid);
1101 update_lock_timer(data, tmp, cond_timeout_id);
1102 tmp->holdkey_block = holdkey_block;
1105 if (state == S_LCDOFF)
1106 set_process_active(true, pid);
1108 _I("[%s] locked by %5d with %u ms", states[state].name, pid, data->timeout);
1110 if (pid < INTERNAL_LOCK_BASE) {
1112 if (state == S_LCDOFF)
1113 lock_type = PM_LCDOFF_STR;
1114 else if (state == S_LCDDIM)
1115 lock_type = PM_LCDDIM_STR;
1116 else if (state == S_NORMAL)
1117 lock_type = PM_LCDON_STR;
1120 /* power lock signal */
1121 ret = gdbus_signal_emit(NULL,
1122 DEVICED_PATH_DISPLAY,
1123 DEVICED_INTERFACE_DISPLAY,
1125 g_variant_new("(sii)", lock_type, pid, (int)data->timeout));
1127 _E("Failed to send dbus signal PowerLock.");
1131 _SD("be requested LOCK info pname(%s), holdkeyblock(%d) flags(%d) killable_daemon(%d)",
1132 pname, holdkey_block, flags, tmp->killable_daemon);
1133 set_lock_time(pid, pname, state);
1135 device_notify(DEVICE_NOTIFIER_DISPLAY_LOCK, (void *)&value);
1138 static void proc_condition_unlock(PMMsg *data)
1140 pid_t pid = data->pid;
1143 char pname[PATH_MAX];
1147 const char *lock_type = NULL;
1149 state = GET_COND_STATE(data->cond);
1153 flags = GET_COND_FLAG(data->cond);
1154 display_misc_get_process_name(pid, pname);
1156 tmp = find_node(state, pid);
1157 del_node(state, tmp);
1159 if (state == S_LCDOFF)
1160 set_process_active(false, pid);
1162 _I("[%s] unlocked by %5d", states[state].name, pid);
1164 if (pid < INTERNAL_LOCK_BASE) {
1166 if (state == S_LCDOFF)
1167 lock_type = PM_LCDOFF_STR;
1168 else if (state == S_LCDDIM)
1169 lock_type = PM_LCDDIM_STR;
1170 else if (state == S_NORMAL)
1171 lock_type = PM_LCDON_STR;
1174 /* power unlock signal */
1175 ret = gdbus_signal_emit(NULL,
1176 DEVICED_PATH_DISPLAY,
1177 DEVICED_INTERFACE_DISPLAY,
1179 g_variant_new("(sii)", lock_type, pid, (int)data->timeout));
1181 _E("Failed to send dbus signal PowerUnlock.");
1185 _SD("be requested UNLOCK info pname(%s) flag(%d)", pname, flags);
1186 set_unlock_time(pid, state);
1188 device_notify(DEVICE_NOTIFIER_DISPLAY_LOCK, (void *)&value);
1191 static int proc_condition(PMMsg *data)
1195 if (IS_COND_REQUEST_LOCK(data->cond))
1196 proc_condition_lock(data);
1198 if (IS_COND_REQUEST_UNLOCK(data->cond))
1199 proc_condition_unlock(data);
1201 if (!display_conf.timeout_enable)
1204 flags = GET_COND_FLAG(data->cond);
1206 /* guard time for suspend */
1207 if (get_pm_cur_state() == S_LCDOFF)
1208 display_state_transition_reset_state_transition_timeout(states[S_LCDOFF].timeout);
1210 if (flags & PM_FLAG_RESET_TIMER)
1211 display_state_transition_reset_state_transition_timeout(states[get_pm_cur_state()].timeout);
1214 if (!display_state_transition_is_there_state_transition_timer())
1215 states[get_pm_cur_state()].trans(EVENT_TIMEOUT);
1220 void update_lcdoff_source(int source)
1225 case VCONFKEY_PM_LCDOFF_BY_TIMEOUT:
1226 _I("LCD OFF by timeout.");
1228 case VCONFKEY_PM_LCDOFF_BY_POWERKEY:
1229 _I("LCD OFF by powerkey.");
1232 _E("Invalid value(%d).", source);
1235 ret = vconf_set_int(VCONFKEY_PM_LCDOFF_SOURCE, source);
1237 _E("Failed to set vconf value for lcd off source: %d", vconf_get_ext_errno());
1240 void print_info(int fd)
1243 char buf[PATH_MAX + 255];
1246 char pname[PATH_MAX];
1254 snprintf(buf, sizeof(buf),
1255 "\n==========================================="
1256 "===========================\n");
1257 ret = write(fd, buf, strlen(buf));
1259 _E("Write() failed: %d", errno);
1260 snprintf(buf, sizeof(buf), "Timeout Info: Run[%dms] Dim[%dms] Off[%dms]\n",
1261 states[S_NORMAL].timeout,
1262 states[S_LCDDIM].timeout, states[S_LCDOFF].timeout);
1263 ret = write(fd, buf, strlen(buf));
1265 _E("Write() failed: %d", errno);
1267 snprintf(buf, sizeof(buf), "Tran. Locked : %s %s %s\n",
1268 (get_trans_condition() & MASK_NORMAL) ? states[S_NORMAL].name : "-",
1269 (get_trans_condition() & MASK_DIM) ? states[S_LCDDIM].name : "-",
1270 (get_trans_condition() & MASK_OFF) ? states[S_LCDOFF].name : "-");
1271 ret = write(fd, buf, strlen(buf));
1273 _E("Write() failed: %d", errno);
1275 snprintf(buf, sizeof(buf), "Current State: %s\n",
1276 states[get_pm_cur_state()].name);
1277 ret = write(fd, buf, strlen(buf));
1279 _E("Write() failed: %d", errno);
1281 snprintf(buf, sizeof(buf), "Current Lock Conditions: \n");
1282 ret = write(fd, buf, strlen(buf));
1284 _E("Write() failed: %d", errno);
1286 for (s_index = S_NORMAL; s_index < S_END; s_index++) {
1287 SYS_G_LIST_FOREACH(get_cond_head(s_index), elem, t) {
1288 display_misc_get_process_name((pid_t)t->pid, pname);
1289 ctime_r(&t->time, time_buf);
1290 time_buf[strlen(time_buf) - 1] = 0;
1291 snprintf(buf, sizeof(buf),
1292 " %d: [%s] locked by pid %d %s %s\n",
1293 i++, states[s_index].name, t->pid, pname, time_buf);
1294 ret = write(fd, buf, strlen(buf));
1296 _E("Write() failed: %d", errno);
1300 print_lock_info_list(fd);
1302 #ifdef ENABLE_PM_LOG
1303 pm_history_print(fd, 250);
1307 void save_display_log(const char *path)
1314 _D("internal state is saved!");
1317 ctime_r(&now_time, time_buf);
1318 time_buf[strlen(time_buf) - 1] = 0;
1320 fd = open(path, O_CREAT | O_TRUNC | O_WRONLY, 0644);
1322 snprintf(buf, sizeof(buf),
1323 "\npm_state_log now-time : %d(s) %s\n\n",
1324 (int)now_time, time_buf);
1325 ret = write(fd, buf, strlen(buf));
1327 _E("write() failed (%d)", errno);
1329 snprintf(buf, sizeof(buf), "pm_status_flag: %#x\n", get_pm_status_flag());
1330 ret = write(fd, buf, strlen(buf));
1332 _E("write() failed (%d)", errno);
1334 if (disp_plgn->get_lock_screen_state ) {
1335 snprintf(buf, sizeof(buf), "screen lock status : %d\n",
1336 disp_plgn->get_lock_screen_state());
1337 ret = write(fd, buf, strlen(buf));
1339 _E("write() failed (%d)", errno);
1345 fd = open("/dev/console", O_WRONLY);
1352 /* SIGHUP signal handler
1353 * For debug... print info to syslog
1355 static void sig_hup(int signo)
1357 _I("received sig hub %d", signo);
1362 int check_lcdoff_direct(void)
1364 int ret, lock, cradle;
1367 if (get_pm_old_state() != S_NORMAL)
1370 if (get_pm_cur_state() != S_LCDDIM)
1373 if (!display_conf.dimming)
1376 lock = __get_lock_screen_state();
1377 if (lock != VCONFKEY_IDLE_LOCK)
1380 hdmi_state = extcon_get_status(EXTCON_CABLE_HDMI);
1384 ret = vconf_get_int(VCONFKEY_SYSMAN_CRADLE_STATUS, &cradle);
1385 if (ret >= 0 && cradle == DOCK_SOUND)
1388 _E("Failed to get vconf value for cradle status: %d", vconf_get_ext_errno());
1390 _D("Goto LCDOFF direct: lock(%d) hdmi(%d) cradle(%d).", lock, hdmi_state, cradle);
1396 * default transition function
1399 * 3. call enter action function
1401 static int default_trans(int evt)
1403 struct state *st = &states[get_pm_cur_state()];
1405 enum state_t next_state;
1407 display_state_transition_get_next_transition_display_state(get_pm_cur_state(), &next_state, evt);
1409 /* check conditions */
1410 if (st->check && !st->check(get_pm_cur_state(), next_state)) {
1411 /* There is a condition. */
1412 _I("%s locked. Trans to %s failed.", states[get_pm_cur_state()].name,
1413 states[next_state].name);
1417 ret = is_lcdon_blocked();
1418 if (ret != LCDON_BLOCK_NONE) {
1419 if (next_state == S_NORMAL || next_state == S_LCDDIM) {
1420 _W("LCDON is blocked, %d.", ret);
1425 /* state transition */
1426 set_pm_old_state(get_pm_cur_state());
1427 set_pm_cur_state(next_state);
1428 st = &states[get_pm_cur_state()];
1432 if (get_pm_cur_state() == S_LCDOFF)
1433 update_lcdoff_source(VCONFKEY_PM_LCDOFF_BY_TIMEOUT);
1435 if ((get_pm_cur_state() == S_NORMAL) || (get_pm_cur_state() == S_LCDOFF))
1436 if (set_custom_lcdon_timeout(0) == true)
1437 update_display_time();
1439 if (check_lcdoff_direct() == true) {
1440 /* enter next state directly */
1441 states[get_pm_cur_state()].trans(EVENT_TIMEOUT);
1443 if ((get_pm_cur_state() == S_SLEEP)
1444 && (is_emulator() == true || timeout_sleep_support == false))
1447 st->action(st->timeout);
1454 static gboolean lcd_on_expired(void *data)
1456 int lock_state, ret;
1458 if (lock_timeout_id)
1459 lock_timeout_id = 0;
1461 /* check state of lock */
1462 ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
1463 if (ret > 0 && lock_state == VCONFKEY_IDLE_LOCK)
1464 return G_SOURCE_REMOVE;
1466 _E("Failed to get vconf value for idle lock state: %d", vconf_get_ext_errno());
1468 /* lock screen is not launched yet, but lcd is on */
1469 if (check_lcd_is_on() == false)
1470 lcd_on_procedure(LCD_NORMAL, NORMAL_MODE);
1472 return G_SOURCE_REMOVE;
1475 static inline void stop_lock_timer(void)
1477 if (lock_timeout_id) {
1478 g_source_remove(lock_timeout_id);
1479 lock_timeout_id = 0;
1483 static void check_lock_screen(void)
1485 int lock_state, ret;
1489 /* check state of lock */
1490 ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
1491 if (ret < 0 || lock_state == VCONFKEY_IDLE_LOCK)
1494 /* Use time to check lock is done. */
1495 lock_timeout_id = g_timeout_add(display_conf.lock_wait_time,
1496 lcd_on_expired, NULL);
1499 /* default enter action function */
1500 static int default_action(int timeout)
1502 int wakeup_count = -1, pm_cur_state;
1506 static time_t last_update_time = 0;
1507 static int last_timeout = 0;
1508 struct timeval now_tv;
1511 bool lcd_paneloff_mode = false;
1513 if (status != DEVICE_OPS_STATUS_START) {
1514 _E("Display is not started.");
1518 ret = is_lcdon_blocked();
1519 if (ret != LCDON_BLOCK_NONE) {
1520 if ((get_pm_cur_state() == S_NORMAL) || (get_pm_cur_state() == S_LCDDIM)) {
1521 _W("LCDON is blocked, %d.", ret);
1526 if (get_pm_cur_state() != S_SLEEP) {
1527 if ((get_pm_cur_state() == S_NORMAL) &&
1528 lcdon_tv.tv_sec != 0) {
1529 gettimeofday(&now_tv, NULL);
1530 timeout -= DIFF_TIMEVAL_MS(now_tv, lcdon_tv);
1531 lcdon_tv.tv_sec = 0;
1533 /* set timer with current state timeout */
1534 display_state_transition_reset_state_transition_timeout(timeout);
1536 if (get_pm_cur_state() == S_NORMAL) {
1537 time(&last_update_time);
1538 last_timeout = timeout;
1540 _I("Timout set: %s state %d ms",
1541 states[get_pm_cur_state()].name, timeout);
1545 if ((get_pm_cur_state() != get_pm_old_state()) && (get_pm_cur_state() != S_SLEEP)) {
1546 power_request_change_state_strict(DEVICED_POWER_STATE_SLEEP, DEVICED_POWER_STATE_NORMAL,
1547 power_get_wakeup_reason(), NULL);
1548 set_setting_pmstate(get_pm_cur_state());
1549 pm_cur_state = get_pm_cur_state();
1550 device_notify(DEVICE_NOTIFIER_LCD, (void *)&pm_cur_state);
1553 if ((get_pm_old_state() == S_NORMAL) && (get_pm_cur_state() != S_NORMAL)) {
1555 diff = difftime(now, last_update_time);
1556 _I("S_NORMAL is changed to %s (timeout=%d ms diff=%.0f s).",
1557 states[get_pm_cur_state()].name, last_timeout, diff);
1560 /* update status for battery monitor */
1561 update_bds_record(get_pm_cur_state());
1563 switch (get_pm_cur_state()) {
1566 * normal state : backlight on and restore
1567 * the previous brightness
1569 if ((get_pm_old_state() == S_LCDOFF) || (get_pm_old_state() == S_SLEEP))
1570 check_lock_screen();
1571 else if (get_pm_old_state() == S_LCDDIM)
1572 display_backlight_update_by_default_brightness();
1574 if (check_lcd_is_on() == false)
1575 lcd_on_procedure(LCD_NORMAL, NORMAL_MODE);
1579 display_backlight_get_custom_status(&custom_status);
1580 if ((get_pm_old_state() == S_NORMAL) && custom_status) {
1581 display_backlight_get_brightness(&brightness);
1582 display_backlight_set_custom_brightness(brightness);
1584 /* lcd dim state : dim the brightness */
1585 display_backlight_set_brightness_by_dim_brightness();
1587 if ((get_pm_old_state() == S_LCDOFF) || (get_pm_old_state() == S_SLEEP))
1588 lcd_on_procedure(LCD_DIM, NORMAL_MODE);
1592 if ((get_pm_old_state() != S_SLEEP) && (get_pm_old_state() != S_LCDOFF)) {
1594 /* lcd off state : turn off the backlight */
1595 if (display_panel_get_dpms_cached_state() == DPMS_ON)
1596 lcd_off_procedure(LCD_OFF_BY_TIMEOUT);
1599 display_panel_get_lcd_paneloff_mode(&lcd_paneloff_mode);
1600 if (display_panel_get_dpms_cached_state() == DPMS_ON
1601 || lcd_paneloff_mode)
1602 lcd_off_procedure(LCD_OFF_BY_TIMEOUT);
1606 if ((get_pm_old_state() != S_SLEEP) && (get_pm_old_state() != S_LCDOFF))
1609 if (display_panel_get_dpms_cached_state() == DPMS_ON)
1610 lcd_off_procedure(LCD_OFF_BY_TIMEOUT);
1612 if (!pm_get_power_lock_support()) {
1613 /* sleep state : set system mode to SUSPEND */
1614 if (get_wakeup_count(&wakeup_count) < 0)
1615 _E("Wakeup count read error.");
1617 if (wakeup_count < 0) {
1618 _I("Wakup Event. Can not enter suspend mode.");
1622 if (set_wakeup_count(wakeup_count) < 0) {
1623 _E("Wakeup count write error.");
1633 #ifdef ENABLE_PM_LOG
1634 pm_history_save(PM_LOG_SLEEP, get_pm_cur_state());
1636 power_request_change_state(DEVICED_POWER_STATE_SLEEP, HAL_DEVICE_POWER_TRANSITION_REASON_DISPLAY_OFF_TIMEOUT);
1640 if (!pm_get_power_lock_support()) {
1642 states[get_pm_cur_state()].trans(EVENT_DEVICE);
1648 * default check function
1650 * 0 : can't transit, others : transitable
1652 static int default_check(int curr, int next)
1656 makeup_trans_condition();
1658 trans_cond = get_trans_condition() & MASK_BIT;
1660 if (next == S_NORMAL) /* S_NORMAL is exceptional */
1665 trans_cond = trans_cond & MASK_NORMAL;
1668 trans_cond = trans_cond & MASK_DIM;
1671 trans_cond = trans_cond & MASK_OFF;
1678 if (trans_cond != 0) {
1683 return 1; /* transitable */
1686 static void default_saving_mode(int onoff)
1689 set_pm_status_flag(PWRSV_FLAG);
1690 auto_brightness_control(BR_LOWDIM_ON, BR_IMPLICIT);
1692 clear_pm_status_flag(PWRSV_FLAG);
1693 auto_brightness_control(BR_LOWDIM_OFF, BR_IMPLICIT);
1697 int poll_callback(int condition, PMMsg *data)
1699 static time_t last_t;
1702 if (status != DEVICE_OPS_STATUS_START) {
1703 _E("Display logic is not started.");
1707 if (condition == INPUT_POLL_EVENT) {
1708 if ((get_pm_cur_state() == S_LCDOFF) || (get_pm_cur_state() == S_SLEEP))
1709 _I("Input event signal at Display Off");
1711 if ((last_t != now) ||
1712 (get_pm_cur_state() == S_LCDOFF) ||
1713 (get_pm_cur_state() == S_SLEEP)) {
1714 states[get_pm_cur_state()].trans(EVENT_INPUT);
1719 if (condition == PM_CONTROL_EVENT) {
1720 proc_condition(data);
1722 if (IS_COND_REQUEST_CHANGE(data->cond))
1723 proc_change_state(data->cond, data->pid);
1729 static int update_setting(int key_idx, int val)
1734 case SETTING_TO_NORMAL:
1735 update_display_time();
1736 states[get_pm_cur_state()].trans(EVENT_INPUT);
1738 case SETTING_LOW_BATT:
1739 if (display_misc_is_low_battery_state(val)) {
1740 if (!(get_pm_status_flag() & CHRGR_FLAG))
1741 power_saving_func(true);
1742 set_pm_status_flag(LOWBT_FLAG);
1744 if (get_pm_status_flag() & PWRSV_FLAG)
1745 power_saving_func(false);
1746 clear_pm_status_flag(LOWBT_FLAG);
1747 clear_pm_status_flag(BRTCH_FLAG);
1748 ret = vconf_set_bool(VCONFKEY_PM_BRIGHTNESS_CHANGED_IN_LPM, false);
1750 _E("Failed to set vconf value for brightness changed in lpm: %d", vconf_get_ext_errno());
1753 case SETTING_CHARGING:
1755 if (get_pm_status_flag() & LOWBT_FLAG) {
1756 power_saving_func(false);
1757 clear_pm_status_flag(LOWBT_FLAG);
1759 set_pm_status_flag(CHRGR_FLAG);
1762 ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW,
1765 bat_state = VCONFKEY_SYSMAN_BAT_NORMAL;
1766 _E("Failed to get vconf value for battery status low: %d", vconf_get_ext_errno());
1768 if (display_misc_is_low_battery_state(bat_state)) {
1769 power_saving_func(true);
1770 set_pm_status_flag(LOWBT_FLAG);
1772 clear_pm_status_flag(CHRGR_FLAG);
1775 case SETTING_BRT_LEVEL:
1776 if (get_pm_status_flag() & PWRSV_FLAG) {
1777 set_pm_status_flag(BRTCH_FLAG);
1778 ret = vconf_set_bool(VCONFKEY_PM_BRIGHTNESS_CHANGED_IN_LPM, true);
1780 _E("Failed to set vconf value for brightness changed in lpm: %d", vconf_get_ext_errno());
1781 _I("Brightness changed in low battery,"
1782 "escape dim state.");
1784 display_backlight_set_default_brightness(val);
1786 case SETTING_LOCK_SCREEN:
1787 set_lock_screen_state(val);
1789 /* LCD on if lock screen show before waiting time */
1790 if ((get_pm_cur_state() == S_NORMAL) &&
1791 val == VCONFKEY_IDLE_LOCK &&
1792 display_panel_get_dpms_cached_state() != DPMS_ON &&
1793 is_lcdon_blocked() == LCDON_BLOCK_NONE)
1794 lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
1796 update_display_time();
1797 if (get_pm_cur_state() == S_NORMAL)
1798 states[get_pm_cur_state()].trans(EVENT_INPUT);
1800 case SETTING_LOCK_SCREEN_BG:
1801 set_lock_screen_bg_state(val);
1802 update_display_time();
1803 if (get_pm_cur_state() == S_NORMAL)
1804 states[get_pm_cur_state()].trans(EVENT_INPUT);
1806 case SETTING_POWER_CUSTOM_BRIGHTNESS:
1807 if (val == VCONFKEY_PM_CUSTOM_BRIGHTNESS_ON)
1808 display_backlight_set_custom_status(true);
1810 display_backlight_set_custom_status(false);
1819 static void check_seed_status(void)
1827 /* Charging check */
1828 if (fp_get_charging_status && (fp_get_charging_status(&tmp) == 0) && (tmp > 0))
1829 set_pm_status_flag(CHRGR_FLAG);
1831 ret = get_setting_brightness(&tmp);
1832 if (ret != 0 || (tmp < PM_MIN_BRIGHTNESS || tmp > PM_MAX_BRIGHTNESS)) {
1833 _I("Failed to read vconf value for brightness.");
1834 brt = display_conf.pm_default_brightness;
1835 if (tmp < PM_MIN_BRIGHTNESS || tmp > PM_MAX_BRIGHTNESS) {
1836 ret = vconf_set_int(VCONFKEY_SETAPPL_LCD_BRIGHTNESS, brt);
1838 _E("Failed to set vconf value for lcd brightness: %d", vconf_get_ext_errno());
1842 _I("Set brightness(%d) from setting app.", tmp);
1843 display_backlight_set_default_brightness(tmp);
1844 display_backlight_set_brightness(tmp);
1846 ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, &bat_state);
1848 bat_state = VCONFKEY_SYSMAN_BAT_NORMAL;
1849 _E("Failed to get vconf value for battery status low: %d", vconf_get_ext_errno());
1851 if (display_misc_is_low_battery_state(bat_state)) {
1852 if (!(get_pm_status_flag() & CHRGR_FLAG)) {
1853 power_saving_func(true);
1854 set_pm_status_flag(LOWBT_FLAG);
1858 /* lock screen check */
1859 ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
1862 _E("Failed to get vconf value for idle lock state: %d", vconf_get_ext_errno());
1864 set_lock_screen_state(lock_state);
1865 if (lock_state == VCONFKEY_IDLE_LOCK) {
1866 states[S_NORMAL].timeout = lock_screen_timeout;
1867 _I("LCD NORMAL timeout(%d ms) is set"
1868 " for lock screen.", lock_screen_timeout);
1874 static void init_lcd_operation(void)
1876 const struct device_ops *ops = NULL;
1878 ops = find_device("display");
1879 if (!check_default(ops))
1880 display_register_dependent_device(ops);
1882 ops = find_device("touchscreen");
1883 if (!check_default(ops))
1884 display_register_dependent_device(ops);
1886 ops = find_device("bezel");
1887 if (!check_default(ops))
1888 display_register_dependent_device(ops);
1891 static void exit_lcd_operation(void)
1893 display_unregister_dependent_device();
1905 static const char *errMSG[INIT_END] = {
1906 [INIT_SETTING] = "setting init error",
1907 [INIT_INTERFACE] = "lowlevel interface(sysfs or others) init error",
1908 [INIT_POLL] = "input devices poll init error",
1909 [INIT_FIFO] = "FIFO poll init error",
1910 [INIT_DBUS] = "d-bus init error",
1913 int set_lcd_timeout(int on, int dim, int holdkey_block, const char *name)
1915 if (on == 0 && dim == 0) {
1916 _I("LCD timeout changed: default setting");
1917 custom_normal_timeout = custom_dim_timeout = 0;
1918 } else if (on < 0 || dim < 0) {
1919 _E("Failed to set value(on=%d dim=%d).", on, dim);
1922 _I("LCD timeout changed: on=%ds dim=%ds", on, dim);
1923 custom_normal_timeout = SEC_TO_MSEC(on);
1924 custom_dim_timeout = SEC_TO_MSEC(dim);
1926 /* Apply new backlight time */
1927 update_display_time();
1928 if (get_pm_cur_state() == S_NORMAL)
1929 states[get_pm_cur_state()].trans(EVENT_INPUT);
1931 if (holdkey_block) {
1932 display_lock_set_custom_holdkey_block(true);
1933 _I("Hold key disabled.");
1935 display_lock_set_custom_holdkey_block(false);
1936 _I("Hold key enabled.");
1939 if (custom_change_name) {
1940 free(custom_change_name);
1941 custom_change_name = 0;
1944 if (custom_normal_timeout == 0 &&
1945 custom_dim_timeout == 0 &&
1949 custom_change_name = strndup(name, strlen(name));
1950 if (!custom_change_name) {
1951 _E("Failed to malloc.");
1952 custom_normal_timeout = custom_dim_timeout = 0;
1953 display_lock_set_custom_holdkey_block(false);
1960 void reset_lcd_timeout(GDBusConnection *conn,
1961 const gchar *sender,
1962 const gchar *unique_name,
1968 if (!custom_change_name)
1971 if (strcmp(sender, custom_change_name))
1974 _I("reset lcd timeout: Set default timeout. sender=%s", sender);
1976 free(custom_change_name);
1977 custom_change_name = 0;
1978 custom_normal_timeout = custom_dim_timeout = 0;
1979 display_lock_set_custom_holdkey_block(false);
1981 update_display_time();
1982 if (get_pm_cur_state() == S_NORMAL)
1983 states[get_pm_cur_state()].trans(EVENT_INPUT);
1986 static int delayed_init_done(void *data)
1988 static bool done = false;
1997 _I("Booting done, release booting lock.");
1998 if (disp_plgn->pm_unlock_internal) {
1999 disp_plgn->pm_unlock_internal(INTERNAL_LOCK_BOOTING, LCD_NORMAL, PM_SLEEP_MARGIN);
2000 disp_plgn->pm_unlock_internal(INTERNAL_LOCK_BOOTING, LCD_OFF, PM_SLEEP_MARGIN);
2006 static int powerlock_load_config(struct parse_result *result, void *user_data)
2010 _D("powerlock_load_config: section=%s name=%s value=%s", result->section, result->name, result->value);
2012 if (MATCH(result->section, "KillableDaemon") && MATCH(result->name, "KillableList")) {
2013 name = strndup(result->value, PATH_MAX - 1);
2015 _E("Not enough memory.");
2019 CRITICAL_LOG("Add %s to killable daemon list.", name);
2020 SYS_G_LIST_APPEND(display_lock_killable_daemon, name);
2026 static gboolean delayed_dpms_init_done(gpointer data)
2030 if (!display_panel_init_dpms())
2031 return G_SOURCE_CONTINUE;
2033 switch (get_pm_cur_state()) {
2036 lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
2037 if (display_conf.timeout_enable) {
2038 timeout = states[S_NORMAL].timeout;
2039 /* check minimun lcd on time */
2040 if (timeout < SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT))
2041 timeout = SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT);
2042 display_state_transition_reset_state_transition_timeout(timeout);
2046 lcd_off_procedure(LCD_OFF_BY_EVENT);
2047 timeout = display_conf.lcdoff_timeout;
2048 display_state_transition_reset_state_transition_timeout(timeout);
2054 return G_SOURCE_REMOVE;
2057 static void add_timer_for_dpms_init(void)
2059 guint id = g_timeout_add(500/* milliseconds */, delayed_dpms_init_done, NULL);
2061 _E("Failed to add display_panel_init_dpms timeout.");
2064 static void init_display_states(void *data)
2066 struct display_plugin *dp = (struct display_plugin *) data;
2067 for(int i = 0; i < S_END; i++)
2068 dp->display_states[i] = &states[i];
2071 * Power manager Main
2074 static int display_probe(void *data)
2077 struct display_plugin *dp = (struct display_plugin *) data;
2080 dp->config = &display_conf;
2081 init_display_states(dp);
2082 setup_display_plugin_backlight_ops(dp);
2083 dp->delete_state_cond = del_state_cond;
2086 * load display service
2087 * if there is no display shared library,
2088 * deviced does not provide any method and function of display.
2090 ret = display_service_load();
2094 /* display_plugin instance initialization */
2095 init_pm_internal(data);
2096 disp_plgn->device_flags_to_string = __device_flags_to_string;
2098 if (battery_plgn->handle) {
2099 fp_get_charging_status = dlsym(battery_plgn->handle, "get_charging_status");
2100 if (!fp_get_charging_status)
2101 _E("Failed to obtain address of get_charging_status");
2103 _I("There is no battery module.");
2108 static int input_init_handler(void)
2110 if (!display_conf.input_support)
2111 remove_device_by_devname("input");
2116 static int power_resume_from_echomem_callback(void *data)
2118 system_wakeup_flag = true;
2119 if (check_wakeup_src() == EVENT_DEVICE)
2120 /* system waked up by devices */
2121 states[get_pm_cur_state()].trans(EVENT_DEVICE);
2123 /* system waked up by user input */
2124 states[get_pm_cur_state()].trans(EVENT_INPUT);
2129 static int poweroff_triggered_callback(void *udata)
2131 int val = (int)(intptr_t) udata;
2134 case VCONFKEY_SYSMAN_POWER_OFF_NONE:
2135 clear_pm_status_flag(PWROFF_FLAG);
2137 case VCONFKEY_SYSMAN_POWER_OFF_DIRECT:
2138 case VCONFKEY_SYSMAN_POWER_OFF_RESTART:
2139 set_pm_status_flag(PWROFF_FLAG);
2146 static void esd_action(void)
2148 const struct device_ops *touchscreen_ops = NULL;
2152 touchscreen_ops = find_device("touchscreen");
2154 if (!check_default(touchscreen_ops))
2155 touchscreen_ops->stop(NORMAL_MODE);
2156 display_panel_set_panel_state_by_off_state(NORMAL_MODE);
2157 display_panel_set_panel_state_by_on_state(NORMAL_MODE);
2158 if (!check_default(touchscreen_ops))
2159 touchscreen_ops->start(NORMAL_MODE);
2162 static void lcd_uevent_changed(struct udev_device *dev)
2164 const char *devpath;
2167 devpath = udev_device_get_devpath(dev);
2171 if (!fnmatch(LCD_ESD_PATH, devpath, 0)) {
2172 action = udev_device_get_action(dev);
2173 if (!strcmp(action, UDEV_CHANGE))
2178 static void sec_dsim_uevent_changed(struct udev_device *dev)
2180 const char *devpath;
2184 devpath = udev_device_get_devpath(dev);
2188 if (!fnmatch(SEC_DSIM_PATH, devpath, 0)) {
2189 action = udev_device_get_action(dev);
2190 if (!strcmp(action, UDEV_CHANGE)) {
2191 ret = gdbus_signal_emit(NULL,
2192 DEVICED_PATH_DISPLAY,
2193 DEVICED_INTERFACE_DISPLAY,
2197 _E("Failed to send dbus signal %s.", DISPLAY_DETACH_STR);
2198 display_off_by_reason(DISPLAY_DETACH_STR);
2203 static const struct uevent_handler lcd_uevent_ops = {
2204 .subsystem = LCD_EVENT_SUBSYSTEM,
2205 .uevent_func = lcd_uevent_changed,
2209 static const struct uevent_handler sec_dsim_uevent_ops = {
2210 .subsystem = SEC_DSIM_EVENT_SUBSYSTEM,
2211 .uevent_func = sec_dsim_uevent_changed,
2215 static void display_init(void *data)
2218 unsigned int flags = (WITHOUT_STARTNOTI | FLAG_X_DPMS);
2221 _I("Start power manager.");
2223 signal(SIGHUP, sig_hup);
2225 power_saving_func = default_saving_mode;
2227 /* load configutation */
2228 ret = display_load_config(&display_conf);
2230 _W("Failed to load '%s', use default value: %d",
2231 DISPLAY_CONF_FILE, ret);
2233 ret = config_parse(POWERLOCK_CONF_FILE, powerlock_load_config, NULL);
2234 /* config file may not exist */
2235 if (ret < 0 && ret != -ENOENT)
2236 _W("Failed to load %s, %d.", POWERLOCK_CONF_FILE, ret);
2237 initialized_killable_daemon_list = true;
2239 register_kernel_uevent_control(&lcd_uevent_ops);
2240 register_kernel_uevent_control(&sec_dsim_uevent_ops);
2242 register_notifier(DEVICE_NOTIFIER_DELAYED_INIT, delayed_init_done);
2243 register_notifier(DEVICE_NOTIFIER_APPLICATION_BACKGROUND, display_app_background);
2244 register_notifier(DEVICE_NOTIFIER_APPLICATION_FOREGROUND, display_app_foreground);
2245 register_notifier(DEVICE_NOTIFIER_APPLICATION_TERMINATED, display_app_terminated);
2246 register_notifier(DEVICE_NOTIFIER_LCD_AUTOBRT_SENSING, display_auto_brightness_sensing);
2247 register_notifier(DEVICE_NOTIFIER_POWER_RESUME_FROM_ECHO_MEM, power_resume_from_echomem_callback);
2248 register_notifier(DEVICE_NOTIFIER_POWEROFF_TRIGGERED, poweroff_triggered_callback);
2250 init_save_userlock();
2252 for (i = INIT_SETTING; i < INIT_END; i++) {
2255 ret = init_setting(update_setting);
2257 case INIT_INTERFACE:
2258 if (display_conf.timeout_enable)
2259 get_lcd_timeout_from_settings();
2260 ret = init_sysfs(flags);
2264 ret = input_init_handler();
2266 pm_lock_detector_init();
2270 ret = init_pm_dbus();
2274 _E("Failed to init: %s", errMSG[i]);
2279 if (i == INIT_END) {
2280 display_ops_init(NULL);
2281 #ifdef ENABLE_PM_LOG
2284 init_lcd_operation();
2285 check_seed_status();
2287 /* In smd test, TSP should be turned off if display panel is not existed. */
2288 if (display_panel_get_dpms_cached_state() == -ENOENT) {
2289 _I("Display panel is not existed.");
2290 lcd_direct_control(DPMS_OFF, NORMAL_MODE);
2291 exit_lcd_operation();
2294 /* wm_ready needs to be checked
2295 * since display manager can be launched later than deviced.
2296 * In the case, display cannot be turned on at the first booting */
2297 // wm_ready = check_wm_ready();
2298 if (display_panel_init_dpms()) {
2299 if (is_lcdon_blocked() != LCDON_BLOCK_NONE)
2300 lcd_off_procedure(LCD_OFF_BY_EVENT);
2302 lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
2304 add_timer_for_dpms_init();
2307 if (display_conf.lcd_always_on) {
2308 _I("LCD always on.");
2309 display_state_transition_set_transition_table_display_state(S_NORMAL, S_NORMAL, EVENT_TIMEOUT);
2312 if (flags & WITHOUT_STARTNOTI) { /* start without noti */
2313 _I("Start Power managing without noti");
2314 power_request_change_state_strict(DEVICED_POWER_STATE_SLEEP, DEVICED_POWER_STATE_NORMAL,
2315 HAL_DEVICE_POWER_TRANSITION_REASON_UNKNOWN, NULL);
2317 * Lock lcd off until booting is done.
2318 * deviced guarantees all booting script is executing.
2319 * Last script of booting unlocks this suspend blocking state.
2321 if (disp_plgn->pm_lock_internal)
2322 disp_plgn->pm_lock_internal(INTERNAL_LOCK_BOOTING, LCD_OFF,
2323 STAY_CUR_STATE, DELAYED_INIT_WATING_TIME);
2325 /* Initial display state right after the booting done */
2326 if (is_lcdon_blocked())
2327 set_pm_cur_state(S_LCDOFF);
2329 set_pm_cur_state(S_NORMAL);
2330 ret = vconf_set_int(VCONFKEY_PM_STATE, get_pm_cur_state());
2332 _E("Failed to set vconf value for pm cur state: %d", vconf_get_ext_errno());
2334 status = DEVICE_OPS_STATUS_START;
2335 if (display_conf.timeout_enable) {
2336 timeout = states[S_NORMAL].timeout;
2337 /* check minimun lcd on time */
2338 if (timeout < SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT))
2339 timeout = SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT);
2341 if (disp_plgn->pm_lock_internal)
2342 disp_plgn->pm_lock_internal(INTERNAL_LOCK_BOOTING, LCD_NORMAL,
2343 STAY_CUR_STATE, timeout);
2348 if (display_conf.input_support)
2349 if (CHECK_OPS(keyfilter_ops, init))
2350 keyfilter_ops->init();
2352 set_display_init_direction(display_conf.display_init_direction);
2356 static void display_exit(void *data)
2360 status = DEVICE_OPS_STATUS_STOP;
2362 /* Set current state to S_NORMAL */
2363 set_pm_cur_state(S_NORMAL);
2364 set_setting_pmstate(get_pm_cur_state());
2365 /* timeout is not needed */
2366 display_state_transition_reset_state_transition_timeout(TIMEOUT_NONE);
2368 if (CHECK_OPS(keyfilter_ops, exit))
2369 keyfilter_ops->exit();
2371 unregister_kernel_uevent_control(&lcd_uevent_ops);
2372 unregister_kernel_uevent_control(&sec_dsim_uevent_ops);
2374 display_ops_exit(NULL);
2376 for (i = i - 1; i >= INIT_SETTING; i--) {
2381 case INIT_INTERFACE:
2385 unregister_notifier(DEVICE_NOTIFIER_DELAYED_INIT, delayed_init_done);
2386 unregister_notifier(DEVICE_NOTIFIER_APPLICATION_BACKGROUND, display_app_background);
2387 unregister_notifier(DEVICE_NOTIFIER_APPLICATION_FOREGROUND, display_app_foreground);
2388 unregister_notifier(DEVICE_NOTIFIER_APPLICATION_TERMINATED, display_app_terminated);
2389 unregister_notifier(DEVICE_NOTIFIER_POWER_RESUME_FROM_ECHO_MEM, power_resume_from_echomem_callback);
2395 exit_lcd_operation();
2396 free_lock_info_list();
2397 free_killable_daemon_list();
2399 /* free display service */
2400 display_service_free();
2402 _I("Stop power manager.");
2405 static int display_start(enum device_flags flags)
2407 const struct display_ops *enhance_ops = NULL;
2410 if (flags & NORMAL_MODE) {
2411 if (flags & LCD_PANEL_OFF_MODE)
2413 display_panel_set_panel_state_by_standby_state(true);
2416 display_panel_set_panel_state_by_on_state(flags);
2417 FIND_DISPLAY(enhance_ops, "enhance");
2418 if (enhance_ops && enhance_ops->func)
2419 enhance_ops->func(RESTORE_ENHANCE_OUTDOOR, &on);
2423 /* CORE LOGIC MODE */
2424 if (!(flags & CORE_LOGIC_MODE))
2427 if (status == DEVICE_OPS_STATUS_START)
2430 if (display_probe(NULL) < 0)
2438 static int display_stop(enum device_flags flags)
2441 if (flags & NORMAL_MODE || flags & FORCE_OFF_MODE) {
2442 display_panel_set_panel_state_by_off_state(flags);
2446 /* CORE LOGIC MODE */
2447 if (!(flags & CORE_LOGIC_MODE))
2450 if (status == DEVICE_OPS_STATUS_STOP)
2458 static int display_status(void)
2463 static const struct device_ops display_plugin_device_ops = {
2464 .disable_auto_init = true,
2465 DECLARE_NAME_LEN("display-plugin"),
2466 .probe = display_probe,
2467 .init = display_init,
2468 .exit = display_exit,
2469 .start = display_start,
2470 .stop = display_stop,
2471 .status = display_status,
2474 DEVICE_OPS_REGISTER(&display_plugin_device_ops)
2476 static void __CONSTRUCTOR__ initialize(void)
2478 disp_plgn = get_var_display_plugin();
2480 _E("Failed to get display plugin variable.");
2482 backlight_ops = get_var_backlight_ops();
2484 _E("Failed to get backlight operator variable.");
2486 battery_plgn = get_var_battery_plugin();
2488 _E("Failed to get battery plugin variable.");