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 guint timeout_src_id;
116 static int system_wakeup_flag = false;
117 static unsigned int custom_normal_timeout = 0;
118 static unsigned int custom_dim_timeout = 0;
119 static char *custom_change_name;
120 static guint lock_timeout_id;
121 static guint transit_timer;
122 static int lock_screen_timeout = LOCK_SCREEN_INPUT_TIMEOUT;
123 static struct timeval lcdon_tv;
125 * The two variables(lcdon_broadcast, pmstate_suspend) must be set initial
126 * state because it should be sent from previous state at booting time.
128 static bool lcdon_broadcast = true;
130 static bool touch_blocked = false;
132 /* default transition, action fuctions */
133 static int default_trans(int evt);
134 static int default_action(int timeout);
135 static int default_check(int curr, int next);
137 static gboolean del_normal_cond(void *data);
138 static gboolean del_dim_cond(void *data);
139 static gboolean del_off_cond(void *data);
141 static int default_proc_change_state(unsigned int cond, pid_t pid);
142 static int (*proc_change_state)(unsigned int cond, pid_t pid) = default_proc_change_state;
144 static struct state states[S_END] = {
145 { S_START, "S_START", NULL, NULL, NULL, NULL },
146 { S_NORMAL, "S_NORMAL", default_trans, default_action, default_check, del_normal_cond },
147 { S_LCDDIM, "S_LCDDIM", default_trans, default_action, default_check, del_dim_cond },
148 { S_LCDOFF, "S_LCDOFF", default_trans, default_action, default_check, del_off_cond },
149 { S_STANDBY, "S_STANDBY", NULL, NULL, NULL, NULL },
150 { S_SLEEP, "S_SLEEP", default_trans, default_action, default_check, NULL },
151 { S_POWEROFF, "S_POWEROFF", NULL, NULL, NULL, NULL },
154 #define SHIFT_UNLOCK 4
155 #define SHIFT_CHANGE_STATE 7
156 #define CHANGE_STATE_BIT 0xF00 /* 1111 0000 0000 */
157 #define SHIFT_LOCK_FLAG 16
158 #define SHIFT_CHANGE_TIMEOUT 20
159 #define CUSTOM_TIMEOUT_BIT 0x1
160 #define CUSTOM_HOLDKEY_BIT 0x2
161 #define HOLD_KEY_BLOCK_BIT 0x1
162 #define TIMEOUT_NONE (-1)
164 #define S_COVER_TIMEOUT 8000
165 #define GET_HOLDKEY_BLOCK_STATE(x) ((x >> SHIFT_LOCK_FLAG) & HOLD_KEY_BLOCK_BIT)
166 #define DELAYED_INIT_WATING_TIME 60000 /* 1 minute */
168 #define LOCK_SCREEN_WATING_TIME 300 /* 0.3 second */
169 #define LONG_PRESS_INTERVAL 500 /* 0.5 seconds */
170 #define SAMPLING_INTERVAL 1 /* 1 sec */
171 #define BRIGHTNESS_CHANGE_STEP 10
172 #define LCD_ALWAYS_ON 0
173 #define ACCEL_SENSOR_ON 1
174 #define CONTINUOUS_SAMPLING 1
175 #define LCDOFF_TIMEOUT 300 /* milli second */
177 #define DIFF_TIMEVAL_MS(a, b) \
178 (((a.tv_sec * 1000000 + a.tv_usec) - \
179 (b.tv_sec * 1000000 + b.tv_usec)) \
182 #define KILLABLE_DAEMON_LOCK_LIMIT 1800 /* seconds, 30min */
183 #define FORCE_RELEASE_LOCK_INTERVAL 5 /* seconds */
185 static void get_comm(pid_t pid, char *comm);
186 static bool is_killable_daemon(pid_t pid);
187 static gboolean pmlock_terminate_daemon_to_release_lock(gpointer data);
188 static int pmlock_check(void *data);
189 static int powerlock_load_config(struct parse_result *result, void *user_data);
190 static void free_killable_daemon_list(void);
192 static GList *display_lock_killable_daemon;
193 static bool initialized_killable_daemon_list;
195 static struct display_config display_conf = {
196 .lock_wait_time = LOCK_SCREEN_WATING_TIME,
197 .longpress_interval = LONG_PRESS_INTERVAL,
198 .lightsensor_interval = SAMPLING_INTERVAL,
199 .lcdoff_timeout = LCDOFF_TIMEOUT,
200 .pm_default_brightness = 70,
201 .brightness_change_step = BRIGHTNESS_CHANGE_STEP,
202 .lcd_always_on = LCD_ALWAYS_ON,
204 .framerate_app = {0, 0, 0, 0},
205 .control_display = 0,
206 .powerkey_doublepress = 0,
207 .accel_sensor_on = ACCEL_SENSOR_ON,
208 .continuous_sampling = CONTINUOUS_SAMPLING,
209 .timeout_enable = true,
210 .input_support = true,
211 .lockcheck_timeout = 600,
212 .display_init_direction = DISPLAY_INIT_DIRECTION_HORIZONTAL,
213 .pmlock_check = pmlock_check,
214 .aod_enter_level = 40,
216 .touch_wakeup = false,
217 .display_on_usb_conn_changed = true,
218 .display_dpms_type = DISPLAY_DPMS_TYPE_WINDOW_MANAGER,
221 struct display_function_info display_info = {
222 .update_auto_brightness = NULL,
223 .set_autobrightness_min = NULL,
224 .reset_autobrightness_min = NULL,
225 .face_detection = NULL,
228 inline const struct display_config *get_var_display_config()
230 return &display_conf;
233 inline struct state *state_st(enum state_t state)
235 return &states[state];
238 guint get_transition_timer(void)
240 return timeout_src_id;
243 static int display_auto_brightness_sensing(void *data)
248 g_source_remove(transit_timer);
254 static const char* __device_flags_to_string(enum device_flags flags)
256 if (flags & (LCD_ON_BY_GESTURE | LCD_OFF_BY_GESTURE))
258 else if (flags & (LCD_ON_BY_POWER_KEY | LCD_OFF_BY_POWER_KEY))
259 return POWER_KEY_STR;
260 else if (flags & (LCD_ON_BY_EVENT | LCD_OFF_BY_EVENT))
262 else if (flags & LCD_ON_BY_BACK_KEY)
264 else if (flags & LCD_ON_BY_TOUCH)
266 else if (flags & LCD_ON_BY_BEZEL)
268 else if (flags & LCD_OFF_BY_TIMEOUT)
270 else if (flags & LCD_OFF_BY_PROXIMITY)
272 else if (flags & LCD_OFF_BY_PALM)
274 else if (flags & LCD_OFF_BY_DISPLAY_DETACH)
275 return DISPLAY_DETACH_STR;
280 static void get_comm(pid_t pid, char *comm)
285 if (pid >= INTERNAL_LOCK_BASE)
286 snprintf(buf, PATH_MAX, "/proc/%d/comm", getpid());
288 snprintf(buf, PATH_MAX, "/proc/%d/comm", pid);
290 fd = open(buf, O_RDONLY);
293 _E("Process(%d) does not exist now(may be dead without unlock).", pid);
297 r = read(fd, comm, PATH_MAX);
298 if ((r > 0) && (r < PATH_MAX)) {
299 if (comm[r - 1] == '\n')
309 static bool is_killable_daemon(pid_t pid)
311 char pname[PATH_MAX] = {0, };
312 const char *blacklist;
315 get_comm(pid, pname);
319 SYS_G_LIST_FOREACH(display_lock_killable_daemon, l, blacklist) {
320 if (MATCH(pname, blacklist))
327 static gboolean pmlock_terminate_daemon_to_release_lock(gpointer data)
334 char pname[PATH_MAX] = {0, };
337 _E("Invalid parameter.");
338 return G_SOURCE_REMOVE;
341 node = (PmLockNode *) data;
346 _E("Invalid lock pid.");
347 del_node(state, node);
348 return G_SOURCE_REMOVE;
351 if (!node->killable_daemon) {
352 _E("Incorrect checker, this is not a killable daemon. Stop checking lock.");
353 return G_SOURCE_REMOVE;
356 pid_exist = (kill(pid, 0) == 0);
358 get_comm(pid, pname);
360 if (node->force_release == false) {
361 /* Stop checking lock if process had been terminated */
363 del_node(state, node);
364 _I("Process %d not found. Stop checking lock.", pid);
365 return G_SOURCE_REMOVE;
368 /* KILLABLE_DAEMON_LOCK_LIMIT is expired. Kill the daemon */
369 CRITICAL_LOG("%s(%d) holds %s lock for %ds. kill SIGTERM.",
370 *pname ? pname : "Unknown", pid, states[state].name, KILLABLE_DAEMON_LOCK_LIMIT);
371 ret = kill(pid, SIGTERM);
373 CRITICAL_LOG_E("Failed to send SIGTERM to process %s(%d), %d.",
374 *pname ? pname : "Unknown", pid, errno);
376 node->force_release = true;
377 node->warning_id = g_timeout_add_seconds(FORCE_RELEASE_LOCK_INTERVAL,
378 pmlock_terminate_daemon_to_release_lock, (gpointer)node);
379 } else if (node->force_release == true) {
380 /* kill confirmation */
382 CRITICAL_LOG("%s(%d) is still alive, kill SIGKILL.",
383 *pname ? pname : "Unknown", pid);
385 ret = kill(pid, SIGKILL);
387 CRITICAL_LOG_E("Failed to kill process %s(%d), %d.",
388 *pname ? pname : "Unknown", pid, errno);
392 CRITICAL_LOG("Release %s lock occupied by PID %d.", states[state].name, pid);
393 del_node(state, node);
394 set_unlock_time(pid, state);
397 states[get_pm_cur_state()].trans(EVENT_TIMEOUT);
400 return G_SOURCE_REMOVE;
403 static int pmlock_check(void *data)
409 node = (PmLockNode *) data;
411 if (!initialized_killable_daemon_list) {
412 ret = config_parse(POWERLOCK_CONF_FILE, powerlock_load_config, NULL);
413 /* config file may not exist */
414 if (ret < 0 && ret != -ENOENT)
415 _W("Failed to load %s, %d.", POWERLOCK_CONF_FILE, ret);
417 if (status == DEVICE_OPS_STATUS_UNINIT) {
418 _W("Lock request before display init. Preloaded killable list.");
419 initialized_killable_daemon_list = true;
420 } else if (status == DEVICE_OPS_STATUS_STOP) {
421 _W("Lock request after display stop. Loaded list will be freed immediately.");
422 node->killable_daemon = is_killable_daemon(node->pid);
423 free_killable_daemon_list();
424 goto killable_marked;
428 node->killable_daemon = is_killable_daemon(node->pid);
431 /* use default lock checker */
432 if (!node->killable_daemon)
435 return g_timeout_add_seconds(KILLABLE_DAEMON_LOCK_LIMIT,
436 pmlock_terminate_daemon_to_release_lock, (gpointer)node);
439 static void free_killable_daemon_list(void)
444 if (!display_lock_killable_daemon)
447 SYS_G_LIST_FOREACH_SAFE(display_lock_killable_daemon, l, l_next, blacklist) {
448 SYS_G_LIST_REMOVE(display_lock_killable_daemon, blacklist);
451 display_lock_killable_daemon = NULL;
452 initialized_killable_daemon_list = false;
455 static unsigned long get_lcd_on_flags(void)
457 unsigned long flags = NORMAL_MODE;
458 bool lcd_paneloff_mode = false;
460 display_panel_get_lcd_paneloff_mode(&lcd_paneloff_mode);
461 if (lcd_paneloff_mode)
462 flags |= LCD_PANEL_OFF_MODE;
464 if (ambient_get_state()) {
465 flags |= AMBIENT_MODE;
466 flags |= LCD_PHASED_TRANSIT_MODE;
472 bool touch_event_blocked(void)
474 return touch_blocked;
477 static gboolean late_transit_on(void *data)
480 return G_SOURCE_REMOVE;
482 g_source_remove(transit_timer);
485 display_backlight_change_brightness_by_dpms_state(DPMS_ON);
486 return G_SOURCE_REMOVE;
489 void lcd_on_procedure(int state, enum device_flags flag)
491 unsigned long flags = get_lcd_on_flags();
496 * Display on procedure
498 * step 2. check if display is detached (only for factory mode)
499 * step 3. broadcast lcd on signal with cause
500 * step 4. set brightness
501 * step 5. set pmstate of vconf
502 * step 6. display on operate
504 * - b. TSP(touch screen) enable
505 * step 7. broadcast lcd on complete signal
506 * step 8. key backlight enable
510 ret = is_lcdon_blocked();
511 if (ret != LCDON_BLOCK_NONE) {
512 _W("LCDON is blocked, %d.", ret);
516 _I("[lcdstep] 0x%lx", flags);
518 if (flags & AMBIENT_MODE) {
519 if (ambient_get_state() == false && display_panel_get_dpms_cached_state() == DPMS_ON)
521 ambient_set_state(false);
524 /* send LCDOn dbus signal */
525 if (!lcdon_broadcast)
526 broadcast_lcd_on(SIGNAL_PRE, flags);
528 if (!(flags & LCD_PHASED_TRANSIT_MODE)) {
529 /* Update brightness level */
530 if (state == LCD_DIM)
531 display_backlight_set_brightness_by_dim_brightness();
532 else if (state == LCD_NORMAL)
533 display_backlight_update_by_default_brightness();
536 if (state == LCD_NORMAL)
537 set_setting_pmstate(S_NORMAL);
538 else if (state == LCD_DIM)
539 set_setting_pmstate(S_LCDDIM);
541 display_start_dependent_device(flags);
543 if (!lcdon_broadcast) {
544 broadcast_lcd_on(SIGNAL_POST, flags);
545 if (flags & LCD_PHASED_TRANSIT_MODE)
546 transit_timer = g_timeout_add_seconds(LATE_LCD_TRANSIT,
547 late_transit_on, NULL);
548 lcdon_broadcast = true;
551 touch_blocked = false;
554 static unsigned long get_lcd_off_flags(void)
556 unsigned long flags = NORMAL_MODE;
557 bool stay_touchscreen_off = false;
559 if (ambient_get_condition() == true) {
560 flags |= AMBIENT_MODE;
561 flags |= LCD_PHASED_TRANSIT_MODE;
564 display_misc_get_stay_touchscreen_off(&stay_touchscreen_off);
565 if (stay_touchscreen_off)
566 flags |= TOUCH_SCREEN_OFF_MODE;
571 inline void lcd_off_procedure(enum device_flags flag)
573 unsigned long flags = get_lcd_off_flags();
577 * Display off procedure
578 * step 0. enhance mode off using nofity (e.g mdnie, HBM, LBM)
579 * step 1. broadcast lcd off signal with cause
580 * step 2. set pmstate of vconf
581 * step 3. display off operate
583 * - b. TSP(touch screen) disable
584 * step 4. broadcast lcd off complete siganl
585 * step 5. enter doze mode if it is enabled
587 _I("[lcdstep] 0x%lx", flags);
591 device_notify(DEVICE_NOTIFIER_LCD_OFF, NULL);
593 if (lcdon_broadcast) {
594 broadcast_lcd_off(SIGNAL_PRE, flags);
595 lcdon_broadcast = false;
600 touch_blocked = true;
602 if (flags & AMBIENT_MODE) {
603 if (ambient_get_state() == true)
605 ambient_set_state(true);
608 set_setting_pmstate(S_LCDOFF);
611 g_source_remove(transit_timer);
615 if (flags & LCD_PHASED_TRANSIT_MODE)
616 display_backlight_change_brightness_by_dpms_state(DPMS_OFF);
618 display_stop_dependent_device(flags);
620 if (flags & AMBIENT_MODE) {
621 broadcast_lcd_off_late(flags);
623 broadcast_lcd_off(SIGNAL_POST, flags);
624 device_notify(DEVICE_NOTIFIER_LCD_OFF_COMPLETE, NULL);
630 static void del_state_cond(void *data, enum state_t state)
632 PmLockNode *tmp = NULL;
638 /* A passed data is a pid_t type data, not a 64bit data. */
639 pid = (pid_t)((intptr_t)data);
640 _I("delete prohibit %s condition by timeout (%d)", states[state].name, pid);
642 if (pid == INTERNAL_LOCK_AMBIENT)
643 ambient_check_invalid_state(pid);
645 tmp = find_node(state, pid);
646 del_node(state, tmp);
647 set_unlock_time(pid, state);
649 /* Change state only when the two conditions below are satisfied.
650 * 1. There should be no running state-transition timer
651 * 2. Released lock is one of the pm_cur_state's lock
652 * This emulates already expired transition timer */
653 if (!timeout_src_id && get_pm_cur_state() == state)
654 states[get_pm_cur_state()].trans(EVENT_TIMEOUT);
656 if (state == S_LCDOFF)
657 set_process_active(false, pid);
660 static gboolean del_normal_cond(void *data)
662 del_state_cond(data, S_NORMAL);
663 return G_SOURCE_REMOVE;
666 static gboolean del_dim_cond(void *data)
668 del_state_cond(data, S_LCDDIM);
669 return G_SOURCE_REMOVE;
672 static gboolean del_off_cond(void *data)
674 del_state_cond(data, S_LCDOFF);
675 return G_SOURCE_REMOVE;
678 /* timeout handler */
679 gboolean timeout_handler(void *data)
681 _I("Time out state %s", states[get_pm_cur_state()].name);
683 if (timeout_src_id) {
684 g_source_remove(timeout_src_id);
688 states[get_pm_cur_state()].trans(EVENT_TIMEOUT);
689 return G_SOURCE_REMOVE;
692 void reset_timeout(int timeout)
694 enum state_t next_state;
696 if (!display_conf.timeout_enable)
699 if ((get_pm_cur_state() == S_LCDOFF)
700 && (is_emulator() == true || timeout_sleep_support == false))
703 _I("Reset timeout(%d ms).", timeout);
704 if (timeout_src_id != 0) {
705 g_source_remove(timeout_src_id);
709 display_state_transition_get_next_transition_display_state(get_pm_cur_state(), &next_state, EVENT_TIMEOUT);
710 if (next_state == get_pm_cur_state())
714 timeout_src_id = g_timeout_add(timeout,
715 timeout_handler, NULL);
716 else if (timeout == 0)
717 states[get_pm_cur_state()].trans(EVENT_TIMEOUT);
720 /* get configurations from setting */
721 static int get_lcd_timeout_from_settings(void)
726 for (i = 0; i < S_END; i++) {
727 switch (states[i].state) {
729 get_run_timeout(&val);
732 get_dim_timeout(&val);
735 val = display_conf.lcdoff_timeout;
738 /* This state doesn't need to set time out. */
743 states[i].timeout = val;
745 _I("State(%s) timeout(%d) ms", states[i].name,
752 static void update_display_time(void)
754 int run_timeout, val;
756 /* first priority : custom timeout */
757 if (custom_normal_timeout > 0) {
758 states[S_NORMAL].timeout = custom_normal_timeout;
759 states[S_LCDDIM].timeout = custom_dim_timeout;
760 _I("CUSTOM : timeout is set by normal(%d ms), dim(%d ms)",
761 custom_normal_timeout, custom_dim_timeout);
765 /* second priority : lock state */
766 if ((__get_lock_screen_state() == VCONFKEY_IDLE_LOCK) &&
767 !get_lock_screen_bg_state()) {
768 /* timeout is different according to key or event. */
769 states[S_NORMAL].timeout = lock_screen_timeout;
770 _I("LOCK: Timeout(%d ms) is set by normal.",
771 lock_screen_timeout);
775 /* default setting */
776 get_run_timeout(&run_timeout);
779 * if the run_timeout is zero, it regards AlwaysOn state
781 if (run_timeout == 0 || display_conf.lcd_always_on) {
782 run_timeout = ALWAYS_ON_TIMEOUT;
783 _I("LCD always on.");
786 states[S_NORMAL].timeout = run_timeout;
788 get_dim_timeout(&val);
789 states[S_LCDDIM].timeout = val;
791 _I("Normal: NORMAL timeout is set by %d ms", states[S_NORMAL].timeout);
792 _I("Normal: DIM timeout is set by %d ms", states[S_LCDDIM].timeout);
795 static void update_display_locktime(int time)
797 lock_screen_timeout = time;
798 update_display_time();
801 void set_dim_state(bool on)
803 _I("Dim state is %d.", on);
804 update_display_time();
805 states[get_pm_cur_state()].trans(EVENT_INPUT);
808 void lcd_on_direct(enum device_flags flags)
810 enum hal_device_power_transition_reason reason;
812 if (flags & LCD_ON_BY_POWER_KEY)
813 reason = HAL_DEVICE_POWER_TRANSITION_REASON_POWER_KEY;
814 else if (flags & LCD_ON_BY_TOUCH)
815 reason = HAL_DEVICE_POWER_TRANSITION_REASON_TOUCH_SCREEN;
817 reason = HAL_DEVICE_POWER_TRANSITION_REASON_UNKNOWN;
819 power_request_change_state_strict(DEVICED_POWER_STATE_SLEEP, DEVICED_POWER_STATE_NORMAL, reason, NULL);
820 set_pm_cur_state(S_NORMAL);
822 _D("lcd is on directly");
823 gettimeofday(&lcdon_tv, NULL);
824 lcd_on_procedure(LCD_NORMAL, flags);
826 update_display_locktime(LOCK_SCREEN_INPUT_TIMEOUT);
829 static inline bool check_lcd_is_on(void)
831 if (display_panel_get_dpms_cached_state() != DPMS_ON)
837 static gboolean timer_refresh_cb(gpointer data)
842 ret = vconf_get_int(VCONFKEY_HOMESCREEN_WATCHFACE_VISIBILITY, &v);
844 _E("Failed to get homescreen watchface visibility");
850 * In watchface, it will be applied at 5 seconds for reduce power-supply.
851 * When the device's screen is another app, it will do turn off after 7 seconds.
853 if (set_custom_lcdon_timeout(5000) == true)
854 update_display_time();
856 /* state transition */
857 set_pm_old_state(get_pm_cur_state());
858 set_pm_cur_state(S_NORMAL);
859 st = &states[get_pm_cur_state()];
862 st->action(st->timeout);
867 int custom_lcdon(int timeout)
876 if (check_lcd_is_on() == false)
877 lcd_on_direct(LCD_ON_BY_GESTURE);
880 * During tutorial, reset timeout by default timeout, not the given timeout */
881 ret = vconf_get_int(VCONFKEY_HOMESCREEN_TUTORIAL_OOBE_ENABLED, &tutorial);
882 if (ret == 0 && tutorial) {
883 _D("During tutorial, reset timeout to default timeout.");
884 update = set_custom_lcdon_timeout(0);
886 _D("Custom lcd on timeout %dms.", timeout);
887 update = set_custom_lcdon_timeout(timeout);
891 update_display_time();
893 /* state transition */
894 set_pm_old_state(get_pm_cur_state());
895 set_pm_cur_state(S_NORMAL);
896 st = &states[get_pm_cur_state()];
900 st->action(st->timeout);
903 g_idle_add(timer_refresh_cb, NULL);
908 int custom_lcdoff(enum device_flags flag)
912 check_processes(S_NORMAL);
913 check_processes(S_LCDDIM);
915 /* check holdkey block flag in lock node */
916 if (check_lock_condition(S_NORMAL) || check_lock_condition(S_LCDDIM)) {
918 * When another proccess is normal lock, device is received call then,
919 * call app can be changed to lcd state by proximity.
920 * If proximity is near then normal lock will be unlocked.
922 if (flag & LCD_OFF_BY_PROXIMITY) {
923 _I("custom lcd off by proximity, delete normal lock");
924 delete_condition(S_NORMAL);
926 _I("skip custom lcd off");
931 _I("custom lcd off by flag(%d)", flag);
932 if (display_panel_get_dpms_cached_state() == DPMS_ON)
933 lcd_off_procedure(flag);
935 if (set_custom_lcdon_timeout(0) == true)
936 update_display_time();
938 /* state transition */
939 set_pm_old_state(get_pm_cur_state());
940 set_pm_cur_state(S_LCDOFF);
941 st = &states[get_pm_cur_state()];
945 st->action(st->timeout);
950 int display_on_by_reason(const char *reason, int timeout)
956 str_len = strlen(reason);
958 if (!strncmp(reason, GESTURE_STR, str_len))
959 flag = LCD_ON_BY_GESTURE;
960 else if (!strncmp(reason, EVENT_STR, str_len))
961 flag = LCD_ON_BY_EVENT;
963 _E("Reason is unknown(%s)", reason);
968 _E("Cannot setting timeout %d", timeout);
972 if (check_lcd_is_on() == false)
975 _I("platform lcd on by %s (%d ms)", reason, timeout);
976 if (set_custom_lcdon_timeout(timeout) == true)
977 update_display_time();
979 /* state transition */
980 set_pm_old_state(get_pm_cur_state());
981 set_pm_cur_state(S_NORMAL);
982 st = &states[get_pm_cur_state()];
986 st->action(st->timeout);
991 int display_off_by_reason(const char *reason)
997 str_len = strlen(reason);
999 if (!strncmp(reason, GESTURE_STR, str_len)) {
1000 check_processes(S_NORMAL);
1001 check_processes(S_LCDDIM);
1003 /* check holdkey block flag in lock node */
1004 if (check_lock_condition(S_NORMAL) || check_lock_condition(S_LCDDIM)) {
1005 _I("skip platform lcd off by gesture");
1008 flag = LCD_OFF_BY_GESTURE;
1009 } else if (!strncmp(reason, PALM_STR, str_len)) {
1010 delete_condition(S_NORMAL);
1011 delete_condition(S_LCDDIM);
1013 flag = LCD_OFF_BY_PALM;
1014 } else if (!strncmp(reason, DISPLAY_DETACH_STR, str_len)) {
1015 delete_condition(S_NORMAL);
1016 delete_condition(S_LCDDIM);
1018 flag = LCD_OFF_BY_DISPLAY_DETACH;
1020 _E("Reason is unknown(%s)", reason);
1024 _I("platform lcd off by %s", reason);
1025 if (display_panel_get_dpms_cached_state() == DPMS_ON)
1026 lcd_off_procedure(flag);
1028 /* state transition */
1029 set_pm_old_state(get_pm_cur_state());
1030 set_pm_cur_state(S_LCDOFF);
1031 st = &states[get_pm_cur_state()];
1035 st->action(st->timeout);
1040 static void default_proc_change_state_action(enum state_t next, int timeout)
1044 set_pm_old_state(get_pm_cur_state());
1045 set_pm_cur_state(next);
1047 st = &states[get_pm_cur_state()];
1049 if (st && st->action) {
1051 st->action(st->timeout);
1053 st->action(timeout);
1057 static int default_proc_change_state(unsigned int cond, pid_t pid)
1061 next = GET_COND_STATE(cond);
1062 _I("Change process(%d) state to %s.", pid, states[next].name);
1066 if (check_lcd_is_on() == false)
1067 lcd_on_direct(LCD_ON_BY_EVENT);
1068 update_display_locktime(LOCK_SCREEN_CONTROL_TIMEOUT);
1069 default_proc_change_state_action(next, -1);
1072 default_proc_change_state_action(next, -1);
1075 if (display_panel_get_dpms_cached_state() == DPMS_ON)
1076 lcd_off_procedure(LCD_OFF_BY_EVENT);
1077 if (set_custom_lcdon_timeout(0))
1078 update_display_time();
1079 default_proc_change_state_action(next, -1);
1082 _I("Dangerous requests.");
1083 /* at first LCD_OFF and then goto sleep */
1084 /* state transition */
1085 default_proc_change_state_action(S_LCDOFF, TIMEOUT_NONE);
1086 delete_condition(S_NORMAL);
1087 delete_condition(S_LCDDIM);
1088 delete_condition(S_LCDOFF);
1089 if (lcdon_broadcast) {
1090 _I("broadcast lcd off signal at non-lcd device");
1091 broadcast_lcd_off(SIGNAL_PRE, 0);
1092 broadcast_lcd_off(SIGNAL_POST, 0);
1094 default_proc_change_state_action(S_SLEEP, TIMEOUT_NONE);
1104 static void proc_condition_lock(PMMsg *data)
1107 guint cond_timeout_id = 0;
1108 char pname[PATH_MAX];
1109 pid_t pid = data->pid;
1111 int holdkey_block, ret;
1114 const char *lock_type = NULL;
1116 state = GET_COND_STATE(data->cond);
1117 if (state == S_START)
1120 flags = GET_COND_FLAG(data->cond);
1121 display_misc_get_process_name(pid, pname);
1123 if ((state == S_LCDOFF) && (get_pm_cur_state() == S_SLEEP) &&
1124 (pm_get_power_lock() == POWER_UNLOCK))
1125 proc_change_state(data->cond, INTERNAL_LOCK_PM);
1127 if (data->timeout > 0) {
1128 /* To pass a pid_t data through the timer infrastructure
1129 * without memory allocation, a pid_t data becomes typecast
1130 * to intptr_t and void *(64bit) type. */
1131 cond_timeout_id = g_timeout_add(
1133 states[state].timeout_cb,
1134 (void*)((intptr_t)pid));
1135 if (!cond_timeout_id)
1136 _E("Failed to register display timer.");
1139 holdkey_block = GET_COND_FLAG(data->cond) & PM_FLAG_BLOCK_HOLDKEY;
1141 tmp = find_node(state, pid);
1143 tmp = add_node(state, pid, cond_timeout_id, holdkey_block);
1145 _E("Failed to acquire lock, state: %d, pid: %d.", state, pid);
1149 update_lock_timer(data, tmp, cond_timeout_id);
1150 tmp->holdkey_block = holdkey_block;
1153 if (state == S_LCDOFF)
1154 set_process_active(true, pid);
1156 _I("[%s] locked by %5d with %u ms", states[state].name, pid, data->timeout);
1158 if (pid < INTERNAL_LOCK_BASE) {
1160 if (state == S_LCDOFF)
1161 lock_type = PM_LCDOFF_STR;
1162 else if (state == S_LCDDIM)
1163 lock_type = PM_LCDDIM_STR;
1164 else if (state == S_NORMAL)
1165 lock_type = PM_LCDON_STR;
1168 /* power lock signal */
1169 ret = gdbus_signal_emit(NULL,
1170 DEVICED_PATH_DISPLAY,
1171 DEVICED_INTERFACE_DISPLAY,
1173 g_variant_new("(sii)", lock_type, pid, (int)data->timeout));
1175 _E("Failed to send dbus signal PowerLock.");
1179 _SD("be requested LOCK info pname(%s), holdkeyblock(%d) flags(%d) killable_daemon(%d)",
1180 pname, holdkey_block, flags, tmp->killable_daemon);
1181 set_lock_time(pid, pname, state);
1183 device_notify(DEVICE_NOTIFIER_DISPLAY_LOCK, (void *)&value);
1186 static void proc_condition_unlock(PMMsg *data)
1188 pid_t pid = data->pid;
1191 char pname[PATH_MAX];
1195 const char *lock_type = NULL;
1197 state = GET_COND_STATE(data->cond);
1201 flags = GET_COND_FLAG(data->cond);
1202 display_misc_get_process_name(pid, pname);
1204 tmp = find_node(state, pid);
1205 del_node(state, tmp);
1207 if (state == S_LCDOFF)
1208 set_process_active(false, pid);
1210 _I("[%s] unlocked by %5d", states[state].name, pid);
1212 if (pid < INTERNAL_LOCK_BASE) {
1214 if (state == S_LCDOFF)
1215 lock_type = PM_LCDOFF_STR;
1216 else if (state == S_LCDDIM)
1217 lock_type = PM_LCDDIM_STR;
1218 else if (state == S_NORMAL)
1219 lock_type = PM_LCDON_STR;
1222 /* power unlock signal */
1223 ret = gdbus_signal_emit(NULL,
1224 DEVICED_PATH_DISPLAY,
1225 DEVICED_INTERFACE_DISPLAY,
1227 g_variant_new("(sii)", lock_type, pid, (int)data->timeout));
1229 _E("Failed to send dbus signal PowerUnlock.");
1233 _SD("be requested UNLOCK info pname(%s) flag(%d)", pname, flags);
1234 set_unlock_time(pid, state);
1236 device_notify(DEVICE_NOTIFIER_DISPLAY_LOCK, (void *)&value);
1239 static int proc_condition(PMMsg *data)
1243 if (IS_COND_REQUEST_LOCK(data->cond))
1244 proc_condition_lock(data);
1246 if (IS_COND_REQUEST_UNLOCK(data->cond))
1247 proc_condition_unlock(data);
1249 if (!display_conf.timeout_enable)
1252 flags = GET_COND_FLAG(data->cond);
1254 /* guard time for suspend */
1255 if (get_pm_cur_state() == S_LCDOFF)
1256 reset_timeout(states[S_LCDOFF].timeout);
1258 if (flags & PM_FLAG_RESET_TIMER)
1259 reset_timeout(states[get_pm_cur_state()].timeout);
1262 if (!timeout_src_id)
1263 states[get_pm_cur_state()].trans(EVENT_TIMEOUT);
1268 void update_lcdoff_source(int source)
1273 case VCONFKEY_PM_LCDOFF_BY_TIMEOUT:
1274 _I("LCD OFF by timeout.");
1276 case VCONFKEY_PM_LCDOFF_BY_POWERKEY:
1277 _I("LCD OFF by powerkey.");
1280 _E("Invalid value(%d).", source);
1283 ret = vconf_set_int(VCONFKEY_PM_LCDOFF_SOURCE, source);
1285 _E("Failed to set vconf value for lcd off source: %d", vconf_get_ext_errno());
1288 void print_info(int fd)
1291 char buf[PATH_MAX + 255];
1294 char pname[PATH_MAX];
1302 snprintf(buf, sizeof(buf),
1303 "\n==========================================="
1304 "===========================\n");
1305 ret = write(fd, buf, strlen(buf));
1307 _E("Write() failed: %d", errno);
1308 snprintf(buf, sizeof(buf), "Timeout Info: Run[%dms] Dim[%dms] Off[%dms]\n",
1309 states[S_NORMAL].timeout,
1310 states[S_LCDDIM].timeout, states[S_LCDOFF].timeout);
1311 ret = write(fd, buf, strlen(buf));
1313 _E("Write() failed: %d", errno);
1315 snprintf(buf, sizeof(buf), "Tran. Locked : %s %s %s\n",
1316 (get_trans_condition() & MASK_NORMAL) ? states[S_NORMAL].name : "-",
1317 (get_trans_condition() & MASK_DIM) ? states[S_LCDDIM].name : "-",
1318 (get_trans_condition() & MASK_OFF) ? states[S_LCDOFF].name : "-");
1319 ret = write(fd, buf, strlen(buf));
1321 _E("Write() failed: %d", errno);
1323 snprintf(buf, sizeof(buf), "Current State: %s\n",
1324 states[get_pm_cur_state()].name);
1325 ret = write(fd, buf, strlen(buf));
1327 _E("Write() failed: %d", errno);
1329 snprintf(buf, sizeof(buf), "Current Lock Conditions: \n");
1330 ret = write(fd, buf, strlen(buf));
1332 _E("Write() failed: %d", errno);
1334 for (s_index = S_NORMAL; s_index < S_END; s_index++) {
1335 SYS_G_LIST_FOREACH(get_cond_head(s_index), elem, t) {
1336 display_misc_get_process_name((pid_t)t->pid, pname);
1337 ctime_r(&t->time, time_buf);
1338 time_buf[strlen(time_buf) - 1] = 0;
1339 snprintf(buf, sizeof(buf),
1340 " %d: [%s] locked by pid %d %s %s\n",
1341 i++, states[s_index].name, t->pid, pname, time_buf);
1342 ret = write(fd, buf, strlen(buf));
1344 _E("Write() failed: %d", errno);
1348 print_lock_info_list(fd);
1350 #ifdef ENABLE_PM_LOG
1351 pm_history_print(fd, 250);
1355 void save_display_log(const char *path)
1362 _D("internal state is saved!");
1365 ctime_r(&now_time, time_buf);
1366 time_buf[strlen(time_buf) - 1] = 0;
1368 fd = open(path, O_CREAT | O_TRUNC | O_WRONLY, 0644);
1370 snprintf(buf, sizeof(buf),
1371 "\npm_state_log now-time : %d(s) %s\n\n",
1372 (int)now_time, time_buf);
1373 ret = write(fd, buf, strlen(buf));
1375 _E("write() failed (%d)", errno);
1377 snprintf(buf, sizeof(buf), "pm_status_flag: %#x\n", get_pm_status_flag());
1378 ret = write(fd, buf, strlen(buf));
1380 _E("write() failed (%d)", errno);
1382 if (disp_plgn->get_lock_screen_state ) {
1383 snprintf(buf, sizeof(buf), "screen lock status : %d\n",
1384 disp_plgn->get_lock_screen_state());
1385 ret = write(fd, buf, strlen(buf));
1387 _E("write() failed (%d)", errno);
1393 fd = open("/dev/console", O_WRONLY);
1400 /* SIGHUP signal handler
1401 * For debug... print info to syslog
1403 static void sig_hup(int signo)
1405 _I("received sig hub %d", signo);
1410 int check_lcdoff_direct(void)
1412 int ret, lock, cradle;
1415 if (get_pm_old_state() != S_NORMAL)
1418 if (get_pm_cur_state() != S_LCDDIM)
1421 if (!display_conf.dimming)
1424 lock = __get_lock_screen_state();
1425 if (lock != VCONFKEY_IDLE_LOCK)
1428 hdmi_state = extcon_get_status(EXTCON_CABLE_HDMI);
1432 ret = vconf_get_int(VCONFKEY_SYSMAN_CRADLE_STATUS, &cradle);
1433 if (ret >= 0 && cradle == DOCK_SOUND)
1436 _E("Failed to get vconf value for cradle status: %d", vconf_get_ext_errno());
1438 _D("Goto LCDOFF direct: lock(%d) hdmi(%d) cradle(%d).", lock, hdmi_state, cradle);
1444 * default transition function
1447 * 3. call enter action function
1449 static int default_trans(int evt)
1451 struct state *st = &states[get_pm_cur_state()];
1453 enum state_t next_state;
1455 display_state_transition_get_next_transition_display_state(get_pm_cur_state(), &next_state, evt);
1457 /* check conditions */
1458 if (st->check && !st->check(get_pm_cur_state(), next_state)) {
1459 /* There is a condition. */
1460 _I("%s locked. Trans to %s failed.", states[get_pm_cur_state()].name,
1461 states[next_state].name);
1465 ret = is_lcdon_blocked();
1466 if (ret != LCDON_BLOCK_NONE) {
1467 if (next_state == S_NORMAL || next_state == S_LCDDIM) {
1468 _W("LCDON is blocked, %d.", ret);
1473 /* state transition */
1474 set_pm_old_state(get_pm_cur_state());
1475 set_pm_cur_state(next_state);
1476 st = &states[get_pm_cur_state()];
1480 if (get_pm_cur_state() == S_LCDOFF)
1481 update_lcdoff_source(VCONFKEY_PM_LCDOFF_BY_TIMEOUT);
1483 if ((get_pm_cur_state() == S_NORMAL) || (get_pm_cur_state() == S_LCDOFF))
1484 if (set_custom_lcdon_timeout(0) == true)
1485 update_display_time();
1487 if (check_lcdoff_direct() == true) {
1488 /* enter next state directly */
1489 states[get_pm_cur_state()].trans(EVENT_TIMEOUT);
1491 if ((get_pm_cur_state() == S_SLEEP)
1492 && (is_emulator() == true || timeout_sleep_support == false))
1495 st->action(st->timeout);
1502 static gboolean lcd_on_expired(void *data)
1504 int lock_state, ret;
1506 if (lock_timeout_id)
1507 lock_timeout_id = 0;
1509 /* check state of lock */
1510 ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
1511 if (ret > 0 && lock_state == VCONFKEY_IDLE_LOCK)
1512 return G_SOURCE_REMOVE;
1514 _E("Failed to get vconf value for idle lock state: %d", vconf_get_ext_errno());
1516 /* lock screen is not launched yet, but lcd is on */
1517 if (check_lcd_is_on() == false)
1518 lcd_on_procedure(LCD_NORMAL, NORMAL_MODE);
1520 return G_SOURCE_REMOVE;
1523 static inline void stop_lock_timer(void)
1525 if (lock_timeout_id) {
1526 g_source_remove(lock_timeout_id);
1527 lock_timeout_id = 0;
1531 static void check_lock_screen(void)
1533 int lock_state, ret;
1537 /* check state of lock */
1538 ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
1539 if (ret < 0 || lock_state == VCONFKEY_IDLE_LOCK)
1542 /* Use time to check lock is done. */
1543 lock_timeout_id = g_timeout_add(display_conf.lock_wait_time,
1544 lcd_on_expired, NULL);
1547 /* default enter action function */
1548 static int default_action(int timeout)
1550 int wakeup_count = -1, pm_cur_state;
1554 static time_t last_update_time = 0;
1555 static int last_timeout = 0;
1556 struct timeval now_tv;
1559 bool lcd_paneloff_mode = false;
1561 if (status != DEVICE_OPS_STATUS_START) {
1562 _E("Display is not started.");
1566 ret = is_lcdon_blocked();
1567 if (ret != LCDON_BLOCK_NONE) {
1568 if ((get_pm_cur_state() == S_NORMAL) || (get_pm_cur_state() == S_LCDDIM)) {
1569 _W("LCDON is blocked, %d.", ret);
1574 if (get_pm_cur_state() != S_SLEEP) {
1575 if ((get_pm_cur_state() == S_NORMAL) &&
1576 lcdon_tv.tv_sec != 0) {
1577 gettimeofday(&now_tv, NULL);
1578 timeout -= DIFF_TIMEVAL_MS(now_tv, lcdon_tv);
1579 lcdon_tv.tv_sec = 0;
1581 /* set timer with current state timeout */
1582 reset_timeout(timeout);
1584 if (get_pm_cur_state() == S_NORMAL) {
1585 time(&last_update_time);
1586 last_timeout = timeout;
1588 _I("Timout set: %s state %d ms",
1589 states[get_pm_cur_state()].name, timeout);
1593 if ((get_pm_cur_state() != get_pm_old_state()) && (get_pm_cur_state() != S_SLEEP)) {
1594 power_request_change_state_strict(DEVICED_POWER_STATE_SLEEP, DEVICED_POWER_STATE_NORMAL,
1595 power_get_wakeup_reason(), NULL);
1596 set_setting_pmstate(get_pm_cur_state());
1597 pm_cur_state = get_pm_cur_state();
1598 device_notify(DEVICE_NOTIFIER_LCD, (void *)&pm_cur_state);
1601 if ((get_pm_old_state() == S_NORMAL) && (get_pm_cur_state() != S_NORMAL)) {
1603 diff = difftime(now, last_update_time);
1604 _I("S_NORMAL is changed to %s (timeout=%d ms diff=%.0f s).",
1605 states[get_pm_cur_state()].name, last_timeout, diff);
1608 /* update status for battery monitor */
1609 update_bds_record(get_pm_cur_state());
1611 switch (get_pm_cur_state()) {
1614 * normal state : backlight on and restore
1615 * the previous brightness
1617 if ((get_pm_old_state() == S_LCDOFF) || (get_pm_old_state() == S_SLEEP))
1618 check_lock_screen();
1619 else if (get_pm_old_state() == S_LCDDIM)
1620 display_backlight_update_by_default_brightness();
1622 if (check_lcd_is_on() == false)
1623 lcd_on_procedure(LCD_NORMAL, NORMAL_MODE);
1627 display_backlight_get_custom_status(&custom_status);
1628 if ((get_pm_old_state() == S_NORMAL) && custom_status) {
1629 display_backlight_get_brightness(&brightness);
1630 display_backlight_set_custom_brightness(brightness);
1632 /* lcd dim state : dim the brightness */
1633 display_backlight_set_brightness_by_dim_brightness();
1635 if ((get_pm_old_state() == S_LCDOFF) || (get_pm_old_state() == S_SLEEP))
1636 lcd_on_procedure(LCD_DIM, NORMAL_MODE);
1640 if ((get_pm_old_state() != S_SLEEP) && (get_pm_old_state() != S_LCDOFF)) {
1642 /* lcd off state : turn off the backlight */
1643 if (display_panel_get_dpms_cached_state() == DPMS_ON)
1644 lcd_off_procedure(LCD_OFF_BY_TIMEOUT);
1647 display_panel_get_lcd_paneloff_mode(&lcd_paneloff_mode);
1648 if (display_panel_get_dpms_cached_state() == DPMS_ON
1649 || lcd_paneloff_mode)
1650 lcd_off_procedure(LCD_OFF_BY_TIMEOUT);
1654 if ((get_pm_old_state() != S_SLEEP) && (get_pm_old_state() != S_LCDOFF))
1657 if (display_panel_get_dpms_cached_state() == DPMS_ON)
1658 lcd_off_procedure(LCD_OFF_BY_TIMEOUT);
1660 if (!pm_get_power_lock_support()) {
1661 /* sleep state : set system mode to SUSPEND */
1662 if (get_wakeup_count(&wakeup_count) < 0)
1663 _E("Wakeup count read error.");
1665 if (wakeup_count < 0) {
1666 _I("Wakup Event. Can not enter suspend mode.");
1670 if (set_wakeup_count(wakeup_count) < 0) {
1671 _E("Wakeup count write error.");
1681 #ifdef ENABLE_PM_LOG
1682 pm_history_save(PM_LOG_SLEEP, get_pm_cur_state());
1684 power_request_change_state(DEVICED_POWER_STATE_SLEEP, HAL_DEVICE_POWER_TRANSITION_REASON_DISPLAY_OFF_TIMEOUT);
1688 if (!pm_get_power_lock_support()) {
1690 states[get_pm_cur_state()].trans(EVENT_DEVICE);
1696 * default check function
1698 * 0 : can't transit, others : transitable
1700 static int default_check(int curr, int next)
1704 makeup_trans_condition();
1706 trans_cond = get_trans_condition() & MASK_BIT;
1708 if (next == S_NORMAL) /* S_NORMAL is exceptional */
1713 trans_cond = trans_cond & MASK_NORMAL;
1716 trans_cond = trans_cond & MASK_DIM;
1719 trans_cond = trans_cond & MASK_OFF;
1726 if (trans_cond != 0) {
1731 return 1; /* transitable */
1734 static void default_saving_mode(int onoff)
1737 set_pm_status_flag(PWRSV_FLAG);
1738 auto_brightness_control(BR_LOWDIM_ON, BR_IMPLICIT);
1740 clear_pm_status_flag(PWRSV_FLAG);
1741 auto_brightness_control(BR_LOWDIM_OFF, BR_IMPLICIT);
1745 int poll_callback(int condition, PMMsg *data)
1747 static time_t last_t;
1750 if (status != DEVICE_OPS_STATUS_START) {
1751 _E("Display logic is not started.");
1755 if (condition == INPUT_POLL_EVENT) {
1756 if ((get_pm_cur_state() == S_LCDOFF) || (get_pm_cur_state() == S_SLEEP))
1757 _I("Input event signal at Display Off");
1759 if ((last_t != now) ||
1760 (get_pm_cur_state() == S_LCDOFF) ||
1761 (get_pm_cur_state() == S_SLEEP)) {
1762 states[get_pm_cur_state()].trans(EVENT_INPUT);
1767 if (condition == PM_CONTROL_EVENT) {
1768 proc_condition(data);
1770 if (IS_COND_REQUEST_CHANGE(data->cond))
1771 proc_change_state(data->cond, data->pid);
1777 static int update_setting(int key_idx, int val)
1782 case SETTING_TO_NORMAL:
1783 update_display_time();
1784 states[get_pm_cur_state()].trans(EVENT_INPUT);
1786 case SETTING_LOW_BATT:
1787 if (display_misc_is_low_battery_state(val)) {
1788 if (!(get_pm_status_flag() & CHRGR_FLAG))
1789 power_saving_func(true);
1790 set_pm_status_flag(LOWBT_FLAG);
1792 if (get_pm_status_flag() & PWRSV_FLAG)
1793 power_saving_func(false);
1794 clear_pm_status_flag(LOWBT_FLAG);
1795 clear_pm_status_flag(BRTCH_FLAG);
1796 ret = vconf_set_bool(VCONFKEY_PM_BRIGHTNESS_CHANGED_IN_LPM, false);
1798 _E("Failed to set vconf value for brightness changed in lpm: %d", vconf_get_ext_errno());
1801 case SETTING_CHARGING:
1803 if (get_pm_status_flag() & LOWBT_FLAG) {
1804 power_saving_func(false);
1805 clear_pm_status_flag(LOWBT_FLAG);
1807 set_pm_status_flag(CHRGR_FLAG);
1810 ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW,
1813 bat_state = VCONFKEY_SYSMAN_BAT_NORMAL;
1814 _E("Failed to get vconf value for battery status low: %d", vconf_get_ext_errno());
1816 if (display_misc_is_low_battery_state(bat_state)) {
1817 power_saving_func(true);
1818 set_pm_status_flag(LOWBT_FLAG);
1820 clear_pm_status_flag(CHRGR_FLAG);
1823 case SETTING_BRT_LEVEL:
1824 if (get_pm_status_flag() & PWRSV_FLAG) {
1825 set_pm_status_flag(BRTCH_FLAG);
1826 ret = vconf_set_bool(VCONFKEY_PM_BRIGHTNESS_CHANGED_IN_LPM, true);
1828 _E("Failed to set vconf value for brightness changed in lpm: %d", vconf_get_ext_errno());
1829 _I("Brightness changed in low battery,"
1830 "escape dim state.");
1832 display_backlight_set_default_brightness(val);
1834 case SETTING_LOCK_SCREEN:
1835 set_lock_screen_state(val);
1837 /* LCD on if lock screen show before waiting time */
1838 if ((get_pm_cur_state() == S_NORMAL) &&
1839 val == VCONFKEY_IDLE_LOCK &&
1840 display_panel_get_dpms_cached_state() != DPMS_ON &&
1841 is_lcdon_blocked() == LCDON_BLOCK_NONE)
1842 lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
1844 update_display_time();
1845 if (get_pm_cur_state() == S_NORMAL)
1846 states[get_pm_cur_state()].trans(EVENT_INPUT);
1848 case SETTING_LOCK_SCREEN_BG:
1849 set_lock_screen_bg_state(val);
1850 update_display_time();
1851 if (get_pm_cur_state() == S_NORMAL)
1852 states[get_pm_cur_state()].trans(EVENT_INPUT);
1854 case SETTING_POWER_CUSTOM_BRIGHTNESS:
1855 if (val == VCONFKEY_PM_CUSTOM_BRIGHTNESS_ON)
1856 display_backlight_set_custom_status(true);
1858 display_backlight_set_custom_status(false);
1867 static void check_seed_status(void)
1875 /* Charging check */
1876 if (fp_get_charging_status && (fp_get_charging_status(&tmp) == 0) && (tmp > 0))
1877 set_pm_status_flag(CHRGR_FLAG);
1879 ret = get_setting_brightness(&tmp);
1880 if (ret != 0 || (tmp < PM_MIN_BRIGHTNESS || tmp > PM_MAX_BRIGHTNESS)) {
1881 _I("Failed to read vconf value for brightness.");
1882 brt = display_conf.pm_default_brightness;
1883 if (tmp < PM_MIN_BRIGHTNESS || tmp > PM_MAX_BRIGHTNESS) {
1884 ret = vconf_set_int(VCONFKEY_SETAPPL_LCD_BRIGHTNESS, brt);
1886 _E("Failed to set vconf value for lcd brightness: %d", vconf_get_ext_errno());
1890 _I("Set brightness(%d) from setting app.", tmp);
1891 display_backlight_set_default_brightness(tmp);
1892 display_backlight_set_brightness(tmp);
1894 ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, &bat_state);
1896 bat_state = VCONFKEY_SYSMAN_BAT_NORMAL;
1897 _E("Failed to get vconf value for battery status low: %d", vconf_get_ext_errno());
1899 if (display_misc_is_low_battery_state(bat_state)) {
1900 if (!(get_pm_status_flag() & CHRGR_FLAG)) {
1901 power_saving_func(true);
1902 set_pm_status_flag(LOWBT_FLAG);
1906 /* lock screen check */
1907 ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
1910 _E("Failed to get vconf value for idle lock state: %d", vconf_get_ext_errno());
1912 set_lock_screen_state(lock_state);
1913 if (lock_state == VCONFKEY_IDLE_LOCK) {
1914 states[S_NORMAL].timeout = lock_screen_timeout;
1915 _I("LCD NORMAL timeout(%d ms) is set"
1916 " for lock screen.", lock_screen_timeout);
1922 static void init_lcd_operation(void)
1924 const struct device_ops *ops = NULL;
1926 ops = find_device("display");
1927 if (!check_default(ops))
1928 display_register_dependent_device(ops);
1930 ops = find_device("touchscreen");
1931 if (!check_default(ops))
1932 display_register_dependent_device(ops);
1934 ops = find_device("bezel");
1935 if (!check_default(ops))
1936 display_register_dependent_device(ops);
1939 static void exit_lcd_operation(void)
1941 display_unregister_dependent_device();
1953 static const char *errMSG[INIT_END] = {
1954 [INIT_SETTING] = "setting init error",
1955 [INIT_INTERFACE] = "lowlevel interface(sysfs or others) init error",
1956 [INIT_POLL] = "input devices poll init error",
1957 [INIT_FIFO] = "FIFO poll init error",
1958 [INIT_DBUS] = "d-bus init error",
1961 int set_lcd_timeout(int on, int dim, int holdkey_block, const char *name)
1963 if (on == 0 && dim == 0) {
1964 _I("LCD timeout changed: default setting");
1965 custom_normal_timeout = custom_dim_timeout = 0;
1966 } else if (on < 0 || dim < 0) {
1967 _E("Failed to set value(on=%d dim=%d).", on, dim);
1970 _I("LCD timeout changed: on=%ds dim=%ds", on, dim);
1971 custom_normal_timeout = SEC_TO_MSEC(on);
1972 custom_dim_timeout = SEC_TO_MSEC(dim);
1974 /* Apply new backlight time */
1975 update_display_time();
1976 if (get_pm_cur_state() == S_NORMAL)
1977 states[get_pm_cur_state()].trans(EVENT_INPUT);
1979 if (holdkey_block) {
1980 display_lock_set_custom_holdkey_block(true);
1981 _I("Hold key disabled.");
1983 display_lock_set_custom_holdkey_block(false);
1984 _I("Hold key enabled.");
1987 if (custom_change_name) {
1988 free(custom_change_name);
1989 custom_change_name = 0;
1992 if (custom_normal_timeout == 0 &&
1993 custom_dim_timeout == 0 &&
1997 custom_change_name = strndup(name, strlen(name));
1998 if (!custom_change_name) {
1999 _E("Failed to malloc.");
2000 custom_normal_timeout = custom_dim_timeout = 0;
2001 display_lock_set_custom_holdkey_block(false);
2008 void reset_lcd_timeout(GDBusConnection *conn,
2009 const gchar *sender,
2010 const gchar *unique_name,
2016 if (!custom_change_name)
2019 if (strcmp(sender, custom_change_name))
2022 _I("reset lcd timeout: Set default timeout. sender=%s", sender);
2024 free(custom_change_name);
2025 custom_change_name = 0;
2026 custom_normal_timeout = custom_dim_timeout = 0;
2027 display_lock_set_custom_holdkey_block(false);
2029 update_display_time();
2030 if (get_pm_cur_state() == S_NORMAL)
2031 states[get_pm_cur_state()].trans(EVENT_INPUT);
2034 static int delayed_init_done(void *data)
2036 static bool done = false;
2045 _I("Booting done, release booting lock.");
2046 if (disp_plgn->pm_unlock_internal) {
2047 disp_plgn->pm_unlock_internal(INTERNAL_LOCK_BOOTING, LCD_NORMAL, PM_SLEEP_MARGIN);
2048 disp_plgn->pm_unlock_internal(INTERNAL_LOCK_BOOTING, LCD_OFF, PM_SLEEP_MARGIN);
2054 static int powerlock_load_config(struct parse_result *result, void *user_data)
2058 _D("powerlock_load_config: section=%s name=%s value=%s", result->section, result->name, result->value);
2060 if (MATCH(result->section, "KillableDaemon") && MATCH(result->name, "KillableList")) {
2061 name = strndup(result->value, PATH_MAX - 1);
2063 _E("Not enough memory.");
2067 CRITICAL_LOG("Add %s to killable daemon list.", name);
2068 SYS_G_LIST_APPEND(display_lock_killable_daemon, name);
2074 static gboolean delayed_dpms_init_done(gpointer data)
2078 if (!display_panel_init_dpms())
2079 return G_SOURCE_CONTINUE;
2081 switch (get_pm_cur_state()) {
2084 lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
2085 if (display_conf.timeout_enable) {
2086 timeout = states[S_NORMAL].timeout;
2087 /* check minimun lcd on time */
2088 if (timeout < SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT))
2089 timeout = SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT);
2090 reset_timeout(timeout);
2094 lcd_off_procedure(LCD_OFF_BY_EVENT);
2095 timeout = display_conf.lcdoff_timeout;
2096 reset_timeout(timeout);
2102 return G_SOURCE_REMOVE;
2105 static void add_timer_for_dpms_init(void)
2107 guint id = g_timeout_add(500/* milliseconds */, delayed_dpms_init_done, NULL);
2109 _E("Failed to add display_panel_init_dpms timeout.");
2112 static void init_display_states(void *data)
2114 struct display_plugin *dp = (struct display_plugin *) data;
2115 for(int i = 0; i < S_END; i++)
2116 dp->display_states[i] = &states[i];
2119 * Power manager Main
2122 static int display_probe(void *data)
2125 struct display_plugin *dp = (struct display_plugin *) data;
2128 dp->config = &display_conf;
2129 init_display_states(dp);
2130 setup_display_plugin_backlight_ops(dp);
2131 dp->delete_state_cond = del_state_cond;
2134 * load display service
2135 * if there is no display shared library,
2136 * deviced does not provide any method and function of display.
2138 ret = display_service_load();
2142 /* display_plugin instance initialization */
2143 init_pm_internal(data);
2144 disp_plgn->device_flags_to_string = __device_flags_to_string;
2146 if (battery_plgn->handle) {
2147 fp_get_charging_status = dlsym(battery_plgn->handle, "get_charging_status");
2148 if (!fp_get_charging_status)
2149 _E("Failed to obtain address of get_charging_status");
2151 _I("There is no battery module.");
2156 static int input_init_handler(void)
2158 if (!display_conf.input_support)
2159 remove_device_by_devname("input");
2164 static int power_resume_from_echomem_callback(void *data)
2166 system_wakeup_flag = true;
2167 if (check_wakeup_src() == EVENT_DEVICE)
2168 /* system waked up by devices */
2169 states[get_pm_cur_state()].trans(EVENT_DEVICE);
2171 /* system waked up by user input */
2172 states[get_pm_cur_state()].trans(EVENT_INPUT);
2177 static int poweroff_triggered_callback(void *udata)
2179 int val = (int)(intptr_t) udata;
2182 case VCONFKEY_SYSMAN_POWER_OFF_NONE:
2183 clear_pm_status_flag(PWROFF_FLAG);
2185 case VCONFKEY_SYSMAN_POWER_OFF_DIRECT:
2186 case VCONFKEY_SYSMAN_POWER_OFF_RESTART:
2187 set_pm_status_flag(PWROFF_FLAG);
2194 static void esd_action(void)
2196 const struct device_ops *touchscreen_ops = NULL;
2200 touchscreen_ops = find_device("touchscreen");
2202 if (!check_default(touchscreen_ops))
2203 touchscreen_ops->stop(NORMAL_MODE);
2204 display_panel_set_panel_state_by_off_state(NORMAL_MODE);
2205 display_panel_set_panel_state_by_on_state(NORMAL_MODE);
2206 if (!check_default(touchscreen_ops))
2207 touchscreen_ops->start(NORMAL_MODE);
2210 static void lcd_uevent_changed(struct udev_device *dev)
2212 const char *devpath;
2215 devpath = udev_device_get_devpath(dev);
2219 if (!fnmatch(LCD_ESD_PATH, devpath, 0)) {
2220 action = udev_device_get_action(dev);
2221 if (!strcmp(action, UDEV_CHANGE))
2226 static void sec_dsim_uevent_changed(struct udev_device *dev)
2228 const char *devpath;
2232 devpath = udev_device_get_devpath(dev);
2236 if (!fnmatch(SEC_DSIM_PATH, devpath, 0)) {
2237 action = udev_device_get_action(dev);
2238 if (!strcmp(action, UDEV_CHANGE)) {
2239 ret = gdbus_signal_emit(NULL,
2240 DEVICED_PATH_DISPLAY,
2241 DEVICED_INTERFACE_DISPLAY,
2245 _E("Failed to send dbus signal %s.", DISPLAY_DETACH_STR);
2246 display_off_by_reason(DISPLAY_DETACH_STR);
2251 static const struct uevent_handler lcd_uevent_ops = {
2252 .subsystem = LCD_EVENT_SUBSYSTEM,
2253 .uevent_func = lcd_uevent_changed,
2257 static const struct uevent_handler sec_dsim_uevent_ops = {
2258 .subsystem = SEC_DSIM_EVENT_SUBSYSTEM,
2259 .uevent_func = sec_dsim_uevent_changed,
2263 static void display_init(void *data)
2266 unsigned int flags = (WITHOUT_STARTNOTI | FLAG_X_DPMS);
2269 _I("Start power manager.");
2271 signal(SIGHUP, sig_hup);
2273 power_saving_func = default_saving_mode;
2275 /* load configutation */
2276 ret = display_load_config(&display_conf);
2278 _W("Failed to load '%s', use default value: %d",
2279 DISPLAY_CONF_FILE, ret);
2281 ret = config_parse(POWERLOCK_CONF_FILE, powerlock_load_config, NULL);
2282 /* config file may not exist */
2283 if (ret < 0 && ret != -ENOENT)
2284 _W("Failed to load %s, %d.", POWERLOCK_CONF_FILE, ret);
2285 initialized_killable_daemon_list = true;
2287 register_kernel_uevent_control(&lcd_uevent_ops);
2288 register_kernel_uevent_control(&sec_dsim_uevent_ops);
2290 register_notifier(DEVICE_NOTIFIER_DELAYED_INIT, delayed_init_done);
2291 register_notifier(DEVICE_NOTIFIER_APPLICATION_BACKGROUND, display_app_background);
2292 register_notifier(DEVICE_NOTIFIER_APPLICATION_FOREGROUND, display_app_foreground);
2293 register_notifier(DEVICE_NOTIFIER_APPLICATION_TERMINATED, display_app_terminated);
2294 register_notifier(DEVICE_NOTIFIER_LCD_AUTOBRT_SENSING, display_auto_brightness_sensing);
2295 register_notifier(DEVICE_NOTIFIER_POWER_RESUME_FROM_ECHO_MEM, power_resume_from_echomem_callback);
2296 register_notifier(DEVICE_NOTIFIER_POWEROFF_TRIGGERED, poweroff_triggered_callback);
2298 init_save_userlock();
2300 for (i = INIT_SETTING; i < INIT_END; i++) {
2303 ret = init_setting(update_setting);
2305 case INIT_INTERFACE:
2306 if (display_conf.timeout_enable)
2307 get_lcd_timeout_from_settings();
2308 ret = init_sysfs(flags);
2312 ret = input_init_handler();
2314 pm_lock_detector_init();
2318 ret = init_pm_dbus();
2322 _E("Failed to init: %s", errMSG[i]);
2327 if (i == INIT_END) {
2328 display_ops_init(NULL);
2329 #ifdef ENABLE_PM_LOG
2332 init_lcd_operation();
2333 check_seed_status();
2335 /* In smd test, TSP should be turned off if display panel is not existed. */
2336 if (display_panel_get_dpms_cached_state() == -ENOENT) {
2337 _I("Display panel is not existed.");
2338 lcd_direct_control(DPMS_OFF, NORMAL_MODE);
2339 exit_lcd_operation();
2342 /* wm_ready needs to be checked
2343 * since display manager can be launched later than deviced.
2344 * In the case, display cannot be turned on at the first booting */
2345 // wm_ready = check_wm_ready();
2346 if (display_panel_init_dpms()) {
2347 if (is_lcdon_blocked() != LCDON_BLOCK_NONE)
2348 lcd_off_procedure(LCD_OFF_BY_EVENT);
2350 lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
2352 add_timer_for_dpms_init();
2355 if (display_conf.lcd_always_on) {
2356 _I("LCD always on.");
2357 display_state_transition_set_transition_table_display_state(S_NORMAL, S_NORMAL, EVENT_TIMEOUT);
2360 if (flags & WITHOUT_STARTNOTI) { /* start without noti */
2361 _I("Start Power managing without noti");
2362 power_request_change_state_strict(DEVICED_POWER_STATE_SLEEP, DEVICED_POWER_STATE_NORMAL,
2363 HAL_DEVICE_POWER_TRANSITION_REASON_UNKNOWN, NULL);
2365 * Lock lcd off until booting is done.
2366 * deviced guarantees all booting script is executing.
2367 * Last script of booting unlocks this suspend blocking state.
2369 if (disp_plgn->pm_lock_internal)
2370 disp_plgn->pm_lock_internal(INTERNAL_LOCK_BOOTING, LCD_OFF,
2371 STAY_CUR_STATE, DELAYED_INIT_WATING_TIME);
2373 /* Initial display state right after the booting done */
2374 if (is_lcdon_blocked())
2375 set_pm_cur_state(S_LCDOFF);
2377 set_pm_cur_state(S_NORMAL);
2378 ret = vconf_set_int(VCONFKEY_PM_STATE, get_pm_cur_state());
2380 _E("Failed to set vconf value for pm cur state: %d", vconf_get_ext_errno());
2382 status = DEVICE_OPS_STATUS_START;
2383 if (display_conf.timeout_enable) {
2384 timeout = states[S_NORMAL].timeout;
2385 /* check minimun lcd on time */
2386 if (timeout < SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT))
2387 timeout = SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT);
2389 if (disp_plgn->pm_lock_internal)
2390 disp_plgn->pm_lock_internal(INTERNAL_LOCK_BOOTING, LCD_NORMAL,
2391 STAY_CUR_STATE, timeout);
2396 if (display_conf.input_support)
2397 if (CHECK_OPS(keyfilter_ops, init))
2398 keyfilter_ops->init();
2400 set_display_init_direction(display_conf.display_init_direction);
2404 static void display_exit(void *data)
2408 status = DEVICE_OPS_STATUS_STOP;
2410 /* Set current state to S_NORMAL */
2411 set_pm_cur_state(S_NORMAL);
2412 set_setting_pmstate(get_pm_cur_state());
2413 /* timeout is not needed */
2414 reset_timeout(TIMEOUT_NONE);
2416 if (CHECK_OPS(keyfilter_ops, exit))
2417 keyfilter_ops->exit();
2419 unregister_kernel_uevent_control(&lcd_uevent_ops);
2420 unregister_kernel_uevent_control(&sec_dsim_uevent_ops);
2422 display_ops_exit(NULL);
2424 for (i = i - 1; i >= INIT_SETTING; i--) {
2429 case INIT_INTERFACE:
2433 unregister_notifier(DEVICE_NOTIFIER_DELAYED_INIT, delayed_init_done);
2434 unregister_notifier(DEVICE_NOTIFIER_APPLICATION_BACKGROUND, display_app_background);
2435 unregister_notifier(DEVICE_NOTIFIER_APPLICATION_FOREGROUND, display_app_foreground);
2436 unregister_notifier(DEVICE_NOTIFIER_APPLICATION_TERMINATED, display_app_terminated);
2437 unregister_notifier(DEVICE_NOTIFIER_POWER_RESUME_FROM_ECHO_MEM, power_resume_from_echomem_callback);
2443 exit_lcd_operation();
2444 free_lock_info_list();
2445 free_killable_daemon_list();
2447 /* free display service */
2448 display_service_free();
2450 _I("Stop power manager.");
2453 static int display_start(enum device_flags flags)
2455 const struct display_ops *enhance_ops = NULL;
2458 if (flags & NORMAL_MODE) {
2459 if (flags & LCD_PANEL_OFF_MODE)
2461 display_panel_set_panel_state_by_standby_state(true);
2464 display_panel_set_panel_state_by_on_state(flags);
2465 FIND_DISPLAY(enhance_ops, "enhance");
2466 if (enhance_ops && enhance_ops->func)
2467 enhance_ops->func(RESTORE_ENHANCE_OUTDOOR, &on);
2471 /* CORE LOGIC MODE */
2472 if (!(flags & CORE_LOGIC_MODE))
2475 if (status == DEVICE_OPS_STATUS_START)
2478 if (display_probe(NULL) < 0)
2486 static int display_stop(enum device_flags flags)
2489 if (flags & NORMAL_MODE || flags & FORCE_OFF_MODE) {
2490 display_panel_set_panel_state_by_off_state(flags);
2494 /* CORE LOGIC MODE */
2495 if (!(flags & CORE_LOGIC_MODE))
2498 if (status == DEVICE_OPS_STATUS_STOP)
2506 static int display_status(void)
2511 static const struct device_ops display_plugin_device_ops = {
2512 .disable_auto_init = true,
2513 DECLARE_NAME_LEN("display-plugin"),
2514 .probe = display_probe,
2515 .init = display_init,
2516 .exit = display_exit,
2517 .start = display_start,
2518 .stop = display_stop,
2519 .status = display_status,
2522 DEVICE_OPS_REGISTER(&display_plugin_device_ops)
2524 static void __CONSTRUCTOR__ initialize(void)
2526 disp_plgn = get_var_display_plugin();
2528 _E("Failed to get display plugin variable.");
2530 backlight_ops = get_var_backlight_ops();
2532 _E("Failed to get backlight operator variable.");
2534 battery_plgn = get_var_battery_plugin();
2536 _E("Failed to get battery plugin variable.");