4 * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
6 * Licensed under the Apache License, Version 2.0 (the License);
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
22 * @brief Power manager main loop.
24 * This file includes Main loop, the FSM, signal processing.
35 #include <sys/types.h>
40 #include <vconf-keys.h>
42 #include <libsyscommon/list.h>
43 #include <hal/device/hal-device-power.h>
45 #include "ambient-mode.h"
49 #include "lock-detector.h"
50 #include "display-ops.h"
51 #include "shared/devices.h"
52 #include "shared/device-notifier.h"
53 #include "core/udev.h"
54 #include "shared/common.h"
55 #include "shared/apps.h"
56 #include "extcon/extcon.h"
57 #include "battery/power-supply.h"
58 #include "power/power.h"
59 #include "power/power-off.h"
60 #include "power/power-suspend.h"
61 #include "power/power-boot.h"
62 #include "power/power-doze.h"
63 #include "device-interface.h"
64 #include "display-plugin.h"
65 #include "display-signal.h"
66 #include "display-lock.h"
67 #include "display-backlight.h"
68 #include "display-misc.h"
69 #include "display-panel.h"
70 #include "display-config.h"
71 #include "display-state-transition.h"
72 #include "shared/plugin.h"
73 #include "led/touch-key.h"
76 * @addtogroup POWER_MANAGER
80 #define LOCK_SCREEN_CONTROL_TIMEOUT 5000
82 #define GESTURE_STR "gesture"
83 #define POWER_KEY_STR "powerkey"
84 #define TOUCH_STR "touch"
85 #define EVENT_STR "event"
86 #define TIMEOUT_STR "timeout"
87 #define PROXI_STR "proximity"
88 #define PALM_STR "palm"
89 #define UNKNOWN_STR "unknown"
91 extern void init_save_userlock(void);
93 static struct display_plugin *disp_plgn;
94 static struct display_backlight_ops *backlight_ops;
95 static struct battery_plugin *battery_plgn;
96 static int (*fp_get_charging_status) (int *val);
98 static void (*power_saving_func) (int onoff);
99 static enum device_ops_status status = DEVICE_OPS_STATUS_UNINIT;
101 static int system_wakeup_flag = false;
102 static char *custom_change_name;
104 static int default_proc_change_state(unsigned int cond, pid_t pid);
105 static int (*proc_change_state)(unsigned int cond, pid_t pid) = default_proc_change_state;
107 static struct state states[S_END] = {
108 { S_START, "S_START", NULL, NULL, NULL, NULL },
109 { S_NORMAL, "S_NORMAL", NULL, NULL, NULL, NULL },
110 { S_LCDDIM, "S_LCDDIM", NULL, NULL, NULL, NULL },
111 { S_LCDOFF, "S_LCDOFF", NULL, NULL, NULL, NULL },
112 { S_STANDBY, "S_STANDBY", NULL, NULL, NULL, NULL },
113 { S_SLEEP, "S_SLEEP", NULL, NULL, NULL, NULL },
114 { S_POWEROFF, "S_POWEROFF", NULL, NULL, NULL, NULL },
117 #define TIMEOUT_NONE (-1)
119 #define DELAYED_INIT_WATING_TIME 60000 /* 1 minute */
121 #define LOCK_SCREEN_WATING_TIME 300 /* 0.3 second */
122 #define LONG_PRESS_INTERVAL 2 /* 2 seconds */
123 #define SAMPLING_INTERVAL 1 /* 1 sec */
124 #define BRIGHTNESS_CHANGE_STEP 10
125 #define LCD_ALWAYS_ON 0
126 #define ACCEL_SENSOR_ON 1
127 #define CONTINUOUS_SAMPLING 1
128 #define LCDOFF_TIMEOUT 300 /* milli second */
130 static struct display_config display_conf = {
131 .lock_wait_time = LOCK_SCREEN_WATING_TIME,
132 .longpress_interval = LONG_PRESS_INTERVAL,
133 .lightsensor_interval = SAMPLING_INTERVAL,
134 .lcdoff_timeout = LCDOFF_TIMEOUT,
135 .pm_default_brightness = 80,
136 .brightness_change_step = BRIGHTNESS_CHANGE_STEP,
137 .lcd_always_on = LCD_ALWAYS_ON,
139 .framerate_app = {0, 0, 0, 0},
140 .control_display = 0,
141 .powerkey_doublepress = 0,
142 .accel_sensor_on = ACCEL_SENSOR_ON,
143 .continuous_sampling = CONTINUOUS_SAMPLING,
144 .timeout_enable = true,
145 .input_support = true,
146 .display_init_direction = DISPLAY_INIT_DIRECTION_HORIZONTAL,
147 .aod_enter_level = 40,
149 .touch_wakeup = false,
150 .display_on_usb_conn_changed = true,
151 .display_dpms_type = DISPLAY_DPMS_TYPE_WINDOW_MANAGER,
154 struct display_function_info display_info = {
155 .update_auto_brightness = NULL,
156 .set_autobrightness_min = NULL,
157 .reset_autobrightness_min = NULL,
158 .face_detection = NULL,
161 inline const struct display_config* get_var_display_config()
163 return &display_conf;
166 inline struct state* state_st(enum state_t state)
168 return &states[state];
171 static const char* __device_flags_to_string(enum device_flags flags)
173 if (flags & LCD_ON_BY_GESTURE)
175 else if (flags & (LCD_ON_BY_POWER_KEY | LCD_OFF_BY_POWER_KEY))
176 return POWER_KEY_STR;
177 else if (flags & (LCD_ON_BY_EVENT | LCD_OFF_BY_EVENT))
179 else if (flags & LCD_ON_BY_TOUCH)
181 else if (flags & LCD_OFF_BY_TIMEOUT)
187 static gboolean timer_refresh_cb(gpointer data)
191 /* state transition */
192 set_pm_old_state(get_pm_cur_state());
193 set_pm_cur_state(S_NORMAL);
194 st = &states[get_pm_cur_state()];
196 display_state_transition_do_state_action(st->timeout);
201 int custom_lcdon(int timeout)
208 if (display_panel_get_dpms_cached_state() != DPMS_ON)
209 display_panel_lcd_on_direct(LCD_ON_BY_GESTURE);
211 _I("Custom lcd on timeout(%d ms).", timeout);
212 if (set_custom_lcdon_timeout(timeout) == true)
213 display_state_transition_update_display_state_timeout_by_priority();
215 /* state transition */
216 set_pm_old_state(get_pm_cur_state());
217 set_pm_cur_state(S_NORMAL);
218 st = &states[get_pm_cur_state()];
220 display_state_transition_do_state_action(st->timeout);
222 g_idle_add(timer_refresh_cb, NULL);
227 int custom_lcdoff(enum device_flags flag)
231 if (display_lock_is_state_locked(S_NORMAL) || display_lock_is_state_locked(S_LCDDIM)) {
233 * When another proccess is normal lock, device is received call then,
234 * call app can be changed to lcd state by proximity.
235 * If proximity is near then normal lock will be unlocked.
237 if (flag & LCD_OFF_BY_PROXIMITY) {
238 _I("custom lcd off by proximity, delete normal lock");
239 display_lock_release_lock_all(S_NORMAL);
241 _I("skip custom lcd off");
246 _I("custom lcd off by flag(%d)", flag);
247 if (display_panel_get_dpms_cached_state() == DPMS_ON)
248 display_panel_lcd_off_procedure(flag);
250 if (set_custom_lcdon_timeout(0) == true)
251 display_state_transition_update_display_state_timeout_by_priority();
253 /* state transition */
254 set_pm_old_state(get_pm_cur_state());
255 set_pm_cur_state(S_LCDOFF);
256 st = &states[get_pm_cur_state()];
258 display_state_transition_do_state_action(st->timeout);
263 int display_on_by_reason(const char *reason, int timeout)
269 str_len = strlen(reason);
271 if (!strncmp(reason, GESTURE_STR, str_len))
272 flag = LCD_ON_BY_GESTURE;
273 else if (!strncmp(reason, EVENT_STR, str_len))
274 flag = LCD_ON_BY_EVENT;
276 _E("Reason is unknown(%s)", reason);
281 _E("Cannot setting timeout %d", timeout);
285 if (display_panel_get_dpms_cached_state() != DPMS_ON)
286 display_panel_lcd_on_direct(flag);
288 _I("platform lcd on by %s (%d ms)", reason, timeout);
289 if (set_custom_lcdon_timeout(timeout) == true)
290 display_state_transition_update_display_state_timeout_by_priority();
292 /* state transition */
293 set_pm_old_state(get_pm_cur_state());
294 set_pm_cur_state(S_NORMAL);
295 st = &states[get_pm_cur_state()];
297 display_state_transition_do_state_action(st->timeout);
302 int display_off_by_reason(const char *reason)
308 str_len = strlen(reason);
310 if (!strncmp(reason, GESTURE_STR, str_len)) {
311 if (display_lock_is_state_locked(S_NORMAL) || display_lock_is_state_locked(S_LCDDIM)) {
312 _I("skip platform lcd off by gesture");
315 flag = LCD_OFF_BY_GESTURE;
316 } else if (!strncmp(reason, PALM_STR, str_len)) {
317 display_lock_release_lock_all(S_NORMAL);
318 display_lock_release_lock_all(S_LCDDIM);
320 flag = LCD_OFF_BY_PALM;
322 _E("Reason is unknown(%s)", reason);
326 _I("platform lcd off by %s", reason);
327 if (display_panel_get_dpms_cached_state() == DPMS_ON)
328 display_panel_lcd_off_procedure(flag);
330 /* state transition */
331 set_pm_old_state(get_pm_cur_state());
332 set_pm_cur_state(S_LCDOFF);
333 st = &states[get_pm_cur_state()];
335 display_state_transition_do_state_action(st->timeout);
340 static void default_proc_change_state_action(enum state_t next, int timeout)
344 set_pm_old_state(get_pm_cur_state());
345 set_pm_cur_state(next);
347 st = &states[get_pm_cur_state()];
350 display_state_transition_do_state_action(st->timeout);
352 display_state_transition_do_state_action(timeout);
355 static int default_proc_change_state(unsigned int cond, pid_t pid)
359 next = GET_COND_STATE(cond);
360 _I("Change process(%d) state to %s.", pid, states[next].name);
364 if (display_panel_get_dpms_cached_state() != DPMS_ON)
365 display_panel_lcd_on_direct(LCD_ON_BY_EVENT);
366 display_state_transition_update_lock_screen_timeout(LOCK_SCREEN_CONTROL_TIMEOUT);
367 default_proc_change_state_action(next, -1);
370 default_proc_change_state_action(next, -1);
373 if (display_panel_get_dpms_cached_state() == DPMS_ON)
374 display_panel_lcd_off_procedure(LCD_OFF_BY_EVENT);
375 if (set_custom_lcdon_timeout(0))
376 display_state_transition_update_display_state_timeout_by_priority();
377 default_proc_change_state_action(next, -1);
380 _I("Dangerous requests.");
381 /* at first LCD_OFF and then goto sleep */
382 /* state transition */
383 default_proc_change_state_action(S_LCDOFF, TIMEOUT_NONE);
384 display_lock_release_lock_all(S_NORMAL);
385 display_lock_release_lock_all(S_LCDDIM);
386 display_lock_release_lock_all(S_LCDOFF);
387 if (display_panel_is_lcd_on_state_broadcasted()) {
388 _I("broadcast lcd off signal at non-lcd device");
389 broadcast_lcd_off(SIGNAL_PRE, 0);
390 broadcast_lcd_off(SIGNAL_POST, 0);
392 default_proc_change_state_action(S_SLEEP, TIMEOUT_NONE);
402 static void proc_condition_lock(PMMsg *data)
404 char pname[PATH_MAX];
405 pid_t pid = data->pid;
410 const char *lock_type = NULL;
412 state = GET_COND_STATE(data->cond);
413 if (state == S_START)
416 flags = GET_COND_FLAG(data->cond);
417 display_misc_get_process_name(pid, pname);
419 if ((state == S_LCDOFF) && (get_pm_cur_state() == S_SLEEP) &&
420 (pm_get_power_lock() == POWER_UNLOCK))
421 proc_change_state(data->cond, INTERNAL_LOCK_PM);
423 ret = display_lock_request_lock(state, pid, data->timeout);
424 if (ret == -EALREADY)
425 ret = display_lock_update_lock(state, pid, data->timeout);
428 _E("Failed to acquire lock, state: %d, pid: %d.", state, pid);
432 if (state == S_LCDOFF)
433 set_process_active(true, pid);
435 _I("[%s] locked by %5d with %u ms", states[state].name, pid, data->timeout);
437 if (pid < INTERNAL_LOCK_BASE) {
439 if (state == S_LCDOFF)
440 lock_type = PM_LCDOFF_STR;
441 else if (state == S_LCDDIM)
442 lock_type = PM_LCDDIM_STR;
443 else if (state == S_NORMAL)
444 lock_type = PM_LCDON_STR;
447 /* power lock signal */
448 ret = gdbus_signal_emit(NULL,
449 DEVICED_PATH_DISPLAY,
450 DEVICED_INTERFACE_DISPLAY,
452 g_variant_new("(sii)", lock_type, pid, (int)data->timeout));
454 _E("Failed to send dbus signal PowerLock.");
458 _SD("be requested LOCK info pname(%s), flags(%d)",
460 set_lock_time(pid, pname, state);
462 device_notify(DEVICE_NOTIFIER_DISPLAY_LOCK, (void *)&value);
465 static void proc_condition_unlock(PMMsg *data)
467 pid_t pid = data->pid;
469 char pname[PATH_MAX];
473 const char *lock_type = NULL;
475 state = GET_COND_STATE(data->cond);
479 flags = GET_COND_FLAG(data->cond);
480 display_misc_get_process_name(pid, pname);
482 display_lock_release_lock(state, pid);
484 if (state == S_LCDOFF)
485 set_process_active(false, pid);
487 _I("[%s] unlocked by %5d", states[state].name, pid);
489 if (pid < INTERNAL_LOCK_BASE) {
491 if (state == S_LCDOFF)
492 lock_type = PM_LCDOFF_STR;
493 else if (state == S_LCDDIM)
494 lock_type = PM_LCDDIM_STR;
495 else if (state == S_NORMAL)
496 lock_type = PM_LCDON_STR;
499 /* power unlock signal */
500 ret = gdbus_signal_emit(NULL,
501 DEVICED_PATH_DISPLAY,
502 DEVICED_INTERFACE_DISPLAY,
504 g_variant_new("(sii)", lock_type, pid, (int)data->timeout));
506 _E("Failed to send dbus signal PowerUnlock.");
510 _SD("be requested UNLOCK info pname(%s) flag(%d)", pname, flags);
511 set_unlock_time(pid, state);
513 device_notify(DEVICE_NOTIFIER_DISPLAY_LOCK, (void *)&value);
516 static int proc_condition(PMMsg *data)
520 if (IS_COND_REQUEST_LOCK(data->cond))
521 proc_condition_lock(data);
523 if (IS_COND_REQUEST_UNLOCK(data->cond))
524 proc_condition_unlock(data);
526 if (!display_conf.timeout_enable)
529 flags = GET_COND_FLAG(data->cond);
531 /* guard time for suspend */
532 if (get_pm_cur_state() == S_LCDOFF)
533 display_state_transition_reset_state_transition_timeout(states[S_LCDOFF].timeout);
535 if (flags & PM_FLAG_RESET_TIMER)
536 display_state_transition_reset_state_transition_timeout(states[get_pm_cur_state()].timeout);
539 if (!display_state_transition_is_there_state_transition_timer())
540 display_state_transition_do_state_transition(get_pm_cur_state(), EVENT_TIMEOUT);
545 /* SIGHUP signal handler
546 * For debug... print info to syslog
548 static void sig_hup(int signo)
550 _I("received sig hub %d", signo);
555 static void default_saving_mode(int onoff)
558 set_pm_status_flag(PWRSV_FLAG);
560 clear_pm_status_flag(PWRSV_FLAG);
562 if (get_pm_cur_state() == S_NORMAL)
563 display_backlight_update_by_default_brightness();
566 int poll_callback(int condition, PMMsg *data)
568 static time_t last_t;
571 display_get_display_ops_status(&status);
572 if (status != DEVICE_OPS_STATUS_START) {
573 _E("Display logic is not started.");
577 if (condition == INPUT_POLL_EVENT) {
578 if ((get_pm_cur_state() == S_LCDOFF) || (get_pm_cur_state() == S_SLEEP))
579 _I("Input event signal at Display Off");
581 if ((last_t != now) ||
582 (get_pm_cur_state() == S_LCDOFF) ||
583 (get_pm_cur_state() == S_SLEEP)) {
584 display_state_transition_do_state_transition(get_pm_cur_state(), EVENT_INPUT);
589 if (condition == PM_CONTROL_EVENT) {
590 proc_condition(data);
592 if (IS_COND_REQUEST_CHANGE(data->cond))
593 proc_change_state(data->cond, data->pid);
599 static int update_setting(int key_idx, int val)
604 case SETTING_TO_NORMAL:
605 display_state_transition_update_display_state_timeout_by_priority();
606 display_state_transition_do_state_transition(get_pm_cur_state(), EVENT_INPUT);
608 case SETTING_LOW_BATT:
609 if (display_misc_is_low_battery_state(val)) {
610 if (!(get_pm_status_flag() & CHRGR_FLAG))
611 power_saving_func(true);
612 set_pm_status_flag(LOWBT_FLAG);
614 if (get_pm_status_flag() & PWRSV_FLAG)
615 power_saving_func(false);
616 clear_pm_status_flag(LOWBT_FLAG);
617 clear_pm_status_flag(BRTCH_FLAG);
618 ret = vconf_set_bool(VCONFKEY_PM_BRIGHTNESS_CHANGED_IN_LPM, false);
620 _E("Failed to set vconf value for brightness changed in lpm: %d", vconf_get_ext_errno());
623 case SETTING_CHARGING:
625 if (get_pm_status_flag() & LOWBT_FLAG) {
626 power_saving_func(false);
627 clear_pm_status_flag(LOWBT_FLAG);
629 set_pm_status_flag(CHRGR_FLAG);
632 ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW,
635 bat_state = VCONFKEY_SYSMAN_BAT_NORMAL;
636 _E("Failed to get vconf value for battery status low: %d", vconf_get_ext_errno());
638 if (display_misc_is_low_battery_state(bat_state)) {
639 power_saving_func(true);
640 set_pm_status_flag(LOWBT_FLAG);
642 clear_pm_status_flag(CHRGR_FLAG);
645 case SETTING_BRT_LEVEL:
646 if (get_pm_status_flag() & PWRSV_FLAG) {
647 set_pm_status_flag(BRTCH_FLAG);
648 ret = vconf_set_bool(VCONFKEY_PM_BRIGHTNESS_CHANGED_IN_LPM, true);
650 _E("Failed to set vconf value for brightness changed in lpm: %d", vconf_get_ext_errno());
651 _I("Brightness changed in low battery,"
652 "escape dim state.");
654 display_backlight_set_default_brightness(val);
656 case SETTING_LOCK_SCREEN:
657 set_lock_screen_state(val);
658 if (val == VCONFKEY_IDLE_UNLOCK)
659 touchled_control_backlight(TOUCHLED_DIRECT_OFF);
661 /* LCD on if lock screen show before waiting time */
662 if ((get_pm_cur_state() == S_NORMAL) &&
663 val == VCONFKEY_IDLE_LOCK &&
664 display_panel_get_dpms_cached_state() != DPMS_ON &&
665 is_lcdon_blocked() == LCDON_BLOCK_NONE)
666 display_panel_lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
667 display_state_transition_update_display_state_timeout_by_priority();
668 if (get_pm_cur_state() == S_NORMAL)
669 display_state_transition_do_state_transition(get_pm_cur_state(), EVENT_INPUT);
671 case SETTING_LOCK_SCREEN_BG:
672 set_lock_screen_bg_state(val);
673 display_state_transition_update_display_state_timeout_by_priority();
674 if (get_pm_cur_state() == S_NORMAL)
675 display_state_transition_do_state_transition(get_pm_cur_state(), EVENT_INPUT);
677 case SETTING_POWER_CUSTOM_BRIGHTNESS:
678 if (val == VCONFKEY_PM_CUSTOM_BRIGHTNESS_ON)
679 display_backlight_set_custom_status(true);
681 display_backlight_set_custom_status(false);
690 static void check_seed_status(void)
697 int lock_screen_timeout = 0;
700 if (fp_get_charging_status && (fp_get_charging_status(&tmp) == 0) && (tmp > 0))
701 set_pm_status_flag(CHRGR_FLAG);
703 ret = get_setting_brightness(&tmp);
704 if (ret != 0 || (tmp < PM_MIN_BRIGHTNESS || tmp > PM_MAX_BRIGHTNESS)) {
705 _I("Failed to read vconf value for brightness.");
706 brt = display_conf.pm_default_brightness;
707 if (tmp < PM_MIN_BRIGHTNESS || tmp > PM_MAX_BRIGHTNESS) {
708 ret = vconf_set_int(VCONFKEY_SETAPPL_LCD_BRIGHTNESS, brt);
710 _E("Failed to set vconf value for lcd brightness: %d", vconf_get_ext_errno());
714 _I("Set brightness(%d) from setting app.", tmp);
715 display_backlight_set_default_brightness(tmp);
716 display_backlight_set_brightness(tmp);
718 ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, &bat_state);
720 bat_state = VCONFKEY_SYSMAN_BAT_NORMAL;
721 _E("Failed to get vconf value for battery status low: %d", vconf_get_ext_errno());
723 if (display_misc_is_low_battery_state(bat_state)) {
724 if (!(get_pm_status_flag() & CHRGR_FLAG)) {
725 power_saving_func(true);
726 set_pm_status_flag(LOWBT_FLAG);
730 /* lock screen check */
731 ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
734 _E("Failed to get vconf value for idle lock state: %d", vconf_get_ext_errno());
736 set_lock_screen_state(lock_state);
737 display_state_transition_get_lock_screen_timeout(&lock_screen_timeout);
738 if (lock_state == VCONFKEY_IDLE_LOCK) {
739 states[S_NORMAL].timeout = lock_screen_timeout;
740 _I("LCD NORMAL timeout(%d ms) is set"
741 " for lock screen.", lock_screen_timeout);
747 static void init_lcd_operation(void)
749 const struct device_ops *ops = NULL;
751 ops = find_device("display");
752 if (!check_default(ops))
753 display_register_dependent_device(ops);
755 ops = find_device("touchkey");
756 if (!check_default(ops))
757 display_register_dependent_device(ops);
759 ops = find_device("touchscreen");
760 if (!check_default(ops))
761 display_register_dependent_device(ops);
764 static void exit_lcd_operation(void)
766 display_unregister_dependent_device();
778 static const char *errMSG[INIT_END] = {
779 [INIT_SETTING] = "setting init error",
780 [INIT_INTERFACE] = "lowlevel interface(sysfs or others) init error",
781 [INIT_POLL] = "input devices poll init error",
782 [INIT_FIFO] = "FIFO poll init error",
783 [INIT_DBUS] = "d-bus init error",
786 int set_lcd_timeout(int on, int dim, const char *name)
788 unsigned int custom_normal_timeout = 0;
789 unsigned int custom_dim_timeout = 0;
791 if (on == 0 && dim == 0) {
792 _I("LCD timeout changed: default setting");
793 display_state_transition_set_custom_timeout(S_NORMAL, 0);
794 display_state_transition_set_custom_timeout(S_LCDDIM, 0);
795 } else if (on < 0 || dim < 0) {
796 _E("Failed to set value(on=%d dim=%d).", on, dim);
799 _I("LCD timeout changed: on=%ds dim=%ds", on, dim);
800 display_state_transition_set_custom_timeout(S_NORMAL, SEC_TO_MSEC(on));
801 display_state_transition_set_custom_timeout(S_LCDDIM, SEC_TO_MSEC(dim));
803 /* Apply new backlight time */
804 display_state_transition_update_display_state_timeout_by_priority();
805 if (get_pm_cur_state() == S_NORMAL)
806 display_state_transition_do_state_transition(get_pm_cur_state(), EVENT_INPUT);
808 if (custom_change_name) {
809 free(custom_change_name);
810 custom_change_name = 0;
813 display_state_transition_get_custom_timeout(S_NORMAL, &custom_normal_timeout);
814 display_state_transition_get_custom_timeout(S_LCDDIM, &custom_dim_timeout);
815 if (custom_normal_timeout == 0 && custom_dim_timeout == 0)
818 custom_change_name = strndup(name, strlen(name));
819 if (!custom_change_name) {
820 _E("Failed to malloc.");
821 display_state_transition_set_custom_timeout(S_NORMAL, 0);
822 display_state_transition_set_custom_timeout(S_LCDDIM, 0);
829 void reset_lcd_timeout(GDBusConnection *conn,
831 const gchar *unique_name,
837 if (!custom_change_name)
840 if (strcmp(sender, custom_change_name))
843 _I("reset lcd timeout: Set default timeout. sender=%s", sender);
845 free(custom_change_name);
846 custom_change_name = 0;
847 display_state_transition_set_custom_timeout(S_NORMAL, 0);
848 display_state_transition_set_custom_timeout(S_LCDDIM, 0);
850 display_state_transition_update_display_state_timeout_by_priority();
851 if (get_pm_cur_state() == S_NORMAL)
852 display_state_transition_do_state_transition(get_pm_cur_state(), EVENT_INPUT);
855 static int delayed_init_done(void *data)
857 static bool done = false;
866 _I("Booting done, release booting lock.");
867 if (disp_plgn->pm_unlock_internal) {
868 disp_plgn->pm_unlock_internal(INTERNAL_LOCK_BOOTING, LCD_NORMAL, PM_SLEEP_MARGIN);
869 disp_plgn->pm_unlock_internal(INTERNAL_LOCK_BOOTING, LCD_OFF, PM_SLEEP_MARGIN);
875 static gboolean delayed_dpms_init_done(gpointer data)
879 if (!display_panel_init_dpms())
880 return G_SOURCE_CONTINUE;
882 switch (get_pm_cur_state()) {
885 display_panel_lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
886 if (display_conf.timeout_enable) {
887 timeout = states[S_NORMAL].timeout;
888 /* check minimun lcd on time */
889 if (timeout < SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT))
890 timeout = SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT);
891 display_state_transition_reset_state_transition_timeout(timeout);
895 display_panel_lcd_off_procedure(LCD_OFF_BY_EVENT);
896 timeout = display_conf.lcdoff_timeout;
897 display_state_transition_reset_state_transition_timeout(timeout);
903 return G_SOURCE_REMOVE;
906 static void add_timer_for_dpms_init(void)
908 guint id = g_timeout_add(500/* milliseconds */, delayed_dpms_init_done, NULL);
910 _E("Failed to add display_panel_init_dpms timeout.");
913 static void init_display_states(void *data)
915 struct display_plugin *dp = (struct display_plugin *) data;
916 for(int i = 0; i < S_END; i++)
917 dp->display_states[i] = &states[i];
924 static int display_probe(void *data)
927 struct display_plugin *dp = (struct display_plugin *) data;
930 dp->config = &display_conf;
931 init_display_states(dp);
932 setup_display_plugin_backlight_ops(dp);
933 dp->set_dim_state = NULL;
934 dp->get_device_flags = NULL;
935 dp->lcd_on_procedure = NULL;
936 dp->lcd_off_procedure = NULL;
937 setup_display_plugin_backlight_ops(dp);
940 * load display service
941 * if there is no display shared library,
942 * deviced does not provide any method and function of display.
944 ret = display_service_load();
948 /* display_plugin instance initialization */
949 init_pm_internal(data);
950 disp_plgn->device_flags_to_string = __device_flags_to_string;
952 if (battery_plgn->handle) {
953 fp_get_charging_status = dlsym(battery_plgn->handle, "get_charging_status");
954 if (!fp_get_charging_status)
955 _E("Failed to obtain address of get_charging_status");
957 _I("There is no battery module.");
962 static int input_init_handler(void)
964 if (!display_conf.input_support)
965 remove_device_by_devname("input");
970 static int power_resume_from_echomem_callback(void *data)
972 system_wakeup_flag = true;
973 if (check_wakeup_src() == EVENT_DEVICE)
974 /* system waked up by devices */
975 display_state_transition_do_state_transition(get_pm_cur_state(), EVENT_DEVICE);
977 /* system waked up by user input */
978 display_state_transition_do_state_transition(get_pm_cur_state(), EVENT_INPUT);
983 static int poweroff_triggered_callback(void *udata)
985 int val = (int)(intptr_t) udata;
988 case VCONFKEY_SYSMAN_POWER_OFF_NONE:
989 clear_pm_status_flag(PWROFF_FLAG);
991 case VCONFKEY_SYSMAN_POWER_OFF_DIRECT:
992 case VCONFKEY_SYSMAN_POWER_OFF_RESTART:
993 set_pm_status_flag(PWROFF_FLAG);
1000 static void esd_action(void)
1002 const struct device_ops *touchscreen_ops = NULL;
1006 touchscreen_ops = find_device("touchscreen");
1008 if (!check_default(touchscreen_ops))
1009 touchscreen_ops->stop(NORMAL_MODE);
1010 display_panel_set_panel_state_by_off_state(NORMAL_MODE);
1011 display_panel_set_panel_state_by_on_state(NORMAL_MODE);
1012 if (!check_default(touchscreen_ops))
1013 touchscreen_ops->start(NORMAL_MODE);
1016 static void lcd_uevent_changed(struct udev_device *dev)
1018 const char *devpath;
1021 devpath = udev_device_get_devpath(dev);
1025 if (!fnmatch(LCD_ESD_PATH, devpath, 0)) {
1026 action = udev_device_get_action(dev);
1027 if (!strcmp(action, UDEV_CHANGE))
1032 static const struct uevent_handler lcd_uevent_ops = {
1033 .subsystem = LCD_EVENT_SUBSYSTEM,
1034 .uevent_func = lcd_uevent_changed,
1038 static void display_init(void *data)
1041 unsigned int flags = (WITHOUT_STARTNOTI | FLAG_X_DPMS);
1044 _I("Start power manager.");
1046 signal(SIGHUP, sig_hup);
1048 power_saving_func = default_saving_mode;
1050 /* load configutation */
1051 ret = display_load_config(&display_conf);
1053 _W("Failed to load '%s', use default value: %d",
1054 DISPLAY_CONF_FILE, ret);
1056 register_kernel_uevent_control(&lcd_uevent_ops);
1058 register_notifier(DEVICE_NOTIFIER_DELAYED_INIT, delayed_init_done);
1059 register_notifier(DEVICE_NOTIFIER_APPLICATION_BACKGROUND, display_app_background);
1060 register_notifier(DEVICE_NOTIFIER_APPLICATION_FOREGROUND, display_app_foreground);
1061 register_notifier(DEVICE_NOTIFIER_APPLICATION_TERMINATED, display_app_terminated);
1062 register_notifier(DEVICE_NOTIFIER_POWER_RESUME_FROM_ECHO_MEM, power_resume_from_echomem_callback);
1063 register_notifier(DEVICE_NOTIFIER_POWEROFF_TRIGGERED, poweroff_triggered_callback);
1065 init_save_userlock();
1067 for (i = INIT_SETTING; i < INIT_END; i++) {
1070 ret = init_setting(update_setting);
1072 case INIT_INTERFACE:
1073 if (display_conf.timeout_enable)
1074 display_initialize_display_state_timeout_from_setting();
1075 ret = init_sysfs(flags);
1079 ret = input_init_handler();
1081 pm_lock_detector_init();
1085 ret = init_pm_dbus();
1089 _E("Failed to init: %s", errMSG[i]);
1094 if (i == INIT_END) {
1095 display_ops_init(NULL);
1096 #ifdef ENABLE_PM_LOG
1099 init_lcd_operation();
1100 check_seed_status();
1102 /* In smd test, TSP should be turned off if display panel is not existed. */
1103 if (display_panel_get_dpms_cached_state() == -ENOENT) {
1104 _I("Display panel is not existed.");
1105 lcd_direct_control(DPMS_OFF, NORMAL_MODE);
1106 exit_lcd_operation();
1109 /* wm_ready needs to be checked
1110 * since display manager can be launched later than deviced.
1111 * In the case, display cannot be turned on at the first booting */
1112 // wm_ready = check_wm_ready();
1113 if (display_panel_init_dpms()) {
1114 if (is_lcdon_blocked() != LCDON_BLOCK_NONE)
1115 display_panel_lcd_off_procedure(LCD_OFF_BY_EVENT);
1117 display_panel_lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
1119 add_timer_for_dpms_init();
1122 if (display_conf.lcd_always_on) {
1123 _I("LCD always on.");
1124 display_state_transition_set_transition_table_display_state(S_NORMAL, S_NORMAL, EVENT_TIMEOUT);
1127 if (flags & WITHOUT_STARTNOTI) { /* start without noti */
1128 _I("Start Power managing without noti");
1129 power_request_change_state_strict(DEVICED_POWER_STATE_SLEEP, DEVICED_POWER_STATE_NORMAL,
1130 HAL_DEVICE_POWER_TRANSITION_REASON_UNKNOWN, NULL);
1132 * Lock lcd off until booting is done.
1133 * deviced guarantees all booting script is executing.
1134 * Last script of booting unlocks this suspend blocking state.
1136 if (disp_plgn->pm_lock_internal)
1137 disp_plgn->pm_lock_internal(INTERNAL_LOCK_BOOTING, LCD_OFF,
1138 STAY_CUR_STATE, DELAYED_INIT_WATING_TIME);
1140 /* Initial display state right after the booting done */
1141 if (is_lcdon_blocked())
1142 set_pm_cur_state(S_LCDOFF);
1144 set_pm_cur_state(S_NORMAL);
1145 ret = vconf_set_int(VCONFKEY_PM_STATE, get_pm_cur_state());
1147 _E("Failed to set vconf value for pm cur state: %d", vconf_get_ext_errno());
1149 display_set_display_ops_status(DEVICE_OPS_STATUS_START);
1150 if (display_conf.timeout_enable) {
1151 timeout = states[S_NORMAL].timeout;
1152 /* check minimun lcd on time */
1153 if (timeout < SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT))
1154 timeout = SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT);
1156 if (disp_plgn->pm_lock_internal)
1157 disp_plgn->pm_lock_internal(INTERNAL_LOCK_BOOTING, LCD_NORMAL,
1158 STAY_CUR_STATE, timeout);
1163 set_display_init_direction(display_conf.display_init_direction);
1167 static void display_exit(void *data)
1171 display_set_display_ops_status(DEVICE_OPS_STATUS_STOP);
1173 /* Set current state to S_NORMAL */
1174 set_pm_cur_state(S_NORMAL);
1175 set_setting_pmstate(get_pm_cur_state());
1176 /* timeout is not needed */
1177 display_state_transition_reset_state_transition_timeout(TIMEOUT_NONE);
1179 unregister_kernel_uevent_control(&lcd_uevent_ops);
1181 display_ops_exit(NULL);
1183 for (i = i - 1; i >= INIT_SETTING; i--) {
1188 case INIT_INTERFACE:
1192 unregister_notifier(DEVICE_NOTIFIER_DELAYED_INIT, delayed_init_done);
1193 unregister_notifier(DEVICE_NOTIFIER_APPLICATION_BACKGROUND, display_app_background);
1194 unregister_notifier(DEVICE_NOTIFIER_APPLICATION_FOREGROUND, display_app_foreground);
1195 unregister_notifier(DEVICE_NOTIFIER_APPLICATION_TERMINATED, display_app_terminated);
1196 unregister_notifier(DEVICE_NOTIFIER_POWER_RESUME_FROM_ECHO_MEM, power_resume_from_echomem_callback);
1202 exit_lcd_operation();
1203 free_lock_info_list();
1205 /* free display service */
1206 display_service_free();
1208 _I("Stop power manager.");
1211 static int display_start(enum device_flags flags)
1214 if (flags & NORMAL_MODE) {
1215 if (flags & LCD_PANEL_OFF_MODE)
1217 display_panel_set_panel_state_by_standby_state(true);
1220 display_panel_set_panel_state_by_on_state(flags);
1225 /* CORE LOGIC MODE */
1226 if (!(flags & CORE_LOGIC_MODE))
1229 display_get_display_ops_status(&status);
1230 if (status == DEVICE_OPS_STATUS_START)
1233 if (display_probe(NULL) < 0)
1241 static int display_stop(enum device_flags flags)
1244 if (flags & NORMAL_MODE || flags & FORCE_OFF_MODE) {
1245 display_panel_set_panel_state_by_off_state(flags);
1249 /* CORE LOGIC MODE */
1250 if (!(flags & CORE_LOGIC_MODE))
1253 display_get_display_ops_status(&status);
1254 if (status == DEVICE_OPS_STATUS_STOP)
1262 static int display_status(void)
1267 static const struct device_ops display_plugin_device_ops = {
1268 .disable_auto_init = true,
1269 DECLARE_NAME_LEN("display-plugin"),
1270 .probe = display_probe,
1271 .init = display_init,
1272 .exit = display_exit,
1273 .start = display_start,
1274 .stop = display_stop,
1275 .status = display_status,
1278 DEVICE_OPS_REGISTER(&display_plugin_device_ops)
1280 static void __CONSTRUCTOR__ initialize(void)
1282 disp_plgn = get_var_display_plugin();
1284 _E("Failed to get display plugin variable.");
1286 backlight_ops = get_var_backlight_ops();
1288 _E("Failed to get backlight operator variable.");
1290 battery_plgn = get_var_battery_plugin();
1292 _E("Failed to get battery plugin variable.");