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 int get_device_flags(unsigned long *device_flags)
454 *device_flags = NORMAL_MODE;
455 bool lcd_paneloff_mode = false;
456 bool stay_touchscreen_off = false;
457 display_panel_get_lcd_paneloff_mode(&lcd_paneloff_mode);
458 display_misc_get_stay_touchscreen_off(&stay_touchscreen_off);
460 if (lcd_paneloff_mode) {
461 *device_flags |= LCD_PANEL_OFF_MODE;
464 if (stay_touchscreen_off) {
465 *device_flags |= TOUCH_SCREEN_OFF_MODE;
468 if (ambient_get_state()) {
469 *device_flags |= AMBIENT_MODE;
470 *device_flags |= LCD_PHASED_TRANSIT_MODE;
476 bool touch_event_blocked(void)
478 return touch_blocked;
481 static gboolean late_transit_on(void *data)
484 return G_SOURCE_REMOVE;
486 g_source_remove(transit_timer);
489 display_backlight_change_brightness_by_dpms_state(DPMS_ON);
490 return G_SOURCE_REMOVE;
493 void lcd_on_procedure(int state, enum device_flags flag)
495 unsigned long flags = NORMAL_MODE;
496 display_plugin_get_device_flags(&flags);
501 * Display on procedure
503 * step 2. check if display is detached (only for factory mode)
504 * step 3. broadcast lcd on signal with cause
505 * step 4. set brightness
506 * step 5. set pmstate of vconf
507 * step 6. display on operate
509 * - b. TSP(touch screen) enable
510 * step 7. broadcast lcd on complete signal
511 * step 8. key backlight enable
515 ret = is_lcdon_blocked();
516 if (ret != LCDON_BLOCK_NONE) {
517 _W("LCDON is blocked, %d.", ret);
521 _I("[lcdstep] 0x%lx", flags);
523 if (flags & AMBIENT_MODE) {
524 if (ambient_get_state() == false && display_panel_get_dpms_cached_state() == DPMS_ON)
526 ambient_set_state(false);
529 /* send LCDOn dbus signal */
530 if (!lcdon_broadcast)
531 broadcast_lcd_on(SIGNAL_PRE, flags);
533 if (!(flags & LCD_PHASED_TRANSIT_MODE)) {
534 /* Update brightness level */
535 if (state == LCD_DIM)
536 display_backlight_set_brightness_by_dim_brightness();
537 else if (state == LCD_NORMAL)
538 display_backlight_update_by_default_brightness();
541 if (state == LCD_NORMAL)
542 set_setting_pmstate(S_NORMAL);
543 else if (state == LCD_DIM)
544 set_setting_pmstate(S_LCDDIM);
546 display_start_dependent_device(flags);
548 if (!lcdon_broadcast) {
549 broadcast_lcd_on(SIGNAL_POST, flags);
550 if (flags & LCD_PHASED_TRANSIT_MODE)
551 transit_timer = g_timeout_add_seconds(LATE_LCD_TRANSIT,
552 late_transit_on, NULL);
553 lcdon_broadcast = true;
556 touch_blocked = false;
559 inline void lcd_off_procedure(enum device_flags flag)
561 unsigned long flags = NORMAL_MODE;
562 display_plugin_get_device_flags(&flags);
566 * Display off procedure
567 * step 0. enhance mode off using nofity (e.g mdnie, HBM, LBM)
568 * step 1. broadcast lcd off signal with cause
569 * step 2. set pmstate of vconf
570 * step 3. display off operate
572 * - b. TSP(touch screen) disable
573 * step 4. broadcast lcd off complete siganl
574 * step 5. enter doze mode if it is enabled
576 _I("[lcdstep] 0x%lx", flags);
580 device_notify(DEVICE_NOTIFIER_LCD_OFF, NULL);
582 if (lcdon_broadcast) {
583 broadcast_lcd_off(SIGNAL_PRE, flags);
584 lcdon_broadcast = false;
589 touch_blocked = true;
591 if (flags & AMBIENT_MODE) {
592 if (ambient_get_state() == true)
594 ambient_set_state(true);
597 set_setting_pmstate(S_LCDOFF);
600 g_source_remove(transit_timer);
604 if (flags & LCD_PHASED_TRANSIT_MODE)
605 display_backlight_change_brightness_by_dpms_state(DPMS_OFF);
607 display_stop_dependent_device(flags);
609 if (flags & AMBIENT_MODE) {
610 broadcast_lcd_off_late(flags);
612 broadcast_lcd_off(SIGNAL_POST, flags);
613 device_notify(DEVICE_NOTIFIER_LCD_OFF_COMPLETE, NULL);
619 static void del_state_cond(void *data, enum state_t state)
621 PmLockNode *tmp = NULL;
627 /* A passed data is a pid_t type data, not a 64bit data. */
628 pid = (pid_t)((intptr_t)data);
629 _I("delete prohibit %s condition by timeout (%d)", states[state].name, pid);
631 if (pid == INTERNAL_LOCK_AMBIENT)
632 ambient_check_invalid_state(pid);
634 tmp = find_node(state, pid);
635 del_node(state, tmp);
636 set_unlock_time(pid, state);
638 /* Change state only when the two conditions below are satisfied.
639 * 1. There should be no running state-transition timer
640 * 2. Released lock is one of the pm_cur_state's lock
641 * This emulates already expired transition timer */
642 if (!display_state_transition_is_there_state_transition_timer() && (get_pm_cur_state() == state))
643 states[get_pm_cur_state()].trans(EVENT_TIMEOUT);
645 if (state == S_LCDOFF)
646 set_process_active(false, pid);
649 static gboolean del_normal_cond(void *data)
651 del_state_cond(data, S_NORMAL);
652 return G_SOURCE_REMOVE;
655 static gboolean del_dim_cond(void *data)
657 del_state_cond(data, S_LCDDIM);
658 return G_SOURCE_REMOVE;
661 static gboolean del_off_cond(void *data)
663 del_state_cond(data, S_LCDOFF);
664 return G_SOURCE_REMOVE;
667 /* get configurations from setting */
668 static int get_lcd_timeout_from_settings(void)
673 for (i = 0; i < S_END; i++) {
674 switch (states[i].state) {
676 get_run_timeout(&val);
679 get_dim_timeout(&val);
682 val = display_conf.lcdoff_timeout;
685 /* This state doesn't need to set time out. */
690 states[i].timeout = val;
692 _I("State(%s) timeout(%d) ms", states[i].name,
699 static void update_display_time(void)
701 int run_timeout, val;
703 /* first priority : custom timeout */
704 if (custom_normal_timeout > 0) {
705 states[S_NORMAL].timeout = custom_normal_timeout;
706 states[S_LCDDIM].timeout = custom_dim_timeout;
707 _I("CUSTOM : timeout is set by normal(%d ms), dim(%d ms)",
708 custom_normal_timeout, custom_dim_timeout);
712 /* second priority : lock state */
713 if ((__get_lock_screen_state() == VCONFKEY_IDLE_LOCK) &&
714 !get_lock_screen_bg_state()) {
715 /* timeout is different according to key or event. */
716 states[S_NORMAL].timeout = lock_screen_timeout;
717 _I("LOCK: Timeout(%d ms) is set by normal.",
718 lock_screen_timeout);
722 /* default setting */
723 get_run_timeout(&run_timeout);
726 * if the run_timeout is zero, it regards AlwaysOn state
728 if (run_timeout == 0 || display_conf.lcd_always_on) {
729 run_timeout = ALWAYS_ON_TIMEOUT;
730 _I("LCD always on.");
733 states[S_NORMAL].timeout = run_timeout;
735 get_dim_timeout(&val);
736 states[S_LCDDIM].timeout = val;
738 _I("Normal: NORMAL timeout is set by %d ms", states[S_NORMAL].timeout);
739 _I("Normal: DIM timeout is set by %d ms", states[S_LCDDIM].timeout);
742 static void update_display_locktime(int time)
744 lock_screen_timeout = time;
745 update_display_time();
748 void set_dim_state(bool on)
750 _I("Dim state is %d.", on);
751 update_display_time();
752 states[get_pm_cur_state()].trans(EVENT_INPUT);
755 void lcd_on_direct(enum device_flags flags)
757 enum hal_device_power_transition_reason reason;
759 if (flags & LCD_ON_BY_POWER_KEY)
760 reason = HAL_DEVICE_POWER_TRANSITION_REASON_POWER_KEY;
761 else if (flags & LCD_ON_BY_TOUCH)
762 reason = HAL_DEVICE_POWER_TRANSITION_REASON_TOUCH_SCREEN;
764 reason = HAL_DEVICE_POWER_TRANSITION_REASON_UNKNOWN;
766 power_request_change_state_strict(DEVICED_POWER_STATE_SLEEP, DEVICED_POWER_STATE_NORMAL, reason, NULL);
767 set_pm_cur_state(S_NORMAL);
769 _D("lcd is on directly");
770 gettimeofday(&lcdon_tv, NULL);
771 lcd_on_procedure(LCD_NORMAL, flags);
773 update_display_locktime(LOCK_SCREEN_INPUT_TIMEOUT);
776 static inline bool check_lcd_is_on(void)
778 if (display_panel_get_dpms_cached_state() != DPMS_ON)
784 static gboolean timer_refresh_cb(gpointer data)
789 ret = vconf_get_int(VCONFKEY_HOMESCREEN_WATCHFACE_VISIBILITY, &v);
791 _E("Failed to get homescreen watchface visibility");
797 * In watchface, it will be applied at 5 seconds for reduce power-supply.
798 * When the device's screen is another app, it will do turn off after 7 seconds.
800 if (set_custom_lcdon_timeout(5000) == true)
801 update_display_time();
803 /* state transition */
804 set_pm_old_state(get_pm_cur_state());
805 set_pm_cur_state(S_NORMAL);
806 st = &states[get_pm_cur_state()];
809 st->action(st->timeout);
814 int custom_lcdon(int timeout)
823 if (check_lcd_is_on() == false)
824 lcd_on_direct(LCD_ON_BY_GESTURE);
827 * During tutorial, reset timeout by default timeout, not the given timeout */
828 ret = vconf_get_int(VCONFKEY_HOMESCREEN_TUTORIAL_OOBE_ENABLED, &tutorial);
829 if (ret == 0 && tutorial) {
830 _D("During tutorial, reset timeout to default timeout.");
831 update = set_custom_lcdon_timeout(0);
833 _D("Custom lcd on timeout %dms.", timeout);
834 update = set_custom_lcdon_timeout(timeout);
838 update_display_time();
840 /* state transition */
841 set_pm_old_state(get_pm_cur_state());
842 set_pm_cur_state(S_NORMAL);
843 st = &states[get_pm_cur_state()];
847 st->action(st->timeout);
850 g_idle_add(timer_refresh_cb, NULL);
855 int custom_lcdoff(enum device_flags flag)
859 check_processes(S_NORMAL);
860 check_processes(S_LCDDIM);
862 /* check holdkey block flag in lock node */
863 if (check_lock_condition(S_NORMAL) || check_lock_condition(S_LCDDIM)) {
865 * When another proccess is normal lock, device is received call then,
866 * call app can be changed to lcd state by proximity.
867 * If proximity is near then normal lock will be unlocked.
869 if (flag & LCD_OFF_BY_PROXIMITY) {
870 _I("custom lcd off by proximity, delete normal lock");
871 delete_condition(S_NORMAL);
873 _I("skip custom lcd off");
878 _I("custom lcd off by flag(%d)", flag);
879 if (display_panel_get_dpms_cached_state() == DPMS_ON)
880 lcd_off_procedure(flag);
882 if (set_custom_lcdon_timeout(0) == true)
883 update_display_time();
885 /* state transition */
886 set_pm_old_state(get_pm_cur_state());
887 set_pm_cur_state(S_LCDOFF);
888 st = &states[get_pm_cur_state()];
892 st->action(st->timeout);
897 int display_on_by_reason(const char *reason, int timeout)
903 str_len = strlen(reason);
905 if (!strncmp(reason, GESTURE_STR, str_len))
906 flag = LCD_ON_BY_GESTURE;
907 else if (!strncmp(reason, EVENT_STR, str_len))
908 flag = LCD_ON_BY_EVENT;
910 _E("Reason is unknown(%s)", reason);
915 _E("Cannot setting timeout %d", timeout);
919 if (check_lcd_is_on() == false)
922 _I("platform lcd on by %s (%d ms)", reason, timeout);
923 if (set_custom_lcdon_timeout(timeout) == true)
924 update_display_time();
926 /* state transition */
927 set_pm_old_state(get_pm_cur_state());
928 set_pm_cur_state(S_NORMAL);
929 st = &states[get_pm_cur_state()];
933 st->action(st->timeout);
938 int display_off_by_reason(const char *reason)
944 str_len = strlen(reason);
946 if (!strncmp(reason, GESTURE_STR, str_len)) {
947 check_processes(S_NORMAL);
948 check_processes(S_LCDDIM);
950 /* check holdkey block flag in lock node */
951 if (check_lock_condition(S_NORMAL) || check_lock_condition(S_LCDDIM)) {
952 _I("skip platform lcd off by gesture");
955 flag = LCD_OFF_BY_GESTURE;
956 } else if (!strncmp(reason, PALM_STR, str_len)) {
957 delete_condition(S_NORMAL);
958 delete_condition(S_LCDDIM);
960 flag = LCD_OFF_BY_PALM;
961 } else if (!strncmp(reason, DISPLAY_DETACH_STR, str_len)) {
962 delete_condition(S_NORMAL);
963 delete_condition(S_LCDDIM);
965 flag = LCD_OFF_BY_DISPLAY_DETACH;
967 _E("Reason is unknown(%s)", reason);
971 _I("platform lcd off by %s", reason);
972 if (display_panel_get_dpms_cached_state() == DPMS_ON)
973 lcd_off_procedure(flag);
975 /* state transition */
976 set_pm_old_state(get_pm_cur_state());
977 set_pm_cur_state(S_LCDOFF);
978 st = &states[get_pm_cur_state()];
982 st->action(st->timeout);
987 static void default_proc_change_state_action(enum state_t next, int timeout)
991 set_pm_old_state(get_pm_cur_state());
992 set_pm_cur_state(next);
994 st = &states[get_pm_cur_state()];
996 if (st && st->action) {
998 st->action(st->timeout);
1000 st->action(timeout);
1004 static int default_proc_change_state(unsigned int cond, pid_t pid)
1008 next = GET_COND_STATE(cond);
1009 _I("Change process(%d) state to %s.", pid, states[next].name);
1013 if (check_lcd_is_on() == false)
1014 lcd_on_direct(LCD_ON_BY_EVENT);
1015 update_display_locktime(LOCK_SCREEN_CONTROL_TIMEOUT);
1016 default_proc_change_state_action(next, -1);
1019 default_proc_change_state_action(next, -1);
1022 if (display_panel_get_dpms_cached_state() == DPMS_ON)
1023 lcd_off_procedure(LCD_OFF_BY_EVENT);
1024 if (set_custom_lcdon_timeout(0))
1025 update_display_time();
1026 default_proc_change_state_action(next, -1);
1029 _I("Dangerous requests.");
1030 /* at first LCD_OFF and then goto sleep */
1031 /* state transition */
1032 default_proc_change_state_action(S_LCDOFF, TIMEOUT_NONE);
1033 delete_condition(S_NORMAL);
1034 delete_condition(S_LCDDIM);
1035 delete_condition(S_LCDOFF);
1036 if (lcdon_broadcast) {
1037 _I("broadcast lcd off signal at non-lcd device");
1038 broadcast_lcd_off(SIGNAL_PRE, 0);
1039 broadcast_lcd_off(SIGNAL_POST, 0);
1041 default_proc_change_state_action(S_SLEEP, TIMEOUT_NONE);
1051 static void proc_condition_lock(PMMsg *data)
1054 guint cond_timeout_id = 0;
1055 char pname[PATH_MAX];
1056 pid_t pid = data->pid;
1058 int holdkey_block, ret;
1061 const char *lock_type = NULL;
1063 state = GET_COND_STATE(data->cond);
1064 if (state == S_START)
1067 flags = GET_COND_FLAG(data->cond);
1068 display_misc_get_process_name(pid, pname);
1070 if ((state == S_LCDOFF) && (get_pm_cur_state() == S_SLEEP) &&
1071 (pm_get_power_lock() == POWER_UNLOCK))
1072 proc_change_state(data->cond, INTERNAL_LOCK_PM);
1074 if (data->timeout > 0) {
1075 /* To pass a pid_t data through the timer infrastructure
1076 * without memory allocation, a pid_t data becomes typecast
1077 * to intptr_t and void *(64bit) type. */
1078 cond_timeout_id = g_timeout_add(
1080 states[state].timeout_cb,
1081 (void*)((intptr_t)pid));
1082 if (!cond_timeout_id)
1083 _E("Failed to register display timer.");
1086 holdkey_block = GET_COND_FLAG(data->cond) & PM_FLAG_BLOCK_HOLDKEY;
1088 tmp = find_node(state, pid);
1090 tmp = add_node(state, pid, cond_timeout_id, holdkey_block);
1092 _E("Failed to acquire lock, state: %d, pid: %d.", state, pid);
1096 update_lock_timer(data, tmp, cond_timeout_id);
1097 tmp->holdkey_block = holdkey_block;
1100 if (state == S_LCDOFF)
1101 set_process_active(true, pid);
1103 _I("[%s] locked by %5d with %u ms", states[state].name, pid, data->timeout);
1105 if (pid < INTERNAL_LOCK_BASE) {
1107 if (state == S_LCDOFF)
1108 lock_type = PM_LCDOFF_STR;
1109 else if (state == S_LCDDIM)
1110 lock_type = PM_LCDDIM_STR;
1111 else if (state == S_NORMAL)
1112 lock_type = PM_LCDON_STR;
1115 /* power lock signal */
1116 ret = gdbus_signal_emit(NULL,
1117 DEVICED_PATH_DISPLAY,
1118 DEVICED_INTERFACE_DISPLAY,
1120 g_variant_new("(sii)", lock_type, pid, (int)data->timeout));
1122 _E("Failed to send dbus signal PowerLock.");
1126 _SD("be requested LOCK info pname(%s), holdkeyblock(%d) flags(%d) killable_daemon(%d)",
1127 pname, holdkey_block, flags, tmp->killable_daemon);
1128 set_lock_time(pid, pname, state);
1130 device_notify(DEVICE_NOTIFIER_DISPLAY_LOCK, (void *)&value);
1133 static void proc_condition_unlock(PMMsg *data)
1135 pid_t pid = data->pid;
1138 char pname[PATH_MAX];
1142 const char *lock_type = NULL;
1144 state = GET_COND_STATE(data->cond);
1148 flags = GET_COND_FLAG(data->cond);
1149 display_misc_get_process_name(pid, pname);
1151 tmp = find_node(state, pid);
1152 del_node(state, tmp);
1154 if (state == S_LCDOFF)
1155 set_process_active(false, pid);
1157 _I("[%s] unlocked by %5d", states[state].name, pid);
1159 if (pid < INTERNAL_LOCK_BASE) {
1161 if (state == S_LCDOFF)
1162 lock_type = PM_LCDOFF_STR;
1163 else if (state == S_LCDDIM)
1164 lock_type = PM_LCDDIM_STR;
1165 else if (state == S_NORMAL)
1166 lock_type = PM_LCDON_STR;
1169 /* power unlock signal */
1170 ret = gdbus_signal_emit(NULL,
1171 DEVICED_PATH_DISPLAY,
1172 DEVICED_INTERFACE_DISPLAY,
1174 g_variant_new("(sii)", lock_type, pid, (int)data->timeout));
1176 _E("Failed to send dbus signal PowerUnlock.");
1180 _SD("be requested UNLOCK info pname(%s) flag(%d)", pname, flags);
1181 set_unlock_time(pid, state);
1183 device_notify(DEVICE_NOTIFIER_DISPLAY_LOCK, (void *)&value);
1186 static int proc_condition(PMMsg *data)
1190 if (IS_COND_REQUEST_LOCK(data->cond))
1191 proc_condition_lock(data);
1193 if (IS_COND_REQUEST_UNLOCK(data->cond))
1194 proc_condition_unlock(data);
1196 if (!display_conf.timeout_enable)
1199 flags = GET_COND_FLAG(data->cond);
1201 /* guard time for suspend */
1202 if (get_pm_cur_state() == S_LCDOFF)
1203 display_state_transition_reset_state_transition_timeout(states[S_LCDOFF].timeout);
1205 if (flags & PM_FLAG_RESET_TIMER)
1206 display_state_transition_reset_state_transition_timeout(states[get_pm_cur_state()].timeout);
1209 if (!display_state_transition_is_there_state_transition_timer())
1210 states[get_pm_cur_state()].trans(EVENT_TIMEOUT);
1215 void update_lcdoff_source(int source)
1220 case VCONFKEY_PM_LCDOFF_BY_TIMEOUT:
1221 _I("LCD OFF by timeout.");
1223 case VCONFKEY_PM_LCDOFF_BY_POWERKEY:
1224 _I("LCD OFF by powerkey.");
1227 _E("Invalid value(%d).", source);
1230 ret = vconf_set_int(VCONFKEY_PM_LCDOFF_SOURCE, source);
1232 _E("Failed to set vconf value for lcd off source: %d", vconf_get_ext_errno());
1235 /* SIGHUP signal handler
1236 * For debug... print info to syslog
1238 static void sig_hup(int signo)
1240 _I("received sig hub %d", signo);
1245 int check_lcdoff_direct(void)
1247 int ret, lock, cradle;
1250 if (get_pm_old_state() != S_NORMAL)
1253 if (get_pm_cur_state() != S_LCDDIM)
1256 if (!display_conf.dimming)
1259 lock = __get_lock_screen_state();
1260 if (lock != VCONFKEY_IDLE_LOCK)
1263 hdmi_state = extcon_get_status(EXTCON_CABLE_HDMI);
1267 ret = vconf_get_int(VCONFKEY_SYSMAN_CRADLE_STATUS, &cradle);
1268 if (ret >= 0 && cradle == DOCK_SOUND)
1271 _E("Failed to get vconf value for cradle status: %d", vconf_get_ext_errno());
1273 _D("Goto LCDOFF direct: lock(%d) hdmi(%d) cradle(%d).", lock, hdmi_state, cradle);
1279 * default transition function
1282 * 3. call enter action function
1284 static int default_trans(int evt)
1286 struct state *st = &states[get_pm_cur_state()];
1288 enum state_t next_state;
1290 display_state_transition_get_next_transition_display_state(get_pm_cur_state(), &next_state, evt);
1292 /* check conditions */
1293 if (st->check && !st->check(get_pm_cur_state(), next_state)) {
1294 /* There is a condition. */
1295 _I("%s locked. Trans to %s failed.", states[get_pm_cur_state()].name,
1296 states[next_state].name);
1300 ret = is_lcdon_blocked();
1301 if (ret != LCDON_BLOCK_NONE) {
1302 if (next_state == S_NORMAL || next_state == S_LCDDIM) {
1303 _W("LCDON is blocked, %d.", ret);
1308 /* state transition */
1309 set_pm_old_state(get_pm_cur_state());
1310 set_pm_cur_state(next_state);
1311 st = &states[get_pm_cur_state()];
1315 if (get_pm_cur_state() == S_LCDOFF)
1316 update_lcdoff_source(VCONFKEY_PM_LCDOFF_BY_TIMEOUT);
1318 if ((get_pm_cur_state() == S_NORMAL) || (get_pm_cur_state() == S_LCDOFF))
1319 if (set_custom_lcdon_timeout(0) == true)
1320 update_display_time();
1322 if (check_lcdoff_direct() == true) {
1323 /* enter next state directly */
1324 states[get_pm_cur_state()].trans(EVENT_TIMEOUT);
1326 if ((get_pm_cur_state() == S_SLEEP)
1327 && (is_emulator() == true || timeout_sleep_support == false))
1330 st->action(st->timeout);
1337 static gboolean lcd_on_expired(void *data)
1339 int lock_state, ret;
1341 if (lock_timeout_id)
1342 lock_timeout_id = 0;
1344 /* check state of lock */
1345 ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
1346 if (ret > 0 && lock_state == VCONFKEY_IDLE_LOCK)
1347 return G_SOURCE_REMOVE;
1349 _E("Failed to get vconf value for idle lock state: %d", vconf_get_ext_errno());
1351 /* lock screen is not launched yet, but lcd is on */
1352 if (check_lcd_is_on() == false)
1353 lcd_on_procedure(LCD_NORMAL, NORMAL_MODE);
1355 return G_SOURCE_REMOVE;
1358 static inline void stop_lock_timer(void)
1360 if (lock_timeout_id) {
1361 g_source_remove(lock_timeout_id);
1362 lock_timeout_id = 0;
1366 static void check_lock_screen(void)
1368 int lock_state, ret;
1372 /* check state of lock */
1373 ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
1374 if (ret < 0 || lock_state == VCONFKEY_IDLE_LOCK)
1377 /* Use time to check lock is done. */
1378 lock_timeout_id = g_timeout_add(display_conf.lock_wait_time,
1379 lcd_on_expired, NULL);
1382 /* default enter action function */
1383 static int default_action(int timeout)
1385 int wakeup_count = -1, pm_cur_state;
1389 static time_t last_update_time = 0;
1390 static int last_timeout = 0;
1391 struct timeval now_tv;
1394 bool lcd_paneloff_mode = false;
1396 if (status != DEVICE_OPS_STATUS_START) {
1397 _E("Display is not started.");
1401 ret = is_lcdon_blocked();
1402 if (ret != LCDON_BLOCK_NONE) {
1403 if ((get_pm_cur_state() == S_NORMAL) || (get_pm_cur_state() == S_LCDDIM)) {
1404 _W("LCDON is blocked, %d.", ret);
1409 if (get_pm_cur_state() != S_SLEEP) {
1410 if ((get_pm_cur_state() == S_NORMAL) &&
1411 lcdon_tv.tv_sec != 0) {
1412 gettimeofday(&now_tv, NULL);
1413 timeout -= DIFF_TIMEVAL_MS(now_tv, lcdon_tv);
1414 lcdon_tv.tv_sec = 0;
1416 /* set timer with current state timeout */
1417 display_state_transition_reset_state_transition_timeout(timeout);
1419 if (get_pm_cur_state() == S_NORMAL) {
1420 time(&last_update_time);
1421 last_timeout = timeout;
1423 _I("Timout set: %s state %d ms",
1424 states[get_pm_cur_state()].name, timeout);
1428 if ((get_pm_cur_state() != get_pm_old_state()) && (get_pm_cur_state() != S_SLEEP)) {
1429 power_request_change_state_strict(DEVICED_POWER_STATE_SLEEP, DEVICED_POWER_STATE_NORMAL,
1430 power_get_wakeup_reason(), NULL);
1431 set_setting_pmstate(get_pm_cur_state());
1432 pm_cur_state = get_pm_cur_state();
1433 device_notify(DEVICE_NOTIFIER_LCD, (void *)&pm_cur_state);
1436 if ((get_pm_old_state() == S_NORMAL) && (get_pm_cur_state() != S_NORMAL)) {
1438 diff = difftime(now, last_update_time);
1439 _I("S_NORMAL is changed to %s (timeout=%d ms diff=%.0f s).",
1440 states[get_pm_cur_state()].name, last_timeout, diff);
1443 /* update status for battery monitor */
1444 update_bds_record(get_pm_cur_state());
1446 switch (get_pm_cur_state()) {
1449 * normal state : backlight on and restore
1450 * the previous brightness
1452 if ((get_pm_old_state() == S_LCDOFF) || (get_pm_old_state() == S_SLEEP))
1453 check_lock_screen();
1454 else if (get_pm_old_state() == S_LCDDIM)
1455 display_backlight_update_by_default_brightness();
1457 if (check_lcd_is_on() == false)
1458 lcd_on_procedure(LCD_NORMAL, NORMAL_MODE);
1462 display_backlight_get_custom_status(&custom_status);
1463 if ((get_pm_old_state() == S_NORMAL) && custom_status) {
1464 display_backlight_get_brightness(&brightness);
1465 display_backlight_set_custom_brightness(brightness);
1467 /* lcd dim state : dim the brightness */
1468 display_backlight_set_brightness_by_dim_brightness();
1470 if ((get_pm_old_state() == S_LCDOFF) || (get_pm_old_state() == S_SLEEP))
1471 lcd_on_procedure(LCD_DIM, NORMAL_MODE);
1475 if ((get_pm_old_state() != S_SLEEP) && (get_pm_old_state() != S_LCDOFF)) {
1477 /* lcd off state : turn off the backlight */
1478 if (display_panel_get_dpms_cached_state() == DPMS_ON)
1479 lcd_off_procedure(LCD_OFF_BY_TIMEOUT);
1482 display_panel_get_lcd_paneloff_mode(&lcd_paneloff_mode);
1483 if (display_panel_get_dpms_cached_state() == DPMS_ON
1484 || lcd_paneloff_mode)
1485 lcd_off_procedure(LCD_OFF_BY_TIMEOUT);
1489 if ((get_pm_old_state() != S_SLEEP) && (get_pm_old_state() != S_LCDOFF))
1492 if (display_panel_get_dpms_cached_state() == DPMS_ON)
1493 lcd_off_procedure(LCD_OFF_BY_TIMEOUT);
1495 if (!pm_get_power_lock_support()) {
1496 /* sleep state : set system mode to SUSPEND */
1497 if (get_wakeup_count(&wakeup_count) < 0)
1498 _E("Wakeup count read error.");
1500 if (wakeup_count < 0) {
1501 _I("Wakup Event. Can not enter suspend mode.");
1505 if (set_wakeup_count(wakeup_count) < 0) {
1506 _E("Wakeup count write error.");
1516 #ifdef ENABLE_PM_LOG
1517 pm_history_save(PM_LOG_SLEEP, get_pm_cur_state());
1519 power_request_change_state(DEVICED_POWER_STATE_SLEEP, HAL_DEVICE_POWER_TRANSITION_REASON_DISPLAY_OFF_TIMEOUT);
1523 if (!pm_get_power_lock_support()) {
1525 states[get_pm_cur_state()].trans(EVENT_DEVICE);
1531 * default check function
1533 * 0 : can't transit, others : transitable
1535 static int default_check(int curr, int next)
1539 makeup_trans_condition();
1541 trans_cond = get_trans_condition() & MASK_BIT;
1543 if (next == S_NORMAL) /* S_NORMAL is exceptional */
1548 trans_cond = trans_cond & MASK_NORMAL;
1551 trans_cond = trans_cond & MASK_DIM;
1554 trans_cond = trans_cond & MASK_OFF;
1561 if (trans_cond != 0) {
1566 return 1; /* transitable */
1569 static void default_saving_mode(int onoff)
1572 set_pm_status_flag(PWRSV_FLAG);
1573 auto_brightness_control(BR_LOWDIM_ON, BR_IMPLICIT);
1575 clear_pm_status_flag(PWRSV_FLAG);
1576 auto_brightness_control(BR_LOWDIM_OFF, BR_IMPLICIT);
1580 int poll_callback(int condition, PMMsg *data)
1582 static time_t last_t;
1585 if (status != DEVICE_OPS_STATUS_START) {
1586 _E("Display logic is not started.");
1590 if (condition == INPUT_POLL_EVENT) {
1591 if ((get_pm_cur_state() == S_LCDOFF) || (get_pm_cur_state() == S_SLEEP))
1592 _I("Input event signal at Display Off");
1594 if ((last_t != now) ||
1595 (get_pm_cur_state() == S_LCDOFF) ||
1596 (get_pm_cur_state() == S_SLEEP)) {
1597 states[get_pm_cur_state()].trans(EVENT_INPUT);
1602 if (condition == PM_CONTROL_EVENT) {
1603 proc_condition(data);
1605 if (IS_COND_REQUEST_CHANGE(data->cond))
1606 proc_change_state(data->cond, data->pid);
1612 static int update_setting(int key_idx, int val)
1617 case SETTING_TO_NORMAL:
1618 update_display_time();
1619 states[get_pm_cur_state()].trans(EVENT_INPUT);
1621 case SETTING_LOW_BATT:
1622 if (display_misc_is_low_battery_state(val)) {
1623 if (!(get_pm_status_flag() & CHRGR_FLAG))
1624 power_saving_func(true);
1625 set_pm_status_flag(LOWBT_FLAG);
1627 if (get_pm_status_flag() & PWRSV_FLAG)
1628 power_saving_func(false);
1629 clear_pm_status_flag(LOWBT_FLAG);
1630 clear_pm_status_flag(BRTCH_FLAG);
1631 ret = vconf_set_bool(VCONFKEY_PM_BRIGHTNESS_CHANGED_IN_LPM, false);
1633 _E("Failed to set vconf value for brightness changed in lpm: %d", vconf_get_ext_errno());
1636 case SETTING_CHARGING:
1638 if (get_pm_status_flag() & LOWBT_FLAG) {
1639 power_saving_func(false);
1640 clear_pm_status_flag(LOWBT_FLAG);
1642 set_pm_status_flag(CHRGR_FLAG);
1645 ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW,
1648 bat_state = VCONFKEY_SYSMAN_BAT_NORMAL;
1649 _E("Failed to get vconf value for battery status low: %d", vconf_get_ext_errno());
1651 if (display_misc_is_low_battery_state(bat_state)) {
1652 power_saving_func(true);
1653 set_pm_status_flag(LOWBT_FLAG);
1655 clear_pm_status_flag(CHRGR_FLAG);
1658 case SETTING_BRT_LEVEL:
1659 if (get_pm_status_flag() & PWRSV_FLAG) {
1660 set_pm_status_flag(BRTCH_FLAG);
1661 ret = vconf_set_bool(VCONFKEY_PM_BRIGHTNESS_CHANGED_IN_LPM, true);
1663 _E("Failed to set vconf value for brightness changed in lpm: %d", vconf_get_ext_errno());
1664 _I("Brightness changed in low battery,"
1665 "escape dim state.");
1667 display_backlight_set_default_brightness(val);
1669 case SETTING_LOCK_SCREEN:
1670 set_lock_screen_state(val);
1672 /* LCD on if lock screen show before waiting time */
1673 if ((get_pm_cur_state() == S_NORMAL) &&
1674 val == VCONFKEY_IDLE_LOCK &&
1675 display_panel_get_dpms_cached_state() != DPMS_ON &&
1676 is_lcdon_blocked() == LCDON_BLOCK_NONE)
1677 lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
1679 update_display_time();
1680 if (get_pm_cur_state() == S_NORMAL)
1681 states[get_pm_cur_state()].trans(EVENT_INPUT);
1683 case SETTING_LOCK_SCREEN_BG:
1684 set_lock_screen_bg_state(val);
1685 update_display_time();
1686 if (get_pm_cur_state() == S_NORMAL)
1687 states[get_pm_cur_state()].trans(EVENT_INPUT);
1689 case SETTING_POWER_CUSTOM_BRIGHTNESS:
1690 if (val == VCONFKEY_PM_CUSTOM_BRIGHTNESS_ON)
1691 display_backlight_set_custom_status(true);
1693 display_backlight_set_custom_status(false);
1702 static void check_seed_status(void)
1710 /* Charging check */
1711 if (fp_get_charging_status && (fp_get_charging_status(&tmp) == 0) && (tmp > 0))
1712 set_pm_status_flag(CHRGR_FLAG);
1714 ret = get_setting_brightness(&tmp);
1715 if (ret != 0 || (tmp < PM_MIN_BRIGHTNESS || tmp > PM_MAX_BRIGHTNESS)) {
1716 _I("Failed to read vconf value for brightness.");
1717 brt = display_conf.pm_default_brightness;
1718 if (tmp < PM_MIN_BRIGHTNESS || tmp > PM_MAX_BRIGHTNESS) {
1719 ret = vconf_set_int(VCONFKEY_SETAPPL_LCD_BRIGHTNESS, brt);
1721 _E("Failed to set vconf value for lcd brightness: %d", vconf_get_ext_errno());
1725 _I("Set brightness(%d) from setting app.", tmp);
1726 display_backlight_set_default_brightness(tmp);
1727 display_backlight_set_brightness(tmp);
1729 ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, &bat_state);
1731 bat_state = VCONFKEY_SYSMAN_BAT_NORMAL;
1732 _E("Failed to get vconf value for battery status low: %d", vconf_get_ext_errno());
1734 if (display_misc_is_low_battery_state(bat_state)) {
1735 if (!(get_pm_status_flag() & CHRGR_FLAG)) {
1736 power_saving_func(true);
1737 set_pm_status_flag(LOWBT_FLAG);
1741 /* lock screen check */
1742 ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
1745 _E("Failed to get vconf value for idle lock state: %d", vconf_get_ext_errno());
1747 set_lock_screen_state(lock_state);
1748 if (lock_state == VCONFKEY_IDLE_LOCK) {
1749 states[S_NORMAL].timeout = lock_screen_timeout;
1750 _I("LCD NORMAL timeout(%d ms) is set"
1751 " for lock screen.", lock_screen_timeout);
1757 static void init_lcd_operation(void)
1759 const struct device_ops *ops = NULL;
1761 ops = find_device("display");
1762 if (!check_default(ops))
1763 display_register_dependent_device(ops);
1765 ops = find_device("touchscreen");
1766 if (!check_default(ops))
1767 display_register_dependent_device(ops);
1769 ops = find_device("bezel");
1770 if (!check_default(ops))
1771 display_register_dependent_device(ops);
1774 static void exit_lcd_operation(void)
1776 display_unregister_dependent_device();
1788 static const char *errMSG[INIT_END] = {
1789 [INIT_SETTING] = "setting init error",
1790 [INIT_INTERFACE] = "lowlevel interface(sysfs or others) init error",
1791 [INIT_POLL] = "input devices poll init error",
1792 [INIT_FIFO] = "FIFO poll init error",
1793 [INIT_DBUS] = "d-bus init error",
1796 int set_lcd_timeout(int on, int dim, int holdkey_block, const char *name)
1798 if (on == 0 && dim == 0) {
1799 _I("LCD timeout changed: default setting");
1800 custom_normal_timeout = custom_dim_timeout = 0;
1801 } else if (on < 0 || dim < 0) {
1802 _E("Failed to set value(on=%d dim=%d).", on, dim);
1805 _I("LCD timeout changed: on=%ds dim=%ds", on, dim);
1806 custom_normal_timeout = SEC_TO_MSEC(on);
1807 custom_dim_timeout = SEC_TO_MSEC(dim);
1809 /* Apply new backlight time */
1810 update_display_time();
1811 if (get_pm_cur_state() == S_NORMAL)
1812 states[get_pm_cur_state()].trans(EVENT_INPUT);
1814 if (holdkey_block) {
1815 display_lock_set_custom_holdkey_block(true);
1816 _I("Hold key disabled.");
1818 display_lock_set_custom_holdkey_block(false);
1819 _I("Hold key enabled.");
1822 if (custom_change_name) {
1823 free(custom_change_name);
1824 custom_change_name = 0;
1827 if (custom_normal_timeout == 0 &&
1828 custom_dim_timeout == 0 &&
1832 custom_change_name = strndup(name, strlen(name));
1833 if (!custom_change_name) {
1834 _E("Failed to malloc.");
1835 custom_normal_timeout = custom_dim_timeout = 0;
1836 display_lock_set_custom_holdkey_block(false);
1843 void reset_lcd_timeout(GDBusConnection *conn,
1844 const gchar *sender,
1845 const gchar *unique_name,
1851 if (!custom_change_name)
1854 if (strcmp(sender, custom_change_name))
1857 _I("reset lcd timeout: Set default timeout. sender=%s", sender);
1859 free(custom_change_name);
1860 custom_change_name = 0;
1861 custom_normal_timeout = custom_dim_timeout = 0;
1862 display_lock_set_custom_holdkey_block(false);
1864 update_display_time();
1865 if (get_pm_cur_state() == S_NORMAL)
1866 states[get_pm_cur_state()].trans(EVENT_INPUT);
1869 static int delayed_init_done(void *data)
1871 static bool done = false;
1880 _I("Booting done, release booting lock.");
1881 if (disp_plgn->pm_unlock_internal) {
1882 disp_plgn->pm_unlock_internal(INTERNAL_LOCK_BOOTING, LCD_NORMAL, PM_SLEEP_MARGIN);
1883 disp_plgn->pm_unlock_internal(INTERNAL_LOCK_BOOTING, LCD_OFF, PM_SLEEP_MARGIN);
1889 static int powerlock_load_config(struct parse_result *result, void *user_data)
1893 _D("powerlock_load_config: section=%s name=%s value=%s", result->section, result->name, result->value);
1895 if (MATCH(result->section, "KillableDaemon") && MATCH(result->name, "KillableList")) {
1896 name = strndup(result->value, PATH_MAX - 1);
1898 _E("Not enough memory.");
1902 CRITICAL_LOG("Add %s to killable daemon list.", name);
1903 SYS_G_LIST_APPEND(display_lock_killable_daemon, name);
1909 static gboolean delayed_dpms_init_done(gpointer data)
1913 if (!display_panel_init_dpms())
1914 return G_SOURCE_CONTINUE;
1916 switch (get_pm_cur_state()) {
1919 lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
1920 if (display_conf.timeout_enable) {
1921 timeout = states[S_NORMAL].timeout;
1922 /* check minimun lcd on time */
1923 if (timeout < SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT))
1924 timeout = SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT);
1925 display_state_transition_reset_state_transition_timeout(timeout);
1929 lcd_off_procedure(LCD_OFF_BY_EVENT);
1930 timeout = display_conf.lcdoff_timeout;
1931 display_state_transition_reset_state_transition_timeout(timeout);
1937 return G_SOURCE_REMOVE;
1940 static void add_timer_for_dpms_init(void)
1942 guint id = g_timeout_add(500/* milliseconds */, delayed_dpms_init_done, NULL);
1944 _E("Failed to add display_panel_init_dpms timeout.");
1947 static void init_display_states(void *data)
1949 struct display_plugin *dp = (struct display_plugin *) data;
1950 for(int i = 0; i < S_END; i++)
1951 dp->display_states[i] = &states[i];
1954 * Power manager Main
1957 static int display_probe(void *data)
1960 struct display_plugin *dp = (struct display_plugin *) data;
1963 dp->config = &display_conf;
1964 init_display_states(dp);
1965 setup_display_plugin_backlight_ops(dp);
1966 dp->delete_state_cond = del_state_cond;
1967 dp->set_dim_state = set_dim_state;
1968 dp->get_device_flags = get_device_flags;
1969 setup_display_plugin_backlight_ops(dp);
1972 * load display service
1973 * if there is no display shared library,
1974 * deviced does not provide any method and function of display.
1976 ret = display_service_load();
1980 /* display_plugin instance initialization */
1981 init_pm_internal(data);
1982 disp_plgn->device_flags_to_string = __device_flags_to_string;
1984 if (battery_plgn->handle) {
1985 fp_get_charging_status = dlsym(battery_plgn->handle, "get_charging_status");
1986 if (!fp_get_charging_status)
1987 _E("Failed to obtain address of get_charging_status");
1989 _I("There is no battery module.");
1994 static int input_init_handler(void)
1996 if (!display_conf.input_support)
1997 remove_device_by_devname("input");
2002 static int power_resume_from_echomem_callback(void *data)
2004 system_wakeup_flag = true;
2005 if (check_wakeup_src() == EVENT_DEVICE)
2006 /* system waked up by devices */
2007 states[get_pm_cur_state()].trans(EVENT_DEVICE);
2009 /* system waked up by user input */
2010 states[get_pm_cur_state()].trans(EVENT_INPUT);
2015 static int poweroff_triggered_callback(void *udata)
2017 int val = (int)(intptr_t) udata;
2020 case VCONFKEY_SYSMAN_POWER_OFF_NONE:
2021 clear_pm_status_flag(PWROFF_FLAG);
2023 case VCONFKEY_SYSMAN_POWER_OFF_DIRECT:
2024 case VCONFKEY_SYSMAN_POWER_OFF_RESTART:
2025 set_pm_status_flag(PWROFF_FLAG);
2032 static void esd_action(void)
2034 const struct device_ops *touchscreen_ops = NULL;
2038 touchscreen_ops = find_device("touchscreen");
2040 if (!check_default(touchscreen_ops))
2041 touchscreen_ops->stop(NORMAL_MODE);
2042 display_panel_set_panel_state_by_off_state(NORMAL_MODE);
2043 display_panel_set_panel_state_by_on_state(NORMAL_MODE);
2044 if (!check_default(touchscreen_ops))
2045 touchscreen_ops->start(NORMAL_MODE);
2048 static void lcd_uevent_changed(struct udev_device *dev)
2050 const char *devpath;
2053 devpath = udev_device_get_devpath(dev);
2057 if (!fnmatch(LCD_ESD_PATH, devpath, 0)) {
2058 action = udev_device_get_action(dev);
2059 if (!strcmp(action, UDEV_CHANGE))
2064 static void sec_dsim_uevent_changed(struct udev_device *dev)
2066 const char *devpath;
2070 devpath = udev_device_get_devpath(dev);
2074 if (!fnmatch(SEC_DSIM_PATH, devpath, 0)) {
2075 action = udev_device_get_action(dev);
2076 if (!strcmp(action, UDEV_CHANGE)) {
2077 ret = gdbus_signal_emit(NULL,
2078 DEVICED_PATH_DISPLAY,
2079 DEVICED_INTERFACE_DISPLAY,
2083 _E("Failed to send dbus signal %s.", DISPLAY_DETACH_STR);
2084 display_off_by_reason(DISPLAY_DETACH_STR);
2089 static const struct uevent_handler lcd_uevent_ops = {
2090 .subsystem = LCD_EVENT_SUBSYSTEM,
2091 .uevent_func = lcd_uevent_changed,
2095 static const struct uevent_handler sec_dsim_uevent_ops = {
2096 .subsystem = SEC_DSIM_EVENT_SUBSYSTEM,
2097 .uevent_func = sec_dsim_uevent_changed,
2101 static void display_init(void *data)
2104 unsigned int flags = (WITHOUT_STARTNOTI | FLAG_X_DPMS);
2107 _I("Start power manager.");
2109 signal(SIGHUP, sig_hup);
2111 power_saving_func = default_saving_mode;
2113 /* load configutation */
2114 ret = display_load_config(&display_conf);
2116 _W("Failed to load '%s', use default value: %d",
2117 DISPLAY_CONF_FILE, ret);
2119 ret = config_parse(POWERLOCK_CONF_FILE, powerlock_load_config, NULL);
2120 /* config file may not exist */
2121 if (ret < 0 && ret != -ENOENT)
2122 _W("Failed to load %s, %d.", POWERLOCK_CONF_FILE, ret);
2123 initialized_killable_daemon_list = true;
2125 register_kernel_uevent_control(&lcd_uevent_ops);
2126 register_kernel_uevent_control(&sec_dsim_uevent_ops);
2128 register_notifier(DEVICE_NOTIFIER_DELAYED_INIT, delayed_init_done);
2129 register_notifier(DEVICE_NOTIFIER_APPLICATION_BACKGROUND, display_app_background);
2130 register_notifier(DEVICE_NOTIFIER_APPLICATION_FOREGROUND, display_app_foreground);
2131 register_notifier(DEVICE_NOTIFIER_APPLICATION_TERMINATED, display_app_terminated);
2132 register_notifier(DEVICE_NOTIFIER_LCD_AUTOBRT_SENSING, display_auto_brightness_sensing);
2133 register_notifier(DEVICE_NOTIFIER_POWER_RESUME_FROM_ECHO_MEM, power_resume_from_echomem_callback);
2134 register_notifier(DEVICE_NOTIFIER_POWEROFF_TRIGGERED, poweroff_triggered_callback);
2136 init_save_userlock();
2138 for (i = INIT_SETTING; i < INIT_END; i++) {
2141 ret = init_setting(update_setting);
2143 case INIT_INTERFACE:
2144 if (display_conf.timeout_enable)
2145 get_lcd_timeout_from_settings();
2146 ret = init_sysfs(flags);
2150 ret = input_init_handler();
2152 pm_lock_detector_init();
2156 ret = init_pm_dbus();
2160 _E("Failed to init: %s", errMSG[i]);
2165 if (i == INIT_END) {
2166 display_ops_init(NULL);
2167 #ifdef ENABLE_PM_LOG
2170 init_lcd_operation();
2171 check_seed_status();
2173 /* In smd test, TSP should be turned off if display panel is not existed. */
2174 if (display_panel_get_dpms_cached_state() == -ENOENT) {
2175 _I("Display panel is not existed.");
2176 lcd_direct_control(DPMS_OFF, NORMAL_MODE);
2177 exit_lcd_operation();
2180 /* wm_ready needs to be checked
2181 * since display manager can be launched later than deviced.
2182 * In the case, display cannot be turned on at the first booting */
2183 // wm_ready = check_wm_ready();
2184 if (display_panel_init_dpms()) {
2185 if (is_lcdon_blocked() != LCDON_BLOCK_NONE)
2186 lcd_off_procedure(LCD_OFF_BY_EVENT);
2188 lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
2190 add_timer_for_dpms_init();
2193 if (display_conf.lcd_always_on) {
2194 _I("LCD always on.");
2195 display_state_transition_set_transition_table_display_state(S_NORMAL, S_NORMAL, EVENT_TIMEOUT);
2198 if (flags & WITHOUT_STARTNOTI) { /* start without noti */
2199 _I("Start Power managing without noti");
2200 power_request_change_state_strict(DEVICED_POWER_STATE_SLEEP, DEVICED_POWER_STATE_NORMAL,
2201 HAL_DEVICE_POWER_TRANSITION_REASON_UNKNOWN, NULL);
2203 * Lock lcd off until booting is done.
2204 * deviced guarantees all booting script is executing.
2205 * Last script of booting unlocks this suspend blocking state.
2207 if (disp_plgn->pm_lock_internal)
2208 disp_plgn->pm_lock_internal(INTERNAL_LOCK_BOOTING, LCD_OFF,
2209 STAY_CUR_STATE, DELAYED_INIT_WATING_TIME);
2211 /* Initial display state right after the booting done */
2212 if (is_lcdon_blocked())
2213 set_pm_cur_state(S_LCDOFF);
2215 set_pm_cur_state(S_NORMAL);
2216 ret = vconf_set_int(VCONFKEY_PM_STATE, get_pm_cur_state());
2218 _E("Failed to set vconf value for pm cur state: %d", vconf_get_ext_errno());
2220 status = DEVICE_OPS_STATUS_START;
2221 if (display_conf.timeout_enable) {
2222 timeout = states[S_NORMAL].timeout;
2223 /* check minimun lcd on time */
2224 if (timeout < SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT))
2225 timeout = SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT);
2227 if (disp_plgn->pm_lock_internal)
2228 disp_plgn->pm_lock_internal(INTERNAL_LOCK_BOOTING, LCD_NORMAL,
2229 STAY_CUR_STATE, timeout);
2234 if (display_conf.input_support)
2235 if (CHECK_OPS(keyfilter_ops, init))
2236 keyfilter_ops->init();
2238 set_display_init_direction(display_conf.display_init_direction);
2242 static void display_exit(void *data)
2246 status = DEVICE_OPS_STATUS_STOP;
2248 /* Set current state to S_NORMAL */
2249 set_pm_cur_state(S_NORMAL);
2250 set_setting_pmstate(get_pm_cur_state());
2251 /* timeout is not needed */
2252 display_state_transition_reset_state_transition_timeout(TIMEOUT_NONE);
2254 if (CHECK_OPS(keyfilter_ops, exit))
2255 keyfilter_ops->exit();
2257 unregister_kernel_uevent_control(&lcd_uevent_ops);
2258 unregister_kernel_uevent_control(&sec_dsim_uevent_ops);
2260 display_ops_exit(NULL);
2262 for (i = i - 1; i >= INIT_SETTING; i--) {
2267 case INIT_INTERFACE:
2271 unregister_notifier(DEVICE_NOTIFIER_DELAYED_INIT, delayed_init_done);
2272 unregister_notifier(DEVICE_NOTIFIER_APPLICATION_BACKGROUND, display_app_background);
2273 unregister_notifier(DEVICE_NOTIFIER_APPLICATION_FOREGROUND, display_app_foreground);
2274 unregister_notifier(DEVICE_NOTIFIER_APPLICATION_TERMINATED, display_app_terminated);
2275 unregister_notifier(DEVICE_NOTIFIER_POWER_RESUME_FROM_ECHO_MEM, power_resume_from_echomem_callback);
2281 exit_lcd_operation();
2282 free_lock_info_list();
2283 free_killable_daemon_list();
2285 /* free display service */
2286 display_service_free();
2288 _I("Stop power manager.");
2291 static int display_start(enum device_flags flags)
2293 const struct display_ops *enhance_ops = NULL;
2296 if (flags & NORMAL_MODE) {
2297 if (flags & LCD_PANEL_OFF_MODE)
2299 display_panel_set_panel_state_by_standby_state(true);
2302 display_panel_set_panel_state_by_on_state(flags);
2303 FIND_DISPLAY(enhance_ops, "enhance");
2304 if (enhance_ops && enhance_ops->func)
2305 enhance_ops->func(RESTORE_ENHANCE_OUTDOOR, &on);
2309 /* CORE LOGIC MODE */
2310 if (!(flags & CORE_LOGIC_MODE))
2313 if (status == DEVICE_OPS_STATUS_START)
2316 if (display_probe(NULL) < 0)
2324 static int display_stop(enum device_flags flags)
2327 if (flags & NORMAL_MODE || flags & FORCE_OFF_MODE) {
2328 display_panel_set_panel_state_by_off_state(flags);
2332 /* CORE LOGIC MODE */
2333 if (!(flags & CORE_LOGIC_MODE))
2336 if (status == DEVICE_OPS_STATUS_STOP)
2344 static int display_status(void)
2349 static const struct device_ops display_plugin_device_ops = {
2350 .disable_auto_init = true,
2351 DECLARE_NAME_LEN("display-plugin"),
2352 .probe = display_probe,
2353 .init = display_init,
2354 .exit = display_exit,
2355 .start = display_start,
2356 .stop = display_stop,
2357 .status = display_status,
2360 DEVICE_OPS_REGISTER(&display_plugin_device_ops)
2362 static void __CONSTRUCTOR__ initialize(void)
2364 disp_plgn = get_var_display_plugin();
2366 _E("Failed to get display plugin variable.");
2368 backlight_ops = get_var_backlight_ops();
2370 _E("Failed to get backlight operator variable.");
2372 battery_plgn = get_var_battery_plugin();
2374 _E("Failed to get battery plugin variable.");