4 * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
6 * Licensed under the Apache License, Version 2.0 (the License);
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
22 * @brief Power manager main loop.
24 * This file includes Main loop, the FSM, signal processing.
35 #include <sys/types.h>
40 #include <vconf-keys.h>
42 #include <libsyscommon/list.h>
43 #include <device/display-internal.h>
44 #include <hal/device/hal-device-power.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-signal.h"
67 #include "display-lock.h"
68 #include "display-backlight.h"
69 #include "display-misc.h"
70 #include "display-panel.h"
71 #include "display-config.h"
72 #include "display-state-transition.h"
73 #include "shared/plugin.h"
76 * @addtogroup POWER_MANAGER
80 #define LOCK_SCREEN_INPUT_TIMEOUT 10000
81 #define LOCK_SCREEN_CONTROL_TIMEOUT 5000
82 #define ALWAYS_ON_TIMEOUT 360000000
84 #define GESTURE_STR "gesture"
85 #define POWER_KEY_STR "powerkey"
86 #define TOUCH_STR "touch"
87 #define EVENT_STR "event"
88 #define TIMEOUT_STR "timeout"
89 #define PROXI_STR "proximity"
90 #define PALM_STR "palm"
91 #define UNKNOWN_STR "unknown"
93 extern void init_save_userlock(void);
95 static struct display_plugin *disp_plgn;
96 static struct display_backlight_ops *backlight_ops;
97 static struct battery_plugin *battery_plgn;
98 static int (*fp_get_charging_status) (int *val);
99 static void (*power_saving_func) (int onoff);
100 static enum device_ops_status status = DEVICE_OPS_STATUS_UNINIT;
102 static int system_wakeup_flag = false;
103 static unsigned int custom_normal_timeout = 0;
104 static unsigned int custom_dim_timeout = 0;
105 static char *custom_change_name;
106 static guint lock_timeout_id;
107 static int lock_screen_timeout = LOCK_SCREEN_INPUT_TIMEOUT;
108 static struct timeval lcdon_tv;
110 * The two variables(lcdon_broadcast, pmstate_suspend) must be set initial
111 * state because it should be sent from previous state at booting time.
113 static bool lcdon_broadcast = true;
115 static bool touch_blocked = false;
117 /* default transition, action fuctions */
118 static int default_trans(int evt);
119 static int default_action(int timeout);
120 static int default_check(int curr, int next);
122 static gboolean del_normal_cond(void *data);
123 static gboolean del_dim_cond(void *data);
124 static gboolean del_off_cond(void *data);
126 static int default_proc_change_state(unsigned int cond, pid_t pid);
127 static int (*proc_change_state)(unsigned int cond, pid_t pid) = default_proc_change_state;
129 static struct state states[S_END] = {
130 { S_START, "S_START", NULL, NULL, NULL, NULL },
131 { S_NORMAL, "S_NORMAL", default_trans, default_action, default_check, del_normal_cond },
132 { S_LCDDIM, "S_LCDDIM", default_trans, default_action, default_check, del_dim_cond },
133 { S_LCDOFF, "S_LCDOFF", default_trans, default_action, default_check, del_off_cond },
134 { S_STANDBY, "S_STANDBY", NULL, NULL, NULL, NULL },
135 { S_SLEEP, "S_SLEEP", default_trans, default_action, default_check, NULL },
136 { S_POWEROFF, "S_POWEROFF", NULL, NULL, NULL, NULL },
139 #define SHIFT_UNLOCK 4
140 #define SHIFT_CHANGE_STATE 7
141 #define CHANGE_STATE_BIT 0xF00 /* 1111 0000 0000 */
142 #define SHIFT_LOCK_FLAG 16
143 #define SHIFT_CHANGE_TIMEOUT 20
144 #define CUSTOM_TIMEOUT_BIT 0x1
145 #define CUSTOM_HOLDKEY_BIT 0x2
146 #define HOLD_KEY_BLOCK_BIT 0x1
147 #define TIMEOUT_NONE (-1)
149 #define S_COVER_TIMEOUT 8000
150 #define GET_HOLDKEY_BLOCK_STATE(x) ((x >> SHIFT_LOCK_FLAG) & HOLD_KEY_BLOCK_BIT)
151 #define DELAYED_INIT_WATING_TIME 60000 /* 1 minute */
153 #define LOCK_SCREEN_WATING_TIME 300 /* 0.3 second */
154 #define LONG_PRESS_INTERVAL 2 /* 2 seconds */
155 #define SAMPLING_INTERVAL 1 /* 1 sec */
156 #define BRIGHTNESS_CHANGE_STEP 10
157 #define LCD_ALWAYS_ON 0
158 #define ACCEL_SENSOR_ON 1
159 #define CONTINUOUS_SAMPLING 1
160 #define LCDOFF_TIMEOUT 300 /* milli second */
162 #define DIFF_TIMEVAL_MS(a, b) \
163 (((a.tv_sec * 1000000 + a.tv_usec) - \
164 (b.tv_sec * 1000000 + b.tv_usec)) \
167 static struct display_config display_conf = {
168 .lock_wait_time = LOCK_SCREEN_WATING_TIME,
169 .longpress_interval = LONG_PRESS_INTERVAL,
170 .lightsensor_interval = SAMPLING_INTERVAL,
171 .lcdoff_timeout = LCDOFF_TIMEOUT,
172 .pm_default_brightness = 80,
173 .brightness_change_step = BRIGHTNESS_CHANGE_STEP,
174 .lcd_always_on = LCD_ALWAYS_ON,
176 .framerate_app = {0, 0, 0, 0},
177 .control_display = 0,
178 .powerkey_doublepress = 0,
179 .accel_sensor_on = ACCEL_SENSOR_ON,
180 .continuous_sampling = CONTINUOUS_SAMPLING,
181 .timeout_enable = true,
182 .input_support = true,
183 .lockcheck_timeout = 600,
184 .display_init_direction = DISPLAY_INIT_DIRECTION_HORIZONTAL,
185 .aod_enter_level = 40,
187 .touch_wakeup = false,
188 .display_on_usb_conn_changed = true,
189 .display_dpms_type = DISPLAY_DPMS_TYPE_WINDOW_MANAGER,
192 struct display_function_info display_info = {
193 .update_auto_brightness = NULL,
194 .set_autobrightness_min = NULL,
195 .reset_autobrightness_min = NULL,
196 .face_detection = NULL,
199 inline const struct display_config* get_var_display_config()
201 return &display_conf;
204 inline struct state* state_st(enum state_t state)
206 return &states[state];
209 static const char* __device_flags_to_string(enum device_flags flags)
211 if (flags & LCD_ON_BY_GESTURE)
213 else if (flags & (LCD_ON_BY_POWER_KEY | LCD_OFF_BY_POWER_KEY))
214 return POWER_KEY_STR;
215 else if (flags & (LCD_ON_BY_EVENT | LCD_OFF_BY_EVENT))
217 else if (flags & LCD_ON_BY_TOUCH)
219 else if (flags & LCD_OFF_BY_TIMEOUT)
225 static unsigned long get_lcd_on_flags(void)
227 unsigned long flags = NORMAL_MODE;
228 bool lcd_paneloff_mode = false;
230 display_panel_get_lcd_paneloff_mode(&lcd_paneloff_mode);
231 if (lcd_paneloff_mode)
232 flags |= LCD_PANEL_OFF_MODE;
237 bool touch_event_blocked(void)
239 return touch_blocked;
242 void lcd_on_procedure(int state, enum device_flags flag)
244 unsigned long flags = get_lcd_on_flags();
248 * Display on procedure
250 * step 2. broadcast lcd on signal with cause
251 * step 3. set brightness
252 * step 4. set pmstate of vconf
253 * step 5. display on operate
255 * - b. TSP(touch screen) and touchkey enable
256 * step 6. broadcast lcd on complete signal
257 * step 7. key backlight enable
261 _I("[lcdstep] 0x%lx", flags);
263 /* send LCDOn dbus signal */
264 if (!lcdon_broadcast)
265 broadcast_lcd_on(SIGNAL_PRE, flags);
267 /* Update brightness level */
268 if (state == LCD_DIM)
269 display_backlight_set_brightness_by_dim_brightness();
270 else if (state == LCD_NORMAL)
271 display_backlight_update_by_default_brightness();
273 if (state == LCD_NORMAL)
274 set_setting_pmstate(S_NORMAL);
275 else if (state == LCD_DIM)
276 set_setting_pmstate(S_LCDDIM);
278 display_start_dependent_device(flags);
280 if (!lcdon_broadcast) {
281 broadcast_lcd_on(SIGNAL_POST, flags);
282 lcdon_broadcast = true;
285 if (CHECK_OPS(keyfilter_ops, backlight_enable))
286 keyfilter_ops->backlight_enable(true);
288 touch_blocked = false;
291 static unsigned long get_lcd_off_flags(void)
293 unsigned long flags = NORMAL_MODE;
294 bool stay_touchscreen_off = false;
296 display_misc_get_stay_touchscreen_off(&stay_touchscreen_off);
297 if (stay_touchscreen_off)
298 flags |= TOUCH_SCREEN_OFF_MODE;
303 inline void lcd_off_procedure(enum device_flags flag)
305 unsigned long flags = get_lcd_off_flags();
309 * Display off procedure
310 * step 0. enhance mode off using nofity (e.g mdnie, HBM, LBM)
311 * step 1. broadcast lcd off signal with cause
312 * step 2. set pmstate of vconf
313 * step 3. display off operate
315 * - b. TSP(touch screen) and touchkey disable
316 * step 4. broadcast lcd off complete siganl
317 * step 5. enter doze mode if it is enabled
319 _I("[lcdstep] 0x%lx", flags);
323 device_notify(DEVICE_NOTIFIER_LCD_OFF, NULL);
325 if (lcdon_broadcast) {
326 broadcast_lcd_off(SIGNAL_PRE, flags);
327 lcdon_broadcast = false;
332 touch_blocked = true;
334 set_setting_pmstate(S_LCDOFF);
336 if (CHECK_OPS(keyfilter_ops, backlight_enable))
337 keyfilter_ops->backlight_enable(false);
339 display_stop_dependent_device(flags);
341 broadcast_lcd_off(SIGNAL_POST, flags);
342 device_notify(DEVICE_NOTIFIER_LCD_OFF_COMPLETE, NULL);
347 static void del_state_cond(void *data, enum state_t state)
349 PmLockNode *tmp = NULL;
355 /* A passed data is a pid_t type data, not a 64bit data. */
356 pid = (pid_t)((intptr_t)data);
357 _I("delete prohibit %s condition by timeout (%d)", states[state].name, pid);
359 if (pid == INTERNAL_LOCK_AMBIENT)
360 ambient_check_invalid_state(pid);
362 tmp = find_node(state, pid);
363 del_node(state, tmp);
364 set_unlock_time(pid, state);
366 /* Change state only when the two conditions below are satisfied.
367 * 1. There should be no running state-transition timer
368 * 2. Released lock is one of the pm_cur_state's lock
369 * This emulates already expired transition timer */
370 if (!display_state_transition_is_there_state_transition_timer() && (get_pm_cur_state() == state))
371 states[get_pm_cur_state()].trans(EVENT_TIMEOUT);
373 if (state == S_LCDOFF)
374 set_process_active(false, pid);
377 static gboolean del_normal_cond(void *data)
379 del_state_cond(data, S_NORMAL);
380 return G_SOURCE_REMOVE;
383 static gboolean del_dim_cond(void *data)
385 del_state_cond(data, S_LCDDIM);
386 return G_SOURCE_REMOVE;
389 static gboolean del_off_cond(void *data)
391 del_state_cond(data, S_LCDOFF);
392 return G_SOURCE_REMOVE;
395 /* get configurations from setting */
396 static int get_lcd_timeout_from_settings(void)
401 for (i = 0; i < S_END; i++) {
402 switch (states[i].state) {
404 get_run_timeout(&val);
407 get_dim_timeout(&val);
410 val = display_conf.lcdoff_timeout;
413 /* This state doesn't need to set time out. */
418 states[i].timeout = val;
420 _I("State(%s) timeout(%d) ms", states[i].name,
427 static void update_display_time(void)
429 int run_timeout, val;
431 /* first priority : custom timeout */
432 if (custom_normal_timeout > 0) {
433 states[S_NORMAL].timeout = custom_normal_timeout;
434 states[S_LCDDIM].timeout = custom_dim_timeout;
435 _I("CUSTOM : timeout is set by normal(%d ms), dim(%d ms)",
436 custom_normal_timeout, custom_dim_timeout);
440 /* second priority : lock state */
441 if ((__get_lock_screen_state() == VCONFKEY_IDLE_LOCK) &&
442 !get_lock_screen_bg_state()) {
443 /* timeout is different according to key or event. */
444 states[S_NORMAL].timeout = lock_screen_timeout;
445 _I("LOCK: Timeout(%d ms) is set by normal.",
446 lock_screen_timeout);
450 /* default setting */
451 get_run_timeout(&run_timeout);
454 * if the run_timeout is zero, it regards AlwaysOn state
456 if (run_timeout == 0 || display_conf.lcd_always_on) {
457 run_timeout = ALWAYS_ON_TIMEOUT;
458 _I("LCD always on.");
461 states[S_NORMAL].timeout = run_timeout;
463 get_dim_timeout(&val);
464 states[S_LCDDIM].timeout = val;
466 _I("Normal: NORMAL timeout is set by %d ms", states[S_NORMAL].timeout);
467 _I("Normal: DIM timeout is set by %d ms", states[S_LCDDIM].timeout);
470 static void update_display_locktime(int time)
472 lock_screen_timeout = time;
473 update_display_time();
476 void set_dim_state(bool on)
478 _I("Dim state is %d.", on);
479 update_display_time();
480 states[get_pm_cur_state()].trans(EVENT_INPUT);
483 void lcd_on_direct(enum device_flags flags)
485 enum hal_device_power_transition_reason reason;
487 if (flags & LCD_ON_BY_POWER_KEY)
488 reason = HAL_DEVICE_POWER_TRANSITION_REASON_POWER_KEY;
489 else if (flags & LCD_ON_BY_TOUCH)
490 reason = HAL_DEVICE_POWER_TRANSITION_REASON_TOUCH_SCREEN;
492 reason = HAL_DEVICE_POWER_TRANSITION_REASON_UNKNOWN;
494 power_request_change_state_strict(DEVICED_POWER_STATE_SLEEP, DEVICED_POWER_STATE_NORMAL, reason, NULL);
495 set_pm_cur_state(S_NORMAL);
497 _D("lcd is on directly");
498 gettimeofday(&lcdon_tv, NULL);
499 lcd_on_procedure(LCD_NORMAL, flags);
501 update_display_locktime(LOCK_SCREEN_INPUT_TIMEOUT);
504 static inline bool check_lcd_is_on(void)
506 if (display_panel_get_dpms_cached_state() != DPMS_ON)
512 static gboolean timer_refresh_cb(gpointer data)
516 /* state transition */
517 set_pm_old_state(get_pm_cur_state());
518 set_pm_cur_state(S_NORMAL);
519 st = &states[get_pm_cur_state()];
522 st->action(st->timeout);
527 int custom_lcdon(int timeout)
534 if (check_lcd_is_on() == false)
535 lcd_on_direct(LCD_ON_BY_GESTURE);
537 _I("Custom lcd on timeout(%d ms).", timeout);
538 if (set_custom_lcdon_timeout(timeout) == true)
539 update_display_time();
541 /* state transition */
542 set_pm_old_state(get_pm_cur_state());
543 set_pm_cur_state(S_NORMAL);
544 st = &states[get_pm_cur_state()];
548 st->action(st->timeout);
550 g_idle_add(timer_refresh_cb, NULL);
555 int custom_lcdoff(enum device_flags flag)
559 check_processes(S_NORMAL);
560 check_processes(S_LCDDIM);
562 /* check holdkey block flag in lock node */
563 if (check_lock_condition(S_NORMAL) || check_lock_condition(S_LCDDIM)) {
565 * When another proccess is normal lock, device is received call then,
566 * call app can be changed to lcd state by proximity.
567 * If proximity is near then normal lock will be unlocked.
569 if (flag & LCD_OFF_BY_PROXIMITY) {
570 _I("custom lcd off by proximity, delete normal lock");
571 delete_condition(S_NORMAL);
573 _I("skip custom lcd off");
578 _I("custom lcd off by flag(%d)", flag);
579 if (display_panel_get_dpms_cached_state() == DPMS_ON)
580 lcd_off_procedure(flag);
582 if (set_custom_lcdon_timeout(0) == true)
583 update_display_time();
585 /* state transition */
586 set_pm_old_state(get_pm_cur_state());
587 set_pm_cur_state(S_LCDOFF);
588 st = &states[get_pm_cur_state()];
592 st->action(st->timeout);
597 int display_on_by_reason(const char *reason, int timeout)
603 str_len = strlen(reason);
605 if (!strncmp(reason, GESTURE_STR, str_len))
606 flag = LCD_ON_BY_GESTURE;
607 else if (!strncmp(reason, EVENT_STR, str_len))
608 flag = LCD_ON_BY_EVENT;
610 _E("Reason is unknown(%s)", reason);
615 _E("Cannot setting timeout %d", timeout);
619 if (check_lcd_is_on() == false)
622 _I("platform lcd on by %s (%d ms)", reason, timeout);
623 if (set_custom_lcdon_timeout(timeout) == true)
624 update_display_time();
626 /* state transition */
627 set_pm_old_state(get_pm_cur_state());
628 set_pm_cur_state(S_NORMAL);
629 st = &states[get_pm_cur_state()];
633 st->action(st->timeout);
638 int display_off_by_reason(const char *reason)
644 str_len = strlen(reason);
646 if (!strncmp(reason, GESTURE_STR, str_len)) {
647 check_processes(S_NORMAL);
648 check_processes(S_LCDDIM);
650 /* check holdkey block flag in lock node */
651 if (check_lock_condition(S_NORMAL) || check_lock_condition(S_LCDDIM)) {
652 _I("skip platform lcd off by gesture");
655 flag = LCD_OFF_BY_GESTURE;
656 } else if (!strncmp(reason, PALM_STR, str_len)) {
657 delete_condition(S_NORMAL);
658 delete_condition(S_LCDDIM);
660 flag = LCD_OFF_BY_PALM;
662 _E("Reason is unknown(%s)", reason);
666 _I("platform lcd off by %s", reason);
667 if (display_panel_get_dpms_cached_state() == DPMS_ON)
668 lcd_off_procedure(flag);
670 /* state transition */
671 set_pm_old_state(get_pm_cur_state());
672 set_pm_cur_state(S_LCDOFF);
673 st = &states[get_pm_cur_state()];
677 st->action(st->timeout);
682 static void default_proc_change_state_action(enum state_t next, int timeout)
686 set_pm_old_state(get_pm_cur_state());
687 set_pm_cur_state(next);
689 st = &states[get_pm_cur_state()];
691 if (st && st->action) {
693 st->action(st->timeout);
699 static int default_proc_change_state(unsigned int cond, pid_t pid)
703 next = GET_COND_STATE(cond);
704 _I("Change process(%d) state to %s.", pid, states[next].name);
708 if (check_lcd_is_on() == false)
709 lcd_on_direct(LCD_ON_BY_EVENT);
710 update_display_locktime(LOCK_SCREEN_CONTROL_TIMEOUT);
711 default_proc_change_state_action(next, -1);
714 default_proc_change_state_action(next, -1);
717 if (display_panel_get_dpms_cached_state() == DPMS_ON)
718 lcd_off_procedure(LCD_OFF_BY_EVENT);
719 if (set_custom_lcdon_timeout(0))
720 update_display_time();
721 default_proc_change_state_action(next, -1);
724 _I("Dangerous requests.");
725 /* at first LCD_OFF and then goto sleep */
726 /* state transition */
727 default_proc_change_state_action(S_LCDOFF, TIMEOUT_NONE);
728 delete_condition(S_NORMAL);
729 delete_condition(S_LCDDIM);
730 delete_condition(S_LCDOFF);
731 if (lcdon_broadcast) {
732 _I("broadcast lcd off signal at non-lcd device");
733 broadcast_lcd_off(SIGNAL_PRE, 0);
734 broadcast_lcd_off(SIGNAL_POST, 0);
736 default_proc_change_state_action(S_SLEEP, TIMEOUT_NONE);
746 static void proc_condition_lock(PMMsg *data)
749 guint cond_timeout_id = 0;
750 char pname[PATH_MAX];
751 pid_t pid = data->pid;
753 int holdkey_block, ret;
756 const char *lock_type = NULL;
758 state = GET_COND_STATE(data->cond);
759 if (state == S_START)
762 flags = GET_COND_FLAG(data->cond);
763 display_misc_get_process_name(pid, pname);
765 if ((state == S_LCDOFF) && (get_pm_cur_state() == S_SLEEP) &&
766 (pm_get_power_lock() == POWER_UNLOCK))
767 proc_change_state(data->cond, INTERNAL_LOCK_PM);
769 if (data->timeout > 0) {
770 /* To pass a pid_t data through the timer infrastructure
771 * without memory allocation, a pid_t data becomes typecast
772 * to intptr_t and void *(64bit) type. */
773 cond_timeout_id = g_timeout_add(
775 states[state].timeout_cb,
776 (void*)((intptr_t)pid));
777 if (!cond_timeout_id)
778 _E("Failed to register display timer.");
781 holdkey_block = GET_COND_FLAG(data->cond) & PM_FLAG_BLOCK_HOLDKEY;
783 tmp = find_node(state, pid);
785 tmp = add_node(state, pid, cond_timeout_id, holdkey_block);
787 _E("Failed to acquire lock, state: %d, pid: %d.", state, pid);
791 update_lock_timer(data, tmp, cond_timeout_id);
792 tmp->holdkey_block = holdkey_block;
795 if (state == S_LCDOFF)
796 set_process_active(true, pid);
798 _I("[%s] locked by %5d with %u ms", states[state].name, pid, data->timeout);
800 if (pid < INTERNAL_LOCK_BASE) {
802 if (state == S_LCDOFF)
803 lock_type = PM_LCDOFF_STR;
804 else if (state == S_LCDDIM)
805 lock_type = PM_LCDDIM_STR;
806 else if (state == S_NORMAL)
807 lock_type = PM_LCDON_STR;
810 /* power lock signal */
811 ret = gdbus_signal_emit(NULL,
812 DEVICED_PATH_DISPLAY,
813 DEVICED_INTERFACE_DISPLAY,
815 g_variant_new("(sii)", lock_type, pid, (int)data->timeout));
817 _E("Failed to send dbus signal PowerLock.");
821 _SD("be requested LOCK info pname(%s), holdkeyblock(%d) flags(%d)",
822 pname, holdkey_block, flags);
823 set_lock_time(pid, pname, state);
825 device_notify(DEVICE_NOTIFIER_DISPLAY_LOCK, (void *)&value);
828 static void proc_condition_unlock(PMMsg *data)
830 pid_t pid = data->pid;
833 char pname[PATH_MAX];
837 const char *lock_type = NULL;
839 state = GET_COND_STATE(data->cond);
843 flags = GET_COND_FLAG(data->cond);
844 display_misc_get_process_name(pid, pname);
846 tmp = find_node(state, pid);
847 del_node(state, tmp);
849 if (state == S_LCDOFF)
850 set_process_active(false, pid);
852 _I("[%s] unlocked by %5d", states[state].name, pid);
854 if (pid < INTERNAL_LOCK_BASE) {
856 if (state == S_LCDOFF)
857 lock_type = PM_LCDOFF_STR;
858 else if (state == S_LCDDIM)
859 lock_type = PM_LCDDIM_STR;
860 else if (state == S_NORMAL)
861 lock_type = PM_LCDON_STR;
864 /* power unlock signal */
865 ret = gdbus_signal_emit(NULL,
866 DEVICED_PATH_DISPLAY,
867 DEVICED_INTERFACE_DISPLAY,
869 g_variant_new("(sii)", lock_type, pid, (int)data->timeout));
871 _E("Failed to send dbus signal PowerUnlock.");
875 _SD("be requested UNLOCK info pname(%s) flag(%d)", pname, flags);
876 set_unlock_time(pid, state);
878 device_notify(DEVICE_NOTIFIER_DISPLAY_LOCK, (void *)&value);
881 static int proc_condition(PMMsg *data)
885 if (IS_COND_REQUEST_LOCK(data->cond))
886 proc_condition_lock(data);
888 if (IS_COND_REQUEST_UNLOCK(data->cond))
889 proc_condition_unlock(data);
891 if (!display_conf.timeout_enable)
894 flags = GET_COND_FLAG(data->cond);
896 /* guard time for suspend */
897 if (get_pm_cur_state() == S_LCDOFF)
898 display_state_transition_reset_state_transition_timeout(states[S_LCDOFF].timeout);
900 if (flags & PM_FLAG_RESET_TIMER)
901 display_state_transition_reset_state_transition_timeout(states[get_pm_cur_state()].timeout);
904 if (!display_state_transition_is_there_state_transition_timer())
905 states[get_pm_cur_state()].trans(EVENT_TIMEOUT);
910 void update_lcdoff_source(int source)
915 case VCONFKEY_PM_LCDOFF_BY_TIMEOUT:
916 _I("LCD OFF by timeout.");
918 case VCONFKEY_PM_LCDOFF_BY_POWERKEY:
919 _I("LCD OFF by powerkey.");
922 _E("Invalid value(%d).", source);
925 ret = vconf_set_int(VCONFKEY_PM_LCDOFF_SOURCE, source);
927 _E("Failed to set vconf value for lcd off source: %d", vconf_get_ext_errno());
930 void print_info(int fd)
933 char buf[PATH_MAX + 255];
936 char pname[PATH_MAX];
944 snprintf(buf, sizeof(buf),
945 "\n==========================================="
946 "===========================\n");
947 ret = write(fd, buf, strlen(buf));
949 _E("Write() failed: %d", errno);
950 snprintf(buf, sizeof(buf), "Timeout Info: Run[%dms] Dim[%dms] Off[%dms]\n",
951 states[S_NORMAL].timeout,
952 states[S_LCDDIM].timeout, states[S_LCDOFF].timeout);
953 ret = write(fd, buf, strlen(buf));
955 _E("Write() failed: %d", errno);
957 snprintf(buf, sizeof(buf), "Tran. Locked : %s %s %s\n",
958 (get_trans_condition() & MASK_NORMAL) ? states[S_NORMAL].name : "-",
959 (get_trans_condition() & MASK_DIM) ? states[S_LCDDIM].name : "-",
960 (get_trans_condition() & MASK_OFF) ? states[S_LCDOFF].name : "-");
961 ret = write(fd, buf, strlen(buf));
963 _E("Write() failed: %d", errno);
965 snprintf(buf, sizeof(buf), "Current State: %s\n",
966 states[get_pm_cur_state()].name);
967 ret = write(fd, buf, strlen(buf));
969 _E("Write() failed: %d", errno);
971 snprintf(buf, sizeof(buf), "Current Lock Conditions: \n");
972 ret = write(fd, buf, strlen(buf));
974 _E("Write() failed: %d", errno);
976 for (s_index = S_NORMAL; s_index < S_END; s_index++) {
977 SYS_G_LIST_FOREACH(get_cond_head(s_index), elem, t) {
978 display_misc_get_process_name((pid_t)t->pid, pname);
979 ctime_r(&t->time, time_buf);
980 time_buf[strlen(time_buf) - 1] = 0;
981 snprintf(buf, sizeof(buf),
982 " %d: [%s] locked by pid %d %s %s\n",
983 i++, states[s_index].name, t->pid, pname, time_buf);
984 ret = write(fd, buf, strlen(buf));
986 _E("Write() failed: %d", errno);
990 print_lock_info_list(fd);
993 pm_history_print(fd, 250);
997 void save_display_log(const char *path)
1004 _D("internal state is saved!");
1007 ctime_r(&now_time, time_buf);
1008 time_buf[strlen(time_buf) - 1] = 0;
1010 fd = open(path, O_CREAT | O_TRUNC | O_WRONLY, 0644);
1012 snprintf(buf, sizeof(buf),
1013 "\npm_state_log now-time : %d(s) %s\n\n",
1014 (int)now_time, time_buf);
1015 ret = write(fd, buf, strlen(buf));
1017 _E("write() failed (%d)", errno);
1019 snprintf(buf, sizeof(buf), "pm_status_flag: %#x\n", get_pm_status_flag());
1020 ret = write(fd, buf, strlen(buf));
1022 _E("write() failed (%d)", errno);
1024 if (disp_plgn->get_lock_screen_state ) {
1025 snprintf(buf, sizeof(buf), "screen lock status : %d\n",
1026 disp_plgn->get_lock_screen_state());
1027 ret = write(fd, buf, strlen(buf));
1029 _E("write() failed (%d)", errno);
1035 fd = open("/dev/console", O_WRONLY);
1042 /* SIGHUP signal handler
1043 * For debug... print info to syslog
1045 static void sig_hup(int signo)
1047 _I("received sig hub %d", signo);
1052 int check_lcdoff_direct(void)
1054 int ret, lock, cradle;
1057 if (get_pm_old_state() != S_NORMAL)
1060 if (get_pm_cur_state() != S_LCDDIM)
1063 if (!display_conf.dimming)
1066 lock = __get_lock_screen_state();
1067 if (lock != VCONFKEY_IDLE_LOCK)
1070 hdmi_state = extcon_get_status(EXTCON_CABLE_HDMI);
1074 ret = vconf_get_int(VCONFKEY_SYSMAN_CRADLE_STATUS, &cradle);
1075 if (ret >= 0 && cradle == DOCK_SOUND)
1078 _E("Failed to get vconf value for cradle status: %d", vconf_get_ext_errno());
1080 _D("Goto LCDOFF direct: lock(%d) hdmi(%d) cradle(%d).", lock, hdmi_state, cradle);
1086 * default transition function
1089 * 3. call enter action function
1091 static int default_trans(int evt)
1093 struct state *st = &states[get_pm_cur_state()];
1094 enum state_t next_state;
1096 display_state_transition_get_next_transition_display_state(get_pm_cur_state(), &next_state, evt);
1098 /* check conditions */
1099 if (st->check && !st->check(get_pm_cur_state(), next_state)) {
1100 /* There is a condition. */
1101 _I("%s locked. Trans to %s failed.", states[get_pm_cur_state()].name,
1102 states[next_state].name);
1106 /* state transition */
1107 set_pm_old_state(get_pm_cur_state());
1108 set_pm_cur_state(next_state);
1109 st = &states[get_pm_cur_state()];
1113 if (get_pm_cur_state() == S_LCDOFF)
1114 update_lcdoff_source(VCONFKEY_PM_LCDOFF_BY_TIMEOUT);
1116 if ((get_pm_cur_state() == S_NORMAL) || (get_pm_cur_state() == S_LCDOFF))
1117 if (set_custom_lcdon_timeout(0) == true)
1118 update_display_time();
1120 if (check_lcdoff_direct() == true) {
1121 /* enter next state directly */
1122 states[get_pm_cur_state()].trans(EVENT_TIMEOUT);
1124 if ((get_pm_cur_state() == S_SLEEP)
1125 && (is_emulator() == true || timeout_sleep_support == false))
1128 st->action(st->timeout);
1135 static gboolean lcd_on_expired(void *data)
1137 int lock_state, ret;
1139 if (lock_timeout_id)
1140 lock_timeout_id = 0;
1142 /* check state of lock */
1143 ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
1144 if (ret > 0 && lock_state == VCONFKEY_IDLE_LOCK)
1145 return G_SOURCE_REMOVE;
1147 _E("Failed to get vconf value for idle lock state: %d", vconf_get_ext_errno());
1149 /* lock screen is not launched yet, but lcd is on */
1150 if (check_lcd_is_on() == false)
1151 lcd_on_procedure(LCD_NORMAL, NORMAL_MODE);
1153 return G_SOURCE_REMOVE;
1156 static inline void stop_lock_timer(void)
1158 if (lock_timeout_id) {
1159 g_source_remove(lock_timeout_id);
1160 lock_timeout_id = 0;
1164 static void check_lock_screen(void)
1166 int lock_state, ret;
1170 /* check state of lock */
1171 ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
1172 if (ret < 0 || lock_state == VCONFKEY_IDLE_LOCK)
1175 /* Use time to check lock is done. */
1176 lock_timeout_id = g_timeout_add(display_conf.lock_wait_time,
1177 lcd_on_expired, NULL);
1180 /* default enter action function */
1181 static int default_action(int timeout)
1183 int wakeup_count = -1, pm_cur_state;
1186 static time_t last_update_time = 0;
1187 static int last_timeout = 0;
1188 struct timeval now_tv;
1191 bool lcd_paneloff_mode = false;
1193 if (status != DEVICE_OPS_STATUS_START) {
1194 _E("Display is not started.");
1198 if (get_pm_cur_state() != S_SLEEP) {
1199 if ((get_pm_cur_state() == S_NORMAL) &&
1200 lcdon_tv.tv_sec != 0) {
1201 gettimeofday(&now_tv, NULL);
1202 timeout -= DIFF_TIMEVAL_MS(now_tv, lcdon_tv);
1203 lcdon_tv.tv_sec = 0;
1205 /* set timer with current state timeout */
1206 display_state_transition_reset_state_transition_timeout(timeout);
1208 if (get_pm_cur_state() == S_NORMAL) {
1209 time(&last_update_time);
1210 last_timeout = timeout;
1212 _I("Timout set: %s state %d ms",
1213 states[get_pm_cur_state()].name, timeout);
1217 if ((get_pm_cur_state() != get_pm_old_state()) && (get_pm_cur_state() != S_SLEEP)) {
1218 power_request_change_state_strict(DEVICED_POWER_STATE_SLEEP, DEVICED_POWER_STATE_NORMAL,
1219 power_get_wakeup_reason(), NULL);
1220 set_setting_pmstate(get_pm_cur_state());
1221 pm_cur_state = get_pm_cur_state();
1222 device_notify(DEVICE_NOTIFIER_LCD, (void *)&pm_cur_state);
1225 if ((get_pm_old_state() == S_NORMAL) && (get_pm_cur_state() != S_NORMAL)) {
1227 diff = difftime(now, last_update_time);
1228 _I("S_NORMAL is changed to %s (timeout=%d ms diff=%.0f s).",
1229 states[get_pm_cur_state()].name, last_timeout, diff);
1232 switch (get_pm_cur_state()) {
1235 * normal state : backlight on and restore
1236 * the previous brightness
1238 if ((get_pm_old_state() == S_LCDOFF) || (get_pm_old_state() == S_SLEEP))
1239 check_lock_screen();
1240 else if (get_pm_old_state() == S_LCDDIM)
1241 display_backlight_update_by_default_brightness();
1243 if (check_lcd_is_on() == false)
1244 lcd_on_procedure(LCD_NORMAL, NORMAL_MODE);
1248 display_backlight_get_custom_status(&custom_status);
1249 if ((get_pm_old_state() == S_NORMAL) && custom_status) {
1250 display_backlight_get_brightness(&brightness);
1251 display_backlight_set_custom_brightness(brightness);
1253 /* lcd dim state : dim the brightness */
1254 display_backlight_set_brightness_by_dim_brightness();
1256 if ((get_pm_old_state() == S_LCDOFF) || (get_pm_old_state() == S_SLEEP))
1257 lcd_on_procedure(LCD_DIM, NORMAL_MODE);
1261 if ((get_pm_old_state() != S_SLEEP) && (get_pm_old_state() != S_LCDOFF)) {
1263 /* lcd off state : turn off the backlight */
1264 if (display_panel_get_dpms_cached_state() == DPMS_ON)
1265 lcd_off_procedure(LCD_OFF_BY_TIMEOUT);
1268 display_panel_get_lcd_paneloff_mode(&lcd_paneloff_mode);
1269 if (display_panel_get_dpms_cached_state() == DPMS_ON
1270 || lcd_paneloff_mode)
1271 lcd_off_procedure(LCD_OFF_BY_TIMEOUT);
1275 if ((get_pm_old_state() != S_SLEEP) && (get_pm_old_state() != S_LCDOFF))
1278 if (display_panel_get_dpms_cached_state() == DPMS_ON)
1279 lcd_off_procedure(LCD_OFF_BY_TIMEOUT);
1281 if (!pm_get_power_lock_support()) {
1282 /* sleep state : set system mode to SUSPEND */
1283 if (get_wakeup_count(&wakeup_count) < 0)
1284 _E("Wakeup count read error.");
1286 if (wakeup_count < 0) {
1287 _I("Wakup Event. Can not enter suspend mode.");
1291 if (set_wakeup_count(wakeup_count) < 0) {
1292 _E("Wakeup count write error.");
1302 #ifdef ENABLE_PM_LOG
1303 pm_history_save(PM_LOG_SLEEP, get_pm_cur_state());
1305 power_request_change_state(DEVICED_POWER_STATE_SLEEP, HAL_DEVICE_POWER_TRANSITION_REASON_DISPLAY_OFF_TIMEOUT);
1309 if (!pm_get_power_lock_support()) {
1311 states[get_pm_cur_state()].trans(EVENT_DEVICE);
1317 * default check function
1319 * 0 : can't transit, others : transitable
1321 static int default_check(int curr, int next)
1325 makeup_trans_condition();
1327 trans_cond = get_trans_condition() & MASK_BIT;
1329 if (next == S_NORMAL) /* S_NORMAL is exceptional */
1334 trans_cond = trans_cond & MASK_NORMAL;
1337 trans_cond = trans_cond & MASK_DIM;
1340 trans_cond = trans_cond & MASK_OFF;
1347 if (trans_cond != 0) {
1352 return 1; /* transitable */
1355 static void default_saving_mode(int onoff)
1358 set_pm_status_flag(PWRSV_FLAG);
1360 clear_pm_status_flag(PWRSV_FLAG);
1362 if (get_pm_cur_state() == S_NORMAL)
1363 display_backlight_update_by_default_brightness();
1366 int poll_callback(int condition, PMMsg *data)
1368 static time_t last_t;
1371 if (status != DEVICE_OPS_STATUS_START) {
1372 _E("Display logic is not started.");
1376 if (condition == INPUT_POLL_EVENT) {
1377 if ((get_pm_cur_state() == S_LCDOFF) || (get_pm_cur_state() == S_SLEEP))
1378 _I("Input event signal at Display Off");
1380 if ((last_t != now) ||
1381 (get_pm_cur_state() == S_LCDOFF) ||
1382 (get_pm_cur_state() == S_SLEEP)) {
1383 states[get_pm_cur_state()].trans(EVENT_INPUT);
1388 if (condition == PM_CONTROL_EVENT) {
1389 proc_condition(data);
1391 if (IS_COND_REQUEST_CHANGE(data->cond))
1392 proc_change_state(data->cond, data->pid);
1398 static int update_setting(int key_idx, int val)
1403 case SETTING_TO_NORMAL:
1404 update_display_time();
1405 states[get_pm_cur_state()].trans(EVENT_INPUT);
1407 case SETTING_LOW_BATT:
1408 if (display_misc_is_low_battery_state(val)) {
1409 if (!(get_pm_status_flag() & CHRGR_FLAG))
1410 power_saving_func(true);
1411 set_pm_status_flag(LOWBT_FLAG);
1413 if (get_pm_status_flag() & PWRSV_FLAG)
1414 power_saving_func(false);
1415 clear_pm_status_flag(LOWBT_FLAG);
1416 clear_pm_status_flag(BRTCH_FLAG);
1417 ret = vconf_set_bool(VCONFKEY_PM_BRIGHTNESS_CHANGED_IN_LPM, false);
1419 _E("Failed to set vconf value for brightness changed in lpm: %d", vconf_get_ext_errno());
1422 case SETTING_CHARGING:
1424 if (get_pm_status_flag() & LOWBT_FLAG) {
1425 power_saving_func(false);
1426 clear_pm_status_flag(LOWBT_FLAG);
1428 set_pm_status_flag(CHRGR_FLAG);
1431 ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW,
1434 bat_state = VCONFKEY_SYSMAN_BAT_NORMAL;
1435 _E("Failed to get vconf value for battery status low: %d", vconf_get_ext_errno());
1437 if (display_misc_is_low_battery_state(bat_state)) {
1438 power_saving_func(true);
1439 set_pm_status_flag(LOWBT_FLAG);
1441 clear_pm_status_flag(CHRGR_FLAG);
1444 case SETTING_BRT_LEVEL:
1445 if (get_pm_status_flag() & PWRSV_FLAG) {
1446 set_pm_status_flag(BRTCH_FLAG);
1447 ret = vconf_set_bool(VCONFKEY_PM_BRIGHTNESS_CHANGED_IN_LPM, true);
1449 _E("Failed to set vconf value for brightness changed in lpm: %d", vconf_get_ext_errno());
1450 _I("Brightness changed in low battery,"
1451 "escape dim state.");
1453 display_backlight_set_default_brightness(val);
1455 case SETTING_LOCK_SCREEN:
1456 set_lock_screen_state(val);
1457 if (val == VCONFKEY_IDLE_UNLOCK) {
1458 if (CHECK_OPS(keyfilter_ops, backlight_enable))
1459 keyfilter_ops->backlight_enable(false);
1462 /* LCD on if lock screen show before waiting time */
1463 if ((get_pm_cur_state() == S_NORMAL) &&
1464 val == VCONFKEY_IDLE_LOCK &&
1465 display_panel_get_dpms_cached_state() != DPMS_ON &&
1466 is_lcdon_blocked() == LCDON_BLOCK_NONE)
1467 lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
1469 update_display_time();
1470 if (get_pm_cur_state() == S_NORMAL)
1471 states[get_pm_cur_state()].trans(EVENT_INPUT);
1473 case SETTING_LOCK_SCREEN_BG:
1474 set_lock_screen_bg_state(val);
1475 update_display_time();
1476 if (get_pm_cur_state() == S_NORMAL)
1477 states[get_pm_cur_state()].trans(EVENT_INPUT);
1479 case SETTING_POWER_CUSTOM_BRIGHTNESS:
1480 if (val == VCONFKEY_PM_CUSTOM_BRIGHTNESS_ON)
1481 display_backlight_set_custom_status(true);
1483 display_backlight_set_custom_status(false);
1492 static void check_seed_status(void)
1500 /* Charging check */
1501 if (fp_get_charging_status && (fp_get_charging_status(&tmp) == 0) && (tmp > 0))
1502 set_pm_status_flag(CHRGR_FLAG);
1504 ret = get_setting_brightness(&tmp);
1505 if (ret != 0 || (tmp < PM_MIN_BRIGHTNESS || tmp > PM_MAX_BRIGHTNESS)) {
1506 _I("Failed to read vconf value for brightness.");
1507 brt = display_conf.pm_default_brightness;
1508 if (tmp < PM_MIN_BRIGHTNESS || tmp > PM_MAX_BRIGHTNESS) {
1509 ret = vconf_set_int(VCONFKEY_SETAPPL_LCD_BRIGHTNESS, brt);
1511 _E("Failed to set vconf value for lcd brightness: %d", vconf_get_ext_errno());
1515 _I("Set brightness(%d) from setting app.", tmp);
1516 display_backlight_set_default_brightness(tmp);
1517 display_backlight_set_brightness(tmp);
1519 ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, &bat_state);
1521 bat_state = VCONFKEY_SYSMAN_BAT_NORMAL;
1522 _E("Failed to get vconf value for battery status low: %d", vconf_get_ext_errno());
1524 if (display_misc_is_low_battery_state(bat_state)) {
1525 if (!(get_pm_status_flag() & CHRGR_FLAG)) {
1526 power_saving_func(true);
1527 set_pm_status_flag(LOWBT_FLAG);
1531 /* lock screen check */
1532 ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
1535 _E("Failed to get vconf value for idle lock state: %d", vconf_get_ext_errno());
1537 set_lock_screen_state(lock_state);
1538 if (lock_state == VCONFKEY_IDLE_LOCK) {
1539 states[S_NORMAL].timeout = lock_screen_timeout;
1540 _I("LCD NORMAL timeout(%d ms) is set"
1541 " for lock screen.", lock_screen_timeout);
1547 static void init_lcd_operation(void)
1549 const struct device_ops *ops = NULL;
1551 ops = find_device("display");
1552 if (!check_default(ops))
1553 display_register_dependent_device(ops);
1555 ops = find_device("touchkey");
1556 if (!check_default(ops))
1557 display_register_dependent_device(ops);
1559 ops = find_device("touchscreen");
1560 if (!check_default(ops))
1561 display_register_dependent_device(ops);
1564 static void exit_lcd_operation(void)
1566 display_unregister_dependent_device();
1578 static const char *errMSG[INIT_END] = {
1579 [INIT_SETTING] = "setting init error",
1580 [INIT_INTERFACE] = "lowlevel interface(sysfs or others) init error",
1581 [INIT_POLL] = "input devices poll init error",
1582 [INIT_FIFO] = "FIFO poll init error",
1583 [INIT_DBUS] = "d-bus init error",
1586 int set_lcd_timeout(int on, int dim, int holdkey_block, const char *name)
1588 if (on == 0 && dim == 0) {
1589 _I("LCD timeout changed: default setting");
1590 custom_normal_timeout = custom_dim_timeout = 0;
1591 } else if (on < 0 || dim < 0) {
1592 _E("Failed to set value(on=%d dim=%d).", on, dim);
1595 _I("LCD timeout changed: on=%ds dim=%ds", on, dim);
1596 custom_normal_timeout = SEC_TO_MSEC(on);
1597 custom_dim_timeout = SEC_TO_MSEC(dim);
1599 /* Apply new backlight time */
1600 update_display_time();
1601 if (get_pm_cur_state() == S_NORMAL)
1602 states[get_pm_cur_state()].trans(EVENT_INPUT);
1604 if (holdkey_block) {
1605 display_lock_set_custom_holdkey_block(true);
1606 _I("Hold key disabled.");
1608 display_lock_set_custom_holdkey_block(false);
1609 _I("Hold key enabled.");
1612 if (custom_change_name) {
1613 free(custom_change_name);
1614 custom_change_name = 0;
1617 if (custom_normal_timeout == 0 &&
1618 custom_dim_timeout == 0 &&
1622 custom_change_name = strndup(name, strlen(name));
1623 if (!custom_change_name) {
1624 _E("Failed to malloc.");
1625 custom_normal_timeout = custom_dim_timeout = 0;
1626 display_lock_set_custom_holdkey_block(false);
1633 void reset_lcd_timeout(GDBusConnection *conn,
1634 const gchar *sender,
1635 const gchar *unique_name,
1641 if (!custom_change_name)
1644 if (strcmp(sender, custom_change_name))
1647 _I("reset lcd timeout: Set default timeout. sender=%s", sender);
1649 free(custom_change_name);
1650 custom_change_name = 0;
1651 custom_normal_timeout = custom_dim_timeout = 0;
1652 display_lock_set_custom_holdkey_block(false);
1654 update_display_time();
1655 if (get_pm_cur_state() == S_NORMAL)
1656 states[get_pm_cur_state()].trans(EVENT_INPUT);
1659 static int delayed_init_done(void *data)
1661 static bool done = false;
1670 _I("Booting done, release booting lock.");
1671 if (disp_plgn->pm_unlock_internal) {
1672 disp_plgn->pm_unlock_internal(INTERNAL_LOCK_BOOTING, LCD_NORMAL, PM_SLEEP_MARGIN);
1673 disp_plgn->pm_unlock_internal(INTERNAL_LOCK_BOOTING, LCD_OFF, PM_SLEEP_MARGIN);
1679 static gboolean delayed_dpms_init_done(gpointer data)
1683 if (!display_panel_init_dpms())
1684 return G_SOURCE_CONTINUE;
1686 switch (get_pm_cur_state()) {
1689 lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
1690 if (display_conf.timeout_enable) {
1691 timeout = states[S_NORMAL].timeout;
1692 /* check minimun lcd on time */
1693 if (timeout < SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT))
1694 timeout = SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT);
1695 display_state_transition_reset_state_transition_timeout(timeout);
1699 lcd_off_procedure(LCD_OFF_BY_EVENT);
1700 timeout = display_conf.lcdoff_timeout;
1701 display_state_transition_reset_state_transition_timeout(timeout);
1707 return G_SOURCE_REMOVE;
1710 static void add_timer_for_dpms_init(void)
1712 guint id = g_timeout_add(500/* milliseconds */, delayed_dpms_init_done, NULL);
1714 _E("Failed to add display_panel_init_dpms timeout.");
1717 static void init_display_states(void *data)
1719 struct display_plugin *dp = (struct display_plugin *) data;
1720 for(int i = 0; i < S_END; i++)
1721 dp->display_states[i] = &states[i];
1724 * Power manager Main
1727 static int display_probe(void *data)
1730 struct display_plugin *dp = (struct display_plugin *) data;
1733 dp->config = &display_conf;
1734 init_display_states(dp);
1735 setup_display_plugin_backlight_ops(dp);
1736 dp->delete_state_cond = del_state_cond;
1738 /* check display feature */
1739 if (!is_feature_display_supported())
1743 * load display service
1744 * if there is no display shared library,
1745 * deviced does not provide any method and function of display.
1747 ret = display_service_load();
1751 /* display_plugin instance initialization */
1752 init_pm_internal(data);
1753 disp_plgn->device_flags_to_string = __device_flags_to_string;
1755 if (battery_plgn->handle) {
1756 fp_get_charging_status = dlsym(battery_plgn->handle, "get_charging_status");
1757 if (!fp_get_charging_status)
1758 _E("Failed to obtain address of get_charging_status");
1760 _I("There is no battery module.");
1765 static int input_init_handler(void)
1767 if (!display_conf.input_support)
1768 remove_device_by_devname("input");
1773 static int power_resume_from_echomem_callback(void *data)
1775 system_wakeup_flag = true;
1776 if (check_wakeup_src() == EVENT_DEVICE)
1777 /* system waked up by devices */
1778 states[get_pm_cur_state()].trans(EVENT_DEVICE);
1780 /* system waked up by user input */
1781 states[get_pm_cur_state()].trans(EVENT_INPUT);
1786 static int poweroff_triggered_callback(void *udata)
1788 int val = (int)(intptr_t) udata;
1791 case VCONFKEY_SYSMAN_POWER_OFF_NONE:
1792 clear_pm_status_flag(PWROFF_FLAG);
1794 case VCONFKEY_SYSMAN_POWER_OFF_DIRECT:
1795 case VCONFKEY_SYSMAN_POWER_OFF_RESTART:
1796 set_pm_status_flag(PWROFF_FLAG);
1803 static void esd_action(void)
1805 const struct device_ops *touchscreen_ops = NULL;
1809 touchscreen_ops = find_device("touchscreen");
1811 if (!check_default(touchscreen_ops))
1812 touchscreen_ops->stop(NORMAL_MODE);
1813 display_panel_set_panel_state_by_off_state(NORMAL_MODE);
1814 display_panel_set_panel_state_by_on_state(NORMAL_MODE);
1815 if (!check_default(touchscreen_ops))
1816 touchscreen_ops->start(NORMAL_MODE);
1819 static void lcd_uevent_changed(struct udev_device *dev)
1821 const char *devpath;
1824 devpath = udev_device_get_devpath(dev);
1828 if (!fnmatch(LCD_ESD_PATH, devpath, 0)) {
1829 action = udev_device_get_action(dev);
1830 if (!strcmp(action, UDEV_CHANGE))
1835 static const struct uevent_handler lcd_uevent_ops = {
1836 .subsystem = LCD_EVENT_SUBSYSTEM,
1837 .uevent_func = lcd_uevent_changed,
1841 static void display_init(void *data)
1844 unsigned int flags = (WITHOUT_STARTNOTI | FLAG_X_DPMS);
1847 _I("Start power manager.");
1849 signal(SIGHUP, sig_hup);
1851 power_saving_func = default_saving_mode;
1853 /* load configutation */
1854 ret = display_load_config(&display_conf);
1856 _W("Failed to load '%s', use default value: %d",
1857 DISPLAY_CONF_FILE, ret);
1859 register_kernel_uevent_control(&lcd_uevent_ops);
1861 register_notifier(DEVICE_NOTIFIER_DELAYED_INIT, delayed_init_done);
1862 register_notifier(DEVICE_NOTIFIER_APPLICATION_BACKGROUND, display_app_background);
1863 register_notifier(DEVICE_NOTIFIER_APPLICATION_FOREGROUND, display_app_foreground);
1864 register_notifier(DEVICE_NOTIFIER_APPLICATION_TERMINATED, display_app_terminated);
1865 register_notifier(DEVICE_NOTIFIER_POWER_RESUME_FROM_ECHO_MEM, power_resume_from_echomem_callback);
1866 register_notifier(DEVICE_NOTIFIER_POWEROFF_TRIGGERED, poweroff_triggered_callback);
1868 init_save_userlock();
1870 for (i = INIT_SETTING; i < INIT_END; i++) {
1873 ret = init_setting(update_setting);
1875 case INIT_INTERFACE:
1876 if (display_conf.timeout_enable)
1877 get_lcd_timeout_from_settings();
1878 ret = init_sysfs(flags);
1882 ret = input_init_handler();
1884 pm_lock_detector_init();
1888 ret = init_pm_dbus();
1892 _E("Failed to init: %s", errMSG[i]);
1897 if (i == INIT_END) {
1898 display_ops_init(NULL);
1899 #ifdef ENABLE_PM_LOG
1902 init_lcd_operation();
1903 check_seed_status();
1905 /* In smd test, TSP should be turned off if display panel is not existed. */
1906 if (display_panel_get_dpms_cached_state() == -ENOENT) {
1907 _I("Display panel is not existed.");
1908 lcd_direct_control(DPMS_OFF, NORMAL_MODE);
1909 exit_lcd_operation();
1912 /* wm_ready needs to be checked
1913 * since display manager can be launched later than deviced.
1914 * In the case, display cannot be turned on at the first booting */
1915 // wm_ready = check_wm_ready();
1916 if (display_panel_init_dpms()) {
1917 if (is_lcdon_blocked() != LCDON_BLOCK_NONE)
1918 lcd_off_procedure(LCD_OFF_BY_EVENT);
1920 lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
1922 add_timer_for_dpms_init();
1925 if (display_conf.lcd_always_on) {
1926 _I("LCD always on.");
1927 display_state_transition_set_transition_table_display_state(S_NORMAL, S_NORMAL, EVENT_TIMEOUT);
1930 if (flags & WITHOUT_STARTNOTI) { /* start without noti */
1931 _I("Start Power managing without noti");
1932 power_request_change_state_strict(DEVICED_POWER_STATE_SLEEP, DEVICED_POWER_STATE_NORMAL,
1933 HAL_DEVICE_POWER_TRANSITION_REASON_UNKNOWN, NULL);
1935 * Lock lcd off until booting is done.
1936 * deviced guarantees all booting script is executing.
1937 * Last script of booting unlocks this suspend blocking state.
1939 if (disp_plgn->pm_lock_internal)
1940 disp_plgn->pm_lock_internal(INTERNAL_LOCK_BOOTING, LCD_OFF,
1941 STAY_CUR_STATE, DELAYED_INIT_WATING_TIME);
1943 /* Initial display state right after the booting done */
1944 if (is_lcdon_blocked())
1945 set_pm_cur_state(S_LCDOFF);
1947 set_pm_cur_state(S_NORMAL);
1948 ret = vconf_set_int(VCONFKEY_PM_STATE, get_pm_cur_state());
1950 _E("Failed to set vconf value for pm cur state: %d", vconf_get_ext_errno());
1952 status = DEVICE_OPS_STATUS_START;
1953 if (display_conf.timeout_enable) {
1954 timeout = states[S_NORMAL].timeout;
1955 /* check minimun lcd on time */
1956 if (timeout < SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT))
1957 timeout = SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT);
1959 if (disp_plgn->pm_lock_internal)
1960 disp_plgn->pm_lock_internal(INTERNAL_LOCK_BOOTING, LCD_NORMAL,
1961 STAY_CUR_STATE, timeout);
1966 if (display_conf.input_support)
1967 if (CHECK_OPS(keyfilter_ops, init))
1968 keyfilter_ops->init();
1970 set_display_init_direction(display_conf.display_init_direction);
1974 static void display_exit(void *data)
1978 status = DEVICE_OPS_STATUS_STOP;
1980 /* Set current state to S_NORMAL */
1981 set_pm_cur_state(S_NORMAL);
1982 set_setting_pmstate(get_pm_cur_state());
1983 /* timeout is not needed */
1984 display_state_transition_reset_state_transition_timeout(TIMEOUT_NONE);
1986 if (CHECK_OPS(keyfilter_ops, exit))
1987 keyfilter_ops->exit();
1989 unregister_kernel_uevent_control(&lcd_uevent_ops);
1991 display_ops_exit(NULL);
1993 for (i = i - 1; i >= INIT_SETTING; i--) {
1998 case INIT_INTERFACE:
2002 unregister_notifier(DEVICE_NOTIFIER_DELAYED_INIT, delayed_init_done);
2003 unregister_notifier(DEVICE_NOTIFIER_APPLICATION_BACKGROUND, display_app_background);
2004 unregister_notifier(DEVICE_NOTIFIER_APPLICATION_FOREGROUND, display_app_foreground);
2005 unregister_notifier(DEVICE_NOTIFIER_APPLICATION_TERMINATED, display_app_terminated);
2006 unregister_notifier(DEVICE_NOTIFIER_POWER_RESUME_FROM_ECHO_MEM, power_resume_from_echomem_callback);
2012 exit_lcd_operation();
2013 free_lock_info_list();
2015 /* free display service */
2016 display_service_free();
2018 _I("Stop power manager.");
2021 static int display_start(enum device_flags flags)
2024 if (flags & NORMAL_MODE) {
2025 if (flags & LCD_PANEL_OFF_MODE)
2027 display_panel_set_panel_state_by_standby_state(true);
2030 display_panel_set_panel_state_by_on_state(flags);
2035 /* CORE LOGIC MODE */
2036 if (!(flags & CORE_LOGIC_MODE))
2039 if (status == DEVICE_OPS_STATUS_START)
2042 if (display_probe(NULL) < 0)
2050 static int display_stop(enum device_flags flags)
2053 if (flags & NORMAL_MODE || flags & FORCE_OFF_MODE) {
2054 display_panel_set_panel_state_by_off_state(flags);
2058 /* CORE LOGIC MODE */
2059 if (!(flags & CORE_LOGIC_MODE))
2062 if (status == DEVICE_OPS_STATUS_STOP)
2070 static int display_status(void)
2075 static const struct device_ops display_plugin_device_ops = {
2076 .disable_auto_init = true,
2077 DECLARE_NAME_LEN("display-plugin"),
2078 .probe = display_probe,
2079 .init = display_init,
2080 .exit = display_exit,
2081 .start = display_start,
2082 .stop = display_stop,
2083 .status = display_status,
2086 DEVICE_OPS_REGISTER(&display_plugin_device_ops)
2088 static void __CONSTRUCTOR__ initialize(void)
2090 disp_plgn = get_var_display_plugin();
2092 _E("Failed to get display plugin variable.");
2094 backlight_ops = get_var_backlight_ops();
2096 _E("Failed to get backlight operator variable.");
2098 battery_plgn = get_var_battery_plugin();
2100 _E("Failed to get battery plugin variable.");