From d134245613be47a5b31f5881f25a9591fc820517 Mon Sep 17 00:00:00 2001 From: Youngjae Cho Date: Thu, 26 May 2022 14:07:46 +0900 Subject: [PATCH 01/16] Fix dbus policy typo Change-Id: I84382003be4a4631fdabdc728a739ab755c291c6 Signed-off-by: Youngjae Cho --- conf/org.tizen.system.deviced.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/org.tizen.system.deviced.conf b/conf/org.tizen.system.deviced.conf index a548416..613a72d 100644 --- a/conf/org.tizen.system.deviced.conf +++ b/conf/org.tizen.system.deviced.conf @@ -40,7 +40,7 @@ - -- 2.7.4 From 5b385f6b415311ba8dc871e4383894f53e0ff9a2 Mon Sep 17 00:00:00 2001 From: Youngjae Cho Date: Tue, 17 May 2022 11:49:27 +0900 Subject: [PATCH 02/16] power: unify power state transition routine Previously, the iot-headless dedicated poweroff was working on top of the core poweroff routine. Integrate them into the single poweroff routine so that all type of poweroff is now take the same subroutine. In addition to this, there two internal functions have been added for deviced to trigger change power state by itself. All power state change thorugh these functions take the same subroutine. - power_request_change_state_strict() - power_request_change_state() Due to the above changes, the deviced is now able to broadcast all types of power change state in the unified manner. Therefore, if someone wants to know the power state change of deviced, just use power API. Change-Id: I6573872eb3aa7c50d2d6af575ccce4dc25cab3de Signed-off-by: Youngjae Cho --- conf/power-profile-iot-headed.conf | 7 - conf/power-profile-iot-headless.conf | 7 - conf/power-profile-mobile.conf | 7 - conf/power-profile-tv.conf | 7 - conf/power-profile-wearable.conf | 7 - plugins/iot-headed/display/core.c | 6 +- plugins/iot-headless/battery/battery-plugin.c | 6 +- plugins/iot-headless/input/input-config.c | 6 +- plugins/mobile/display/core.c | 6 +- plugins/tv/display/core.c | 6 +- plugins/tv/display/state-tv.c | 7 +- plugins/wearable/display/core.c | 6 +- src/battery/lowbat-handler.c | 13 +- src/battery/lowbat-handler.h | 3 +- src/core/main.c | 5 +- src/power/power-boot.c | 28 +- src/power/power-boot.h | 2 +- src/power/power-dbus.c | 2 +- src/power/power-off.c | 526 ++++++-------------------- src/power/power-off.h | 42 +- src/power/power-state-manager.c | 311 --------------- src/power/power-state-manager.h | 62 --- src/power/power-state-wait.c | 55 ++- src/power/power-state-wait.h | 6 +- src/power/power.c | 317 ++++++++++++++++ src/power/power.h | 101 +++++ 26 files changed, 615 insertions(+), 936 deletions(-) delete mode 100644 src/power/power-state-manager.c delete mode 100644 src/power/power-state-manager.h create mode 100644 src/power/power.c create mode 100644 src/power/power.h diff --git a/conf/power-profile-iot-headed.conf b/conf/power-profile-iot-headed.conf index ce213be..b98f41d 100644 --- a/conf/power-profile-iot-headed.conf +++ b/conf/power-profile-iot-headed.conf @@ -1,10 +1,3 @@ -[Reboot] -Option=recovery -Option=download -Option=wdownload -Option=debug -Option=silent - [PowerState] TimeoutSleepSupport=no ChangeStateMaxWaitSecond=10 diff --git a/conf/power-profile-iot-headless.conf b/conf/power-profile-iot-headless.conf index 27c6908..0001706 100644 --- a/conf/power-profile-iot-headless.conf +++ b/conf/power-profile-iot-headless.conf @@ -1,10 +1,3 @@ -[Reboot] -Option=recovery -Option=download -Option=wdownload -Option=debug -Option=silent - [PowerState] TimeoutSleepSupport=yes ChangeStateMaxWaitSecond=10 diff --git a/conf/power-profile-mobile.conf b/conf/power-profile-mobile.conf index 437c672..e659e9f 100644 --- a/conf/power-profile-mobile.conf +++ b/conf/power-profile-mobile.conf @@ -1,10 +1,3 @@ -[Reboot] -Option=recovery -Option=download -Option=wdownload -Option=debug -Option=silent - [PowerState] TimeoutSleepSupport=yes ChangeStateMaxWaitSecond=10 diff --git a/conf/power-profile-tv.conf b/conf/power-profile-tv.conf index 437c672..e659e9f 100644 --- a/conf/power-profile-tv.conf +++ b/conf/power-profile-tv.conf @@ -1,10 +1,3 @@ -[Reboot] -Option=recovery -Option=download -Option=wdownload -Option=debug -Option=silent - [PowerState] TimeoutSleepSupport=yes ChangeStateMaxWaitSecond=10 diff --git a/conf/power-profile-wearable.conf b/conf/power-profile-wearable.conf index 437c672..e659e9f 100644 --- a/conf/power-profile-wearable.conf +++ b/conf/power-profile-wearable.conf @@ -1,10 +1,3 @@ -[Reboot] -Option=recovery -Option=download -Option=wdownload -Option=debug -Option=silent - [PowerState] TimeoutSleepSupport=yes ChangeStateMaxWaitSecond=10 diff --git a/plugins/iot-headed/display/core.c b/plugins/iot-headed/display/core.c index 31d05af..cda404c 100644 --- a/plugins/iot-headed/display/core.c +++ b/plugins/iot-headed/display/core.c @@ -2040,11 +2040,11 @@ static int poweroff_triggered_callback(void *udata) int val = (int)(intptr_t) udata; switch (val) { - case POWEROFF_TYPE_NONE: + case VCONFKEY_SYSMAN_POWER_OFF_NONE: clear_pm_status_flag(PWROFF_FLAG); break; - case POWEROFF_TYPE_DIRECT: - case POWEROFF_TYPE_RESTART: + case VCONFKEY_SYSMAN_POWER_OFF_DIRECT: + case VCONFKEY_SYSMAN_POWER_OFF_RESTART: set_pm_status_flag(PWROFF_FLAG); break; } diff --git a/plugins/iot-headless/battery/battery-plugin.c b/plugins/iot-headless/battery/battery-plugin.c index 2ae0b0b..95a427d 100644 --- a/plugins/iot-headless/battery/battery-plugin.c +++ b/plugins/iot-headless/battery/battery-plugin.c @@ -25,7 +25,7 @@ #include "shared/log.h" #include "battery/battery-ops.h" -#include "power/power-state-manager.h" +#include "power/power.h" #define BATTERY_CONF_PATH "/etc/deviced/battery.conf" @@ -63,8 +63,8 @@ static void add_action_transition_info(struct battery_event_handler *handler, ch * Otherwise, handler->id won't be defined at this point.*/ ti->reason = handler->id; - ti->curr = convert_action_string_to_psm_state(curr); - ti->next = convert_action_string_to_psm_state(next); + ti->curr = convert_action_string_to_power_state(curr); + ti->next = convert_action_string_to_power_state(next); SYS_G_LIST_APPEND(*action_list, ti); } diff --git a/plugins/iot-headless/input/input-config.c b/plugins/iot-headless/input/input-config.c index faeffb8..4635159 100644 --- a/plugins/iot-headless/input/input-config.c +++ b/plugins/iot-headless/input/input-config.c @@ -29,7 +29,7 @@ #include "shared/log.h" #include "input-config.h" -#include "power/power-state-manager.h" +#include "power/power.h" #define INPUT_CONF_PATH "/etc/deviced/input.conf" @@ -137,8 +137,8 @@ static void add_action_transition_info(struct input_event_unit *ieu, char *curr, * Otherwise, ieu->id won't be defined at this point.*/ ti->reason = ieu->id; - ti->curr = convert_action_string_to_psm_state(curr); - ti->next = convert_action_string_to_psm_state(next); + ti->curr = convert_action_string_to_power_state(curr); + ti->next = convert_action_string_to_power_state(next); SYS_G_LIST_APPEND(*action_list, ti); } diff --git a/plugins/mobile/display/core.c b/plugins/mobile/display/core.c index 3011edf..8a0a100 100644 --- a/plugins/mobile/display/core.c +++ b/plugins/mobile/display/core.c @@ -2046,11 +2046,11 @@ static int poweroff_triggered_callback(void *udata) int val = (int)(intptr_t) udata; switch (val) { - case POWEROFF_TYPE_NONE: + case VCONFKEY_SYSMAN_POWER_OFF_NONE: clear_pm_status_flag(PWROFF_FLAG); break; - case POWEROFF_TYPE_DIRECT: - case POWEROFF_TYPE_RESTART: + case VCONFKEY_SYSMAN_POWER_OFF_DIRECT: + case VCONFKEY_SYSMAN_POWER_OFF_RESTART: set_pm_status_flag(PWROFF_FLAG); break; } diff --git a/plugins/tv/display/core.c b/plugins/tv/display/core.c index 3203445..f515e7a 100644 --- a/plugins/tv/display/core.c +++ b/plugins/tv/display/core.c @@ -2037,11 +2037,11 @@ static int poweroff_triggered_callback(void *udata) int val = (int)(intptr_t) udata; switch (val) { - case POWEROFF_TYPE_NONE: + case VCONFKEY_SYSMAN_POWER_OFF_NONE: clear_pm_status_flag(PWROFF_FLAG); break; - case POWEROFF_TYPE_DIRECT: - case POWEROFF_TYPE_RESTART: + case VCONFKEY_SYSMAN_POWER_OFF_DIRECT: + case VCONFKEY_SYSMAN_POWER_OFF_RESTART: set_pm_status_flag(PWROFF_FLAG); break; } diff --git a/plugins/tv/display/state-tv.c b/plugins/tv/display/state-tv.c index 2237011..96d7331 100644 --- a/plugins/tv/display/state-tv.c +++ b/plugins/tv/display/state-tv.c @@ -26,6 +26,7 @@ #include "shared/devices.h" #include "display/display-ops.h" #include "display/display-lock.h" +#include "power/power.h" #include "power/power-off.h" #include "power/power-suspend.h" #include "core.h" @@ -490,11 +491,9 @@ static int poweroff_check(int curr, int next) static int poweroff_action(int timeout) { - static const struct device_ops *ops; + power_request_change_state(POWER_STATE_POWEROFF, 9000); - FIND_DEVICE_INT(ops, "power-state-manager"); - - return ops->execute(POWER_POWEROFF); + return 0; } static int poweroff_trans(int evt) diff --git a/plugins/wearable/display/core.c b/plugins/wearable/display/core.c index d8bfcfe..5b640a3 100644 --- a/plugins/wearable/display/core.c +++ b/plugins/wearable/display/core.c @@ -2329,11 +2329,11 @@ static int poweroff_triggered_callback(void *udata) int val = (int)(intptr_t) udata; switch (val) { - case POWEROFF_TYPE_NONE: + case VCONFKEY_SYSMAN_POWER_OFF_NONE: clear_pm_status_flag(PWROFF_FLAG); break; - case POWEROFF_TYPE_DIRECT: - case POWEROFF_TYPE_RESTART: + case VCONFKEY_SYSMAN_POWER_OFF_DIRECT: + case VCONFKEY_SYSMAN_POWER_OFF_RESTART: set_pm_status_flag(PWROFF_FLAG); break; } diff --git a/src/battery/lowbat-handler.c b/src/battery/lowbat-handler.c index 44b7fd3..3905fe9 100644 --- a/src/battery/lowbat-handler.c +++ b/src/battery/lowbat-handler.c @@ -42,6 +42,7 @@ #include "display/setting.h" #include "display/poll.h" #include "display/display-ops.h" +#include "power/power.h" #include "power/power-off.h" #include "apps/apps.h" #include "power-supply.h" @@ -149,18 +150,16 @@ static int lowbat_add_scenario(int old, int now, int (*func)(void *data)) return 0; } -static int power_execute(void *data) +static int power_execute(int state) { - static const struct device_ops *ops; - if (is_emulator()) { CRITICAL_LOG("Poweroff by lowbattery is disabled at emulator."); return 0; } - FIND_DEVICE_INT(ops, "power-state-manager"); + power_request_change_state(state, LOWBAT_POWEROFF_REASON); - return ops->execute(data); + return 0; } static int delayed_init_done(void *data) @@ -242,7 +241,7 @@ direct_launch: if (launched_poweroff == 1) { _I("Will be foreced power off."); - power_execute(POWER_POWEROFF); + power_execute(POWER_STATE_POWEROFF); return 0; } @@ -296,7 +295,7 @@ static int battery_critical_low_act(void *data) int battery_power_off_act(void *data) { CRITICAL_LOG("Low battery power off."); - return power_execute(POWER_POWEROFF); + return power_execute(POWER_STATE_POWEROFF); } int battery_charge_err_cf_act(void *data) diff --git a/src/battery/lowbat-handler.h b/src/battery/lowbat-handler.h index 26ead12..d7c5551 100644 --- a/src/battery/lowbat-handler.h +++ b/src/battery/lowbat-handler.h @@ -20,7 +20,8 @@ #ifndef __LOWBAT_HANDLER_H__ #define __LOWBAT_HANDLER_H__ -#define RETRY_MAX 5 +#define RETRY_MAX 5 +#define LOWBAT_POWEROFF_REASON 2004 int lowbat_popup(int option); void lowbat_enable_uevent_buffering(void); diff --git a/src/core/main.c b/src/core/main.c index 88a36e4..1f77e48 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -31,6 +31,7 @@ #include "log.h" #include "shared/common.h" #include "shared/devices.h" +#include "power/power.h" #include "power/power-boot.h" #include "power/power-off.h" #include "shared/plugin.h" @@ -106,11 +107,11 @@ static int deviced_main(int argc, char **argv) mainloop = g_main_loop_new(NULL, FALSE); ret = poweroff_check_revived(); - if (ret) { + if (is_poweroff_state(ret)) { /* Restarted: deviced was terminated * in middle of reboot/poweroff - resume procedure */ - poweroff_request_shutdown(); + poweroff_request_shutdown(ret); return 0; } diff --git a/src/power/power-boot.c b/src/power/power-boot.c index 634dd69..f33bbd4 100644 --- a/src/power/power-boot.c +++ b/src/power/power-boot.c @@ -34,17 +34,17 @@ #include "display/display-ops.h" #include "shared/plugin.h" #include "power-doze.h" -#include "power-state-manager.h" +#include "power.h" #define SYSTEMD_DBUS_SIGNAL_SYSTEM_STARTUP_FINISHED "StartupFinished" #define SYSTEMD_DBUS_SIGNAL_USER_STARTUP_FINISHED "UserSessionStartupFinished" #define INIT_CONF_PATH "/etc/deviced/init.conf" -static struct trans_info initial_transition_info = { +static struct trans_info init_ti = { .reason = -1, - .curr = PSM_START, - .next = PSM_NORMAL, + .curr = POWER_STATE_START, + .next = POWER_STATE_NORMAL, }; static guint sig_id[2] = {0, 0}; @@ -125,19 +125,19 @@ static void parse_transition_info(const char *action) char next[16] = { 0, }; if (sscanf(action, "%15[^,],%15s", curr, next) == 2) { - initial_transition_info.curr = convert_action_string_to_psm_state(curr); - initial_transition_info.next = convert_action_string_to_psm_state(next); + init_ti.curr = convert_action_string_to_power_state(curr); + init_ti.next = convert_action_string_to_power_state(next); } } -static void parse_initial_transition_info(const struct parse_result *result) +static void parse_init_ti(const struct parse_result *result) { GList *elem; struct section_property *prop; SYS_G_LIST_FOREACH(result->props, elem, prop) { if (MATCH(prop->key, "Enum")) - initial_transition_info.reason = atoi(prop->value); + init_ti.reason = atoi(prop->value); else if (MATCH(prop->key, "Action")) parse_transition_info(prop->value); } @@ -154,27 +154,21 @@ static int parse_matching_bootreason(const struct parse_result *result, void *da SYS_G_LIST_FOREACH(result->props, elem, prop) { if (MATCH(prop->key, "BootReason") && MATCH(prop->value, bootreason)) - parse_initial_transition_info(result); + parse_init_ti(result); } return 0; } -/* the initial transition by bootreason is defined in init.conf */ -void get_initial_transition_by_bootreason(void *data) +void do_initial_transition_by_bootreason(void) { int retval; char bootreason[64] = "Unknown"; - GList **head = (GList **) data; - - if (!head) - return; retval = hal_device_board_get_boot_reason(bootreason, sizeof(bootreason)); if (retval == 0) libsys_config_parse_by_section(INIT_CONF_PATH, parse_matching_bootreason, bootreason); CRITICAL_LOG("BootReason=%s", bootreason); - - *head = g_list_append(*head, &initial_transition_info); + power_request_change_state_strict(init_ti.curr, init_ti.next, init_ti.reason, NULL); } diff --git a/src/power/power-boot.h b/src/power/power-boot.h index 7c339e0..c0fcda6 100644 --- a/src/power/power-boot.h +++ b/src/power/power-boot.h @@ -21,7 +21,7 @@ void add_delayed_init_done_handler(void *data); void remove_delayed_init_done_handler(void *data); -void get_initial_transition_by_bootreason(void *data); +void do_initial_transition_by_bootreason(void); extern int silent_boot; diff --git a/src/power/power-dbus.c b/src/power/power-dbus.c index e6ec1e9..42b4b06 100644 --- a/src/power/power-dbus.c +++ b/src/power/power-dbus.c @@ -31,7 +31,7 @@ #include "shared/device-notifier.h" #include "power-suspend.h" -#include "power-state-manager.h" +#include "power.h" #include "power-state-wait.h" #ifndef PROCESS_CHECK_TIMEOUT diff --git a/src/power/power-off.c b/src/power/power-off.c index 4f7d402..b7bb97c 100644 --- a/src/power/power-off.c +++ b/src/power/power-off.c @@ -17,6 +17,7 @@ */ #include +#include #include #include #include @@ -47,6 +48,7 @@ #include "display/core.h" #include "display/display-ops.h" #include "power-off.h" +#include "power.h" #include "apps/apps.h" #include "power-boot.h" #include "shared/plugin.h" @@ -58,51 +60,7 @@ #define POWER_CONF_FILE "/etc/deviced/power.conf" static struct timeval tv_start_poweroff; -static GList *poweroff_options_list; -static enum poweroff_type poweroff_type = POWEROFF_TYPE_REBOOT; -static GList *poweroff_handles; - -static const char *poweroff_type_flagpaths[] = { // index denotes type - [POWEROFF_TYPE_POWEROFF] = POWER_FLAG_POWEROFF, - [POWEROFF_TYPE_REBOOT] = POWER_FLAG_REBOOT, - [POWEROFF_TYPE_EXIT] = POWER_FLAG_EXIT, -}; - -static const char *poweroff_type_names[] = { // index denotes type - [POWEROFF_TYPE_POWEROFF] = POWER_POWEROFF, - [POWEROFF_TYPE_REBOOT] = POWER_REBOOT, - [POWEROFF_TYPE_EXIT] = POWER_EXIT, -}; - -enum poweroff_stage { - POWEROFF_DEFAULT, /* Default stage, poweroff has not been triggered */ - POWEROFF_TRIGGERED, /* Poweroff is triggered. Wait timer can be added up to this stage */ - POWEROFF_WAIT_OTHERS, /* Wait for other processes to clean up their resources */ -}; - static int poweroff_delay_second = 0; -static enum poweroff_stage poweroff_stage; - -static const char *poweroff_type_to_name(enum poweroff_type type) -{ - if (type <= 0 || type >= ARRAY_SIZE(poweroff_type_names)) - return NULL; - - return poweroff_type_names[type]; -} - -static enum poweroff_type poweroff_name_to_type(const char *name) -{ - if (!name) - goto out; - - for (int i = 0; i < ARRAY_SIZE(poweroff_type_names); i++) { - if (poweroff_type_names[i] && strcmp(poweroff_type_names[i], name) == 0) - return i; - } -out: - return POWEROFF_TYPE_INVALID; -} static void poweroff_start_animation(void) { @@ -173,26 +131,25 @@ static bool disable_coredump_handler(void) return is_ok; } -void poweroff_request_shutdown(void) +void poweroff_request_shutdown(int state) { - const char *systemd_poweroff_method = "Reboot"; - - if (poweroff_type == POWEROFF_TYPE_REBOOT) { - systemd_poweroff_method = "Reboot"; - } else if (poweroff_type == POWEROFF_TYPE_POWEROFF) { - systemd_poweroff_method = "PowerOff"; - } else if (poweroff_type == POWEROFF_TYPE_EXIT) { - systemd_poweroff_method = "Exit"; - } else { - _E("Invalid poweroff type=%d", poweroff_type); + const char *systemd_method = "PowerOff"; + + if (!is_poweroff_state(state)) return; - } - CRITICAL_LOG("Requested %s via systemd.", systemd_poweroff_method); + if (state == POWER_STATE_POWEROFF) + systemd_method = "PowerOff"; + else if (state == POWER_STATE_REBOOT) + systemd_method = "Reboot"; + else if (state == POWER_STATE_EXIT) + systemd_method = "Exit"; + + CRITICAL_LOG("Requested %s via systemd.", systemd_method); gdbus_call_sync_with_reply_timeout(SYSTEMD_DBUS_DEST, SYSTEMD_DBUS_PATH, SYSTEMD_DBUS_IFACE_MANAGER, - systemd_poweroff_method, + systemd_method, NULL, NULL, POWEROFF_WAIT_SYSTEMD_MS); @@ -231,158 +188,90 @@ static void poweroff_delay_for_seconds(void) watchdog_notify(); } -void poweroff_prepare(void) -{ - if (poweroff_type == POWEROFF_TYPE_POWEROFF) - CRITICAL_LOG("Prepare PowerOff."); - else if (poweroff_type == POWEROFF_TYPE_REBOOT) - CRITICAL_LOG("Prepare Reboot."); - - poweroff_notify_resourced(); - disable_systemd_journald(); - disable_coredump_handler(); - poweroff_delay_for_seconds(); - disable_display(); - - /* Below functions follow after notifying DEVICE_NOTIFIER_POWEROFF - 1. pmlock - - pmlock_detector_poweroff_cb() - - cleanup_pmlock_statistics() - - do_copy_force() - - save_display_log() - 2. tzip - - tzip_poweroff() - - tzip_server_exit() - 3. udev - - device_change_poweroff() - - uevent_control_stop() - */ - device_notify_once(DEVICE_NOTIFIER_POWEROFF, (void *)(intptr_t) poweroff_type); -} - int poweroff_check_revived(void) { - if (access(POWER_FLAG_POWEROFF, F_OK) == 0) { - poweroff_type = POWEROFF_TYPE_POWEROFF; - return 1; + if (access(POWEROFF_OPTPATH_POWEROFF, F_OK) == 0) { + return POWER_STATE_POWEROFF; } - if (access(POWER_FLAG_REBOOT, F_OK) == 0) { - poweroff_type = POWEROFF_TYPE_REBOOT; - return 1; + if (access(POWEROFF_OPTPATH_REBOOT, F_OK) == 0) { + return POWER_STATE_REBOOT; } - if (access(POWER_FLAG_EXIT, F_OK) == 0) { - poweroff_type = POWEROFF_TYPE_EXIT; - return 1; + if (access(POWEROFF_OPTPATH_EXIT, F_OK) == 0) { + return POWER_STATE_EXIT; } - return 0; + return POWER_STATE_NORMAL; } -static void mark_poweroff_option(struct power_option *opt) +static void mark_poweroff_option(const struct trans_info *ti) { - const char *path; int fd; ssize_t len; - - if (!opt) - return; - - enum poweroff_type type = opt->type; - const char *option = opt->option; - - if (type <= 0 || type >= ARRAY_SIZE(poweroff_type_flagpaths)) + const char *optpath; + const char *option; + + if (ti->next == POWER_STATE_POWEROFF) + optpath = POWEROFF_OPTPATH_POWEROFF; + else if (ti->next == POWER_STATE_REBOOT) + optpath = POWEROFF_OPTPATH_REBOOT; + else if (ti->next == POWER_STATE_EXIT) + optpath = POWEROFF_OPTPATH_EXIT; + else return; - path = poweroff_type_flagpaths[type]; - if (!path) - return; + option = (char *) ti->data; - fd = open(path, O_RDWR|O_CREAT, S_IRUSR | S_IWUSR); + fd = open(optpath, O_RDWR|O_CREAT, S_IRUSR | S_IWUSR); if (fd < 0) { - _E("Failed to create '%s'.", path); + _E("Failed to create '%s'.", optpath); return; } - if (option) { - len = write(fd, option, strlen(option)); - if (len <= 0) - _E("Failed to store option: %zd", len < 0 ? errno : len); - } + len = option ? write(fd, option, strlen(option)) : 0; + if (len < 0) + _E("Failed to store option: %zd", len < 0 ? errno : len); close(fd); } -static void poweroff_remove_handle(pid_t pid) -{ - struct poweroff_handle *handle; - GList *elem; - - SYS_G_LIST_FOREACH(poweroff_handles, elem, handle) { - if (handle->pid == pid) - break; - } - - assert(handle); - - _D("Remove handle pid=%d(%s) timeout=%d timeout_id=%d.", handle->pid, handle->comm, handle->timeout, handle->timeout_id); - SYS_G_LIST_REMOVE(poweroff_handles, handle); - - if (handle->timeout_id) { - g_source_remove(handle->timeout_id); - handle->timeout = 0; - handle->timeout_id = 0; - } - - free(handle); -} - -static int poweroff_add_handle(pid_t pid) -{ - struct poweroff_handle *handle; - GList *l; - - SYS_G_LIST_FOREACH(poweroff_handles, l, handle) { - if (handle->pid == pid) - break; - } - - if (handle) - poweroff_remove_handle(pid); - - _D("Make a new handle."); - handle = (struct poweroff_handle *)malloc(sizeof(struct poweroff_handle)); - if (handle == NULL) { - _E("Not enough memory."); - return -ENOMEM; - } - - handle->pid = pid; - handle->timeout_id = 0; - handle->timeout = POWEROFF_WAIT_MAX; - get_command(pid, handle->comm, sizeof(handle->comm)); - - SYS_G_LIST_APPEND(poweroff_handles, handle); - _D("Add a new poweroff timer. pid=%d(%s) timeout=%d", handle->pid, handle->comm, handle->timeout); - - return 0; -} - static gboolean __poweroff_main(gpointer data) { - CRITICAL_LOG("Starting poweroff sequence."); + int state = (int)(intptr_t) data; + + CRITICAL_LOG("Starting poweroff sequence"); // Watchdog timeout 90 -> 30 sec to reduce delay from unexpected poweroff failure. sd_notifyf(0, "WATCHDOG_USEC=%llu", (unsigned long long)POWEROFF_WAIT_SYSTEMD_MS*1000); - poweroff_prepare(); - poweroff_request_shutdown(); + poweroff_notify_resourced(); + disable_systemd_journald(); + disable_coredump_handler(); + poweroff_delay_for_seconds(); + disable_display(); + + /* Below functions follow after notifying DEVICE_NOTIFIER_POWEROFF + 1. pmlock + - pmlock_detector_poweroff_cb() + - cleanup_pmlock_statistics() + - do_copy_force() + - save_display_log() + 2. tzip + - tzip_poweroff() + - tzip_server_exit() + 3. udev + - device_change_poweroff() + - uevent_control_stop() + */ + device_notify_once(DEVICE_NOTIFIER_POWEROFF, data); + + poweroff_request_shutdown(state); return G_SOURCE_REMOVE; } -static void poweroff_main(void) +void poweroff_main(void *udata) { static guint poweroff_id = 0; @@ -392,61 +281,7 @@ static void poweroff_main(void) /* Terminate this subroutine at this point. The procedure returns to the caller, therefore * the RemovePowerOffWait caller would not be blocked, if they invoked method synchronously. * And the deviced enter poweroff_main on the next gmainloop iteration. */ - poweroff_id = g_idle_add(__poweroff_main, NULL); -} - -static gboolean poweroff_wait_timeout_cb(void *data) -{ - pid_t pid = (pid_t)((intptr_t)data); - - poweroff_remove_handle(pid); - - if (poweroff_stage < POWEROFF_WAIT_OTHERS) - return G_SOURCE_REMOVE; - - /* All other processes finished cleanup. Poweroff is now on standby */ - if (SYS_G_LIST_LENGTH(poweroff_handles) == 0) { - _D("The last poweroff wait timer for pid %d is expired. Poweroff is now on standby.", pid); - poweroff_main(); - } else { - _D("Poweroff wait timer for pid %d is expired, but keep waiting for others...", pid); - } - - return G_SOURCE_REMOVE; -} - -static gboolean poweroff_start_timers(void *data) -{ - struct poweroff_handle *handle = NULL; - GList *l, *l_next; - bool timer_exist = false; - - _D("POWEROFF_STAGE=WAIT_OTHERS"); - poweroff_stage = POWEROFF_WAIT_OTHERS; - - SYS_G_LIST_FOREACH_SAFE(poweroff_handles, l, l_next, handle) { - if (kill(handle->pid, 0) == -1) { - _D("Pid=%d(%s) is dead.", handle->pid, handle->comm); - SYS_G_LIST_REMOVE(poweroff_handles, handle); - continue; - } - - _D("Run timer, pid=%d(%s) timeout=%d", handle->pid, handle->comm, handle->timeout); - - handle->timeout_id = g_timeout_add_seconds(handle->timeout, - poweroff_wait_timeout_cb, - (void *)((intptr_t)(handle->pid))); - - timer_exist = true; - } - - if (timer_exist) - return G_SOURCE_REMOVE; - - // No need to wait. Strat main poweroff procedure immediately. - poweroff_main(); - - return G_SOURCE_REMOVE; + poweroff_id = g_idle_add(__poweroff_main, udata); } static void system_shutdown_send_system_event(void) @@ -459,87 +294,32 @@ static void system_shutdown_send_system_event(void) bundle_free(b); } -static void poweroff_send_broadcast(int status) +void poweroff_prepare(const struct trans_info *ti) { - static int old = 0; - int ret_dbus; + int vconf = VCONFKEY_SYSMAN_POWER_OFF_NONE; - if (old == status) + if (!is_poweroff_state(ti->next)) return; - _D("Broadcast poweroff %d.", status); - - old = status; + mark_poweroff_option(ti); - /* Need to notify to deviced-vibrator. deviced-vibrator receives ChangeState signal for POWEROFF_TYPE_DIRECT and POWEROFF_TYPE_RESTART */ - ret_dbus = gdbus_signal_emit(NULL, - DEVICED_PATH_POWEROFF, - DEVICED_INTERFACE_POWEROFF, - SIGNAL_POWEROFF_STATE, - g_variant_new("(i)", status)); - if (ret_dbus < 0) - _E("Failed to send dbus signal(%s)", SIGNAL_POWEROFF_STATE); -} - -static int __poweroff_trigger_poweroff(const char *typename, const char *option) -{ - int ret_val; - GList *l; - struct power_option *opt = NULL; + if (ti->next == POWER_STATE_POWEROFF) + vconf = VCONFKEY_SYSMAN_POWER_OFF_DIRECT; + else if (ti->next == POWER_STATE_REBOOT) + vconf = VCONFKEY_SYSMAN_POWER_OFF_RESTART; + vconf_set_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, vconf); - if (poweroff_stage >= POWEROFF_TRIGGERED) { - _E("Duplicate poweroff request. Poweroff was already triggered."); - return -EINVAL; - } - - enum poweroff_type type = poweroff_name_to_type(typename); - if (type == POWEROFF_TYPE_INVALID) { - _E("Failed to get type enum value(%d).", type); - return -EINVAL; - } - - poweroff_type = type; - - if (option) { - SYS_G_LIST_FOREACH(poweroff_options_list, l, opt) { - if (opt->type == type && strncmp(opt->option, option, sizeof(opt->option)) == 0) - break; - } - - /* It writes option onto file /run/reboot. - * The deviced shutdown binary, which is exec of systemd, refers the file. */ - if (opt) - mark_poweroff_option(opt); - } - - ret_val = vconf_set_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, type); - if (ret_val < 0) - _E("Failed to set vconf value for power off status: %d", vconf_get_ext_errno()); - - _D("POWEROFF_STAGE=TRIGGERED"); - poweroff_stage = POWEROFF_TRIGGERED; power_disable_autosleep(); - device_notify_once(DEVICE_NOTIFIER_POWEROFF_TRIGGERED, (void *)(intptr_t) type); + device_notify_once(DEVICE_NOTIFIER_POWEROFF_TRIGGERED, (void *)(intptr_t) vconf); /* Poweroff event broadcasting */ system_shutdown_send_system_event(); - poweroff_send_broadcast(type); - - /* Skip running animation if option is silent */ - if (opt && strncmp(opt->option, "silent", sizeof("silent")) == 0) - _D("Skip running poweroff animation."); - else - poweroff_start_animation(); - - /* Spare time for AddPowerOffWait requests */ - g_timeout_add_seconds(1, poweroff_start_timers, NULL); - return 0; -} + /* Skip running animation if it is silent reboot */ + if (ti->data && strncmp(ti->data, "silent", sizeof("silent")) == 0) + return; -int poweroff_trigger_poweroff(void *data) -{ - return __poweroff_trigger_poweroff((char *)data, NULL); + poweroff_start_animation(); } static int check_sender_process(GDBusConnection *conn, const char *sender) @@ -560,15 +340,16 @@ static int check_sender_process(GDBusConnection *conn, const char *sender) return pid; } -static GVariant *dbus_power_handler(GDBusConnection *conn, +static GVariant *dbus_poweroff_handler(GDBusConnection *conn, const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) { int ret; char comm[128] = "Unknown"; - char *type_str; + char *type; + int next; - g_variant_get(param, "(s)", &type_str); + g_variant_get(param, "(s)", &type); ret = check_sender_process(conn, sender); if (ret < 0) @@ -576,21 +357,33 @@ static GVariant *dbus_power_handler(GDBusConnection *conn, get_command(ret, comm, sizeof(comm)); - CRITICAL_LOG("Poweroff pid=%d(%s) requests %s.", ret, comm, type_str); - ret = __poweroff_trigger_poweroff(type_str, NULL); + if (strncmp(type, "poweroff", sizeof("poweroff")) == 0) + next = POWER_STATE_POWEROFF; + else if (strncmp(type, "reboot", sizeof("reboot")) == 0) + next = POWER_STATE_REBOOT; + else if (strncmp(type, "exit", sizeof("exit")) == 0) + next = POWER_STATE_EXIT; + else { + ret = -EINVAL; + goto out; + } + + CRITICAL_LOG("Poweroff pid=%d(%s) requests %s.", ret, comm, type); + power_request_change_state_strict(POWER_STATE_ALL, next, 9000, NULL); out: - g_free(type_str); + g_free(type); return g_variant_new("(i)", ret); } -static GVariant *dbus_power_option_handler(GDBusConnection *conn, +static GVariant *dbus_poweroff_option_handler(GDBusConnection *conn, const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) { int ret; char comm[128] = "Unknown"; char *type, *option; + int next; g_variant_get(param, "(ss)", &type, &option); @@ -600,8 +393,19 @@ static GVariant *dbus_power_option_handler(GDBusConnection *conn, get_command(ret, comm, sizeof(comm)); + if (strncmp(type, "poweroff", sizeof("poweroff")) == 0) + next = POWER_STATE_POWEROFF; + else if (strncmp(type, "reboot", sizeof("reboot")) == 0) + next = POWER_STATE_REBOOT; + else if (strncmp(type, "exit", sizeof("exit")) == 0) + next = POWER_STATE_EXIT; + else { + ret = -EINVAL; + goto out; + } + CRITICAL_LOG("Poweroff pid=%d(%s) requests type=%s option=%s.", ret, comm, type, option); - ret = __poweroff_trigger_poweroff(type, option); + power_request_change_state_strict(POWER_STATE_ALL, next, 9000, option); out: g_free(type); @@ -609,70 +413,26 @@ out: return g_variant_new("(i)", ret); } -/* timer can be added before the stage POWEROFF_WAIT_OTHERS */ static GVariant *add_poweroff_time(GDBusConnection *conn, const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) { - int ret; - pid_t pid; - - if (poweroff_stage >= POWEROFF_WAIT_OTHERS) { - _E("It's too late. Poweroff is already in waiting stage."); - ret = -1; - goto out; - } - - ret = check_sender_process(conn, sender); - if (ret < 0) - goto out; - - pid = (pid_t)ret; - ret = poweroff_add_handle(pid); - -out: - return g_variant_new("(i)", ret); + return g_variant_new("(i)", 0); } static GVariant *remove_poweroff_time(GDBusConnection *conn, const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) { - struct poweroff_handle *handle; - GList *l, *l_next; - int ret = 0; - pid_t pid; - - ret = check_sender_process(conn, sender); - if (ret < 0) - goto out; - - pid = (pid_t)ret; - - SYS_G_LIST_FOREACH_SAFE(poweroff_handles, l, l_next, handle) { - if (handle->pid == pid) { - _D("Removed poweroff timer. pid=%d(%s)", handle->pid, handle->comm); - SYS_G_LIST_REMOVE(poweroff_handles, handle); - break; - } - } - - if (poweroff_stage == POWEROFF_WAIT_OTHERS && SYS_G_LIST_LENGTH(poweroff_handles) == 0) - poweroff_main(); - -out: - return g_variant_new("(i)", ret); + return g_variant_new("(i)", 0); } static const dbus_method_s dbus_methods[] = { - { "PowerOff" , "s" , "i", dbus_power_handler }, - { "PowerOffWithOption", "ss", "i", dbus_power_option_handler }, + { "PowerOff" , "s" , "i", dbus_poweroff_handler }, + { "PowerOffWithOption", "ss", "i", dbus_poweroff_option_handler }, /* Public API device_power_reboot() calls this dbus method. */ - { "AddPowerOffWait" , NULL, "i", add_poweroff_time }, - /* It is recommended to invoke RemovePowerOffWait by async as the invocation - * could be the last removal of poweroff waitings. And if it is, the deviced - * immediately fall into poweroff main sequence without returning to the caller. */ - { "RemovePowerOffWait", NULL, "i", remove_poweroff_time }, + { "AddPowerOffWait" , NULL, "i", add_poweroff_time }, /* deprecated */ + { "RemovePowerOffWait", NULL, "i", remove_poweroff_time }, /* deprecated */ /* Add methods here */ }; @@ -683,51 +443,9 @@ static const dbus_interface_u dbus_interface = { .nr_methods = ARRAY_SIZE(dbus_methods), }; -static int add_poweroff_option(enum poweroff_type type, const char *option) -{ - struct power_option *opt; - const char *name; - - name = poweroff_type_to_name(type); - if (!name) { - _E("Invalid type(%d).", type); - return -EINVAL; - } - - opt = calloc(1, sizeof(struct power_option)); - if (!opt) { - _E("Failed to calloc()."); - return -ENOMEM; - } - - opt->type = type; - if (option) - strncpy(opt->option, option, sizeof(opt->option) - 1); - - SYS_G_LIST_APPEND(poweroff_options_list, opt); - - _D("Add %s option=%s", name, opt->option); - - return 0; -} - -int poweroff_add_wait(pid_t pid) -{ - return poweroff_add_handle(pid); -} - -void poweroff_remove_wait(pid_t pid) -{ - g_idle_add(poweroff_wait_timeout_cb, (void *)(intptr_t) pid); -} - static int load_config(struct parse_result *result, void *user_data) { - if (MATCH(result->section, "PowerOff") && MATCH(result->name, "Option")) { - add_poweroff_option(POWEROFF_TYPE_POWEROFF, result->value); - } else if (MATCH(result->section, "Reboot") && MATCH(result->name, "Option")) { - add_poweroff_option(POWEROFF_TYPE_REBOOT, result->value); - } else if (MATCH(result->section, "PowerState") && MATCH(result->name, "PowerOffDelaySecond")) { + if (MATCH(result->section, "PowerState") && MATCH(result->name, "PowerOffDelaySecond")) { sscanf(result->value, "%d", &poweroff_delay_second); } @@ -759,13 +477,7 @@ void power_off_init(void) register_notifier(DEVICE_NOTIFIER_DELAYED_INIT, delayed_init_done); - add_poweroff_option(POWEROFF_TYPE_POWEROFF, NULL); - add_poweroff_option(POWEROFF_TYPE_RESTART, NULL); - add_poweroff_option(POWEROFF_TYPE_EXIT, NULL); - ret_val = config_parse(POWER_CONF_FILE, load_config, NULL); if (ret_val < 0) _E("Failed to load power off config: %d", ret_val); - - poweroff_stage = POWEROFF_DEFAULT; } diff --git a/src/power/power-off.h b/src/power/power-off.h index c6f8ebf..a3c3466 100644 --- a/src/power/power-off.h +++ b/src/power/power-off.h @@ -19,6 +19,7 @@ #ifndef __DEVICED_POWER_OFF_H__ #define __DEVICED_POWER_OFF_H__ +#include "power.h" #include #define POWER_POWEROFF "poweroff" @@ -26,43 +27,14 @@ #define POWER_OFF_POPUP "pwroff-popup" #define POWER_EXIT "exit" -#define POWER_FLAG_POWEROFF "/run/"POWER_POWEROFF -#define POWER_FLAG_REBOOT "/run/"POWER_REBOOT -#define POWER_FLAG_EXIT "/run/deviced-shutdown-exit" - -// 0: None -// 1: Power Off Popup is launched (not supported since Tizen5.5) -// 2: Poweroff -// 3: Restart -// 4: Exit -enum poweroff_type { - POWEROFF_TYPE_INVALID = 0, - POWEROFF_TYPE_NONE = POWEROFF_TYPE_INVALID, // compat only - POWEROFF_TYPE_POWEROFF = 2, - POWEROFF_TYPE_DIRECT = POWEROFF_TYPE_POWEROFF, // compat only - POWEROFF_TYPE_REBOOT, - POWEROFF_TYPE_RESTART = POWEROFF_TYPE_REBOOT, // compat only - POWEROFF_TYPE_EXIT, -}; - -struct power_option { - enum poweroff_type type; - char option[32]; -}; - -struct poweroff_handle { - pid_t pid; - int timeout; - char comm[128]; - guint timeout_id; -}; +#define POWEROFF_OPTPATH_POWEROFF "/run/"POWER_POWEROFF +#define POWEROFF_OPTPATH_REBOOT "/run/"POWER_REBOOT +#define POWEROFF_OPTPATH_EXIT "/run/deviced-shutdown-exit" void power_off_init(void); - -int poweroff_trigger_poweroff(void *data); int poweroff_check_revived(void); -void poweroff_request_shutdown(void); -int poweroff_add_wait(pid_t pid); -void poweroff_remove_wait(pid_t pid); +void poweroff_request_shutdown(int state); +void poweroff_prepare(const struct trans_info *ti); +void poweroff_main(void *udata); #endif /* __DEVICED_POWER_OFF_H__ */ diff --git a/src/power/power-state-manager.c b/src/power/power-state-manager.c deleted file mode 100644 index 52c622c..0000000 --- a/src/power/power-state-manager.c +++ /dev/null @@ -1,311 +0,0 @@ -/* - * deviced - * - * Copyright (c) 2022 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include -#include - -#include "shared/devices.h" -#include "shared/device-notifier.h" -#include "shared/log.h" -#include "power-state-manager.h" -#include "power-suspend.h" -#include "power-dbus.h" -#include "power-boot.h" -#include "power-off.h" -#include "power-state-wait.h" -#include "power-event-lock.h" - -#define EVENT_TYPE_SLEEP 0 -#define EVENT_TYPE_WAKEUP 1 - -char *psm_name[PSM_MAX] = { - [PSM_START] = "PSM_START", - [PSM_NORMAL] = "PSM_NORMAL", - [PSM_SLEEP] = "PSM_SLEEP", - [PSM_POWEROFF] = "PSM_POWEROFF", - [PSM_REBOOT] = "PSM_REBOOT", -}; - -static int delayed_init_done = 0; -static guint64 state_transition_counter = 0; -static enum psm_state current = PSM_START; - -/* hold trans_info until delayed_init_done */ -static GList *deferred_transition_list; - -static void psm_wake_unlock(void) -{ - /* for PSM_NORMAL, PSM_POWEROFF, do not wake unlock */ - if (current != PSM_SLEEP) { - _E("Ignore sleep wait done, current=%s", psm_name[current]); - return; - } - - power_release_wakelock(); -} - -static void psm_trigger_poweroff(void) -{ - poweroff_trigger_poweroff("poweroff"); -} - -static void broadcast_transition_info(const struct trans_info *ti) -{ - // mapping deviced state to capi signame - static const char *capi_signame[PSM_MAX] = { - [PSM_START] = SIGNAME_CHANGE_STATE_TO_START, - [PSM_NORMAL] = SIGNAME_CHANGE_STATE_TO_NORMAL, - [PSM_SLEEP] = SIGNAME_CHANGE_STATE_TO_SLEEP, - [PSM_POWEROFF] = SIGNAME_CHANGE_STATE_TO_POWEROFF, - [PSM_REBOOT] = SIGNAME_CHANGE_STATE_TO_REBOOT, - }; - - // mapping deviced state to capi state - static const guint64 capi_state[PSM_MAX] = { - [PSM_START] = POWER_STATE_START, - [PSM_NORMAL] = POWER_STATE_NORMAL, - [PSM_SLEEP] = POWER_STATE_SLEEP, - [PSM_POWEROFF] = POWER_STATE_POWEROFF, - [PSM_REBOOT] = POWER_STATE_REBOOT, - }; - - gdbus_signal_emit(NULL, DEVICED_PATH_POWER, DEVICED_INTERFACE_POWER, capi_signame[ti->next], - g_variant_new("(ttti)", capi_state[ti->curr], capi_state[ti->next], state_transition_counter, ti->reason)); -} - -static void psm_transition_start_to_normal(const struct trans_info *ti) -{ - current = PSM_NORMAL; - - power_acquire_wakelock(); - broadcast_transition_info(ti); -} - -static void psm_transition_start_to_sleep(const struct trans_info *ti) -{ - int waiting; - - current = PSM_SLEEP; - - power_acquire_wakelock(); - broadcast_transition_info(ti); - waiting = update_change_state_wait(state_transition_counter, ti, psm_wake_unlock); - if (waiting > 0) { - _D("Defer wake unlock."); - return; - } - - psm_wake_unlock(); -} - -static void psm_transition_normal_to_normal(const struct trans_info *ti) -{ - broadcast_transition_info(ti); - update_change_state_wait(state_transition_counter, ti, NULL); -} - -static void psm_transition_normal_to_sleep(const struct trans_info *ti) -{ - int waiting; - - current = PSM_SLEEP; - - broadcast_transition_info(ti); - waiting = update_change_state_wait(state_transition_counter, ti, psm_wake_unlock); - if (waiting > 0) { - _D("Defer wake unlock."); - return; - } - - psm_wake_unlock(); -} - -static void psm_transition_sleep_to_normal(const struct trans_info *ti) -{ - current = PSM_NORMAL; - - power_acquire_wakelock(); - broadcast_transition_info(ti); - update_change_state_wait(state_transition_counter, ti, NULL); -} - -static void psm_transition_sleep_to_sleep(const struct trans_info *ti) -{ - int waiting; - - power_acquire_wakelock(); - broadcast_transition_info(ti); - waiting = update_change_state_wait(state_transition_counter, ti, psm_wake_unlock); - if (waiting > 0) { - _D("Defer wake unlock."); - return; - } - - psm_wake_unlock(); -} - -static void psm_transition_normal_to_poweroff(const struct trans_info *ti) -{ - int waiting; - - current = PSM_POWEROFF; - - broadcast_transition_info(ti); - waiting = update_change_state_wait(state_transition_counter, ti, psm_trigger_poweroff); - if (waiting > 0) { - _D("Defer poweroff."); - return; - } - - psm_trigger_poweroff(); -} - -static void transition_state(const struct trans_info *ti) -{ - enum psm_state next; - - next = ti->next; - - _D("Transition power state: %s -> %s, reason=%d", - psm_name[current], psm_name[next], ti->reason); - - /* transition */ - ++state_transition_counter; - if (current == PSM_START) { - if (next == PSM_NORMAL) - psm_transition_start_to_normal(ti); - else if (next == PSM_SLEEP) - psm_transition_start_to_sleep(ti); - } else if (current == PSM_NORMAL) { - if (next == PSM_NORMAL) - psm_transition_normal_to_normal(ti); - else if (next == PSM_SLEEP) - psm_transition_normal_to_sleep(ti); - else if (next == PSM_POWEROFF) - psm_transition_normal_to_poweroff(ti); - } else if (current == PSM_SLEEP) { - if (next == PSM_NORMAL) - psm_transition_sleep_to_normal(ti); - else if (next == PSM_SLEEP) - psm_transition_sleep_to_sleep(ti); - } -} - -static void deferred_transition_state(gpointer data) -{ - transition_state(data); - free(data); -} - -static int psm_transition_state_cb(void *data) -{ - GList *action_list, *elem; - const struct trans_info *ti = NULL; - - if (!data) - return 0; - - action_list = (GList *) data; - - /* look for transition defined on the current state */ - SYS_G_LIST_FOREACH(action_list, elem, ti) { - if (ti->curr == current) - break; - } - - if (!ti) - return 0; - - /* defer state transition until delayed_init_done */ - if (!delayed_init_done) { - struct trans_info *deferred_ti = calloc(1, sizeof(struct trans_info)); - if (!deferred_ti) { - CRITICAL_LOG("Failed to defer transition."); - return 0; - } - - // Pseudo state transition. - current = ti->next; - - // Reserve the trans_info. - // Those are used on receiving delayed_init_done for real transitioning state. - memcpy(deferred_ti, ti, sizeof(struct trans_info)); - deferred_transition_list = g_list_append(deferred_transition_list, deferred_ti); - _D("Defer state transition %s->%s until delayed init done.", psm_name[ti->curr], psm_name[ti->next]); - - return 0; - } - - transition_state(ti); - - return 0; -} - -static int delayed_init_cb(void *data) -{ - delayed_init_done = 1; - - _D("Start deferred state transition."); - - /* rewind current state to initial state and do the deferred transition */ - current = PSM_START; - g_list_free_full(g_steal_pointer(&deferred_transition_list), deferred_transition_state); - - /* Enable autosleep at this point. - * This prevents system go suspend(autosleep) before booting done */ - _D("Finished deferred state transition. Enable autosleep."); - power_enable_autosleep(); - - return 0; -} - -void power_state_manager_init(void *data) -{ - GList *initial_ti = NULL; - - register_notifier(DEVICE_NOTIFIER_DELAYED_INIT, delayed_init_cb); - register_notifier(DEVICE_NOTIFIER_REQUEST_TRANSITION_STATE, psm_transition_state_cb); - - power_dbus_init(); - power_off_init(); - power_suspend_init(); - power_event_lock_init(); - power_state_wait_init(); - - /* Take the first transition from PSM_START. - * It is determined by bootreason to which state to transition, PSM_NORMAL or PSM_SLEEP. */ - get_initial_transition_by_bootreason(&initial_ti); - psm_transition_state_cb(initial_ti); - g_list_free(initial_ti); -} - -static const struct device_ops power_state_manager_device_ops = { - DECLARE_NAME_LEN("power-state-manager"), - .init = power_state_manager_init, - /* It should be initilalized earlier than the almost other modules so that - * it can receive and handle power request from the other modules. Therefore - * give a high enough priority. */ - .priority = 990, - .execute = poweroff_trigger_poweroff, -}; - -DEVICE_OPS_REGISTER(&power_state_manager_device_ops) diff --git a/src/power/power-state-manager.h b/src/power/power-state-manager.h deleted file mode 100644 index db3bd6b..0000000 --- a/src/power/power-state-manager.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * deviced - * - * Copyright (c) 2022 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __POWER_STATE_MANAGER_H__ -#define __POWER_STATE_MANAGER_H__ - -#include -#include - -#include "shared/log.h" - -enum psm_state { - PSM_START, - PSM_NORMAL, - PSM_SLEEP, - PSM_POWEROFF, - PSM_REBOOT, - PSM_MAX, -}; -extern char *psm_name[PSM_MAX]; - -struct trans_info { - int reason; - enum psm_state curr; - enum psm_state next; -}; - -typedef void (*psm_transfunc) (const struct trans_info *info); -void power_state_manager_init(void *data); - -static inline enum psm_state convert_action_string_to_psm_state(const char *str) -{ - if (MATCH(str, "start")) - return PSM_START; - else if (MATCH(str, "sleep")) - return PSM_SLEEP; - else if (MATCH(str, "normal")) - return PSM_NORMAL; - else if (MATCH(str, "poweroff")) - return PSM_POWEROFF; - - _W("Invalid psm_state=%s", str); - - return PSM_MAX; -} - -#endif //__POWER_STATE_MANAGER_H__ diff --git a/src/power/power-state-wait.c b/src/power/power-state-wait.c index 44b6ffb..a1c3f65 100644 --- a/src/power/power-state-wait.c +++ b/src/power/power-state-wait.c @@ -26,8 +26,8 @@ #include "shared/device-notifier.h" #include "shared/common.h" +#include "power.h" #include "power-state-wait.h" -#include "power-state-manager.h" #define POWER_CONF_FILE "/etc/deviced/power.conf" #define MAX_WAIT_SECOND 5 /* second */ @@ -44,18 +44,19 @@ struct proc_info { struct change_state_wait { struct proc_info *pi; guint64 id; - enum psm_state state; + int state; }; static GList *proc_list; static GList *waiting_list; static int max_wait_timer; -static void (*__change_state_wait_done) (void); -static enum psm_state waiting_state; +static void (*__change_state_wait_done) (void *); +static void *udata; +static int waiting_state = POWER_STATE_START; static void change_state_wait_done(void) { - _D("%s wait done", psm_name[waiting_state]); + _D("%s wait done", state_name(waiting_state)); if (max_wait_timer) { g_source_remove(max_wait_timer); @@ -63,7 +64,7 @@ static void change_state_wait_done(void) } if (__change_state_wait_done) { - __change_state_wait_done(); + __change_state_wait_done(udata); } } @@ -79,7 +80,7 @@ static gboolean max_wait_expired_cb(void *data) if (kill(csw->pi->pid, 0) != 0) csw->pi->killed = 1; else - _E("pid=%d(%s) hasn't confirmed id=%"PRIu64"(%s)", csw->pi->pid, csw->pi->comm, csw->id, psm_name[csw->state]); + _E("pid=%d(%s) hasn't confirmed id=%"PRIu64"(%s)", csw->pi->pid, csw->pi->comm, csw->id, state_name(csw->state)); waiting_list = g_list_remove_link(waiting_list, elem); g_list_free(elem); free(csw); @@ -152,7 +153,7 @@ int confirm_change_state_wait(pid_t pid, guint64 id) SYS_G_LIST_FOREACH_SAFE(waiting_list, elem, elem_next, csw) { if (csw->pi->pid == pid && csw->id == id) { - _D("pid=%d(%s) confirmed id=%"PRIu64"(%s)", csw->pi->pid, csw->pi->comm, csw->id, psm_name[csw->state]); + _D("pid=%d(%s) confirmed id=%"PRIu64"(%s)", csw->pi->pid, csw->pi->comm, csw->id, state_name(csw->state)); waiting_list = g_list_remove_link(waiting_list, elem); g_list_free(elem); free(csw); @@ -167,29 +168,12 @@ int confirm_change_state_wait(pid_t pid, guint64 id) return 0; } -static int check_proc_requested_wait_for_state(struct proc_info *pi, enum psm_state state) -{ - if (!pi) - return 0; - - if (state == PSM_NORMAL) - return (pi->state_bitmap & POWER_STATE_NORMAL); - if (state == PSM_SLEEP) - return (pi->state_bitmap & POWER_STATE_SLEEP); - if (state == PSM_POWEROFF) - return (pi->state_bitmap & POWER_STATE_POWEROFF); - if (state == PSM_REBOOT) - return (pi->state_bitmap & POWER_STATE_REBOOT); - - return 0; -} - -int update_change_state_wait(guint64 id, const struct trans_info *ti, change_state_wait_done_cb callback) +int update_change_state_wait(guint64 id, const struct trans_info *ti, change_state_wait_done_cb callback, void *user_data) { struct proc_info *pi; struct change_state_wait *csw; GList *elem, *elem_next; - int n_waiting; + static int n_waiting = 0; // initialize timer if (max_wait_timer) { @@ -197,23 +181,29 @@ int update_change_state_wait(guint64 id, const struct trans_info *ti, change_sta max_wait_timer = 0; } + if (is_poweroff_state(waiting_state)) { + _W("No need to wait if poweroff had been triggered."); + return n_waiting; + } + // we are waiting for confirm of transition to the next state waiting_state = ti->next; - _D("%s wait is triggered, id=%"PRIu64, psm_name[waiting_state], id); + + _D("%s wait is triggered, id=%"PRIu64, state_name(waiting_state), id); // cancel all ongoing csw that is not a waiting for the next state SYS_G_LIST_FOREACH_SAFE(waiting_list, elem, elem_next, csw) { - if (csw->state != waiting_state) { + if ((csw->state & waiting_state) == 0) { waiting_list = g_list_remove_link(waiting_list, elem); g_list_free(elem); - _D("Cancel waiting: pid=%d(%s) for id=%"PRIu64"(%s)", csw->pi->pid, csw->pi->comm, csw->id, psm_name[csw->state]); + _D("Cancel waiting: pid=%d(%s) for id=%"PRIu64"(%s)", csw->pi->pid, csw->pi->comm, csw->id, state_name(csw->state)); free(csw); } } // add wait list SYS_G_LIST_FOREACH(proc_list, elem, pi) { - if (check_proc_requested_wait_for_state(pi, waiting_state)) { + if (pi->state_bitmap & waiting_state) { csw = calloc(1, sizeof(struct change_state_wait)); if (!csw) continue; @@ -227,12 +217,13 @@ int update_change_state_wait(guint64 id, const struct trans_info *ti, change_sta n_waiting = SYS_G_LIST_LENGTH(waiting_list); if (n_waiting == 0) { - _D("There were no csw requests for %s, skip waiting", psm_name[waiting_state]); + _D("There were no csw requests for %s, skip waiting", state_name(waiting_state)); __change_state_wait_done = NULL; return 0; } __change_state_wait_done = callback; + udata = user_data; _D("The number of pending wait confirm=%d", n_waiting); max_wait_timer = g_timeout_add_seconds(max_wait_timeout, max_wait_expired_cb, NULL); diff --git a/src/power/power-state-wait.h b/src/power/power-state-wait.h index 9fc7359..3a2660f 100644 --- a/src/power/power-state-wait.h +++ b/src/power/power-state-wait.h @@ -20,14 +20,14 @@ #define __POWER_STATE_WAIT_H__ #include -#include "power-state-manager.h" +#include "power.h" -typedef void (*change_state_wait_done_cb) (void); +typedef void (*change_state_wait_done_cb) (void *); int add_change_state_wait(pid_t pid, guint64 state); void remove_change_state_wait(pid_t pid, guint64 state); int confirm_change_state_wait(pid_t pid, guint64 id); -int update_change_state_wait(guint64 id, const struct trans_info *ti, change_state_wait_done_cb cb); +int update_change_state_wait(guint64 id, const struct trans_info *ti, change_state_wait_done_cb cb, void *user_data); void power_state_wait_init(void); #endif //__POWER_STATE_WAIT_H__ diff --git a/src/power/power.c b/src/power/power.c new file mode 100644 index 0000000..fca5ba3 --- /dev/null +++ b/src/power/power.c @@ -0,0 +1,317 @@ +/* + * deviced + * + * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include + +#include "shared/devices.h" +#include "shared/device-notifier.h" +#include "shared/log.h" +#include "power.h" +#include "power-suspend.h" +#include "power-dbus.h" +#include "power-boot.h" +#include "power-off.h" +#include "power-state-wait.h" +#include "power-event-lock.h" + +#define EVENT_TYPE_SLEEP 0 +#define EVENT_TYPE_WAKEUP 1 + +static int delayed_init_done = 0; +static uint64_t state_transition_counter = 0; +static uint64_t current = POWER_STATE_START; + +/* hold trans_info until delayed_init_done */ +static GList *deferred_transition_list; + +static int power_transition_state(void *data); + +static void power_wake_unlock(void *udata) +{ + /* for POWER_STATE_NORMAL, POWER_STATE_POWEROFF, do not wake unlock */ + if (current != POWER_STATE_SLEEP) { + _E("Ignore sleep wait done, current=%s", state_name(current)); + return; + } + + power_release_wakelock(); +} + +static void broadcast_transition_info(const struct trans_info *ti) +{ + const char *signame; + + if (ti->next == POWER_STATE_START) + signame = SIGNAME_CHANGE_STATE_TO_START; + else if (ti->next == POWER_STATE_NORMAL) + signame = SIGNAME_CHANGE_STATE_TO_NORMAL; + else if (ti->next == POWER_STATE_SLEEP) + signame = SIGNAME_CHANGE_STATE_TO_SLEEP; + else if (ti->next == POWER_STATE_POWEROFF) + signame = SIGNAME_CHANGE_STATE_TO_POWEROFF; + else if (ti->next == POWER_STATE_REBOOT) + signame = SIGNAME_CHANGE_STATE_TO_REBOOT; + else if (ti->next == POWER_STATE_EXIT) + signame = SIGNAME_CHANGE_STATE_TO_EXIT; + else + return; + + gdbus_signal_emit(NULL, DEVICED_PATH_POWER, DEVICED_INTERFACE_POWER, signame, + g_variant_new("(ttti)", ti->curr, ti->next, state_transition_counter, ti->reason)); +} + +static void power_transition_start_to_normal(const struct trans_info *ti) +{ + current = POWER_STATE_NORMAL; + + power_acquire_wakelock(); + broadcast_transition_info(ti); +} + +static void power_transition_start_to_sleep(const struct trans_info *ti) +{ + int waiting; + + current = POWER_STATE_SLEEP; + + power_acquire_wakelock(); + broadcast_transition_info(ti); + waiting = update_change_state_wait(state_transition_counter, ti, power_wake_unlock, NULL); + if (waiting > 0) { + _D("Defer wake unlock."); + return; + } + + power_wake_unlock(NULL); +} + +static void power_transition_normal_to_normal(const struct trans_info *ti) +{ + broadcast_transition_info(ti); + update_change_state_wait(state_transition_counter, ti, NULL, NULL); +} + +static void power_transition_normal_to_sleep(const struct trans_info *ti) +{ + int waiting; + + current = POWER_STATE_SLEEP; + + broadcast_transition_info(ti); + waiting = update_change_state_wait(state_transition_counter, ti, power_wake_unlock, NULL); + if (waiting > 0) { + _D("Defer wake unlock."); + return; + } + + power_wake_unlock(NULL); +} + +static void power_transition_sleep_to_normal(const struct trans_info *ti) +{ + current = POWER_STATE_NORMAL; + + power_acquire_wakelock(); + broadcast_transition_info(ti); + update_change_state_wait(state_transition_counter, ti, NULL, NULL); +} + +static void power_transition_sleep_to_sleep(const struct trans_info *ti) +{ + int waiting; + + power_acquire_wakelock(); + broadcast_transition_info(ti); + waiting = update_change_state_wait(state_transition_counter, ti, power_wake_unlock, NULL); + if (waiting > 0) { + _D("Defer wake unlock."); + return; + } + + power_wake_unlock(NULL); +} + +static void power_transition_to_poweroff(const struct trans_info *ti) +{ + int waiting; + + _D("Transition power state: %s -> %s, option=%s, reason=%d", + state_name(ti->curr), state_name(ti->next), (char *) ti->data, ti->reason); + + current = ti->next; + + // do not transition anymore after poweroff + unregister_notifier(DEVICE_NOTIFIER_REQUEST_TRANSITION_STATE, power_transition_state); + + poweroff_prepare(ti); + broadcast_transition_info(ti); + waiting = update_change_state_wait(state_transition_counter, ti, poweroff_main, (void *)(intptr_t) ti->next); + if (waiting > 0) { + _D("Defer poweroff."); + return; + } + + poweroff_main((void *)(intptr_t) ti->next); +} + +static void transition_state(const struct trans_info *ti) +{ + int next; + struct trans_info __ti = { 0, }; + + if (ti->curr == POWER_STATE_ALL) { + /* replace POWER_STATE_ALL to the current state */ + memcpy(&__ti, ti, sizeof(struct trans_info)); + __ti.curr = current; + ti = &__ti; + } + + _D("Transition power state: %s -> %s, reason=%d", + state_name(ti->curr), state_name(ti->next), ti->reason); + + next = ti->next; + + /* transition */ + ++state_transition_counter; + if (current == POWER_STATE_START) { + if (next == POWER_STATE_NORMAL) + power_transition_start_to_normal(ti); + else if (next == POWER_STATE_SLEEP) + power_transition_start_to_sleep(ti); + else if (is_poweroff_state(next)) + power_transition_to_poweroff(ti); + } else if (current == POWER_STATE_NORMAL) { + if (next == POWER_STATE_NORMAL) + power_transition_normal_to_normal(ti); + else if (next == POWER_STATE_SLEEP) + power_transition_normal_to_sleep(ti); + else if (is_poweroff_state(next)) + power_transition_to_poweroff(ti); + } else if (current == POWER_STATE_SLEEP) { + if (next == POWER_STATE_NORMAL) + power_transition_sleep_to_normal(ti); + else if (next == POWER_STATE_SLEEP) + power_transition_sleep_to_sleep(ti); + else if (is_poweroff_state(next)) + power_transition_to_poweroff(ti); + } +} + +static void deferred_transition_state(gpointer data) +{ + transition_state(data); + free(data); +} + +static int power_transition_state(void *data) +{ + GList *ti_list, *elem; + const struct trans_info *ti = NULL; + + if (!data) + return 0; + + ti_list = (GList *) data; + + // look for trans_info defined on the current state + SYS_G_LIST_FOREACH(ti_list, elem, ti) { + if (ti->curr & current) + break; + } + + if (!ti) + return 0; + + // defer state transition until delayed_init_done unless it is transition to poweroff. + // poweroff shall be handled immediately regardless of the delayed_init_done. + if (!delayed_init_done && !is_poweroff_state(ti->next)) { + struct trans_info *deferred_ti = calloc(1, sizeof(struct trans_info)); + if (!deferred_ti) { + CRITICAL_LOG("Failed to defer transition."); + return 0; + } + + // Pseudo state transition. + current = ti->next; + + // Reserve the trans_info. + // Those are used on receiving delayed_init_done for real transitioning state. + memcpy(deferred_ti, ti, sizeof(struct trans_info)); + deferred_transition_list = g_list_append(deferred_transition_list, deferred_ti); + _D("Defer state transition %s->%s until delayed init done.", state_name(ti->curr), state_name(ti->next)); + + return 0; + } + + transition_state(ti); + + return 0; +} + +static int delayed_init_cb(void *data) +{ + delayed_init_done = 1; + + _D("Start deferred state transition."); + + /* rewind current state to initial state and do the deferred transition */ + current = POWER_STATE_START; + g_list_free_full(g_steal_pointer(&deferred_transition_list), deferred_transition_state); + + /* Enable autosleep at this point. + * This prevents system go suspend(autosleep) before booting done */ + _D("Finished deferred state transition. Enable autosleep."); + power_enable_autosleep(); + + return 0; +} + +void power_state_init(void *data) +{ + register_notifier(DEVICE_NOTIFIER_DELAYED_INIT, delayed_init_cb); + register_notifier(DEVICE_NOTIFIER_REQUEST_TRANSITION_STATE, power_transition_state); + + power_dbus_init(); + power_off_init(); + power_suspend_init(); + power_event_lock_init(); + power_state_wait_init(); + + /* Take the first transition. + * + * It is determined by bootreason to which state to transition, POWER_STATE_NORMAL or POWER_STATE_SLEEP. + * Normally, it will be transitioned to the POWER_STATE_NORMAL unless there is configuration for + * the initial state in init.conf. */ + do_initial_transition_by_bootreason(); +} + +static const struct device_ops power_state_device_ops = { + DECLARE_NAME_LEN("power-state"), + .init = power_state_init, + /* It should be initilalized earlier than the almost other modules so that + * it can receive and handle power request from the other modules. Therefore + * give a high enough priority. */ + .priority = 990, +}; + +DEVICE_OPS_REGISTER(&power_state_device_ops) diff --git a/src/power/power.h b/src/power/power.h new file mode 100644 index 0000000..366b8a4 --- /dev/null +++ b/src/power/power.h @@ -0,0 +1,101 @@ +/* + * deviced + * + * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __POWER_STATE_MANAGER_H__ +#define __POWER_STATE_MANAGER_H__ + +#include +#include +#include +#include + +#include "shared/log-macro.h" +#include "shared/device-notifier.h" + +#define POWER_STATE_NONE 0 + +struct trans_info { + uint64_t curr; + uint64_t next; + int reason; + void *data; +}; + +void power_state_manager_init(void *data); + +static inline uint64_t convert_action_string_to_power_state(const char *str) +{ + if (MATCH(str, "start")) + return POWER_STATE_START; + else if (MATCH(str, "sleep")) + return POWER_STATE_SLEEP; + else if (MATCH(str, "normal")) + return POWER_STATE_NORMAL; + else if (MATCH(str, "poweroff")) + return POWER_STATE_POWEROFF; + else if (MATCH(str, "reboot")) + return POWER_STATE_REBOOT; + else if (MATCH(str, "exit")) + return POWER_STATE_EXIT; + else if (MATCH(str, "current")) + return POWER_STATE_ALL; + + _W("Invalid power state=%s", str); + + return POWER_STATE_NONE; +} + +static inline const char *state_name(uint64_t state) +{ + if (state == POWER_STATE_START) + return "POWER_STATE_START"; + if (state == POWER_STATE_NORMAL) + return "POWER_STATE_NORMAL"; + if (state == POWER_STATE_SLEEP) + return "POWER_STATE_SLEEP"; + if (state == POWER_STATE_POWEROFF) + return "POWER_STATE_POWEROFF"; + if (state == POWER_STATE_REBOOT) + return "POWER_STATE_REBOOT"; + if (state == POWER_STATE_EXIT) + return "POWER_STATE_EXIT"; + if (state == POWER_STATE_ALL) + return "POWER_STATE_ALL"; + + return "POWER_STATE_INVALID"; +} + +static inline int is_poweroff_state(uint64_t state) +{ + return !!(state & (POWER_STATE_POWEROFF | POWER_STATE_REBOOT | POWER_STATE_EXIT)); +} + +static inline void power_request_change_state_strict(uint64_t curr, uint64_t next, int reason, void *udata) +{ + struct trans_info ti = { curr, next, reason, udata }; + GList l = { &ti, NULL, NULL }; + + device_notify(DEVICE_NOTIFIER_REQUEST_TRANSITION_STATE, &l); +} + +static inline void power_request_change_state(uint64_t next, int reason) +{ + power_request_change_state_strict(POWER_STATE_ALL, next, reason, NULL); +} + +#endif //__POWER_STATE_MANAGER_H__ -- 2.7.4 From f424fbe7817c693453725b5a9b8c6d59db967b5a Mon Sep 17 00:00:00 2001 From: Youngjae Cho Date: Tue, 31 May 2022 15:11:10 +0900 Subject: [PATCH 03/16] power: add dbus method for controlling power state Change-Id: I6973dd1fdad1e5c3c9aebbf23aa00be372cd3a1e Signed-off-by: Youngjae Cho --- src/power/power-dbus.c | 27 +++++++++++++++++++++++++++ src/power/power.c | 3 +++ 2 files changed, 30 insertions(+) diff --git a/src/power/power-dbus.c b/src/power/power-dbus.c index 42b4b06..e1f2b9c 100644 --- a/src/power/power-dbus.c +++ b/src/power/power-dbus.c @@ -287,12 +287,39 @@ out: return g_variant_new("(i)", ret); } +static GVariant *dbus_power_change_state(GDBusConnection *conn, + const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, + GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) +{ + int ret = 0; + int index; + guint64 next; + + g_variant_get(param, "(t)", &next); + + for (index = POWER_STATE_MIN_INDEX; index < POWER_STATE_MAX_INDEX; ++index) + if (next == (1UL << index)) + break; + + if (index == POWER_STATE_MAX_INDEX) { + _E("Invalid next state=%#lx", (long) index); + ret = -EINVAL; + goto out; + } + + power_request_change_state_strict(POWER_STATE_ALL, next, 9000, NULL); + +out: + return g_variant_new("(i)", ret); +} + static const dbus_method_s dbus_methods[] = { { "LockCpu", "i", "i", dbus_power_lock_cpu }, { "UnlockCpu", NULL, "i", dbus_power_unlock_cpu }, { "AddChangeStateWait", "t", "i", dbus_power_add_change_state_wait }, { "RemoveChangeStateWait", "t", NULL, dbus_power_remove_change_state_wait }, { "ConfirmChangeStateWait", "t", "i", dbus_power_confirm_change_state_wait }, + { "PowerChangeState", "t", "i", dbus_power_change_state }, /* Add methods here */ }; diff --git a/src/power/power.c b/src/power/power.c index fca5ba3..79c8a08 100644 --- a/src/power/power.c +++ b/src/power/power.c @@ -215,6 +215,9 @@ static void transition_state(const struct trans_info *ti) else if (is_poweroff_state(next)) power_transition_to_poweroff(ti); } + + if (current != ti->next) + _W("Not defined transition. The current still stays at %s", state_name(current)); } static void deferred_transition_state(gpointer data) -- 2.7.4 From c66bec1b27f8d261b8beffa84a1b32d8c8b1fc70 Mon Sep 17 00:00:00 2001 From: Youngjae Cho Date: Thu, 2 Jun 2022 14:05:27 +0900 Subject: [PATCH 04/16] power: change PowerChangeState reason to 0 Change-Id: I597f90d4ecae63b7cf645431f2ef09bb86fa02c8 Signed-off-by: Youngjae Cho --- src/power/power-dbus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/power/power-dbus.c b/src/power/power-dbus.c index e1f2b9c..3f82a3a 100644 --- a/src/power/power-dbus.c +++ b/src/power/power-dbus.c @@ -307,7 +307,7 @@ static GVariant *dbus_power_change_state(GDBusConnection *conn, goto out; } - power_request_change_state_strict(POWER_STATE_ALL, next, 9000, NULL); + power_request_change_state_strict(POWER_STATE_ALL, next, 0, NULL); out: return g_variant_new("(i)", ret); -- 2.7.4 From b1d0ee71af97e00971be70be6b8dd59f77f470ae Mon Sep 17 00:00:00 2001 From: Youngjae Cho Date: Thu, 2 Jun 2022 15:30:19 +0900 Subject: [PATCH 05/16] usb-gadget: make variable null after free The SIGABRT(heap-use-after-free) was raised. It happened rarely when the sdb is re-enabled after disabled due to unstable envrionment. (But it is unclear what the unstable envrionment is.) To prevent this, make a variable null after freeing it. Change-Id: I2218004bf2069d6f8a6c835ba8883ece22f9c75b Signed-off-by: Youngjae Cho --- src/usb-gadget/usb-gadget-cfs-ops.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/usb-gadget/usb-gadget-cfs-ops.c b/src/usb-gadget/usb-gadget-cfs-ops.c index e33fcdf..7379f52 100644 --- a/src/usb-gadget/usb-gadget-cfs-ops.c +++ b/src/usb-gadget/usb-gadget-cfs-ops.c @@ -582,6 +582,7 @@ err_no_udc: usbg_cleanup(g_cfs_client->ctx); err_usbg_init: free(g_cfs_client); + g_cfs_client = NULL; return ret; } @@ -612,6 +613,7 @@ static int usb_gadget_cfs_close(void) usbg_rm_gadget(g_cfs_client->gadget, USBG_RM_RECURSE); usbg_cleanup(g_cfs_client->ctx); free(g_cfs_client); + g_cfs_client = NULL; return 0; } -- 2.7.4 From d034560c955051be399be217152b0d37ef926fa4 Mon Sep 17 00:00:00 2001 From: Youngjae Cho Date: Tue, 3 May 2022 14:04:18 +0900 Subject: [PATCH 06/16] battery: remove unused frequency strength Change-Id: I8e0ecff76defec792b9d0f694996d49435343791 Signed-off-by: Youngjae Cho --- src/battery/power-supply.c | 82 ++++------------------------------------------ src/battery/power-supply.h | 2 -- tests/auto-test/battery.c | 15 ++------- 3 files changed, 9 insertions(+), 90 deletions(-) diff --git a/src/battery/power-supply.c b/src/battery/power-supply.c index ace82a3..214d1b3 100644 --- a/src/battery/power-supply.c +++ b/src/battery/power-supply.c @@ -712,7 +712,6 @@ static void process_power_supply(void *data) int ret_lock = -1; int ret_val; - _D("process_power_supply()"); if (disp_plgn->pm_lock_internal) ret_lock = disp_plgn->pm_lock_internal(INTERNAL_LOCK_BATTERY, LCD_OFF, STAY_CUR_STATE, 0); @@ -785,10 +784,6 @@ static void process_power_supply(void *data) if (power_supply_broadcast(CHARGE_MISC_EVENT_SIGNAL, battery.misc) < 0) broadcasted = false; - if (old_battery.freq_strength != battery.freq_strength) - if (power_supply_broadcast(CHARGE_FREQ_STRENGTH_SIGNAL, battery.freq_strength) < 0) - broadcasted = false; - if (old_battery.charge_full != battery.charge_full) noti_batt_full(); @@ -797,9 +792,8 @@ static void process_power_supply(void *data) old_battery.capacity != battery.capacity || old_battery.health != battery.health || old_battery.misc != battery.misc || - old_battery.freq_strength != battery.freq_strength || old_battery.online_type != battery.online_type) - _I("Signal(%d) %s(%d) %s(%d) %s(%d) %s(%d) %s(%d) %s(%d) %s(%d) %s(%d : %s) %s(%d)", + _I("Signal(%d) %s(%d) %s(%d) %s(%d) %s(%d) %s(%d) %s(%d) %s(%d) %s(%d : %s)", broadcasted, CHARGER_STATUS_SIGNAL, battery.charger_connected, CHARGER_TYPE_SIGNAL, battery.online_type, @@ -808,8 +802,7 @@ static void process_power_supply(void *data) CHARGE_CAPACITY_SIGNAL, battery.capacity, CHARGE_LEVEL_SIGNAL, battery.charging_level, CHARGE_MISC_EVENT_SIGNAL, battery.misc, - CHARGE_HEALTH_SIGNAL, battery.health, battery.health_s, - CHARGE_FREQ_STRENGTH_SIGNAL, battery.freq_strength); + CHARGE_HEALTH_SIGNAL, battery.health, battery.health_s); old_battery.capacity = battery.capacity; old_battery.charging_level = battery.charging_level; @@ -819,7 +812,6 @@ static void process_power_supply(void *data) old_battery.charge_full = battery.charge_full; old_battery.misc = battery.misc; - old_battery.freq_strength = battery.freq_strength; snprintf(old_battery.status_s, sizeof(old_battery.status_s), "%s", battery.status_s); check_abnormal_status(); @@ -919,8 +911,7 @@ static int battery_state(struct battery_info *info) prev_status.charge_now == battery.charge_now && prev_status.health == battery.health && prev_status.present == battery.present && - prev_status.charger_connected == battery.charger_connected && - prev_status.freq_strength == battery.freq_strength) + prev_status.charger_connected == battery.charger_connected) return 0; prev_status.capacity = battery.capacity; @@ -930,7 +921,6 @@ static int battery_state(struct battery_info *info) prev_status.health = battery.health; prev_status.present = battery.present; prev_status.charger_connected = battery.charger_connected; - prev_status.freq_strength = battery.freq_strength; _I("%s(%s) %s(%d) Capa(%d) Hth(%s,%d) Pres(%d) Curr(%d,%d)", info->status, @@ -1011,7 +1001,6 @@ static void battery_changed(struct battery_info *info, void *data) battery.temperature = info->temperature; battery.voltage_now = info->voltage_now; battery.voltage_average = info->voltage_average; - battery.freq_strength = info->freq_strength; battery_initialized = true; @@ -1239,13 +1228,6 @@ static GVariant *dbus_get_misc(GDBusConnection *conn, } -static GVariant *dbus_get_freq_strength(GDBusConnection *conn, - const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, - GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) -{ - return g_variant_new("(i)", battery.freq_strength); -} - static GVariant *dbus_get_power_supply_handler(GDBusConnection *conn, const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) @@ -1255,14 +1237,13 @@ static GVariant *dbus_get_power_supply_handler(GDBusConnection *conn, * had been disabled by test driver. */ lowbat_enable_uevent_buffering(); - return g_variant_new("(iiiiiiiisiiiii)", 0, + return g_variant_new("(iiiiiiisiiiii)", 0, battery.capacity, battery.charging_status, battery.health, battery.charger_connected, battery.present, battery.misc, - battery.freq_strength, battery.power_source_s, battery.voltage_now, battery.voltage_average, @@ -1323,69 +1304,23 @@ static GVariant *dbus_power_supply_handler(GDBusConnection *conn, info.online = charger_connected; info.present = atoi(argv[4]); check_misc_status(argv[5]); - info.freq_strength = atoi(argv[6]); info.power_source = strdup(argv[7]); info.voltage_now = atoi(argv[8]); info.voltage_average = atoi(argv[9]); info.current_now = atoi(argv[10]); info.current_average = atoi(argv[11]); info.temperature = atoi(argv[12]); - _D("C(%d) S(%s) H(%s) O(%d) P(%d) F(%d) SRC(%s) Vol(%d %d) Cur(%d %d) T(%d)", - info.capacity, info.status, info.health, info.online, info.present, info.freq_strength, info.power_source, info.voltage_now, info.voltage_average, info.current_now, info.current_average, info.temperature); + _D("C(%d) S(%s) H(%s) O(%d) P(%d) SRC(%s) Vol(%d %d) Cur(%d %d) T(%d)", + info.capacity, info.status, info.health, info.online, info.present, info.power_source, info.voltage_now, info.voltage_average, info.current_now, info.current_average, info.temperature); if (battery_dev_available) battery_changed(&info, NULL); - /* - snprintf(battery.status_s, sizeof(battery.status_s), "%s", - (battery.charge_now == CHARGER_CHARGING) ? "Charging" : - (battery.charge_now == CHARGER_ABNORMAL) ? "Not Charging" : - (battery.charge_full == CHARGING_FULL) ? "Full" : - "Discharging"); - _I("%s(%d) %s(f:%d n:%d) %s(%d) %s(%d) %s(%d) %s(%d)", - argv[0], - battery.capacity, - argv[1], - battery.charge_full, - battery.charge_now, - argv[2], - battery.health, - //argv[3], - "charger_connected", - battery.charger_connected, - argv[4], - battery.present, - argv[5], - battery.misc); - _I("%s(%d) %s(%s) %s(%d) %s(%d) %s(%d) %s(%d) %s(%d)", - argv[6], - battery.freq_strength, - argv[7], - battery.power_source_s, - argv[8], - battery.voltage_now, - argv[9], - battery.voltage_average, - argv[10], - battery.current_now, - argv[11], - battery.current_average, - argv[12], - battery.temperature); - - if (battery.charger_connected == 1) - power_supply_noti(DEVICE_NOTI_BATT_CHARGE, DEVICE_NOTI_ON); - else - power_supply_noti(DEVICE_NOTI_BATT_CHARGE, DEVICE_NOTI_OFF); - - //process_power_supply(&battery.capacity); - */ out: g_free(type_str); g_free(argv[0]); g_free(argv[1]); g_free(argv[2]); - //g_free(argv[3]); g_free(argv[4]); g_free(argv[5]); g_free(argv[6]); @@ -1421,7 +1356,6 @@ static void battery_get_info(struct battery_info *info, void *data) bat->temperature = info->temperature; bat->voltage_now = info->voltage_now; bat->voltage_average = info->voltage_average; - bat->freq_strength = info->freq_strength; } static GVariant *dbus_get_battery_info(GDBusConnection *conn, @@ -1508,13 +1442,12 @@ static const dbus_method_s dbus_methods[] = { { CHARGE_FULL_SIGNAL, NULL, "i", dbus_is_full }, { CHARGE_HEALTH_SIGNAL, NULL, "s", dbus_get_health }, { POWER_SUBSYSTEM, "sisssisssssssss", "i", dbus_power_supply_handler }, - { GET_POWER_SUBSYSTEM, NULL, "iiiiiiiisiiiii", dbus_get_power_supply_handler }, + { GET_POWER_SUBSYSTEM, NULL, "iiiiiiisiiiii", dbus_get_power_supply_handler }, { "GetBatteryInfo", NULL, "isssiiiiiiii", dbus_get_battery_info }, { CHARGER_TYPE_SIGNAL, NULL, "i", dbus_get_charger_type }, { "ChargerCharging", "i", "i", dbus_charger_charging }, { CHARGE_BATTERY_PROPERTIES, NULL, "iiiiii", dbus_get_battery_props }, { CHARGE_MISC_EVENT_SIGNAL, NULL, "i", dbus_get_misc }, - { CHARGE_FREQ_STRENGTH_SIGNAL, NULL, "i", dbus_get_freq_strength}, }; static const dbus_interface_u dbus_interface = { @@ -1721,7 +1654,6 @@ static void power_supply_init(void *data) memset(&old_battery, 0, sizeof(struct battery_status)); battery.charger_charging = CHARGER_ENABLED; battery.misc = MISC_NONE; - battery.freq_strength = 0; battery.charger_connected = -1; /* It will be true on initializing battery structure */ diff --git a/src/battery/power-supply.h b/src/battery/power-supply.h index 1350299..6579f96 100644 --- a/src/battery/power-supply.h +++ b/src/battery/power-supply.h @@ -109,7 +109,6 @@ struct battery_status { int charging_level; int charger_charging; int misc; - int freq_strength; char status_s[32]; char health_s[32]; char power_source_s[32]; @@ -132,6 +131,5 @@ void relaunch_health_popup(void); #define CHARGE_FULL_SIGNAL "IsFull" #define CHARGE_BATTERY_PROPERTIES "BatteryProperties" #define CHARGE_MISC_EVENT_SIGNAL "MiscEvent" -#define CHARGE_FREQ_STRENGTH_SIGNAL "FreqStrength" #endif /* __POWER_SUPPLY_H__ */ diff --git a/tests/auto-test/battery.c b/tests/auto-test/battery.c index e245b64..b21e87d 100644 --- a/tests/auto-test/battery.c +++ b/tests/auto-test/battery.c @@ -146,7 +146,7 @@ static struct power_supply_type { const char *current_avg; const char *temperature; const char *misc; - const char *freq_strength; + const char *freq_strength; // unused const char *name; } power_supply_types[] = { {"norm", S_ENTER, "100", CHARGENOW, GOOD, 1, PRESENT_NORMAL, USB, VOLT_4P2, VOLT_4P2, CUR_300, CUR_300, TEMP_250, MISC_NORMAL, LEVEL_0, "CHARGE"}, @@ -202,11 +202,6 @@ static struct power_supply_type { {"capa", S_ENTER, "100", DISCHARGE, GOOD, 0, PRESENT_NORMAL, USB, VOLT_4P2, VOLT_4P2, CUR_0, CUR_0, TEMP_250, MISC_NORMAL, LEVEL_0, "CAPACITY"},/* discharging */ {"capa", S_LEAVE, "100", CHARGENOW, GOOD, 1, PRESENT_NORMAL, USB, VOLT_4P2, VOLT_4P2, CUR_100, CUR_100, TEMP_250, MISC_NORMAL, LEVEL_0, "CAPACITY"},/* charging */ - - {"freq", S_ENTER, "100", CHARGENOW, GOOD, 1, PRESENT_NORMAL, WIRELESS, VOLT_4P2, VOLT_4P2, CUR_100, CUR_100, TEMP_250, MISC_NORMAL, LEVEL_0, "CHARGE"}, - {"freq", S_ENTER, "100", CHARGENOW, GOOD, 1, PRESENT_NORMAL, WIRELESS, VOLT_4P2, VOLT_4P2, CUR_100, CUR_100, TEMP_250, MISC_NORMAL, LEVEL_1, "FREQ LEVEL 1 AFTER CHARGE"}, - {"freq", S_ENTER, "100", CHARGENOW, GOOD, 1, PRESENT_NORMAL, WIRELESS, VOLT_4P2, VOLT_4P2, CUR_100, CUR_100, TEMP_250, MISC_NORMAL, LEVEL_2, "FREQ LEVEL 2 AFTER CHARGE"}, - {"freq", S_LEAVE, "100", DISCHARGE, GOOD, 0, PRESENT_NORMAL, WIRELESS, VOLT_4P2, VOLT_4P2, CUR_0, CUR_0, TEMP_250, MISC_NORMAL, LEVEL_0, "DISCHARGE"}, /* init */ }; static bool get_battery_method(const char *method, int *value) @@ -649,11 +644,6 @@ static bool compare_power_supply(struct power_supply_type list, int value[], con return false; } - if (atoi(list.freq_strength) != value[6]) { - _E("Different freq_strength : %d %d", atoi(list.freq_strength), value[6]); - return false; - } - if (strcmp(list.power_source, power_source)) { _E("Different power_source : %s %s", list.power_source, power_source); return false; @@ -765,14 +755,13 @@ static bool get_battery_power_supply(int out_rsp[], char **out_power_source) return ret; } - if (!g_variant_get_safe(reply, "(iiiiiiiisiiiii)", &reply_val, //return value + if (!g_variant_get_safe(reply, "(iiiiiiisiiiii)", &reply_val, //return value &out_rsp[0], //capacity &out_rsp[1], //charging_status &out_rsp[2], //health &out_rsp[3], //online &out_rsp[4], //present &out_rsp[5], //misc - &out_rsp[6], //freq_strength out_power_source, //power_source &out_rsp[7], //voltage_now &out_rsp[8], //voltagge_avg -- 2.7.4 From 09ff00b5de5d63de04f33d968066420dffcd1149 Mon Sep 17 00:00:00 2001 From: Youngjae Cho Date: Tue, 7 Jun 2022 13:20:40 +0900 Subject: [PATCH 07/16] battery: rename charging_level to capacity_level Change-Id: If092c80ced70eb2ed64570383ffa1a99b1f442bf Signed-off-by: Youngjae Cho --- src/battery/lowbat-handler.c | 12 ++++++------ src/battery/power-supply.c | 8 ++++---- src/battery/power-supply.h | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/battery/lowbat-handler.c b/src/battery/lowbat-handler.c index 3905fe9..a0d5b65 100644 --- a/src/battery/lowbat-handler.c +++ b/src/battery/lowbat-handler.c @@ -607,12 +607,12 @@ static int lowbat_monitor(void *data) r = lowbat_initialized(NULL); if (r != BATTERY_ENABLED) - return battery->charging_level; + return battery->capacity_level; if (data == NULL) { r = check_lowbat_percent(&bat_percent); if (r < 0) - return battery->charging_level; + return battery->capacity_level; } else bat_percent = *(int *)data; return lowbat_process(bat_percent, NULL); @@ -739,11 +739,11 @@ static void lowbat_exit(void *data) static gboolean low_battery_charging_status(void *data) { low_batt_sig_timer = 0; - battery->charging_level = lowbat_monitor(data); - if (battery->charging_level > 0 && old_battery.charging_level != battery->charging_level) { - if (vconf_set_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, battery->charging_level) < 0) + battery->capacity_level = lowbat_monitor(data); + if (battery->capacity_level > 0 && old_battery.capacity_level != battery->capacity_level) { + if (vconf_set_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, battery->capacity_level) < 0) _E("Fail to set level."); - if (power_supply_broadcast(CHARGE_LEVEL_SIGNAL, battery->charging_level) < 0) + if (power_supply_broadcast(CHARGE_LEVEL_SIGNAL, battery->capacity_level) < 0) _E("power_supply_broadcast failed"); } return G_SOURCE_REMOVE; diff --git a/src/battery/power-supply.c b/src/battery/power-supply.c index 214d1b3..7a98161 100644 --- a/src/battery/power-supply.c +++ b/src/battery/power-supply.c @@ -800,12 +800,12 @@ static void process_power_supply(void *data) CHARGE_NOW_SIGNAL, battery.charge_now, CHARGE_FULL_SIGNAL, battery.charge_full, CHARGE_CAPACITY_SIGNAL, battery.capacity, - CHARGE_LEVEL_SIGNAL, battery.charging_level, + CHARGE_LEVEL_SIGNAL, battery.capacity_level, CHARGE_MISC_EVENT_SIGNAL, battery.misc, CHARGE_HEALTH_SIGNAL, battery.health, battery.health_s); old_battery.capacity = battery.capacity; - old_battery.charging_level = battery.charging_level; + old_battery.capacity_level = battery.capacity_level; old_battery.charger_connected = battery.charger_connected; old_battery.online_type = battery.online_type; old_battery.charging_status = battery.charging_status; @@ -945,7 +945,7 @@ static void battery_invalidate_vconf(int value) int *member; } list[] = { { VCONFKEY_SYSMAN_BATTERY_CAPACITY, &old_battery.capacity }, - { VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, &old_battery.charging_level }, + { VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, &old_battery.capacity_level }, { VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW, &old_battery.charge_now }, { VCONFKEY_SYSMAN_BATTERY_LEVEL_STATUS, NULL }, }; @@ -1476,7 +1476,7 @@ static int delayed_init_done(void *data) CHARGE_NOW_SIGNAL, battery.charge_now, CHARGE_FULL_SIGNAL, battery.charge_full, CHARGE_CAPACITY_SIGNAL, battery.capacity, - CHARGE_LEVEL_SIGNAL, battery.charging_level, + CHARGE_LEVEL_SIGNAL, battery.capacity_level, CHARGE_MISC_EVENT_SIGNAL, battery.misc, CHARGE_HEALTH_SIGNAL, battery.health, battery.health_s); diff --git a/src/battery/power-supply.h b/src/battery/power-supply.h index 6579f96..6e41b3d 100644 --- a/src/battery/power-supply.h +++ b/src/battery/power-supply.h @@ -106,7 +106,7 @@ struct battery_status { int temperature; int current_now; int current_average; - int charging_level; + int capacity_level; int charger_charging; int misc; char status_s[32]; -- 2.7.4 From e04ab9ded91a5939ef64b8b7d8b425a7f2a612c7 Mon Sep 17 00:00:00 2001 From: Youngjae Cho Date: Tue, 7 Jun 2022 13:41:27 +0900 Subject: [PATCH 08/16] log: add critical-log type of error Change-Id: I4e7abb62edafc719decd2d9f9e6841de46e0fbf7 Signed-off-by: Youngjae Cho --- plugins/wearable/display/core.c | 4 ++-- src/power-command/command.c | 4 ++-- src/power/power.c | 2 +- src/shared/log-macro.h | 5 ++++- src/usb-gadget/usb-gadget-ops.c | 4 ++-- src/usb-gadget/usb-gadget.c | 2 +- 6 files changed, 12 insertions(+), 9 deletions(-) diff --git a/plugins/wearable/display/core.c b/plugins/wearable/display/core.c index 5b640a3..e29e170 100644 --- a/plugins/wearable/display/core.c +++ b/plugins/wearable/display/core.c @@ -430,7 +430,7 @@ static gboolean pmlock_terminate_daemon_to_release_lock(gpointer data) *pname ? pname : "Unknown", pid, states[state].name, KILLABLE_DAEMON_LOCK_LIMIT); ret = kill(pid, SIGTERM); if (ret < 0) - CRITICAL_LOG("Failed to send SIGTERM to process %s(%d), %d.", + CRITICAL_LOG_E("Failed to send SIGTERM to process %s(%d), %d.", *pname ? pname : "Unknown", pid, errno); node->force_release = true; @@ -444,7 +444,7 @@ static gboolean pmlock_terminate_daemon_to_release_lock(gpointer data) ret = kill(pid, SIGKILL); if (ret < 0) - CRITICAL_LOG("Failed to kill process %s(%d), %d.", + CRITICAL_LOG_E("Failed to kill process %s(%d), %d.", *pname ? pname : "Unknown", pid, errno); } diff --git a/src/power-command/command.c b/src/power-command/command.c index 868a666..f50df67 100644 --- a/src/power-command/command.c +++ b/src/power-command/command.c @@ -79,7 +79,7 @@ static bool deviced_call_poweroff_once(const char *action, const char *extra_opt : gdbus_call_sync_with_reply_int(DEVICED_BUS_NAME, DEVICED_PATH_POWEROFF, DEVICED_INTERFACE_POWEROFF, "PowerOff", g_variant_new("(s)", action), NULL) ; if (ret_dbus < 0) { - CRITICAL_LOG("Error while calling deviced: %d", ret_dbus); + CRITICAL_LOG_E("Error while calling deviced: %d", ret_dbus); return false; } else CRITICAL_LOG("Succesfully requested shutdown using deviced"); @@ -109,7 +109,7 @@ static bool deviced_call_poweroff(const char *action, const char *extra_option) break; } - CRITICAL_LOG("Failed to shutdown system using deviced - falling back to systemd shutdown"); + CRITICAL_LOG_E("Failed to shutdown system using deviced - falling back to systemd shutdown"); return false; } diff --git a/src/power/power.c b/src/power/power.c index 79c8a08..793a4a0 100644 --- a/src/power/power.c +++ b/src/power/power.c @@ -250,7 +250,7 @@ static int power_transition_state(void *data) if (!delayed_init_done && !is_poweroff_state(ti->next)) { struct trans_info *deferred_ti = calloc(1, sizeof(struct trans_info)); if (!deferred_ti) { - CRITICAL_LOG("Failed to defer transition."); + CRITICAL_LOG_E("Failed to defer transition."); return 0; } diff --git a/src/shared/log-macro.h b/src/shared/log-macro.h index 440300f..fe998b9 100644 --- a/src/shared/log-macro.h +++ b/src/shared/log-macro.h @@ -27,8 +27,11 @@ #ifdef CRITICAL_LOG_ON #define CRITICAL_LOG(fmt, arg...) \ do { CRITICAL_LOG_(LOG_ID_SYSTEM, DLOG_INFO, LOG_TAG, fmt, ##arg); } while (0) +#define CRITICAL_LOG_E(fmt, arg...) \ + do { CRITICAL_LOG_(LOG_ID_SYSTEM, DLOG_ERROR, LOG_TAG, fmt, ##arg); } while (0) #else -#define CRITICAL_LOG(fmt, arg...) _I(fmt, ##arg) +#define CRITICAL_LOG(fmt, arg...) _I(fmt, ##arg) +#define CRITICAL_LOG_E(fmt, arg...) _E(fmt, ##arg) #endif #define _D(fmt, arg...) \ diff --git a/src/usb-gadget/usb-gadget-ops.c b/src/usb-gadget/usb-gadget-ops.c index 6d7872c..cfc29cb 100644 --- a/src/usb-gadget/usb-gadget-ops.c +++ b/src/usb-gadget/usb-gadget-ops.c @@ -513,7 +513,7 @@ int usb_gadget_ops_init(void) &__usb_gadget_disable, &__usb_gadget_reconfigure); } else { - CRITICAL_LOG("Usb-gadget is not supported."); + CRITICAL_LOG_E("Usb-gadget is not supported."); return -ENOTSUP; } @@ -521,7 +521,7 @@ int usb_gadget_ops_init(void) if (__usb_gadget_open) { ret = __usb_gadget_open(); if (ret != 0) { - CRITICAL_LOG("Failed to open usb-gadget, %d", ret); + CRITICAL_LOG_E("Failed to open usb-gadget, %d", ret); return ret; } } diff --git a/src/usb-gadget/usb-gadget.c b/src/usb-gadget/usb-gadget.c index 6b01ae5..1a0769c 100644 --- a/src/usb-gadget/usb-gadget.c +++ b/src/usb-gadget/usb-gadget.c @@ -286,7 +286,7 @@ static void usb_init(void *data) ret = usb_gadget_ops_init(); if (ret < 0) { - CRITICAL_LOG("USB client cannot be used: %d", ret); + CRITICAL_LOG_E("USB client cannot be used: %d", ret); return; } -- 2.7.4 From d015842e4413445707556227a50215e341b905b6 Mon Sep 17 00:00:00 2001 From: Youngjae Cho Date: Tue, 7 Jun 2022 14:31:25 +0900 Subject: [PATCH 09/16] battery: remove unused variable, charger_charging Change-Id: Ic7ea822a41b9cc1a1561d6b1a2c40da648220a3d Signed-off-by: Youngjae Cho --- src/battery/lowbat-handler.c | 8 +++--- src/battery/power-supply.c | 49 ----------------------------------- src/battery/power-supply.h | 6 ----- tests/auto-test/test_dbus_interface.c | 25 ------------------ 4 files changed, 3 insertions(+), 85 deletions(-) diff --git a/src/battery/lowbat-handler.c b/src/battery/lowbat-handler.c index a0d5b65..54b85f5 100644 --- a/src/battery/lowbat-handler.c +++ b/src/battery/lowbat-handler.c @@ -497,9 +497,7 @@ static int lowbat_process(int bat_percent, void *ad) } if (new_bat_capacity <= battery_info.realoff) { - if (battery->charge_now == CHARGER_CHARGING || battery->charger_charging == CHARGER_DISABLED) { - _I("Skip lowbat poweroff during test (c:%d charge:%d online:%d charger_charging:%d)", - battery->capacity, battery->charge_now, battery->charger_connected, battery->charger_charging); + if (battery->charge_now == CHARGER_CHARGING) { new_bat_state = battery_info.poweroff; if (vconf_state != VCONFKEY_SYSMAN_BAT_POWER_OFF) status = VCONFKEY_SYSMAN_BAT_POWER_OFF; @@ -542,8 +540,8 @@ static int lowbat_process(int bat_percent, void *ad) if (low_bat_skip_cnt >= RETRY_MAX) { new_bat_state = battery_info.realoff; status = VCONFKEY_SYSMAN_BAT_REAL_POWER_OFF; - _I("Go to real poweroff inspite of charging (c:%d charge:%d online:%d charger_charging %d current now %d)", - battery->capacity, battery->charge_now, battery->charger_connected, battery->charger_charging, battery->current_now); + _I("Go to real poweroff inspite of charging (c:%d charge:%d online:%d current_now:%d)", + battery->capacity, battery->charge_now, battery->charger_connected, battery->current_now); low_bat_skip_cnt = 0; } else if (battery->current_now <= MIN_INOW_VALUE) { low_bat_skip_cnt++; diff --git a/src/battery/power-supply.c b/src/battery/power-supply.c index 7a98161..7d33f84 100644 --- a/src/battery/power-supply.c +++ b/src/battery/power-supply.c @@ -326,7 +326,6 @@ int power_supply_broadcast(char *sig, int status) static int old; static char sig_old[32]; int ret; - int chg_on; if (!sig) { _E("There is no signal name."); @@ -339,18 +338,6 @@ int power_supply_broadcast(char *sig, int status) old = status; - if (battery.charger_charging == CHARGER_DISABLED) { - ret = sys_get_int(CHARGER_CHARGE_ON_NODE, &chg_on); - if (ret == 0 && battery.charger_charging != chg_on) { - ret = sys_set_int(CHARGER_CHARGE_ON_NODE, battery.charger_charging); - _I("%s to change status with %d", ((ret == 0) ? "success" : "fail"), battery.charger_charging); - } - if (strncmp(sig, CHARGE_NOW_SIGNAL, strlen(CHARGE_NOW_SIGNAL)) == 0) { - _I("Skip signal while charger disabled."); - return 0; - } - } - snprintf(sig_old, sizeof(sig_old), "%s", sig); ret = gdbus_signal_emit(NULL, @@ -1112,40 +1099,6 @@ static GVariant *dbus_get_charger_type(GDBusConnection *conn, return g_variant_new("(i)", type); } -static GVariant *dbus_charger_charging(GDBusConnection *conn, - const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, - GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) -{ - int ret = 0; - int val; - int chg_on; - - g_variant_get(param, "(i)", &val); - - if (val != CHARGER_ENABLED && val != CHARGER_DISABLED) { - _E("There is no valid input: %d", battery.charger_charging); - ret = -EINVAL; - goto out; - } - if (battery.charger_connected == 0) { - _E("There is no charger(%d) input(%d).", battery.charger_connected, battery.charger_charging); - ret = -EACCES; - goto out; - } - ret = sys_get_int(CHARGER_CHARGE_ON_NODE, &chg_on); - if (ret == 0 && val != chg_on) { - battery.charger_charging = val; - ret = sys_set_int(CHARGER_CHARGE_ON_NODE, battery.charger_charging); - CRITICAL_LOG("chg_on changed to %d %s", battery.charger_charging, - (ret == 0) ? "success" : "fail"); - _I("%s to change status with %d.", ((ret == 0) ? "success" : "fail"), battery.charger_charging); - } else { - _I("Skip change status with %d (ret %d prev %d)", val, ret, battery.charger_charging); - } -out: - return g_variant_new("(i)", ret); -} - static GVariant *dbus_get_charge_now(GDBusConnection *conn, const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) @@ -1445,7 +1398,6 @@ static const dbus_method_s dbus_methods[] = { { GET_POWER_SUBSYSTEM, NULL, "iiiiiiisiiiii", dbus_get_power_supply_handler }, { "GetBatteryInfo", NULL, "isssiiiiiiii", dbus_get_battery_info }, { CHARGER_TYPE_SIGNAL, NULL, "i", dbus_get_charger_type }, - { "ChargerCharging", "i", "i", dbus_charger_charging }, { CHARGE_BATTERY_PROPERTIES, NULL, "iiiiii", dbus_get_battery_props }, { CHARGE_MISC_EVENT_SIGNAL, NULL, "i", dbus_get_misc }, }; @@ -1652,7 +1604,6 @@ static void power_supply_init(void *data) memset(&battery, 0, sizeof(struct battery_status)); memset(&old_battery, 0, sizeof(struct battery_status)); - battery.charger_charging = CHARGER_ENABLED; battery.misc = MISC_NONE; battery.charger_connected = -1; diff --git a/src/battery/power-supply.h b/src/battery/power-supply.h index 6e41b3d..c85cb90 100644 --- a/src/battery/power-supply.h +++ b/src/battery/power-supply.h @@ -80,11 +80,6 @@ enum battery_noti_status { DEVICE_NOTI_ON, }; -enum charger_charging_status { - CHARGER_DISABLED, - CHARGER_ENABLED, -}; - enum charger_type { CHARGER_TYPE_NONE = 0, CHARGER_TYPE_AC, @@ -107,7 +102,6 @@ struct battery_status { int current_now; int current_average; int capacity_level; - int charger_charging; int misc; char status_s[32]; char health_s[32]; diff --git a/tests/auto-test/test_dbus_interface.c b/tests/auto-test/test_dbus_interface.c index 92d7404..f1e2a1e 100644 --- a/tests/auto-test/test_dbus_interface.c +++ b/tests/auto-test/test_dbus_interface.c @@ -554,31 +554,6 @@ GVariant * test_deviced_Battery_BatteryProperties(void) return reply; } -// ChargerCharging : in i, out i - -gint test_deviced_Battery_ChargerCharging(gint param1) -{ - gint val1; - GVariant *reply; - int ret_dbus; - - ret_dbus = gdbus_call_sync_with_reply("org.tizen.system.deviced", - "/Org/Tizen/System/DeviceD/Battery", - "org.tizen.system.deviced.Battery", - "ChargerCharging", - g_variant_new("(i)", param1), - &reply);; - if (ret_dbus < 0) { - _E("failed ChargerCharging"); - return 0; - } - - g_variant_get(reply, "(i)", &val1); - g_variant_unref(reply); - - return val1; -} - // ChargerType : in , out i gint test_deviced_Battery_ChargerType(void) -- 2.7.4 From c1186415d46f0e7d7f4f9c263e5b915eaf6f1904 Mon Sep 17 00:00:00 2001 From: Youngjae Cho Date: Mon, 16 May 2022 15:59:55 +0900 Subject: [PATCH 10/16] battery: disable module if battery.present is 0 The actual behavior of no battery remains same as before. It is the main purpose of this patch that cleaning up handlings and loggins. Change-Id: Iaae8ac1ce6a438f0a2984d7ea6a3e6953ff8a51f Signed-off-by: Youngjae Cho --- src/battery/power-supply.c | 76 +++++++++++++++++++--------------------------- 1 file changed, 32 insertions(+), 44 deletions(-) diff --git a/src/battery/power-supply.c b/src/battery/power-supply.c index 7d33f84..f5c57c4 100644 --- a/src/battery/power-supply.c +++ b/src/battery/power-supply.c @@ -110,6 +110,7 @@ static void update_health(enum battery_noti_status status); static bool battery_dev_available = false; static int load_uevent(struct parse_result *result, void *user_data); static int event_handler_state_changed(void *data); +static void power_supply_exit(void *data); inline struct battery_status *get_var_battery_status(void) { @@ -924,7 +925,7 @@ static int battery_state(struct battery_info *info) return 1; } -static void battery_invalidate_vconf(int value) +static void battery_disable_module(int value) { int retval; static const struct invalidate_list { @@ -950,6 +951,8 @@ static void battery_invalidate_vconf(int value) if (list[i].member) *(list[i].member) = value; } + + power_supply_exit(NULL); } static void battery_changed(struct battery_info *info, void *data) @@ -1014,36 +1017,25 @@ static void battery_changed(struct battery_info *info, void *data) if (battery.present) { process_power_supply(&battery.capacity); } else { - _D("Battery disconnected"); - battery_invalidate_vconf(-ENODEV); + CRITICAL_LOG_E("Battery disconnected. Disable the battery module."); + battery_disable_module(-ENODEV); } } -static void power_supply_status_init(void) +static gboolean power_supply_update_during_booting(void *data) { - int r; + int retval; - r = hal_device_battery_get_current_state(battery_changed, NULL); - if (battery_dev_available && (r != -ENODEV)) { - if (r < 0 || battery.capacity < 0) { - _E("Failed to get battery capacity (capa: %d, ret: %d)", battery.capacity, r); - return; - } - } else { - r = config_parse(POWER_SUPPLY_UEVENT, load_uevent, &battery); - if (r < 0) { - _E("Failed to load %s, %d Use default value.", POWER_SUPPLY_UEVENT, r); - return; - } - battery.health = HEALTH_GOOD; - battery.present = PRESENT_NORMAL; - process_power_supply(&battery.capacity); + if (!battery_dev_available) + return G_SOURCE_REMOVE; + + retval = hal_device_battery_get_current_state(battery_changed, NULL); + if (retval == -ENODEV) { + CRITICAL_LOG_E("There is no battery detected. Disable the battery module."); + battery_disable_module(retval); + return G_SOURCE_REMOVE; } -} -static gboolean power_supply_update(void *data) -{ - power_supply_status_init(); return G_SOURCE_CONTINUE; } @@ -1051,31 +1043,13 @@ static void power_supply_timer_start(void) { _D("Battery init timer during booting."); power_timer = g_timeout_add(BATTERY_CHECK_TIMER_INTERVAL, - power_supply_update, NULL); + power_supply_update_during_booting, NULL); if (power_timer == 0) _E("Failed to add battery init timer during booting."); else _I("Started battery init timer during booting."); } -static void power_supply_timer_stop(void) -{ - int retval; - - if (power_timer == 0) - return; - _I("Stop battery init timer during booting."); - g_source_remove(power_timer); - power_timer = 0; - - /* check battery has been initialized until booting done */ - retval = hal_device_battery_get_current_state(battery_changed, NULL); - if (retval < 0) { - _E("Failed to initialize battery state"); - battery_invalidate_vconf(retval); - } -} - static GVariant *dbus_get_charger_status(GDBusConnection *conn, const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) @@ -1412,6 +1386,7 @@ static const dbus_interface_u dbus_interface = { static int delayed_init_done(void *data) { static int done; + int retval; device_notifier_state_e state = DEVICE_NOTIFIER_STATE_START; if (data == NULL) @@ -1420,7 +1395,19 @@ static int delayed_init_done(void *data) if (done == 0) return done; - power_supply_timer_stop(); + if (power_timer) { + g_source_remove(power_timer); + power_timer = 0; + } + + /* check battery has been initialized */ + retval = hal_device_battery_get_current_state(battery_changed, NULL); + if (retval == -ENODEV) { + CRITICAL_LOG_E("Failed to initialize battery state, %d. Disable the battery module.", retval); + battery_disable_module(retval); + return done; + } + event_handler_state_changed((void *)&state); _I("booting done %s(%d) %s(%d) %s(%d) %s(%d) %s(%d) %s(%d) %s(%d : %s)", @@ -1627,6 +1614,7 @@ static void power_supply_exit(void *data) { device_notifier_state_e state = DEVICE_NOTIFIER_STATE_STOP; + unregister_notifier(DEVICE_NOTIFIER_DELAYED_INIT, delayed_init_done); unregister_notifier(DEVICE_NOTIFIER_EVENT_HANDLER, event_handler_state_changed); event_handler_state_changed((void *)&state); -- 2.7.4 From 6acfb5be496be47651c378d8dcc3c1eba4810245 Mon Sep 17 00:00:00 2001 From: Youngjae Cho Date: Tue, 14 Jun 2022 10:35:50 +0900 Subject: [PATCH 11/16] power: reinforce log at PowerChangeState method Change-Id: I53db2b4855fc8fafb5ab4436d3d95d37e04bbf77 Signed-off-by: Youngjae Cho --- src/power/power-dbus.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/power/power-dbus.c b/src/power/power-dbus.c index 3f82a3a..61c7922 100644 --- a/src/power/power-dbus.c +++ b/src/power/power-dbus.c @@ -294,6 +294,8 @@ static GVariant *dbus_power_change_state(GDBusConnection *conn, int ret = 0; int index; guint64 next; + pid_t pid; + char comm[128] = "Unknown"; g_variant_get(param, "(t)", &next); @@ -307,6 +309,18 @@ static GVariant *dbus_power_change_state(GDBusConnection *conn, goto out; } + pid = gdbus_connection_get_sender_pid(conn, sender); + if (pid == -1 || kill(pid, 0) == -1) + goto out; + + get_command(pid, comm, sizeof(comm)); + + if (is_poweroff_state(next)) + CRITICAL_LOG("Pid=%d(%s) sent request for PowerChangeState to %s", pid, comm, state_name(next)); + else + _I("Pid=%d(%s) sent request for PowerChangeState to %s", pid, comm, state_name(next)); + + power_request_change_state_strict(POWER_STATE_ALL, next, 0, NULL); out: @@ -319,7 +333,7 @@ static const dbus_method_s dbus_methods[] = { { "AddChangeStateWait", "t", "i", dbus_power_add_change_state_wait }, { "RemoveChangeStateWait", "t", NULL, dbus_power_remove_change_state_wait }, { "ConfirmChangeStateWait", "t", "i", dbus_power_confirm_change_state_wait }, - { "PowerChangeState", "t", "i", dbus_power_change_state }, + { "PowerChangeState", "t", "i", dbus_power_change_state }, /* Add methods here */ }; -- 2.7.4 From fa73bf6c049d7808c4eb0209b079acdbb0c86eca Mon Sep 17 00:00:00 2001 From: Youngjae Cho Date: Mon, 13 Jun 2022 14:09:27 +0900 Subject: [PATCH 12/16] Change format of EventAction properties There were two types of Action= property, one is broadcasting and the other is changing state. Separate them to have different property name, Broadcast= and ChangeState=. - Action=broadcast -> ActionBroadcast=yes - Action=curr,next -> ActionChangeState=curr,next In addition to this, changed Duration= to clarify its meaning. - Duration -> DetectionRangeMsec This is intermediate patch. Therefore in this version, the property 'ActionBroadcast=yes' won't work properly. Change-Id: I00440c9bc30557812618b95f1a25663e9466158a Signed-off-by: Youngjae Cho --- conf/battery.conf | 11 +++++---- conf/init.conf | 4 ++-- conf/input-profile-iot-headless.conf | 30 +++++++++++------------ plugins/iot-headless/battery/battery-plugin.c | 7 +++++- plugins/iot-headless/input/input-config.c | 15 ++++++------ plugins/iot-headless/input/input-config.h | 3 +++ plugins/iot-headless/input/input-handler.c | 34 ++++++++------------------- src/power/power-boot.c | 2 +- src/shared/device-notifier.c | 4 ---- src/shared/device-notifier.h | 4 ---- 10 files changed, 50 insertions(+), 64 deletions(-) diff --git a/conf/battery.conf b/conf/battery.conf index 0fcb21c..d3c9c76 100644 --- a/conf/battery.conf +++ b/conf/battery.conf @@ -14,18 +14,19 @@ ChargerWakeLockEnabled=yes # define event-action, iot-headless only # DeviceNotifier= # - define which event(device-notifiy) is filtered -# Action= +# ChangeState= # - define action for the event +# ActionBroadcast=yes +# - broadcast upon occuring the event + [EventAction] Name=CHARGER_CONNECTED Enum=2001 DeviceNotifier=DEVICE_NOTIFIER_BATTERY_CHARGER_CONNECTED -Action=sleep,sleep -Action=normal,normal +ActionBroadcast=yes [EventAction] Name=CHARGER_DISCONNECTED Enum=2002 DeviceNotifier=DEVICE_NOTIFIER_BATTERY_CHARGER_DISCONNECTED -Action=sleep,sleep -Action=normal,normal +ActionBroadcast=yes diff --git a/conf/init.conf b/conf/init.conf index e9df34f..22c910d 100644 --- a/conf/init.conf +++ b/conf/init.conf @@ -2,10 +2,10 @@ #INITIAL_STATE_BY_POWERKEY_BOOTING Enum=3000 BootReason=powerkey -Action=start,normal +ActionChangeState=start,normal [EventAction] #INITIAL_STATE_BY_CHARGER_BOOTING Enum=3001 BootReason=charger -Action=start,sleep +ActionChangeState=start,sleep diff --git a/conf/input-profile-iot-headless.conf b/conf/input-profile-iot-headless.conf index 5640a99..8cf5d8b 100644 --- a/conf/input-profile-iot-headless.conf +++ b/conf/input-profile-iot-headless.conf @@ -6,53 +6,53 @@ # integer in broadcasting dbus signal. # Keycode=integer # - define keycode to filter key event -# Duration=integer,integer +# DetectionRangeMsec=integer,integer # - define time window in milisecond for filtering key event. -1 means no limit. # TriggerType=level/edge # - define event type -# Action=broadcast -# - define broadcast action for the event. -# Action=current,next +# ActionBroadcast=yes +# - Broadcast upon occuring an event, default no. +# ActionChangeState=current,next # - define state transition action for the event. [EventAction] Name=BLINKKEY_EDGE Enum=1000 Keycode=bluetooth -Duration=0,2000 +DetectionRangeMsec=0,2000 TriggerType=edge -Action=sleep,sleep +ActionBroadcast=yes [EventAction] Name=SHORTKEY_LEVEL Enum=1001 Keycode=power -Duration=2000,-1 +DetectionRangeMsec=2000,-1 TriggerType=level -Action=broadcast +ActionBroadcast=yes [EventAction] Name=SHORTKEY_EDGE Enum=1002 Keycode=power -Duration=2000,7000 +DetectionRangeMsec=2000,7000 TriggerType=edge -Action=normal,sleep -Action=sleep,normal +ActionChangeState=normal,sleep +ActionChangeState=sleep,normal [EventAction] Name=LONGKEY_LEVEL Enum=1003 Keycode=power -Duration=7000,-1 +DetectionRangeMsec=7000,-1 TriggerType=level -Action=broadcast +ActionBroadcast=yes [EventAction] Name=LONGKEY_EDGE Enum=1004 Keycode=power -Duration=7000,-1 +DetectionRangeMsec=7000,-1 TriggerType=edge ConditionVconf=memory/sysman/charger_status,int,0 -Action=normal,poweroff +ActionChangeState=normal,poweroff diff --git a/plugins/iot-headless/battery/battery-plugin.c b/plugins/iot-headless/battery/battery-plugin.c index 95a427d..99c9aef 100644 --- a/plugins/iot-headless/battery/battery-plugin.c +++ b/plugins/iot-headless/battery/battery-plugin.c @@ -33,6 +33,9 @@ struct battery_event_handler { char *name; int id; + /* broadcast upon occuring this event */ + int broadcast; + /* which action to do on receiving an event */ enum device_notifier_type action; void *user_data; @@ -99,8 +102,10 @@ static void parse_event_action_property(gpointer data, gpointer user_data) sscanf(prop->value, "%d", &handler->id); } else if (MATCH(prop->key, "DeviceNotifier")) { parse_device_notifier(handler, prop->value); - } else if (MATCH(prop->key, "Action")) { + } else if (MATCH(prop->key, "ActionChangeState")) { parse_action(handler, prop->value); + } else if (MATCH(prop->key, "ActionBroadcast")) { + handler->broadcast = MATCH(prop->value, "yes"); } } diff --git a/plugins/iot-headless/input/input-config.c b/plugins/iot-headless/input/input-config.c index 4635159..a8dd609 100644 --- a/plugins/iot-headless/input/input-config.c +++ b/plugins/iot-headless/input/input-config.c @@ -143,15 +143,12 @@ static void add_action_transition_info(struct input_event_unit *ieu, char *curr, SYS_G_LIST_APPEND(*action_list, ti); } -static void parse_action(struct input_event_unit *ieu, const char *action) +static void parse_change_state(struct input_event_unit *ieu, const char *action) { char curr[16] = { 0, }; char next[16] = { 0, }; - if (MATCH(action, "broadcast")) { - ieu->notifier = DEVICE_NOTIFIER_INPUT_BROADCAST_SIGNAL; - ieu->user_data = (void *) ieu; - } else if (sscanf(action, "%15[^,],%15s", curr, next) == 2) { + if (sscanf(action, "%15[^,],%15s", curr, next) == 2) { ieu->notifier = DEVICE_NOTIFIER_REQUEST_TRANSITION_STATE; /* append transition info to ieu->user_data */ add_action_transition_info(ieu, curr, next); @@ -176,14 +173,16 @@ static void parse_event_action_property(gpointer data, gpointer user_data) sscanf(prop->value, "%d", &ieu->id); } else if (MATCH(prop->key, "Keycode")) { parse_keycode(ieu, prop->value); - } else if (MATCH(prop->key, "Duration")) { + } else if (MATCH(prop->key, "DetectionRangeMsec")) { parse_duration(ieu, prop->value); } else if (MATCH(prop->key, "TriggerType")) { parse_trigger_type(ieu, prop->value); } else if (MATCH(prop->key, "ConditionVconf")) { parse_condition_vconf(ieu, prop->value); - } else if (MATCH(prop->key, "Action")) { - parse_action(ieu, prop->value); + } else if (MATCH(prop->key, "ActionChangeState")) { + parse_change_state(ieu, prop->value); + } else if (MATCH(prop->key, "ActionBroadcast")) { + ieu->broadcast = MATCH(prop->value, "yes"); } } diff --git a/plugins/iot-headless/input/input-config.h b/plugins/iot-headless/input/input-config.h index 8e192a6..9d7d060 100644 --- a/plugins/iot-headless/input/input-config.h +++ b/plugins/iot-headless/input/input-config.h @@ -50,6 +50,9 @@ struct input_event_unit { /* condition for triggering action */ struct condition_vconf cv; + /* broadcast upon occuring this event */ + int broadcast; + /* which action to do on receiving an event */ enum device_notifier_type notifier; void *user_data; diff --git a/plugins/iot-headless/input/input-handler.c b/plugins/iot-headless/input/input-handler.c index cce01be..dd31b2c 100644 --- a/plugins/iot-headless/input/input-handler.c +++ b/plugins/iot-headless/input/input-handler.c @@ -38,24 +38,26 @@ static gboolean level_triggered(gpointer data) ieu->timer = 0; - if (check_input_event_condition(ieu)) { - _D("Trigger(level) event=%s(%d), action=%d", ieu->name, ieu->id, ieu->notifier); - device_notify(ieu->notifier, ieu->user_data); - } else { + if (check_input_event_condition(ieu) == 0) { _D("Skip(level) event=%s(%d), condition=%s isn't meet", ieu->name, ieu->id, ieu->cv.keyname); + return G_SOURCE_REMOVE; } + _D("Trigger(level) event=%s(%d), action=%d", ieu->name, ieu->id, ieu->notifier); + device_notify(ieu->notifier, ieu->user_data); + return G_SOURCE_REMOVE; } static void edge_triggered(struct input_event_unit *ieu) { - if (check_input_event_condition(ieu)) { - _D("Trigger(edge) event=%s(%d), action=%d", ieu->name, ieu->id, ieu->notifier); - device_notify(ieu->notifier, ieu->user_data); - } else { + if (check_input_event_condition(ieu) == 0) { _D("Skip(edge) event=%s(%d), condition=%s isn't meet", ieu->name, ieu->id, ieu->cv.keyname); + return; } + + _D("Trigger(edge) event=%s(%d), action=%d", ieu->name, ieu->id, ieu->notifier); + device_notify(ieu->notifier, ieu->user_data); } static void start_event_timer(struct input_config *ic) @@ -145,24 +147,8 @@ static int input_handler_execute(void *data) return 0; } -static int broadcast_input_signal_cb(void *data) -{ - struct input_event_unit *ieu = (struct input_event_unit *) data; - - if (!ieu) - return 0; - - _D("Broadcast siganl, event=%s(%d)", ieu->name, ieu->id); - gdbus_signal_emit(NULL, DEVICED_PATH_INPUT, DEVICED_INTERFACE_INPUT, - "Key", g_variant_new("(i)", ieu->id)); - - return 0; -} - static void input_handler_init(void *data) { - register_notifier(DEVICE_NOTIFIER_INPUT_BROADCAST_SIGNAL, broadcast_input_signal_cb); - init_input_config(); } diff --git a/src/power/power-boot.c b/src/power/power-boot.c index f33bbd4..9926b68 100644 --- a/src/power/power-boot.c +++ b/src/power/power-boot.c @@ -138,7 +138,7 @@ static void parse_init_ti(const struct parse_result *result) SYS_G_LIST_FOREACH(result->props, elem, prop) { if (MATCH(prop->key, "Enum")) init_ti.reason = atoi(prop->value); - else if (MATCH(prop->key, "Action")) + else if (MATCH(prop->key, "ActionChangeState")) parse_transition_info(prop->value); } } diff --git a/src/shared/device-notifier.c b/src/shared/device-notifier.c index badf4e7..77980fb 100644 --- a/src/shared/device-notifier.c +++ b/src/shared/device-notifier.c @@ -94,10 +94,6 @@ static const char *device_notifier_type_str[DEVICE_NOTIFIER_MAX] = { NOTIFY_STR(DEVICE_NOTIFIER_KEY_PRESS), NOTIFY_STR(DEVICE_NOTIFIER_KEY_RELEASE), - /* action triggered by input event */ - NOTIFY_STR(DEVICE_NOTIFIER_INPUT_TRIGGER_POWEROFF), - NOTIFY_STR(DEVICE_NOTIFIER_INPUT_BROADCAST_SIGNAL), - /* Purpose of calling methods of different modules * Use prefix DEVICE_NOTIFIER_REQUEST */ NOTIFY_STR(DEVICE_NOTIFIER_REQUEST_TRANSITION_STATE), diff --git a/src/shared/device-notifier.h b/src/shared/device-notifier.h index 3acf22e..c81db6a 100644 --- a/src/shared/device-notifier.h +++ b/src/shared/device-notifier.h @@ -67,10 +67,6 @@ enum device_notifier_type { DEVICE_NOTIFIER_KEY_PRESS, DEVICE_NOTIFIER_KEY_RELEASE, - /* action triggered by input event */ - DEVICE_NOTIFIER_INPUT_TRIGGER_POWEROFF, - DEVICE_NOTIFIER_INPUT_BROADCAST_SIGNAL, - /* Purpose of calling methods of different modules * Use prefix DEVICE_NOTIFIER_REQUEST */ DEVICE_NOTIFIER_REQUEST_TRANSITION_STATE, -- 2.7.4 From cd06534f1ae7ff3a12af8e3371134d1c008efd60 Mon Sep 17 00:00:00 2001 From: Youngjae Cho Date: Mon, 13 Jun 2022 15:09:12 +0900 Subject: [PATCH 13/16] event: add event functions to shared library It contains functions that handling wakelock of event, and broadcasting signal about an event itself. The properties, WakeLockDurationSec= and ActionBroadcast= of configuration file, utilize those functions. Change-Id: I926f5e9cf19bfe09042797a200569c69e2b25a21 Signed-off-by: Youngjae Cho --- conf/battery.conf | 2 + conf/input-profile-iot-headless.conf | 1 + plugins/iot-headless/battery/battery-plugin.c | 20 +++++++++- plugins/iot-headless/input/input-config.c | 2 + plugins/iot-headless/input/input-config.h | 9 +++-- plugins/iot-headless/input/input-handler.c | 40 ++++++++++++++------ src/power/power-event-lock.c | 16 ++++++-- src/shared/device-notifier.c | 2 + src/shared/device-notifier.h | 2 + src/shared/event.c | 53 +++++++++++++++++++++++++++ src/shared/event.h | 45 +++++++++++++++++++++++ 11 files changed, 172 insertions(+), 20 deletions(-) create mode 100644 src/shared/event.c create mode 100644 src/shared/event.h diff --git a/conf/battery.conf b/conf/battery.conf index d3c9c76..1bd6a2c 100644 --- a/conf/battery.conf +++ b/conf/battery.conf @@ -24,9 +24,11 @@ Name=CHARGER_CONNECTED Enum=2001 DeviceNotifier=DEVICE_NOTIFIER_BATTERY_CHARGER_CONNECTED ActionBroadcast=yes +WakeLockDurationSec=5 [EventAction] Name=CHARGER_DISCONNECTED Enum=2002 DeviceNotifier=DEVICE_NOTIFIER_BATTERY_CHARGER_DISCONNECTED ActionBroadcast=yes +WakeLockDurationSec=5 diff --git a/conf/input-profile-iot-headless.conf b/conf/input-profile-iot-headless.conf index 8cf5d8b..c422d64 100644 --- a/conf/input-profile-iot-headless.conf +++ b/conf/input-profile-iot-headless.conf @@ -22,6 +22,7 @@ Keycode=bluetooth DetectionRangeMsec=0,2000 TriggerType=edge ActionBroadcast=yes +WakeLockDurationSec=5 [EventAction] Name=SHORTKEY_LEVEL diff --git a/plugins/iot-headless/battery/battery-plugin.c b/plugins/iot-headless/battery/battery-plugin.c index 99c9aef..2c03708 100644 --- a/plugins/iot-headless/battery/battery-plugin.c +++ b/plugins/iot-headless/battery/battery-plugin.c @@ -23,6 +23,7 @@ #include "shared/device-notifier.h" #include "shared/log.h" +#include "shared/event.h" #include "battery/battery-ops.h" #include "power/power.h" @@ -39,6 +40,9 @@ struct battery_event_handler { /* which action to do on receiving an event */ enum device_notifier_type action; void *user_data; + + /* hold wakelock for a duration on detecting the event */ + int wakelock_duration; }; static struct battery_event_handler *handler_connected; @@ -106,6 +110,8 @@ static void parse_event_action_property(gpointer data, gpointer user_data) parse_action(handler, prop->value); } else if (MATCH(prop->key, "ActionBroadcast")) { handler->broadcast = MATCH(prop->value, "yes"); + } else if (MATCH(prop->key, "WakeLockDurationSec")) { + sscanf(prop->value, "%d", &handler->wakelock_duration); } } @@ -130,7 +136,12 @@ static int parse_event_action(const struct parse_result *result, void *data) static int charger_connected_callback(void *data) { _D("event=%s(%d), action=%d", handler_connected->name, handler_connected->id, handler_connected->action); - device_notify(handler_connected->action, handler_connected->user_data); + + if (handler_connected->wakelock_duration) + event_acquire_wakelock(handler_connected->id, handler_connected->wakelock_duration); + + if (handler_connected->action) + device_notify(handler_connected->action, handler_connected->user_data); return 0; } @@ -138,7 +149,12 @@ static int charger_connected_callback(void *data) static int charger_disconnected_callback(void *data) { _D("event=%s(%d), action=%d", handler_disconnected->name, handler_disconnected->id, handler_disconnected->action); - device_notify(handler_disconnected->action, handler_disconnected->user_data); + + if (handler_disconnected->wakelock_duration) + event_acquire_wakelock(handler_disconnected->id, handler_disconnected->wakelock_duration); + + if (handler_disconnected->action) + device_notify(handler_disconnected->action, handler_disconnected->user_data); return 0; } diff --git a/plugins/iot-headless/input/input-config.c b/plugins/iot-headless/input/input-config.c index a8dd609..4a8715d 100644 --- a/plugins/iot-headless/input/input-config.c +++ b/plugins/iot-headless/input/input-config.c @@ -183,6 +183,8 @@ static void parse_event_action_property(gpointer data, gpointer user_data) parse_change_state(ieu, prop->value); } else if (MATCH(prop->key, "ActionBroadcast")) { ieu->broadcast = MATCH(prop->value, "yes"); + } else if (MATCH(prop->key, "WakeLockDurationSec")) { + sscanf(prop->value, "%d", &ieu->wakelock_duration); } } diff --git a/plugins/iot-headless/input/input-config.h b/plugins/iot-headless/input/input-config.h index 9d7d060..4f03f30 100644 --- a/plugins/iot-headless/input/input-config.h +++ b/plugins/iot-headless/input/input-config.h @@ -47,18 +47,21 @@ struct input_event_unit { enum trigger_type type; unsigned long interval[2]; + /* level-trigger timer */ + int timer; + /* condition for triggering action */ struct condition_vconf cv; - /* broadcast upon occuring this event */ + /* broadcast upon occuring the event */ int broadcast; /* which action to do on receiving an event */ enum device_notifier_type notifier; void *user_data; - /* level-trigger timer */ - int timer; + /* hold wakelock for a duration on detecting the event */ + int wakelock_duration; }; struct input_config { diff --git a/plugins/iot-headless/input/input-handler.c b/plugins/iot-headless/input/input-handler.c index dd31b2c..1176963 100644 --- a/plugins/iot-headless/input/input-handler.c +++ b/plugins/iot-headless/input/input-handler.c @@ -17,6 +17,7 @@ */ #include +#include #include #include #include @@ -26,38 +27,55 @@ #include "shared/devices.h" #include "shared/device-notifier.h" #include "shared/log.h" +#include "shared/event.h" #include "input-config.h" #define KEYVALUE_PRESS 1 #define KEYVALUE_RELEASE 0 -static gboolean level_triggered(gpointer data) +static gboolean level_event_detected(gpointer data) { struct input_event_unit *ieu = (struct input_event_unit *) data; ieu->timer = 0; + _D("Detected level event=%s(%d), action=%d", ieu->name, ieu->id, ieu->notifier); + if (check_input_event_condition(ieu) == 0) { - _D("Skip(level) event=%s(%d), condition=%s isn't meet", ieu->name, ieu->id, ieu->cv.keyname); + _D("Skip triggering event=%s(%d), condition=%s isn't meet", ieu->name, ieu->id, ieu->cv.keyname); return G_SOURCE_REMOVE; } - _D("Trigger(level) event=%s(%d), action=%d", ieu->name, ieu->id, ieu->notifier); - device_notify(ieu->notifier, ieu->user_data); + if (ieu->broadcast) + event_broadcast_id(ieu->id); + + if (ieu->wakelock_duration > 0) + event_acquire_wakelock(ieu->id, ieu->wakelock_duration); + + if (ieu->notifier) + device_notify(ieu->notifier, ieu->user_data); return G_SOURCE_REMOVE; } -static void edge_triggered(struct input_event_unit *ieu) +static void edge_event_detected(struct input_event_unit *ieu) { + _D("Detected edge event=%s(%d), action=%d", ieu->name, ieu->id, ieu->notifier); + if (check_input_event_condition(ieu) == 0) { - _D("Skip(edge) event=%s(%d), condition=%s isn't meet", ieu->name, ieu->id, ieu->cv.keyname); + _D("Skip triggering event=%s(%d), condition=%s isn't meet", ieu->name, ieu->id, ieu->cv.keyname); return; } - _D("Trigger(edge) event=%s(%d), action=%d", ieu->name, ieu->id, ieu->notifier); - device_notify(ieu->notifier, ieu->user_data); + if (ieu->broadcast) + event_broadcast_id(ieu->id); + + if (ieu->wakelock_duration > 0) + event_acquire_wakelock(ieu->id, ieu->wakelock_duration); + + if (ieu->notifier) + device_notify(ieu->notifier, ieu->user_data); } static void start_event_timer(struct input_config *ic) @@ -74,7 +92,7 @@ static void start_event_timer(struct input_config *ic) if (ieu->type == TRIGGER_TYPE_LEVEL) { if (ieu->timer) g_source_remove(ieu->timer); - ieu->timer = g_timeout_add(ieu->interval[0], level_triggered, (gpointer) ieu); + ieu->timer = g_timeout_add(ieu->interval[0], level_event_detected, (gpointer) ieu); } } } @@ -102,9 +120,9 @@ static void stop_event_timer(struct input_config *ic) ieu->timer = 0; } - /* trigger edge-trigger action */ + /* detected edge-trigger event */ if (lapse >= ieu->interval[0] && lapse < ieu->interval[1] && ieu->type == TRIGGER_TYPE_EDGE) - edge_triggered(ieu); + edge_event_detected(ieu); } } diff --git a/src/power/power-event-lock.c b/src/power/power-event-lock.c index dc8353c..70bb44c 100644 --- a/src/power/power-event-lock.c +++ b/src/power/power-event-lock.c @@ -43,6 +43,7 @@ enum eventlock_type { EL_KEY_BLUETOOTH, EL_CHARGER, + EL_EVENT_ACTION, /* add eventlock type here */ EL_MAX, }; @@ -60,11 +61,11 @@ static void event_wake_lock(enum eventlock_type type) set_bit(eventlock, type); setcount = count_set_bit(eventlock); - _D("Set eventlock of type=%d, current number of eventlock=%d", type, setcount); + _I("Set eventlock of type=%d, current number of eventlock=%d", type, setcount); if (setcount == 1) { sys_set_str("/sys/power/wake_lock", EVENT_LOCK); - _D("Acquired eventlock"); + _I("Acquired eventlock"); } } @@ -78,11 +79,11 @@ static void event_wake_unlock(enum eventlock_type type) clear_bit(eventlock, type); setcount = count_set_bit(eventlock); - _D("Unset eventlock of type=%d, current number of eventlock=%d", type, setcount); + _I("Unset eventlock of type=%d, current number of eventlock=%d", type, setcount); if (setcount == 0) { sys_set_str("/sys/power/wake_unlock", EVENT_LOCK); - _D("Released eventlock"); + _I("Released eventlock"); } } @@ -163,10 +164,17 @@ void power_event_lock_init(void) config_parse(BATTERY_CONF_FILE, check_charger_wakelock, &charger_wakelock); + /* general events, mostly defined by configuration file */ + register_power_event_lock_controller(EL_EVENT_ACTION, + DEVICE_NOTIFIER_EVENT_ACQUIRE_WAKELOCK, + DEVICE_NOTIFIER_EVENT_RELEASE_WAKELOCK); + + /* key input event */ register_power_event_lock_controller(EL_KEY, DEVICE_NOTIFIER_KEY_PRESS, DEVICE_NOTIFIER_KEY_RELEASE); + /* charger event */ if (charger_wakelock) { register_power_event_lock_controller(EL_CHARGER, DEVICE_NOTIFIER_BATTERY_CHARGER_CONNECTED, diff --git a/src/shared/device-notifier.c b/src/shared/device-notifier.c index 77980fb..61cd1c2 100644 --- a/src/shared/device-notifier.c +++ b/src/shared/device-notifier.c @@ -93,6 +93,8 @@ static const char *device_notifier_type_str[DEVICE_NOTIFIER_MAX] = { NOTIFY_STR(DEVICE_NOTIFIER_EXTCON_COUNT), NOTIFY_STR(DEVICE_NOTIFIER_KEY_PRESS), NOTIFY_STR(DEVICE_NOTIFIER_KEY_RELEASE), + NOTIFY_STR(DEVICE_NOTIFIER_EVENT_ACQUIRE_WAKELOCK), + NOTIFY_STR(DEVICE_NOTIFIER_EVENT_RELEASE_WAKELOCK), /* Purpose of calling methods of different modules * Use prefix DEVICE_NOTIFIER_REQUEST */ diff --git a/src/shared/device-notifier.h b/src/shared/device-notifier.h index c81db6a..bd1880a 100644 --- a/src/shared/device-notifier.h +++ b/src/shared/device-notifier.h @@ -66,6 +66,8 @@ enum device_notifier_type { DEVICE_NOTIFIER_EXTCON_COUNT, DEVICE_NOTIFIER_KEY_PRESS, DEVICE_NOTIFIER_KEY_RELEASE, + DEVICE_NOTIFIER_EVENT_ACQUIRE_WAKELOCK, + DEVICE_NOTIFIER_EVENT_RELEASE_WAKELOCK, /* Purpose of calling methods of different modules * Use prefix DEVICE_NOTIFIER_REQUEST */ diff --git a/src/shared/event.c b/src/shared/event.c new file mode 100644 index 0000000..4915f76 --- /dev/null +++ b/src/shared/event.c @@ -0,0 +1,53 @@ +/* + * deviced + * + * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include "device-notifier.h" +#include "log.h" + +static int wakelock_counter; + +static gboolean event_release_wakelock(gpointer data) +{ + int eventid = (int)(intptr_t) data; + + --wakelock_counter; + + _D("Decreased counter=%d, eventid=%d", wakelock_counter, eventid); + + if (wakelock_counter == 0) + device_notify(DEVICE_NOTIFIER_EVENT_RELEASE_WAKELOCK, NULL); + + return G_SOURCE_REMOVE; +} + +void event_acquire_wakelock(int eventid, int timeout) +{ + if (timeout <= 0) + return; + + ++wakelock_counter; + + _D("Increased counter=%d, eventid=%d, timeout=%d", wakelock_counter, eventid, timeout); + g_timeout_add_seconds(timeout, event_release_wakelock, (gpointer)(intptr_t) eventid); + + if (wakelock_counter == 1) + device_notify(DEVICE_NOTIFIER_EVENT_ACQUIRE_WAKELOCK, NULL); +} diff --git a/src/shared/event.h b/src/shared/event.h new file mode 100644 index 0000000..44821e5 --- /dev/null +++ b/src/shared/event.h @@ -0,0 +1,45 @@ +/* + * deviced + * + * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __DD_EVENT_H__ +#define __DD_EVENT_H__ + +#include + +#define DEVICED_PATH_EVENT "/Org/Tizen/System/DeviceD/Event" +#define DEVICED_INTERFACE_EVENT "org.tizen.system.deviced.Event" +#define DEVICED_SIGNAME_ID "Id" + +static inline void event_broadcast_id(int id) +{ + _I("Broadcast eventid=%d", id); + + gdbus_signal_emit(NULL, + DEVICED_PATH_EVENT, + DEVICED_INTERFACE_EVENT, + DEVICED_SIGNAME_ID, + g_variant_new("(i)", id)); +} + +/** + * Hold wakelock for a specified timeout. + * The parameter eventid is only used for logging + */ +void event_acquire_wakelock(int eventid, int timeout); + +#endif //__DD_EVENT_H__ -- 2.7.4 From 750ac44ddbac46babedeadae439ab8de2999e57e Mon Sep 17 00:00:00 2001 From: Youngjae Cho Date: Wed, 15 Jun 2022 14:28:17 +0900 Subject: [PATCH 14/16] Reconfigure input for iot-headless Change-Id: I035784568172ce7d8367f26361460d136b7d9c32 Signed-off-by: Youngjae Cho --- conf/battery.conf | 2 ++ conf/input-profile-iot-headless.conf | 57 +++++++++++++++++++++++++++--------- 2 files changed, 45 insertions(+), 14 deletions(-) diff --git a/conf/battery.conf b/conf/battery.conf index 1bd6a2c..d854e14 100644 --- a/conf/battery.conf +++ b/conf/battery.conf @@ -18,6 +18,8 @@ ChargerWakeLockEnabled=yes # - define action for the event # ActionBroadcast=yes # - broadcast upon occuring the event +# WakeLockDurationSec= +# - acquire wakelock for a specfied timeout [EventAction] Name=CHARGER_CONNECTED diff --git a/conf/input-profile-iot-headless.conf b/conf/input-profile-iot-headless.conf index c422d64..a2c0284 100644 --- a/conf/input-profile-iot-headless.conf +++ b/conf/input-profile-iot-headless.conf @@ -14,9 +14,11 @@ # - Broadcast upon occuring an event, default no. # ActionChangeState=current,next # - define state transition action for the event. +# WakeLockDurationSec= +# - acquire wakelock for a specfied timeout [EventAction] -Name=BLINKKEY_EDGE +Name=BTKEY_SHORT Enum=1000 Keycode=bluetooth DetectionRangeMsec=0,2000 @@ -25,35 +27,62 @@ ActionBroadcast=yes WakeLockDurationSec=5 [EventAction] -Name=SHORTKEY_LEVEL +Name=BTKEY_LONG Enum=1001 -Keycode=power -DetectionRangeMsec=2000,-1 -TriggerType=level +Keycode=bluetooth +DetectionRangeMsec=2000,7000 +TriggerType=edge ActionBroadcast=yes [EventAction] -Name=SHORTKEY_EDGE +Name=PWKEY_SHORT Enum=1002 Keycode=power -DetectionRangeMsec=2000,7000 +DetectionRangeMsec=0,2000 TriggerType=edge -ActionChangeState=normal,sleep -ActionChangeState=sleep,normal +ActionBroadcast=yes [EventAction] -Name=LONGKEY_LEVEL +Name=PWKEY_LONG Enum=1003 Keycode=power -DetectionRangeMsec=7000,-1 -TriggerType=level -ActionBroadcast=yes +DetectionRangeMsec=2000,7000 +TriggerType=edge +ActionChangeState=normal,sleep +ActionChangeState=sleep,normal [EventAction] -Name=LONGKEY_EDGE +Name=PWKEY_LONGEST Enum=1004 Keycode=power DetectionRangeMsec=7000,-1 TriggerType=edge ConditionVconf=memory/sysman/charger_status,int,0 ActionChangeState=normal,poweroff + +# This doesn't trigger any action. +# It is just for logging that bluetooth key has been pressed for 2000ms +[EventAction] +Name=BTKEY_CHECKPOINT_LONG +Enum=1005 +Keycode=bluetooth +DetectionRangeMsec=2000,-1 +TriggerType=level + +# This doesn't trigger any action. +# It is just for logging that powerkey has been pressed for 2000ms +[EventAction] +Name=PWKEY_CHECKPOINT_LONG +Enum=1006 +Keycode=power +DetectionRangeMsec=2000,-1 +TriggerType=level + +# Powerkey has been pressed for 7000ms +# It is just for logging that powerkey has been pressed for 7000ms +[EventAction] +Name=PWKEY_CHECKPOINT_LONGEST +Enum=1007 +Keycode=power +DetectionRangeMsec=7000,-1 +TriggerType=level -- 2.7.4 From d932a1f0057f9892d2ad11b042eeed3aebf04c9d Mon Sep 17 00:00:00 2001 From: Youngjae Cho Date: Thu, 16 Jun 2022 14:22:07 +0900 Subject: [PATCH 15/16] input: add broadcasting action for level event Change-Id: I57090ba79f082d9c8c2a3c657e586ccc7f12a97f Signed-off-by: Youngjae Cho --- conf/input-profile-iot-headless.conf | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/conf/input-profile-iot-headless.conf b/conf/input-profile-iot-headless.conf index a2c0284..0545f06 100644 --- a/conf/input-profile-iot-headless.conf +++ b/conf/input-profile-iot-headless.conf @@ -60,29 +60,26 @@ TriggerType=edge ConditionVconf=memory/sysman/charger_status,int,0 ActionChangeState=normal,poweroff -# This doesn't trigger any action. -# It is just for logging that bluetooth key has been pressed for 2000ms [EventAction] Name=BTKEY_CHECKPOINT_LONG Enum=1005 Keycode=bluetooth DetectionRangeMsec=2000,-1 TriggerType=level +ActionBroadcast=yes -# This doesn't trigger any action. -# It is just for logging that powerkey has been pressed for 2000ms [EventAction] Name=PWKEY_CHECKPOINT_LONG Enum=1006 Keycode=power DetectionRangeMsec=2000,-1 TriggerType=level +ActionBroadcast=yes -# Powerkey has been pressed for 7000ms -# It is just for logging that powerkey has been pressed for 7000ms [EventAction] Name=PWKEY_CHECKPOINT_LONGEST Enum=1007 Keycode=power DetectionRangeMsec=7000,-1 TriggerType=level +ActionBroadcast=yes -- 2.7.4 From 357be092c844952322166dbceb083dbcbe46166f Mon Sep 17 00:00:00 2001 From: Youngjae Cho Date: Thu, 16 Jun 2022 14:23:50 +0900 Subject: [PATCH 16/16] input: rearrange EventAction in chronological order Change-Id: Idd1363d61ca4c303936fcd027b812eb57c6efb5c Signed-off-by: Youngjae Cho --- conf/input-profile-iot-headless.conf | 48 ++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/conf/input-profile-iot-headless.conf b/conf/input-profile-iot-headless.conf index 0545f06..3acdc6a 100644 --- a/conf/input-profile-iot-headless.conf +++ b/conf/input-profile-iot-headless.conf @@ -18,33 +18,24 @@ # - acquire wakelock for a specfied timeout [EventAction] -Name=BTKEY_SHORT +Name=PWKEY_SHORT Enum=1000 -Keycode=bluetooth +Keycode=power DetectionRangeMsec=0,2000 TriggerType=edge ActionBroadcast=yes -WakeLockDurationSec=5 [EventAction] -Name=BTKEY_LONG +Name=PWKEY_CHECKPOINT_LONG Enum=1001 -Keycode=bluetooth -DetectionRangeMsec=2000,7000 -TriggerType=edge -ActionBroadcast=yes - -[EventAction] -Name=PWKEY_SHORT -Enum=1002 Keycode=power -DetectionRangeMsec=0,2000 -TriggerType=edge +DetectionRangeMsec=2000,-1 +TriggerType=level ActionBroadcast=yes [EventAction] Name=PWKEY_LONG -Enum=1003 +Enum=1002 Keycode=power DetectionRangeMsec=2000,7000 TriggerType=edge @@ -52,6 +43,14 @@ ActionChangeState=normal,sleep ActionChangeState=sleep,normal [EventAction] +Name=PWKEY_CHECKPOINT_LONGEST +Enum=1003 +Keycode=power +DetectionRangeMsec=7000,-1 +TriggerType=level +ActionBroadcast=yes + +[EventAction] Name=PWKEY_LONGEST Enum=1004 Keycode=power @@ -61,25 +60,26 @@ ConditionVconf=memory/sysman/charger_status,int,0 ActionChangeState=normal,poweroff [EventAction] -Name=BTKEY_CHECKPOINT_LONG +Name=BTKEY_SHORT Enum=1005 Keycode=bluetooth -DetectionRangeMsec=2000,-1 -TriggerType=level +DetectionRangeMsec=0,2000 +TriggerType=edge ActionBroadcast=yes +WakeLockDurationSec=5 [EventAction] -Name=PWKEY_CHECKPOINT_LONG +Name=BTKEY_CHECKPOINT_LONG Enum=1006 -Keycode=power +Keycode=bluetooth DetectionRangeMsec=2000,-1 TriggerType=level ActionBroadcast=yes [EventAction] -Name=PWKEY_CHECKPOINT_LONGEST +Name=BTKEY_LONG Enum=1007 -Keycode=power -DetectionRangeMsec=7000,-1 -TriggerType=level +Keycode=bluetooth +DetectionRangeMsec=2000,7000 +TriggerType=edge ActionBroadcast=yes -- 2.7.4