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 "shared/plugin.h"
74 * @addtogroup POWER_MANAGER
78 #define LOCK_SCREEN_INPUT_TIMEOUT 10000
79 #define LOCK_SCREEN_CONTROL_TIMEOUT 5000
80 #define ALWAYS_ON_TIMEOUT 360000000
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 guint timeout_src_id;
102 static int system_wakeup_flag = false;
103 static unsigned int custom_normal_timeout = 0;
104 static unsigned int custom_dim_timeout = 0;
105 int custom_holdkey_block = false;
106 static char *custom_change_name;
107 static guint lock_timeout_id;
108 static int lock_screen_timeout = LOCK_SCREEN_INPUT_TIMEOUT;
109 static struct timeval lcdon_tv;
111 * The two variables(lcdon_broadcast, pmstate_suspend) must be set initial
112 * state because it should be sent from previous state at booting time.
114 static bool lcdon_broadcast = true;
116 static bool touch_blocked = false;
118 /* default transition, action fuctions */
119 static int default_trans(int evt);
120 static int default_action(int timeout);
121 static int default_check(int curr, int next);
123 static gboolean del_normal_cond(void *data);
124 static gboolean del_dim_cond(void *data);
125 static gboolean del_off_cond(void *data);
127 static int default_proc_change_state(unsigned int cond, pid_t pid);
128 static int (*proc_change_state)(unsigned int cond, pid_t pid) = default_proc_change_state;
130 static struct state states[S_END] = {
131 { S_START, "S_START", NULL, NULL, NULL, NULL },
132 { S_NORMAL, "S_NORMAL", default_trans, default_action, default_check, del_normal_cond },
133 { S_LCDDIM, "S_LCDDIM", default_trans, default_action, default_check, del_dim_cond },
134 { S_LCDOFF, "S_LCDOFF", default_trans, default_action, default_check, del_off_cond },
135 { S_STANDBY, "S_STANDBY", NULL, NULL, NULL, NULL },
136 { S_SLEEP, "S_SLEEP", default_trans, default_action, default_check, NULL },
137 { S_POWEROFF, "S_POWEROFF", NULL, NULL, NULL, NULL },
140 static int trans_table[S_END][EVENT_END] = {
142 { S_START, S_START }, /* S_START */
143 { S_LCDDIM, S_NORMAL }, /* S_NORMAL */
144 { S_LCDOFF, S_NORMAL }, /* S_LCDDIM */
145 { S_SLEEP, S_NORMAL }, /* S_LCDOFF */
146 { S_SLEEP, S_STANDBY }, /* S_STANDBY */
147 { S_LCDOFF, S_NORMAL }, /* S_SLEEP */
148 { S_POWEROFF, S_POWEROFF }, /* S_POWEROFF */
151 #define SHIFT_UNLOCK 4
152 #define SHIFT_CHANGE_STATE 7
153 #define CHANGE_STATE_BIT 0xF00 /* 1111 0000 0000 */
154 #define SHIFT_LOCK_FLAG 16
155 #define SHIFT_CHANGE_TIMEOUT 20
156 #define CUSTOM_TIMEOUT_BIT 0x1
157 #define CUSTOM_HOLDKEY_BIT 0x2
158 #define HOLD_KEY_BLOCK_BIT 0x1
159 #define TIMEOUT_NONE (-1)
161 #define S_COVER_TIMEOUT 8000
162 #define GET_HOLDKEY_BLOCK_STATE(x) ((x >> SHIFT_LOCK_FLAG) & HOLD_KEY_BLOCK_BIT)
163 #define DELAYED_INIT_WATING_TIME 60000 /* 1 minute */
165 #define LOCK_SCREEN_WATING_TIME 300 /* 0.3 second */
166 #define LONG_PRESS_INTERVAL 2 /* 2 seconds */
167 #define SAMPLING_INTERVAL 1 /* 1 sec */
168 #define BRIGHTNESS_CHANGE_STEP 10
169 #define LCD_ALWAYS_ON 0
170 #define ACCEL_SENSOR_ON 1
171 #define CONTINUOUS_SAMPLING 1
172 #define LCDOFF_TIMEOUT 300 /* milli second */
174 #define DIFF_TIMEVAL_MS(a, b) \
175 (((a.tv_sec * 1000000 + a.tv_usec) - \
176 (b.tv_sec * 1000000 + b.tv_usec)) \
179 static struct display_config display_conf = {
180 .lock_wait_time = LOCK_SCREEN_WATING_TIME,
181 .longpress_interval = LONG_PRESS_INTERVAL,
182 .lightsensor_interval = SAMPLING_INTERVAL,
183 .lcdoff_timeout = LCDOFF_TIMEOUT,
184 .pm_default_brightness = 80,
185 .brightness_change_step = BRIGHTNESS_CHANGE_STEP,
186 .lcd_always_on = LCD_ALWAYS_ON,
188 .framerate_app = {0, 0, 0, 0},
189 .control_display = 0,
190 .powerkey_doublepress = 0,
191 .accel_sensor_on = ACCEL_SENSOR_ON,
192 .continuous_sampling = CONTINUOUS_SAMPLING,
193 .timeout_enable = true,
194 .input_support = true,
195 .display_init_direction = DISPLAY_INIT_DIRECTION_HORIZONTAL,
196 .lockcheck_timeout = 600,
197 .aod_enter_level = 40,
199 .touch_wakeup = false,
200 .display_on_usb_conn_changed = true,
201 .display_dpms_type = DISPLAY_DPMS_TYPE_WINDOW_MANAGER,
204 struct display_function_info display_info = {
205 .update_auto_brightness = NULL,
206 .set_autobrightness_min = NULL,
207 .reset_autobrightness_min = NULL,
208 .face_detection = NULL,
211 inline const struct display_config* get_var_display_config()
213 return &display_conf;
216 inline struct state* state_st(enum state_t state)
218 return &states[state];
221 guint get_transition_timer(void)
223 return timeout_src_id;
226 static const char* __device_flags_to_string(enum device_flags flags)
228 if (flags & LCD_ON_BY_GESTURE)
230 else if (flags & (LCD_ON_BY_POWER_KEY | LCD_OFF_BY_POWER_KEY))
231 return POWER_KEY_STR;
232 else if (flags & (LCD_ON_BY_EVENT | LCD_OFF_BY_EVENT))
234 else if (flags & LCD_ON_BY_TOUCH)
236 else if (flags & LCD_OFF_BY_TIMEOUT)
242 static unsigned long get_lcd_on_flags(void)
244 unsigned long flags = NORMAL_MODE;
245 bool lcd_paneloff_mode = false;
247 display_panel_get_lcd_paneloff_mode(&lcd_paneloff_mode);
248 if (lcd_paneloff_mode)
249 flags |= LCD_PANEL_OFF_MODE;
254 bool touch_event_blocked(void)
256 return touch_blocked;
259 void lcd_on_procedure(int state, enum device_flags flag)
261 unsigned long flags = get_lcd_on_flags();
265 * Display on procedure
267 * step 2. broadcast lcd on signal with cause
268 * step 3. set brightness
269 * step 4. set pmstate of vconf
270 * step 5. display on operate
272 * - b. TSP(touch screen) and touchkey enable
273 * step 6. broadcast lcd on complete signal
274 * step 7. key backlight enable
278 _I("[lcdstep] 0x%lx", flags);
280 /* send LCDOn dbus signal */
281 if (!lcdon_broadcast)
282 broadcast_lcd_on(SIGNAL_PRE, flags);
284 /* Update brightness level */
285 if (state == LCD_DIM)
286 display_backlight_set_brightness_by_dim_brightness();
287 else if (state == LCD_NORMAL)
288 display_backlight_update_by_default_brightness();
290 if (state == LCD_NORMAL)
291 set_setting_pmstate(S_NORMAL);
292 else if (state == LCD_DIM)
293 set_setting_pmstate(S_LCDDIM);
295 display_start_dependent_device(flags);
297 if (!lcdon_broadcast) {
298 broadcast_lcd_on(SIGNAL_POST, flags);
299 lcdon_broadcast = true;
302 if (CHECK_OPS(keyfilter_ops, backlight_enable))
303 keyfilter_ops->backlight_enable(true);
305 touch_blocked = false;
308 static unsigned long get_lcd_off_flags(void)
310 unsigned long flags = NORMAL_MODE;
311 bool stay_touchscreen_off = false;
313 display_misc_get_stay_touchscreen_off(&stay_touchscreen_off);
314 if (stay_touchscreen_off)
315 flags |= TOUCH_SCREEN_OFF_MODE;
320 inline void lcd_off_procedure(enum device_flags flag)
322 unsigned long flags = get_lcd_off_flags();
326 * Display off procedure
327 * step 0. enhance mode off using nofity (e.g mdnie, HBM, LBM)
328 * step 1. broadcast lcd off signal with cause
329 * step 2. set pmstate of vconf
330 * step 3. display off operate
332 * - b. TSP(touch screen) and touchkey disable
333 * step 4. broadcast lcd off complete siganl
334 * step 5. enter doze mode if it is enabled
336 _I("[lcdstep] 0x%lx", flags);
340 device_notify(DEVICE_NOTIFIER_LCD_OFF, NULL);
342 if (lcdon_broadcast) {
343 broadcast_lcd_off(SIGNAL_PRE, flags);
344 lcdon_broadcast = false;
349 touch_blocked = true;
351 set_setting_pmstate(S_LCDOFF);
353 if (CHECK_OPS(keyfilter_ops, backlight_enable))
354 keyfilter_ops->backlight_enable(false);
356 display_stop_dependent_device(flags);
358 broadcast_lcd_off(SIGNAL_POST, flags);
359 device_notify(DEVICE_NOTIFIER_LCD_OFF_COMPLETE, NULL);
364 static void del_state_cond(void *data, enum state_t state)
366 PmLockNode *tmp = NULL;
372 /* A passed data is a pid_t type data, not a 64bit data. */
373 pid = (pid_t)((intptr_t)data);
374 _I("delete prohibit %s condition by timeout (%d)", states[state].name, pid);
376 if (pid == INTERNAL_LOCK_AMBIENT)
377 ambient_check_invalid_state(pid);
379 tmp = find_node(state, pid);
380 del_node(state, tmp);
381 set_unlock_time(pid, state);
383 /* Change state only when the two conditions below are satisfied.
384 * 1. There should be no running state-transition timer
385 * 2. Released lock is one of the pm_cur_state's lock
386 * This emulates already expired transition timer */
387 if (!timeout_src_id && get_pm_cur_state() == state)
388 states[get_pm_cur_state()].trans(EVENT_TIMEOUT);
390 if (state == S_LCDOFF)
391 set_process_active(false, pid);
394 static gboolean del_normal_cond(void *data)
396 del_state_cond(data, S_NORMAL);
397 return G_SOURCE_REMOVE;
400 static gboolean del_dim_cond(void *data)
402 del_state_cond(data, S_LCDDIM);
403 return G_SOURCE_REMOVE;
406 static gboolean del_off_cond(void *data)
408 del_state_cond(data, S_LCDOFF);
409 return G_SOURCE_REMOVE;
412 /* timeout handler */
413 gboolean timeout_handler(void *data)
415 _I("Time out state %s", states[get_pm_cur_state()].name);
417 if (timeout_src_id) {
418 g_source_remove(timeout_src_id);
422 states[get_pm_cur_state()].trans(EVENT_TIMEOUT);
423 return G_SOURCE_REMOVE;
426 void reset_timeout(int timeout)
428 if (!display_conf.timeout_enable)
431 if ((get_pm_cur_state() == S_LCDOFF)
432 && (is_emulator() == true || timeout_sleep_support == false))
435 _I("Reset timeout(%d ms) pm_cur_state(%d).", timeout, get_pm_cur_state());
436 if (timeout_src_id != 0) {
437 g_source_remove(timeout_src_id);
441 if (trans_table[get_pm_cur_state()][EVENT_TIMEOUT] == get_pm_cur_state())
445 timeout_src_id = g_timeout_add(timeout,
446 timeout_handler, NULL);
447 else if (timeout == 0)
448 states[get_pm_cur_state()].trans(EVENT_TIMEOUT);
451 /* get configurations from setting */
452 static int get_lcd_timeout_from_settings(void)
457 for (i = 0; i < S_END; i++) {
458 switch (states[i].state) {
460 get_run_timeout(&val);
463 get_dim_timeout(&val);
466 val = display_conf.lcdoff_timeout;
469 /* This state doesn't need to set time out. */
474 states[i].timeout = val;
476 _I("State(%s) timeout(%d) ms", states[i].name,
483 static void update_display_time(void)
485 int run_timeout, val;
487 /* first priority : custom timeout */
488 if (custom_normal_timeout > 0) {
489 states[S_NORMAL].timeout = custom_normal_timeout;
490 states[S_LCDDIM].timeout = custom_dim_timeout;
491 _I("CUSTOM : timeout is set by normal(%d ms), dim(%d ms)",
492 custom_normal_timeout, custom_dim_timeout);
496 /* second priority : lock state */
497 if ((__get_lock_screen_state() == VCONFKEY_IDLE_LOCK) &&
498 !get_lock_screen_bg_state()) {
499 /* timeout is different according to key or event. */
500 states[S_NORMAL].timeout = lock_screen_timeout;
501 _I("LOCK: Timeout(%d ms) is set by normal.",
502 lock_screen_timeout);
506 /* default setting */
507 get_run_timeout(&run_timeout);
510 * if the run_timeout is zero, it regards AlwaysOn state
512 if (run_timeout == 0 || display_conf.lcd_always_on) {
513 run_timeout = ALWAYS_ON_TIMEOUT;
514 _I("LCD always on.");
517 states[S_NORMAL].timeout = run_timeout;
519 get_dim_timeout(&val);
520 states[S_LCDDIM].timeout = val;
522 _I("Normal: NORMAL timeout is set by %d ms", states[S_NORMAL].timeout);
523 _I("Normal: DIM timeout is set by %d ms", states[S_LCDDIM].timeout);
526 static void update_display_locktime(int time)
528 lock_screen_timeout = time;
529 update_display_time();
532 void set_dim_state(bool on)
534 _I("Dim state is %d.", on);
535 update_display_time();
536 states[get_pm_cur_state()].trans(EVENT_INPUT);
539 void lcd_on_direct(enum device_flags flags)
541 enum hal_device_power_transition_reason reason;
543 if (flags & LCD_ON_BY_POWER_KEY)
544 reason = HAL_DEVICE_POWER_TRANSITION_REASON_POWER_KEY;
545 else if (flags & LCD_ON_BY_TOUCH)
546 reason = HAL_DEVICE_POWER_TRANSITION_REASON_TOUCH_SCREEN;
548 reason = HAL_DEVICE_POWER_TRANSITION_REASON_UNKNOWN;
550 power_request_change_state_strict(DEVICED_POWER_STATE_SLEEP, DEVICED_POWER_STATE_NORMAL, reason, NULL);
551 set_pm_cur_state(S_NORMAL);
553 _D("lcd is on directly");
554 gettimeofday(&lcdon_tv, NULL);
555 lcd_on_procedure(LCD_NORMAL, flags);
557 update_display_locktime(LOCK_SCREEN_INPUT_TIMEOUT);
560 static inline bool check_lcd_is_on(void)
562 if (display_panel_get_dpms_cached_state() != DPMS_ON)
568 static gboolean timer_refresh_cb(gpointer data)
572 /* state transition */
573 set_pm_old_state(get_pm_cur_state());
574 set_pm_cur_state(S_NORMAL);
575 st = &states[get_pm_cur_state()];
578 st->action(st->timeout);
583 int custom_lcdon(int timeout)
590 if (check_lcd_is_on() == false)
591 lcd_on_direct(LCD_ON_BY_GESTURE);
593 _I("Custom lcd on timeout(%d ms).", timeout);
594 if (set_custom_lcdon_timeout(timeout) == true)
595 update_display_time();
597 /* state transition */
598 set_pm_old_state(get_pm_cur_state());
599 set_pm_cur_state(S_NORMAL);
600 st = &states[get_pm_cur_state()];
604 st->action(st->timeout);
606 g_idle_add(timer_refresh_cb, NULL);
611 int custom_lcdoff(enum device_flags flag)
615 check_processes(S_NORMAL);
616 check_processes(S_LCDDIM);
618 /* check holdkey block flag in lock node */
619 if (check_lock_condition(S_NORMAL) || check_lock_condition(S_LCDDIM)) {
621 * When another proccess is normal lock, device is received call then,
622 * call app can be changed to lcd state by proximity.
623 * If proximity is near then normal lock will be unlocked.
625 if (flag & LCD_OFF_BY_PROXIMITY) {
626 _I("custom lcd off by proximity, delete normal lock");
627 delete_condition(S_NORMAL);
629 _I("skip custom lcd off");
634 _I("custom lcd off by flag(%d)", flag);
635 if (display_panel_get_dpms_cached_state() == DPMS_ON)
636 lcd_off_procedure(flag);
638 if (set_custom_lcdon_timeout(0) == true)
639 update_display_time();
641 /* state transition */
642 set_pm_old_state(get_pm_cur_state());
643 set_pm_cur_state(S_LCDOFF);
644 st = &states[get_pm_cur_state()];
648 st->action(st->timeout);
653 int display_on_by_reason(const char *reason, int timeout)
659 str_len = strlen(reason);
661 if (!strncmp(reason, GESTURE_STR, str_len))
662 flag = LCD_ON_BY_GESTURE;
663 else if (!strncmp(reason, EVENT_STR, str_len))
664 flag = LCD_ON_BY_EVENT;
666 _E("Reason is unknown(%s)", reason);
671 _E("Cannot setting timeout %d", timeout);
675 if (check_lcd_is_on() == false)
678 _I("platform lcd on by %s (%d ms)", reason, timeout);
679 if (set_custom_lcdon_timeout(timeout) == true)
680 update_display_time();
682 /* state transition */
683 set_pm_old_state(get_pm_cur_state());
684 set_pm_cur_state(S_NORMAL);
685 st = &states[get_pm_cur_state()];
689 st->action(st->timeout);
694 int display_off_by_reason(const char *reason)
700 str_len = strlen(reason);
702 if (!strncmp(reason, GESTURE_STR, str_len)) {
703 check_processes(S_NORMAL);
704 check_processes(S_LCDDIM);
706 /* check holdkey block flag in lock node */
707 if (check_lock_condition(S_NORMAL) || check_lock_condition(S_LCDDIM)) {
708 _I("skip platform lcd off by gesture");
711 flag = LCD_OFF_BY_GESTURE;
712 } else if (!strncmp(reason, PALM_STR, str_len)) {
713 delete_condition(S_NORMAL);
714 delete_condition(S_LCDDIM);
716 flag = LCD_OFF_BY_PALM;
718 _E("Reason is unknown(%s)", reason);
722 _I("platform lcd off by %s", reason);
723 if (display_panel_get_dpms_cached_state() == DPMS_ON)
724 lcd_off_procedure(flag);
726 /* state transition */
727 set_pm_old_state(get_pm_cur_state());
728 set_pm_cur_state(S_LCDOFF);
729 st = &states[get_pm_cur_state()];
733 st->action(st->timeout);
738 static void default_proc_change_state_action(enum state_t next, int timeout)
742 set_pm_old_state(get_pm_cur_state());
743 set_pm_cur_state(next);
745 st = &states[get_pm_cur_state()];
747 if (st && st->action) {
749 st->action(st->timeout);
755 static int default_proc_change_state(unsigned int cond, pid_t pid)
759 next = GET_COND_STATE(cond);
760 _I("Change process(%d) state to %s.", pid, states[next].name);
764 if (check_lcd_is_on() == false)
765 lcd_on_direct(LCD_ON_BY_EVENT);
766 update_display_locktime(LOCK_SCREEN_CONTROL_TIMEOUT);
767 default_proc_change_state_action(next, -1);
770 default_proc_change_state_action(next, -1);
773 if (display_panel_get_dpms_cached_state() == DPMS_ON)
774 lcd_off_procedure(LCD_OFF_BY_EVENT);
775 if (set_custom_lcdon_timeout(0))
776 update_display_time();
777 default_proc_change_state_action(next, -1);
780 _I("Dangerous requests.");
781 /* at first LCD_OFF and then goto sleep */
782 /* state transition */
783 default_proc_change_state_action(S_LCDOFF, TIMEOUT_NONE);
784 delete_condition(S_NORMAL);
785 delete_condition(S_LCDDIM);
786 delete_condition(S_LCDOFF);
787 if (lcdon_broadcast) {
788 _I("broadcast lcd off signal at non-lcd device");
789 broadcast_lcd_off(SIGNAL_PRE, 0);
790 broadcast_lcd_off(SIGNAL_POST, 0);
792 default_proc_change_state_action(S_SLEEP, TIMEOUT_NONE);
802 static void proc_condition_lock(PMMsg *data)
805 guint cond_timeout_id = 0;
806 char pname[PATH_MAX];
807 pid_t pid = data->pid;
809 int holdkey_block, ret;
812 const char *lock_type = NULL;
814 state = GET_COND_STATE(data->cond);
815 if (state == S_START)
818 flags = GET_COND_FLAG(data->cond);
819 display_misc_get_process_name(pid, pname);
821 if ((state == S_LCDOFF) && (get_pm_cur_state() == S_SLEEP) &&
822 (pm_get_power_lock() == POWER_UNLOCK))
823 proc_change_state(data->cond, INTERNAL_LOCK_PM);
825 if (data->timeout > 0) {
826 /* To pass a pid_t data through the timer infrastructure
827 * without memory allocation, a pid_t data becomes typecast
828 * to intptr_t and void *(64bit) type. */
829 cond_timeout_id = g_timeout_add(
831 states[state].timeout_cb,
832 (void*)((intptr_t)pid));
833 if (!cond_timeout_id)
834 _E("Failed to register display timer.");
837 holdkey_block = GET_COND_FLAG(data->cond) & PM_FLAG_BLOCK_HOLDKEY;
839 tmp = find_node(state, pid);
841 tmp = add_node(state, pid, cond_timeout_id, holdkey_block);
843 _E("Failed to acquire lock, state: %d, pid: %d.", state, pid);
847 update_lock_timer(data, tmp, cond_timeout_id);
848 tmp->holdkey_block = holdkey_block;
851 if (state == S_LCDOFF)
852 set_process_active(true, pid);
854 _I("[%s] locked by %5d with %u ms", states[state].name, pid, data->timeout);
856 if (pid < INTERNAL_LOCK_BASE) {
858 if (state == S_LCDOFF)
859 lock_type = PM_LCDOFF_STR;
860 else if (state == S_LCDDIM)
861 lock_type = PM_LCDDIM_STR;
862 else if (state == S_NORMAL)
863 lock_type = PM_LCDON_STR;
866 /* power lock signal */
867 ret = gdbus_signal_emit(NULL,
868 DEVICED_PATH_DISPLAY,
869 DEVICED_INTERFACE_DISPLAY,
871 g_variant_new("(sii)", lock_type, pid, (int)data->timeout));
873 _E("Failed to send dbus signal PowerLock.");
877 _SD("be requested LOCK info pname(%s), holdkeyblock(%d) flags(%d)",
878 pname, holdkey_block, flags);
879 set_lock_time(pid, pname, state);
881 device_notify(DEVICE_NOTIFIER_DISPLAY_LOCK, (void *)&value);
884 static void proc_condition_unlock(PMMsg *data)
886 pid_t pid = data->pid;
889 char pname[PATH_MAX];
893 const char *lock_type = NULL;
895 state = GET_COND_STATE(data->cond);
899 flags = GET_COND_FLAG(data->cond);
900 display_misc_get_process_name(pid, pname);
902 tmp = find_node(state, pid);
903 del_node(state, tmp);
905 if (state == S_LCDOFF)
906 set_process_active(false, pid);
908 _I("[%s] unlocked by %5d", states[state].name, pid);
910 if (pid < INTERNAL_LOCK_BASE) {
912 if (state == S_LCDOFF)
913 lock_type = PM_LCDOFF_STR;
914 else if (state == S_LCDDIM)
915 lock_type = PM_LCDDIM_STR;
916 else if (state == S_NORMAL)
917 lock_type = PM_LCDON_STR;
920 /* power unlock signal */
921 ret = gdbus_signal_emit(NULL,
922 DEVICED_PATH_DISPLAY,
923 DEVICED_INTERFACE_DISPLAY,
925 g_variant_new("(sii)", lock_type, pid, (int)data->timeout));
927 _E("Failed to send dbus signal PowerUnlock.");
931 _SD("be requested UNLOCK info pname(%s) flag(%d)", pname, flags);
932 set_unlock_time(pid, state);
934 device_notify(DEVICE_NOTIFIER_DISPLAY_LOCK, (void *)&value);
937 static int proc_condition(PMMsg *data)
941 if (IS_COND_REQUEST_LOCK(data->cond))
942 proc_condition_lock(data);
944 if (IS_COND_REQUEST_UNLOCK(data->cond))
945 proc_condition_unlock(data);
947 if (!display_conf.timeout_enable)
950 flags = GET_COND_FLAG(data->cond);
952 /* guard time for suspend */
953 if (get_pm_cur_state() == S_LCDOFF)
954 reset_timeout(states[S_LCDOFF].timeout);
956 if (flags & PM_FLAG_RESET_TIMER)
957 reset_timeout(states[get_pm_cur_state()].timeout);
961 states[get_pm_cur_state()].trans(EVENT_TIMEOUT);
966 void update_lcdoff_source(int source)
971 case VCONFKEY_PM_LCDOFF_BY_TIMEOUT:
972 _I("LCD OFF by timeout.");
974 case VCONFKEY_PM_LCDOFF_BY_POWERKEY:
975 _I("LCD OFF by powerkey.");
978 _E("Invalid value(%d).", source);
981 ret = vconf_set_int(VCONFKEY_PM_LCDOFF_SOURCE, source);
983 _E("Failed to set vconf value for lcd off source: %d", vconf_get_ext_errno());
986 void print_info(int fd)
989 char buf[PATH_MAX + 255];
992 char pname[PATH_MAX];
1000 snprintf(buf, sizeof(buf),
1001 "\n==========================================="
1002 "===========================\n");
1003 ret = write(fd, buf, strlen(buf));
1005 _E("Write() failed: %d", errno);
1006 snprintf(buf, sizeof(buf), "Timeout Info: Run[%dms] Dim[%dms] Off[%dms]\n",
1007 states[S_NORMAL].timeout,
1008 states[S_LCDDIM].timeout, states[S_LCDOFF].timeout);
1009 ret = write(fd, buf, strlen(buf));
1011 _E("Write() failed: %d", errno);
1013 snprintf(buf, sizeof(buf), "Tran. Locked : %s %s %s\n",
1014 (get_trans_condition() & MASK_NORMAL) ? states[S_NORMAL].name : "-",
1015 (get_trans_condition() & MASK_DIM) ? states[S_LCDDIM].name : "-",
1016 (get_trans_condition() & MASK_OFF) ? states[S_LCDOFF].name : "-");
1017 ret = write(fd, buf, strlen(buf));
1019 _E("Write() failed: %d", errno);
1021 snprintf(buf, sizeof(buf), "Current State: %s\n",
1022 states[get_pm_cur_state()].name);
1023 ret = write(fd, buf, strlen(buf));
1025 _E("Write() failed: %d", errno);
1027 snprintf(buf, sizeof(buf), "Current Lock Conditions: \n");
1028 ret = write(fd, buf, strlen(buf));
1030 _E("Write() failed: %d", errno);
1032 for (s_index = S_NORMAL; s_index < S_END; s_index++) {
1033 SYS_G_LIST_FOREACH(get_cond_head(s_index), elem, t) {
1034 display_misc_get_process_name((pid_t)t->pid, pname);
1035 ctime_r(&t->time, time_buf);
1036 time_buf[strlen(time_buf) - 1] = 0;
1037 snprintf(buf, sizeof(buf),
1038 " %d: [%s] locked by pid %d %s %s\n",
1039 i++, states[s_index].name, t->pid, pname, time_buf);
1040 ret = write(fd, buf, strlen(buf));
1042 _E("Write() failed: %d", errno);
1046 print_lock_info_list(fd);
1048 #ifdef ENABLE_PM_LOG
1049 pm_history_print(fd, 250);
1053 void save_display_log(const char *path)
1060 _D("internal state is saved!");
1063 ctime_r(&now_time, time_buf);
1064 time_buf[strlen(time_buf) - 1] = 0;
1066 fd = open(path, O_CREAT | O_TRUNC | O_WRONLY, 0644);
1068 snprintf(buf, sizeof(buf),
1069 "\npm_state_log now-time : %d(s) %s\n\n",
1070 (int)now_time, time_buf);
1071 ret = write(fd, buf, strlen(buf));
1073 _E("write() failed (%d)", errno);
1075 snprintf(buf, sizeof(buf), "pm_status_flag: %#x\n", get_pm_status_flag());
1076 ret = write(fd, buf, strlen(buf));
1078 _E("write() failed (%d)", errno);
1080 if (disp_plgn->get_lock_screen_state ) {
1081 snprintf(buf, sizeof(buf), "screen lock status : %d\n",
1082 disp_plgn->get_lock_screen_state());
1083 ret = write(fd, buf, strlen(buf));
1085 _E("write() failed (%d)", errno);
1091 fd = open("/dev/console", O_WRONLY);
1098 /* SIGHUP signal handler
1099 * For debug... print info to syslog
1101 static void sig_hup(int signo)
1103 _I("received sig hub %d", signo);
1108 int check_lcdoff_direct(void)
1110 int ret, lock, cradle;
1113 if (get_pm_old_state() != S_NORMAL)
1116 if (get_pm_cur_state() != S_LCDDIM)
1119 if (!display_conf.dimming)
1122 lock = __get_lock_screen_state();
1123 if (lock != VCONFKEY_IDLE_LOCK)
1126 hdmi_state = extcon_get_status(EXTCON_CABLE_HDMI);
1130 ret = vconf_get_int(VCONFKEY_SYSMAN_CRADLE_STATUS, &cradle);
1131 if (ret >= 0 && cradle == DOCK_SOUND)
1134 _E("Failed to get vconf value for cradle status: %d", vconf_get_ext_errno());
1136 _D("Goto LCDOFF direct: lock(%d) hdmi(%d) cradle(%d).", lock, hdmi_state, cradle);
1142 * default transition function
1145 * 3. call enter action function
1147 static int default_trans(int evt)
1149 struct state *st = &states[get_pm_cur_state()];
1152 next_state = (enum state_t)trans_table[get_pm_cur_state()][evt];
1154 /* check conditions */
1155 if (st->check && !st->check(get_pm_cur_state(), next_state)) {
1156 /* There is a condition. */
1157 _I("%s locked. Trans to %s failed.", states[get_pm_cur_state()].name,
1158 states[next_state].name);
1162 /* state transition */
1163 set_pm_old_state(get_pm_cur_state());
1164 set_pm_cur_state(next_state);
1165 st = &states[get_pm_cur_state()];
1169 if (get_pm_cur_state() == S_LCDOFF)
1170 update_lcdoff_source(VCONFKEY_PM_LCDOFF_BY_TIMEOUT);
1172 if ((get_pm_cur_state() == S_NORMAL) || (get_pm_cur_state() == S_LCDOFF))
1173 if (set_custom_lcdon_timeout(0) == true)
1174 update_display_time();
1176 if (check_lcdoff_direct() == true) {
1177 /* enter next state directly */
1178 states[get_pm_cur_state()].trans(EVENT_TIMEOUT);
1180 if ((get_pm_cur_state() == S_SLEEP)
1181 && (is_emulator() == true || timeout_sleep_support == false))
1184 st->action(st->timeout);
1191 static gboolean lcd_on_expired(void *data)
1193 int lock_state, ret;
1195 if (lock_timeout_id)
1196 lock_timeout_id = 0;
1198 /* check state of lock */
1199 ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
1200 if (ret > 0 && lock_state == VCONFKEY_IDLE_LOCK)
1201 return G_SOURCE_REMOVE;
1203 _E("Failed to get vconf value for idle lock state: %d", vconf_get_ext_errno());
1205 /* lock screen is not launched yet, but lcd is on */
1206 if (check_lcd_is_on() == false)
1207 lcd_on_procedure(LCD_NORMAL, NORMAL_MODE);
1209 return G_SOURCE_REMOVE;
1212 static inline void stop_lock_timer(void)
1214 if (lock_timeout_id) {
1215 g_source_remove(lock_timeout_id);
1216 lock_timeout_id = 0;
1220 static void check_lock_screen(void)
1222 int lock_state, ret;
1226 /* check state of lock */
1227 ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
1228 if (ret < 0 || lock_state == VCONFKEY_IDLE_LOCK)
1231 /* Use time to check lock is done. */
1232 lock_timeout_id = g_timeout_add(display_conf.lock_wait_time,
1233 lcd_on_expired, NULL);
1236 /* default enter action function */
1237 static int default_action(int timeout)
1239 int wakeup_count = -1, pm_cur_state;
1242 static time_t last_update_time = 0;
1243 static int last_timeout = 0;
1244 struct timeval now_tv;
1247 bool lcd_paneloff_mode = false;
1249 if (status != DEVICE_OPS_STATUS_START) {
1250 _E("Display is not started.");
1254 if (get_pm_cur_state() != S_SLEEP) {
1255 if ((get_pm_cur_state() == S_NORMAL) &&
1256 lcdon_tv.tv_sec != 0) {
1257 gettimeofday(&now_tv, NULL);
1258 timeout -= DIFF_TIMEVAL_MS(now_tv, lcdon_tv);
1259 lcdon_tv.tv_sec = 0;
1261 /* set timer with current state timeout */
1262 reset_timeout(timeout);
1264 if (get_pm_cur_state() == S_NORMAL) {
1265 time(&last_update_time);
1266 last_timeout = timeout;
1268 _I("Timout set: %s state %d ms",
1269 states[get_pm_cur_state()].name, timeout);
1273 if ((get_pm_cur_state() != get_pm_old_state()) && (get_pm_cur_state() != S_SLEEP)) {
1274 power_request_change_state_strict(DEVICED_POWER_STATE_SLEEP, DEVICED_POWER_STATE_NORMAL,
1275 power_get_wakeup_reason(), NULL);
1276 set_setting_pmstate(get_pm_cur_state());
1277 pm_cur_state = get_pm_cur_state();
1278 device_notify(DEVICE_NOTIFIER_LCD, (void *)&pm_cur_state);
1281 if ((get_pm_old_state() == S_NORMAL) && (get_pm_cur_state() != S_NORMAL)) {
1283 diff = difftime(now, last_update_time);
1284 _I("S_NORMAL is changed to %s (timeout=%d ms diff=%.0f s).",
1285 states[get_pm_cur_state()].name, last_timeout, diff);
1288 switch (get_pm_cur_state()) {
1291 * normal state : backlight on and restore
1292 * the previous brightness
1294 if ((get_pm_old_state() == S_LCDOFF) || (get_pm_old_state() == S_SLEEP))
1295 check_lock_screen();
1296 else if (get_pm_old_state() == S_LCDDIM)
1297 display_backlight_update_by_default_brightness();
1299 if (check_lcd_is_on() == false)
1300 lcd_on_procedure(LCD_NORMAL, NORMAL_MODE);
1304 display_backlight_get_custom_status(&custom_status);
1305 if ((get_pm_old_state() == S_NORMAL) && custom_status) {
1306 display_backlight_get_brightness(&brightness);
1307 display_backlight_set_custom_brightness(brightness);
1309 /* lcd dim state : dim the brightness */
1310 display_backlight_set_brightness_by_dim_brightness();
1312 if ((get_pm_old_state() == S_LCDOFF) || (get_pm_old_state() == S_SLEEP))
1313 lcd_on_procedure(LCD_DIM, NORMAL_MODE);
1317 if ((get_pm_old_state() != S_SLEEP) && (get_pm_old_state() != S_LCDOFF)) {
1319 /* lcd off state : turn off the backlight */
1320 if (display_panel_get_dpms_cached_state() == DPMS_ON)
1321 lcd_off_procedure(LCD_OFF_BY_TIMEOUT);
1324 display_panel_get_lcd_paneloff_mode(&lcd_paneloff_mode);
1325 if (display_panel_get_dpms_cached_state() == DPMS_ON
1326 || lcd_paneloff_mode)
1327 lcd_off_procedure(LCD_OFF_BY_TIMEOUT);
1331 if ((get_pm_old_state() != S_SLEEP) && (get_pm_old_state() != S_LCDOFF))
1334 if (display_panel_get_dpms_cached_state() == DPMS_ON)
1335 lcd_off_procedure(LCD_OFF_BY_TIMEOUT);
1337 if (!pm_get_power_lock_support()) {
1338 /* sleep state : set system mode to SUSPEND */
1339 if (get_wakeup_count(&wakeup_count) < 0)
1340 _E("Wakeup count read error.");
1342 if (wakeup_count < 0) {
1343 _I("Wakup Event. Can not enter suspend mode.");
1347 if (set_wakeup_count(wakeup_count) < 0) {
1348 _E("Wakeup count write error.");
1358 #ifdef ENABLE_PM_LOG
1359 pm_history_save(PM_LOG_SLEEP, get_pm_cur_state());
1361 power_request_change_state(DEVICED_POWER_STATE_SLEEP, HAL_DEVICE_POWER_TRANSITION_REASON_DISPLAY_OFF_TIMEOUT);
1365 if (!pm_get_power_lock_support()) {
1367 states[get_pm_cur_state()].trans(EVENT_DEVICE);
1373 * default check function
1375 * 0 : can't transit, others : transitable
1377 static int default_check(int curr, int next)
1381 makeup_trans_condition();
1383 trans_cond = get_trans_condition() & MASK_BIT;
1385 if (next == S_NORMAL) /* S_NORMAL is exceptional */
1390 trans_cond = trans_cond & MASK_NORMAL;
1393 trans_cond = trans_cond & MASK_DIM;
1396 trans_cond = trans_cond & MASK_OFF;
1403 if (trans_cond != 0) {
1408 return 1; /* transitable */
1411 static void default_saving_mode(int onoff)
1414 set_pm_status_flag(PWRSV_FLAG);
1416 clear_pm_status_flag(PWRSV_FLAG);
1418 if (get_pm_cur_state() == S_NORMAL)
1419 display_backlight_update_by_default_brightness();
1422 int poll_callback(int condition, PMMsg *data)
1424 static time_t last_t;
1427 if (status != DEVICE_OPS_STATUS_START) {
1428 _E("Display logic is not started.");
1432 if (condition == INPUT_POLL_EVENT) {
1433 if ((get_pm_cur_state() == S_LCDOFF) || (get_pm_cur_state() == S_SLEEP))
1434 _I("Input event signal at Display Off");
1436 if ((last_t != now) ||
1437 (get_pm_cur_state() == S_LCDOFF) ||
1438 (get_pm_cur_state() == S_SLEEP)) {
1439 states[get_pm_cur_state()].trans(EVENT_INPUT);
1444 if (condition == PM_CONTROL_EVENT) {
1445 proc_condition(data);
1447 if (IS_COND_REQUEST_CHANGE(data->cond))
1448 proc_change_state(data->cond, data->pid);
1454 static int update_setting(int key_idx, int val)
1459 case SETTING_TO_NORMAL:
1460 update_display_time();
1461 states[get_pm_cur_state()].trans(EVENT_INPUT);
1463 case SETTING_LOW_BATT:
1464 if (display_misc_is_low_battery_state(val)) {
1465 if (!(get_pm_status_flag() & CHRGR_FLAG))
1466 power_saving_func(true);
1467 set_pm_status_flag(LOWBT_FLAG);
1469 if (get_pm_status_flag() & PWRSV_FLAG)
1470 power_saving_func(false);
1471 clear_pm_status_flag(LOWBT_FLAG);
1472 clear_pm_status_flag(BRTCH_FLAG);
1473 ret = vconf_set_bool(VCONFKEY_PM_BRIGHTNESS_CHANGED_IN_LPM, false);
1475 _E("Failed to set vconf value for brightness changed in lpm: %d", vconf_get_ext_errno());
1478 case SETTING_CHARGING:
1480 if (get_pm_status_flag() & LOWBT_FLAG) {
1481 power_saving_func(false);
1482 clear_pm_status_flag(LOWBT_FLAG);
1484 set_pm_status_flag(CHRGR_FLAG);
1487 ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW,
1490 bat_state = VCONFKEY_SYSMAN_BAT_NORMAL;
1491 _E("Failed to get vconf value for battery status low: %d", vconf_get_ext_errno());
1493 if (display_misc_is_low_battery_state(bat_state)) {
1494 power_saving_func(true);
1495 set_pm_status_flag(LOWBT_FLAG);
1497 clear_pm_status_flag(CHRGR_FLAG);
1500 case SETTING_BRT_LEVEL:
1501 if (get_pm_status_flag() & PWRSV_FLAG) {
1502 set_pm_status_flag(BRTCH_FLAG);
1503 ret = vconf_set_bool(VCONFKEY_PM_BRIGHTNESS_CHANGED_IN_LPM, true);
1505 _E("Failed to set vconf value for brightness changed in lpm: %d", vconf_get_ext_errno());
1506 _I("Brightness changed in low battery,"
1507 "escape dim state.");
1509 display_backlight_set_default_brightness(val);
1511 case SETTING_LOCK_SCREEN:
1512 set_lock_screen_state(val);
1513 if (val == VCONFKEY_IDLE_UNLOCK) {
1514 if (CHECK_OPS(keyfilter_ops, backlight_enable))
1515 keyfilter_ops->backlight_enable(false);
1518 /* LCD on if lock screen show before waiting time */
1519 if ((get_pm_cur_state() == S_NORMAL) &&
1520 val == VCONFKEY_IDLE_LOCK &&
1521 display_panel_get_dpms_cached_state() != DPMS_ON &&
1522 is_lcdon_blocked() == LCDON_BLOCK_NONE)
1523 lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
1525 update_display_time();
1526 if (get_pm_cur_state() == S_NORMAL)
1527 states[get_pm_cur_state()].trans(EVENT_INPUT);
1529 case SETTING_LOCK_SCREEN_BG:
1530 set_lock_screen_bg_state(val);
1531 update_display_time();
1532 if (get_pm_cur_state() == S_NORMAL)
1533 states[get_pm_cur_state()].trans(EVENT_INPUT);
1535 case SETTING_POWER_CUSTOM_BRIGHTNESS:
1536 if (val == VCONFKEY_PM_CUSTOM_BRIGHTNESS_ON)
1537 display_backlight_set_custom_status(true);
1539 display_backlight_set_custom_status(false);
1548 static void check_seed_status(void)
1556 /* Charging check */
1557 if (fp_get_charging_status && (fp_get_charging_status(&tmp) == 0) && (tmp > 0))
1558 set_pm_status_flag(CHRGR_FLAG);
1560 ret = get_setting_brightness(&tmp);
1561 if (ret != 0 || (tmp < PM_MIN_BRIGHTNESS || tmp > PM_MAX_BRIGHTNESS)) {
1562 _I("Failed to read vconf value for brightness.");
1563 brt = display_conf.pm_default_brightness;
1564 if (tmp < PM_MIN_BRIGHTNESS || tmp > PM_MAX_BRIGHTNESS) {
1565 ret = vconf_set_int(VCONFKEY_SETAPPL_LCD_BRIGHTNESS, brt);
1567 _E("Failed to set vconf value for lcd brightness: %d", vconf_get_ext_errno());
1571 _I("Set brightness(%d) from setting app.", tmp);
1572 display_backlight_set_default_brightness(tmp);
1573 display_backlight_set_brightness(tmp);
1575 ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, &bat_state);
1577 bat_state = VCONFKEY_SYSMAN_BAT_NORMAL;
1578 _E("Failed to get vconf value for battery status low: %d", vconf_get_ext_errno());
1580 if (display_misc_is_low_battery_state(bat_state)) {
1581 if (!(get_pm_status_flag() & CHRGR_FLAG)) {
1582 power_saving_func(true);
1583 set_pm_status_flag(LOWBT_FLAG);
1587 /* lock screen check */
1588 ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
1591 _E("Failed to get vconf value for idle lock state: %d", vconf_get_ext_errno());
1593 set_lock_screen_state(lock_state);
1594 if (lock_state == VCONFKEY_IDLE_LOCK) {
1595 states[S_NORMAL].timeout = lock_screen_timeout;
1596 _I("LCD NORMAL timeout(%d ms) is set"
1597 " for lock screen.", lock_screen_timeout);
1603 static void init_lcd_operation(void)
1605 const struct device_ops *ops = NULL;
1607 ops = find_device("display");
1608 if (!check_default(ops))
1609 display_register_dependent_device(ops);
1611 ops = find_device("touchkey");
1612 if (!check_default(ops))
1613 display_register_dependent_device(ops);
1615 ops = find_device("touchscreen");
1616 if (!check_default(ops))
1617 display_register_dependent_device(ops);
1620 static void exit_lcd_operation(void)
1622 display_unregister_dependent_device();
1634 static const char *errMSG[INIT_END] = {
1635 [INIT_SETTING] = "setting init error",
1636 [INIT_INTERFACE] = "lowlevel interface(sysfs or others) init error",
1637 [INIT_POLL] = "input devices poll init error",
1638 [INIT_FIFO] = "FIFO poll init error",
1639 [INIT_DBUS] = "d-bus init error",
1642 int set_lcd_timeout(int on, int dim, int holdkey_block, const char *name)
1644 if (on == 0 && dim == 0) {
1645 _I("LCD timeout changed: default setting");
1646 custom_normal_timeout = custom_dim_timeout = 0;
1647 } else if (on < 0 || dim < 0) {
1648 _E("Failed to set value(on=%d dim=%d).", on, dim);
1651 _I("LCD timeout changed: on=%ds dim=%ds", on, dim);
1652 custom_normal_timeout = SEC_TO_MSEC(on);
1653 custom_dim_timeout = SEC_TO_MSEC(dim);
1655 /* Apply new backlight time */
1656 update_display_time();
1657 if (get_pm_cur_state() == S_NORMAL)
1658 states[get_pm_cur_state()].trans(EVENT_INPUT);
1660 if (holdkey_block) {
1661 custom_holdkey_block = true;
1662 _I("Hold key disabled.");
1664 custom_holdkey_block = false;
1665 _I("Hold key enabled.");
1668 if (custom_change_name) {
1669 free(custom_change_name);
1670 custom_change_name = 0;
1673 if (custom_normal_timeout == 0 &&
1674 custom_dim_timeout == 0 &&
1678 custom_change_name = strndup(name, strlen(name));
1679 if (!custom_change_name) {
1680 _E("Failed to malloc.");
1681 custom_normal_timeout = custom_dim_timeout = 0;
1682 custom_holdkey_block = false;
1689 void reset_lcd_timeout(GDBusConnection *conn,
1690 const gchar *sender,
1691 const gchar *unique_name,
1697 if (!custom_change_name)
1700 if (strcmp(sender, custom_change_name))
1703 _I("reset lcd timeout: Set default timeout. sender=%s", sender);
1705 free(custom_change_name);
1706 custom_change_name = 0;
1707 custom_normal_timeout = custom_dim_timeout = 0;
1708 custom_holdkey_block = false;
1710 update_display_time();
1711 if (get_pm_cur_state() == S_NORMAL)
1712 states[get_pm_cur_state()].trans(EVENT_INPUT);
1715 static int delayed_init_done(void *data)
1717 static bool done = false;
1726 _I("Booting done, release booting lock.");
1727 if (disp_plgn->pm_unlock_internal) {
1728 disp_plgn->pm_unlock_internal(INTERNAL_LOCK_BOOTING, LCD_NORMAL, PM_SLEEP_MARGIN);
1729 disp_plgn->pm_unlock_internal(INTERNAL_LOCK_BOOTING, LCD_OFF, PM_SLEEP_MARGIN);
1735 static int battery_health_changed(void *data)
1737 int health = DATA_VALUE_INT(data);
1739 _I("battery health change %d", health);
1741 if (health == HEALTH_GOOD) {
1742 clear_pm_status_flag(BATTERY_FLAG);
1743 clear_pm_status_flag(DIMSTAY_FLAG);
1744 } else if (health == HEALTH_LOW || health == HEALTH_HIGH || health == HEALTH_OVP) {
1745 set_pm_status_flag(BATTERY_FLAG);
1746 set_pm_status_flag(DIMSTAY_FLAG);
1749 if (display_panel_get_dpms_cached_state() == DPMS_ON)
1750 display_backlight_update_by_default_brightness();
1755 static gboolean delayed_dpms_init_done(gpointer data)
1759 if (!display_panel_init_dpms())
1760 return G_SOURCE_CONTINUE;
1762 switch (get_pm_cur_state()) {
1765 lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
1766 if (display_conf.timeout_enable) {
1767 timeout = states[S_NORMAL].timeout;
1768 /* check minimun lcd on time */
1769 if (timeout < SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT))
1770 timeout = SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT);
1771 reset_timeout(timeout);
1775 lcd_off_procedure(LCD_OFF_BY_EVENT);
1776 timeout = display_conf.lcdoff_timeout;
1777 reset_timeout(timeout);
1783 return G_SOURCE_REMOVE;
1786 static void add_timer_for_dpms_init(void)
1788 guint id = g_timeout_add(500/* milliseconds */, delayed_dpms_init_done, NULL);
1790 _E("Failed to add display_panel_init_dpms timeout.");
1794 * Power manager Main
1798 static int display_probe(void *data)
1801 struct display_plugin *dp = (struct display_plugin *) data;
1804 dp->config = &display_conf;
1805 setup_display_plugin_backlight_ops(dp);
1808 * load display service
1809 * if there is no display shared library,
1810 * deviced does not provide any method and function of display.
1812 ret = display_service_load();
1816 /* display_plugin instance initialization */
1817 init_pm_internal(data);
1818 disp_plgn->device_flags_to_string = __device_flags_to_string;
1820 if (battery_plgn->handle) {
1821 fp_get_charging_status = dlsym(battery_plgn->handle, "get_charging_status");
1822 if (!fp_get_charging_status)
1823 _E("Failed to obtain address of get_charging_status");
1825 _I("There is no battery module.");
1830 static int input_init_handler(void)
1832 if (!display_conf.input_support)
1833 remove_device_by_devname("input");
1838 static int power_resume_from_echomem_callback(void *data)
1840 system_wakeup_flag = true;
1841 if (check_wakeup_src() == EVENT_DEVICE)
1842 /* system waked up by devices */
1843 states[get_pm_cur_state()].trans(EVENT_DEVICE);
1845 /* system waked up by user input */
1846 states[get_pm_cur_state()].trans(EVENT_INPUT);
1851 static int poweroff_triggered_callback(void *udata)
1853 int val = (int)(intptr_t) udata;
1856 case VCONFKEY_SYSMAN_POWER_OFF_NONE:
1857 clear_pm_status_flag(PWROFF_FLAG);
1859 case VCONFKEY_SYSMAN_POWER_OFF_DIRECT:
1860 case VCONFKEY_SYSMAN_POWER_OFF_RESTART:
1861 set_pm_status_flag(PWROFF_FLAG);
1868 static void esd_action(void)
1870 const struct device_ops *touchscreen_ops = NULL;
1874 touchscreen_ops = find_device("touchscreen");
1876 if (!check_default(touchscreen_ops))
1877 touchscreen_ops->stop(NORMAL_MODE);
1878 display_panel_set_panel_state_by_off_state(NORMAL_MODE);
1879 display_panel_set_panel_state_by_on_state(NORMAL_MODE);
1880 if (!check_default(touchscreen_ops))
1881 touchscreen_ops->start(NORMAL_MODE);
1884 static void lcd_uevent_changed(struct udev_device *dev)
1886 const char *devpath;
1889 devpath = udev_device_get_devpath(dev);
1893 if (!fnmatch(LCD_ESD_PATH, devpath, 0)) {
1894 action = udev_device_get_action(dev);
1895 if (!strcmp(action, UDEV_CHANGE))
1900 static const struct uevent_handler lcd_uevent_ops = {
1901 .subsystem = LCD_EVENT_SUBSYSTEM,
1902 .uevent_func = lcd_uevent_changed,
1906 static void display_init(void *data)
1909 unsigned int flags = (WITHOUT_STARTNOTI | FLAG_X_DPMS);
1912 _I("Start power manager.");
1914 signal(SIGHUP, sig_hup);
1916 power_saving_func = default_saving_mode;
1918 /* load configutation */
1919 ret = display_load_config(&display_conf);
1921 _W("Failed to load '%s', use default value: %d",
1922 DISPLAY_CONF_FILE, ret);
1924 register_kernel_uevent_control(&lcd_uevent_ops);
1926 register_notifier(DEVICE_NOTIFIER_DELAYED_INIT, delayed_init_done);
1927 register_notifier(DEVICE_NOTIFIER_APPLICATION_BACKGROUND, display_app_background);
1928 register_notifier(DEVICE_NOTIFIER_APPLICATION_FOREGROUND, display_app_foreground);
1929 register_notifier(DEVICE_NOTIFIER_APPLICATION_TERMINATED, display_app_terminated);
1930 register_notifier(DEVICE_NOTIFIER_BATTERY_HEALTH, battery_health_changed);
1931 register_notifier(DEVICE_NOTIFIER_POWER_RESUME_FROM_ECHO_MEM, power_resume_from_echomem_callback);
1932 register_notifier(DEVICE_NOTIFIER_POWEROFF_TRIGGERED, poweroff_triggered_callback);
1934 init_save_userlock();
1936 for (i = INIT_SETTING; i < INIT_END; i++) {
1939 ret = init_setting(update_setting);
1941 case INIT_INTERFACE:
1942 if (display_conf.timeout_enable)
1943 get_lcd_timeout_from_settings();
1944 ret = init_sysfs(flags);
1948 ret = input_init_handler();
1950 pm_lock_detector_init();
1954 ret = init_pm_dbus();
1958 _E("Failed to init: %s", errMSG[i]);
1963 if (i == INIT_END) {
1964 display_ops_init(NULL);
1965 #ifdef ENABLE_PM_LOG
1968 init_lcd_operation();
1969 check_seed_status();
1971 /* In smd test, TSP should be turned off if display panel is not existed. */
1972 if (display_panel_get_dpms_cached_state() == -ENOENT) {
1973 _I("Display panel is not existed.");
1974 lcd_direct_control(DPMS_OFF, NORMAL_MODE);
1975 exit_lcd_operation();
1978 /* wm_ready needs to be checked
1979 * since display manager can be launched later than deviced.
1980 * In the case, display cannot be turned on at the first booting */
1981 // wm_ready = check_wm_ready();
1982 if (display_panel_init_dpms()) {
1983 if (is_lcdon_blocked() != LCDON_BLOCK_NONE)
1984 lcd_off_procedure(LCD_OFF_BY_EVENT);
1986 lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
1988 add_timer_for_dpms_init();
1991 if (display_conf.lcd_always_on) {
1992 _I("LCD always on.");
1993 trans_table[S_NORMAL][EVENT_TIMEOUT] = S_NORMAL;
1996 if (flags & WITHOUT_STARTNOTI) { /* start without noti */
1997 _I("Start Power managing without noti");
1998 power_request_change_state_strict(DEVICED_POWER_STATE_SLEEP, DEVICED_POWER_STATE_NORMAL,
1999 HAL_DEVICE_POWER_TRANSITION_REASON_UNKNOWN, NULL);
2001 * Lock lcd off until booting is done.
2002 * deviced guarantees all booting script is executing.
2003 * Last script of booting unlocks this suspend blocking state.
2005 if (disp_plgn->pm_lock_internal)
2006 disp_plgn->pm_lock_internal(INTERNAL_LOCK_BOOTING, LCD_OFF,
2007 STAY_CUR_STATE, DELAYED_INIT_WATING_TIME);
2009 /* Initial display state right after the booting done */
2010 if (is_lcdon_blocked())
2011 set_pm_cur_state(S_LCDOFF);
2013 set_pm_cur_state(S_NORMAL);
2014 ret = vconf_set_int(VCONFKEY_PM_STATE, get_pm_cur_state());
2016 _E("Failed to set vconf value for pm cur state: %d", vconf_get_ext_errno());
2018 status = DEVICE_OPS_STATUS_START;
2019 if (display_conf.timeout_enable) {
2020 timeout = states[S_NORMAL].timeout;
2021 /* check minimun lcd on time */
2022 if (timeout < SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT))
2023 timeout = SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT);
2025 if (disp_plgn->pm_lock_internal)
2026 disp_plgn->pm_lock_internal(INTERNAL_LOCK_BOOTING, LCD_NORMAL,
2027 STAY_CUR_STATE, timeout);
2032 if (display_conf.input_support)
2033 if (CHECK_OPS(keyfilter_ops, init))
2034 keyfilter_ops->init();
2036 set_display_init_direction(display_conf.display_init_direction);
2040 static void display_exit(void *data)
2044 status = DEVICE_OPS_STATUS_STOP;
2046 /* Set current state to S_NORMAL */
2047 set_pm_cur_state(S_NORMAL);
2048 set_setting_pmstate(get_pm_cur_state());
2049 /* timeout is not needed */
2050 reset_timeout(TIMEOUT_NONE);
2052 if (CHECK_OPS(keyfilter_ops, exit))
2053 keyfilter_ops->exit();
2055 unregister_kernel_uevent_control(&lcd_uevent_ops);
2057 display_ops_exit(NULL);
2059 for (i = i - 1; i >= INIT_SETTING; i--) {
2064 case INIT_INTERFACE:
2068 unregister_notifier(DEVICE_NOTIFIER_DELAYED_INIT, delayed_init_done);
2069 unregister_notifier(DEVICE_NOTIFIER_APPLICATION_BACKGROUND, display_app_background);
2070 unregister_notifier(DEVICE_NOTIFIER_APPLICATION_FOREGROUND, display_app_foreground);
2071 unregister_notifier(DEVICE_NOTIFIER_APPLICATION_TERMINATED, display_app_terminated);
2072 unregister_notifier(DEVICE_NOTIFIER_BATTERY_HEALTH, battery_health_changed);
2073 unregister_notifier(DEVICE_NOTIFIER_POWER_RESUME_FROM_ECHO_MEM, power_resume_from_echomem_callback);
2079 exit_lcd_operation();
2080 free_lock_info_list();
2082 /* free display service */
2083 display_service_free();
2085 _I("Stop power manager.");
2088 static int display_start(enum device_flags flags)
2091 if (flags & NORMAL_MODE) {
2092 if (flags & LCD_PANEL_OFF_MODE)
2094 display_panel_set_panel_state_by_standby_state(true);
2097 display_panel_set_panel_state_by_on_state(flags);
2102 /* CORE LOGIC MODE */
2103 if (!(flags & CORE_LOGIC_MODE))
2106 if (status == DEVICE_OPS_STATUS_START)
2109 if (display_probe(NULL) < 0)
2117 static int display_stop(enum device_flags flags)
2120 if (flags & NORMAL_MODE || flags & FORCE_OFF_MODE) {
2121 display_panel_set_panel_state_by_off_state(flags);
2125 /* CORE LOGIC MODE */
2126 if (!(flags & CORE_LOGIC_MODE))
2129 if (status == DEVICE_OPS_STATUS_STOP)
2137 static int display_status(void)
2142 static const struct device_ops display_plugin_device_ops = {
2143 .disable_auto_init = true,
2144 DECLARE_NAME_LEN("display-plugin"),
2145 .probe = display_probe,
2146 .init = display_init,
2147 .exit = display_exit,
2148 .start = display_start,
2149 .stop = display_stop,
2150 .status = display_status,
2153 DEVICE_OPS_REGISTER(&display_plugin_device_ops)
2155 static void __CONSTRUCTOR__ initialize(void)
2157 disp_plgn = get_var_display_plugin();
2159 _E("Failed to get display plugin variable.");
2161 backlight_ops = get_var_backlight_ops();
2163 _E("Failed to get backlight operator variable.");
2165 battery_plgn = get_var_battery_plugin();
2167 _E("Failed to get battery plugin variable.");