power: refactor poweroff sequence 69/274969/8 accepted/tizen/unified/20220526.144053 submit/tizen/20220525.001052
authorYoungjae Cho <y0.cho@samsung.com>
Fri, 13 May 2022 01:49:05 +0000 (10:49 +0900)
committerHyotaek Shim <hyotaek.shim@samsung.com>
Mon, 16 May 2022 02:53:32 +0000 (02:53 +0000)
This is intermediate patch before applying power-state-wait mechanism
to power-off.

Change-Id: Ie5e302962ffd206b61a8b3f9857e83e22f83ed17
Signed-off-by: Youngjae Cho <y0.cho@samsung.com>
plugins/iot-headed/display/core.c
plugins/mobile/display/core.c
plugins/tv/display/core.c
plugins/wearable/display/core.c
src/power/power-off.c
src/power/power-off.h
src/shared/device-notifier.c
src/shared/device-notifier.h

index 841818b..31d05af 100644 (file)
@@ -1729,17 +1729,6 @@ static int update_setting(int key_idx, int val)
                if (get_pm_cur_state() == S_NORMAL)
                        states[get_pm_cur_state()].trans(EVENT_INPUT);
                break;
-       case SETTING_POWEROFF:
-               switch (val) {
-               case POWEROFF_TYPE_NONE:
-                       clear_pm_status_flag(PWROFF_FLAG);
-                       break;
-               case POWEROFF_TYPE_DIRECT:
-               case POWEROFF_TYPE_RESTART:
-                       set_pm_status_flag(PWROFF_FLAG);
-                       break;
-               }
-               break;
        case SETTING_POWER_CUSTOM_BRIGHTNESS:
                if (val == VCONFKEY_PM_CUSTOM_BRIGHTNESS_ON)
                        backlight_ops->set_custom_status(true);
@@ -2046,6 +2035,23 @@ static int input_init_handler(void)
        return 0;
 }
 
+static int poweroff_triggered_callback(void *udata)
+{
+       int val = (int)(intptr_t) udata;
+
+       switch (val) {
+       case POWEROFF_TYPE_NONE:
+               clear_pm_status_flag(PWROFF_FLAG);
+               break;
+       case POWEROFF_TYPE_DIRECT:
+       case POWEROFF_TYPE_RESTART:
+               set_pm_status_flag(PWROFF_FLAG);
+               break;
+       }
+
+       return 0;
+}
+
 static void esd_action(void)
 {
        const struct device_ops *touchscreen_ops = NULL;
@@ -2111,6 +2117,7 @@ static void display_init(void *data)
        register_notifier(DEVICE_NOTIFIER_BATTERY_HEALTH, battery_health_changed);
        register_notifier(DEVICE_NOTIFIER_DISPLAY_BRIGHTNESS, display_brightness_changed);
        register_notifier(DEVICE_NOTIFIER_LCD_AUTOBRT_SENSING, display_auto_brightness_sensing);
+       register_notifier(DEVICE_NOTIFIER_POWEROFF_TRIGGERED, poweroff_triggered_callback);
 
        init_save_userlock();
 
index 918ae54..3011edf 100644 (file)
@@ -1739,17 +1739,6 @@ static int update_setting(int key_idx, int val)
                if (get_pm_cur_state() == S_NORMAL)
                        states[get_pm_cur_state()].trans(EVENT_INPUT);
                break;
-       case SETTING_POWEROFF:
-               switch (val) {
-               case POWEROFF_TYPE_NONE:
-                       clear_pm_status_flag(PWROFF_FLAG);
-                       break;
-               case POWEROFF_TYPE_DIRECT:
-               case POWEROFF_TYPE_RESTART:
-                       set_pm_status_flag(PWROFF_FLAG);
-                       break;
-               }
-               break;
        case SETTING_POWER_CUSTOM_BRIGHTNESS:
                if (val == VCONFKEY_PM_CUSTOM_BRIGHTNESS_ON)
                        backlight_ops->set_custom_status(true);
@@ -2052,6 +2041,23 @@ static int input_init_handler(void)
        return 0;
 }
 
+static int poweroff_triggered_callback(void *udata)
+{
+       int val = (int)(intptr_t) udata;
+
+       switch (val) {
+       case POWEROFF_TYPE_NONE:
+               clear_pm_status_flag(PWROFF_FLAG);
+               break;
+       case POWEROFF_TYPE_DIRECT:
+       case POWEROFF_TYPE_RESTART:
+               set_pm_status_flag(PWROFF_FLAG);
+               break;
+       }
+
+       return 0;
+}
+
 static void esd_action(void)
 {
        const struct device_ops *touchscreen_ops = NULL;
@@ -2117,6 +2123,7 @@ static void display_init(void *data)
        register_notifier(DEVICE_NOTIFIER_BATTERY_HEALTH, battery_health_changed);
        register_notifier(DEVICE_NOTIFIER_DISPLAY_BRIGHTNESS, display_brightness_changed);
        register_notifier(DEVICE_NOTIFIER_LCD_AUTOBRT_SENSING, display_auto_brightness_sensing);
+       register_notifier(DEVICE_NOTIFIER_POWEROFF_TRIGGERED, poweroff_triggered_callback);
 
        init_save_userlock();
 
index 61f435a..3203445 100644 (file)
@@ -1729,17 +1729,6 @@ static int update_setting(int key_idx, int val)
                if (get_pm_cur_state() == S_NORMAL)
                        states[get_pm_cur_state()].trans(EVENT_INPUT);
                break;
-       case SETTING_POWEROFF:
-               switch (val) {
-               case POWEROFF_TYPE_NONE:
-                       clear_pm_status_flag(PWROFF_FLAG);
-                       break;
-               case POWEROFF_TYPE_DIRECT:
-               case POWEROFF_TYPE_RESTART:
-                       set_pm_status_flag(PWROFF_FLAG);
-                       break;
-               }
-               break;
        case SETTING_POWER_CUSTOM_BRIGHTNESS:
                if (val == VCONFKEY_PM_CUSTOM_BRIGHTNESS_ON)
                        backlight_ops->set_custom_status(true);
@@ -2043,6 +2032,23 @@ static int input_init_handler(void)
        return 0;
 }
 
+static int poweroff_triggered_callback(void *udata)
+{
+       int val = (int)(intptr_t) udata;
+
+       switch (val) {
+       case POWEROFF_TYPE_NONE:
+               clear_pm_status_flag(PWROFF_FLAG);
+               break;
+       case POWEROFF_TYPE_DIRECT:
+       case POWEROFF_TYPE_RESTART:
+               set_pm_status_flag(PWROFF_FLAG);
+               break;
+       }
+
+       return 0;
+}
+
 static void esd_action(void)
 {
        const struct device_ops *touchscreen_ops = NULL;
@@ -2108,6 +2114,7 @@ static void display_init(void *data)
        register_notifier(DEVICE_NOTIFIER_BATTERY_HEALTH, battery_health_changed);
        register_notifier(DEVICE_NOTIFIER_DISPLAY_BRIGHTNESS, display_brightness_changed);
        register_notifier(DEVICE_NOTIFIER_LCD_AUTOBRT_SENSING, display_auto_brightness_sensing);
+       register_notifier(DEVICE_NOTIFIER_POWEROFF_TRIGGERED, poweroff_triggered_callback);
 
        init_save_userlock();
 
index ff2c6e0..d8bfcfe 100644 (file)
@@ -2001,17 +2001,6 @@ static int update_setting(int key_idx, int val)
                if (get_pm_cur_state() == S_NORMAL)
                        states[get_pm_cur_state()].trans(EVENT_INPUT);
                break;
-       case SETTING_POWEROFF:
-               switch (val) {
-               case POWEROFF_TYPE_NONE:
-                       clear_pm_status_flag(PWROFF_FLAG);
-                       break;
-               case POWEROFF_TYPE_DIRECT:
-               case POWEROFF_TYPE_RESTART:
-                       set_pm_status_flag(PWROFF_FLAG);
-                       break;
-               }
-               break;
        case SETTING_POWER_CUSTOM_BRIGHTNESS:
                if (val == VCONFKEY_PM_CUSTOM_BRIGHTNESS_ON)
                        backlight_ops->set_custom_status(true);
@@ -2335,6 +2324,23 @@ static int input_init_handler(void)
        return 0;
 }
 
+static int poweroff_triggered_callback(void *udata)
+{
+       int val = (int)(intptr_t) udata;
+
+       switch (val) {
+       case POWEROFF_TYPE_NONE:
+               clear_pm_status_flag(PWROFF_FLAG);
+               break;
+       case POWEROFF_TYPE_DIRECT:
+       case POWEROFF_TYPE_RESTART:
+               set_pm_status_flag(PWROFF_FLAG);
+               break;
+       }
+
+       return 0;
+}
+
 static void esd_action(void)
 {
        const struct device_ops *touchscreen_ops = NULL;
@@ -2438,6 +2444,7 @@ static void display_init(void *data)
        register_notifier(DEVICE_NOTIFIER_BATTERY_HEALTH, battery_health_changed);
        register_notifier(DEVICE_NOTIFIER_DISPLAY_BRIGHTNESS, display_brightness_changed);
        register_notifier(DEVICE_NOTIFIER_LCD_AUTOBRT_SENSING, display_auto_brightness_sensing);
+       register_notifier(DEVICE_NOTIFIER_POWEROFF_TRIGGERED, poweroff_triggered_callback);
 
        init_save_userlock();
 
index 08bbc3d..4f7d402 100644 (file)
 #define SIGNAL_POWEROFF_STATE       "ChangeState"
 #define POWER_CONF_FILE             "/etc/deviced/power.conf"
 
-static struct display_plugin *disp_plgn;
-
 static struct timeval tv_start_poweroff;
-static GList *poweroff_options;
-static struct power_option poweroff_opt;
+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
@@ -177,24 +175,24 @@ static bool disable_coredump_handler(void)
 
 void poweroff_request_shutdown(void)
 {
-       const char *method;
+       const char *systemd_poweroff_method = "Reboot";
 
-       if (poweroff_opt.type == POWEROFF_TYPE_REBOOT)
-               method = "Reboot";
-       else if (poweroff_opt.type == POWEROFF_TYPE_POWEROFF)
-               method = "PowerOff";
-       else if (poweroff_opt.type == POWEROFF_TYPE_EXIT)
-               method = "Exit";
-       else {
-               _E("Poweroff invalid type(%d).", poweroff_opt.type);
+       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);
                return;
        }
 
-       CRITICAL_LOG("Requested %s via systemd.", method);
+       CRITICAL_LOG("Requested %s via systemd.", systemd_poweroff_method);
        gdbus_call_sync_with_reply_timeout(SYSTEMD_DBUS_DEST,
                                        SYSTEMD_DBUS_PATH,
                                        SYSTEMD_DBUS_IFACE_MANAGER,
-                                       method,
+                                       systemd_poweroff_method,
                                        NULL,
                                        NULL,
                                        POWEROFF_WAIT_SYSTEMD_MS);
@@ -235,19 +233,15 @@ static void poweroff_delay_for_seconds(void)
 
 void poweroff_prepare(void)
 {
-       int off = poweroff_opt.type;
-
-       if (off == POWEROFF_TYPE_POWEROFF)
+       if (poweroff_type == POWEROFF_TYPE_POWEROFF)
                CRITICAL_LOG("Prepare PowerOff.");
-       else if (off == POWEROFF_TYPE_REBOOT)
+       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
@@ -263,28 +257,41 @@ void poweroff_prepare(void)
           - device_change_poweroff()
           - uevent_control_stop()
        */
-       device_notify(DEVICE_NOTIFIER_POWEROFF, &off);
+       device_notify_once(DEVICE_NOTIFIER_POWEROFF, (void *)(intptr_t) poweroff_type);
 }
 
 int poweroff_check_revived(void)
 {
-       for (int i = 0; i < ARRAY_SIZE(poweroff_type_flagpaths); i++) {
-               if (access(poweroff_type_flagpaths[i], F_OK) == 0) {
-                       poweroff_opt.type = i;
-                       poweroff_opt.option = NULL;
-                       return 1;
-               }
+       if (access(POWER_FLAG_POWEROFF, F_OK) == 0) {
+               poweroff_type = POWEROFF_TYPE_POWEROFF;
+               return 1;
+       }
+
+       if (access(POWER_FLAG_REBOOT, F_OK) == 0) {
+               poweroff_type = POWEROFF_TYPE_REBOOT;
+               return 1;
+       }
+
+       if (access(POWER_FLAG_EXIT, F_OK) == 0) {
+               poweroff_type = POWEROFF_TYPE_EXIT;
+               return 1;
        }
 
        return 0;
 }
 
-static void make_power_flag(enum poweroff_type type, const char *option)
+static void mark_poweroff_option(struct power_option *opt)
 {
        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))
                return;
 
@@ -362,30 +369,45 @@ static int poweroff_add_handle(pid_t pid)
        return 0;
 }
 
-static gboolean poweroff_wait_timeout_cb(void *data)
+static gboolean __poweroff_main(gpointer data)
 {
-       char timeout[50] = {0,};
-       pid_t pid = (pid_t)((intptr_t)data);
+       CRITICAL_LOG("Starting poweroff sequence.");
 
-       poweroff_remove_handle(pid);
+       // 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);
 
-       /* All other processes finished cleanup. Poweroff is now on standby */
-       if (poweroff_stage == POWEROFF_WAIT_OTHERS && 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_prepare();
+       poweroff_request_shutdown();
 
-               CRITICAL_LOG("Starting poweroff sequence.");
+       return G_SOURCE_REMOVE;
+}
+
+static void poweroff_main(void)
+{
+       static guint poweroff_id = 0;
 
-               // Watchdog timeout 90 -> 30 sec to reduce delay from unexpected poweroff failure.
-               snprintf(timeout, sizeof(timeout), "WATCHDOG_USEC=%llu", (unsigned long long)POWEROFF_WAIT_SYSTEMD_MS*1000);
-               sd_notify(0, timeout);
+       if (poweroff_id > 0)
+               return;
 
-               make_power_flag(poweroff_opt.type, poweroff_opt.option);
+       /* 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);
+}
 
-               if (disp_plgn->pm_lock_internal)
-                       disp_plgn->pm_lock_internal(INTERNAL_LOCK_POWEROFF, LCD_OFF, STAY_CUR_STATE, 0);
+static gboolean poweroff_wait_timeout_cb(void *data)
+{
+       pid_t pid = (pid_t)((intptr_t)data);
+
+       poweroff_remove_handle(pid);
 
-               poweroff_prepare();
-               poweroff_request_shutdown();
+       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);
        }
@@ -396,20 +418,20 @@ static gboolean poweroff_wait_timeout_cb(void *data)
 static gboolean poweroff_start_timers(void *data)
 {
        struct poweroff_handle *handle = NULL;
-       GList *l;
+       GList *l, *l_next;
        bool timer_exist = false;
-       int pid_alive = 0;
 
+       _D("POWEROFF_STAGE=WAIT_OTHERS");
        poweroff_stage = POWEROFF_WAIT_OTHERS;
 
-       SYS_G_LIST_FOREACH(poweroff_handles, l, handle) {
-               pid_alive = kill(handle->pid, 0);
-               if (pid_alive == -1) {
+       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);
-                       handle->timeout = 0;
+                       SYS_G_LIST_REMOVE(poweroff_handles, handle);
+                       continue;
                }
 
-               _D("Run timer, pid=%d(%s) timeout=%d timeout_id=%d.", handle->pid, handle->comm, handle->timeout, handle->timeout_id);
+               _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,
@@ -418,33 +440,11 @@ static gboolean poweroff_start_timers(void *data)
                timer_exist = true;
        }
 
-       if (timer_exist) {
+       if (timer_exist)
                return G_SOURCE_REMOVE;
-       } else {
-               _D("Handle is NULL.");
-
-               handle = (struct poweroff_handle *)malloc(sizeof(struct poweroff_handle));
-               if (handle == NULL) {
-                       _E("Not enough memory.");
-                       return G_SOURCE_REMOVE;
-               }
 
-               handle->pid = getpid();
-               handle->timeout = 0;
-               handle->timeout_id = g_timeout_add_seconds(handle->timeout,
-                               poweroff_wait_timeout_cb,
-                               (void *)((intptr_t)(handle->pid)));
-
-               if (!handle->timeout_id) {
-                       _E("Failed to timer_add.");
-                       free(handle);
-                       return G_SOURCE_REMOVE;
-               }
-
-               SYS_G_LIST_APPEND(poweroff_handles, handle);
-       }
-
-       _D("Last Timer: timer_id=%d pid=%d timeout=%d", handle->timeout_id, handle->pid, handle->timeout);
+       // No need to wait. Strat main poweroff procedure immediately.
+       poweroff_main();
 
        return G_SOURCE_REMOVE;
 }
@@ -459,31 +459,6 @@ static void system_shutdown_send_system_event(void)
        bundle_free(b);
 }
 
-static int poweroff_option_valid(enum poweroff_type type_e, const char *option)
-{
-       GList *l;
-       struct power_option *elem;
-
-       SYS_G_LIST_FOREACH(poweroff_options, l, elem) {
-               if (elem->type != type_e)
-                       continue;
-
-               /* Do not match option
-               if (option) {
-                       if (elem->option == NULL)
-                               continue;
-                       if (strncmp(elem->option, option, strlen(elem->option)))
-                               continue;
-               } else {
-                       if (elem->option != NULL)
-                               continue;
-               } */
-               return 1;
-       }
-
-       return 0;
-}
-
 static void poweroff_send_broadcast(int status)
 {
        static int old = 0;
@@ -509,43 +484,49 @@ static void poweroff_send_broadcast(int status)
 static int __poweroff_trigger_poweroff(const char *typename, const char *option)
 {
        int ret_val;
+       GList *l;
+       struct power_option *opt = NULL;
 
        if (poweroff_stage >= POWEROFF_TRIGGERED) {
                _E("Duplicate poweroff request. Poweroff was already triggered.");
                return -EINVAL;
        }
 
-       enum poweroff_type type_e = poweroff_name_to_type(typename);
-       if (type_e == POWEROFF_TYPE_INVALID) {
-               _E("Failed to get type enum value(%d).", type_e);
+       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;
        }
 
-       if (poweroff_option_valid(type_e, option)) {
-               poweroff_opt.type = type_e;
-               free(poweroff_opt.option);
-               poweroff_opt.option = NULL;
-               if (option)
-                       poweroff_opt.option = strdup(option);
-       } else {
-               _E("Failed to find supported type(%s). option=%s", typename, (option ? option : "NULL"));
-               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, poweroff_opt.type);
+       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;
-       if (disp_plgn->update_pm_setting)
-               disp_plgn->update_pm_setting(SETTING_POWEROFF, poweroff_opt.type);
+       power_disable_autosleep();
+       device_notify_once(DEVICE_NOTIFIER_POWEROFF_TRIGGERED, (void *)(intptr_t) type);
 
        /* Poweroff event broadcasting */
        system_shutdown_send_system_event();
-       poweroff_send_broadcast(poweroff_opt.type);
+       poweroff_send_broadcast(type);
 
        /* Skip running animation if option is silent */
-       if (poweroff_opt.option != NULL && !strcmp(poweroff_opt.option, "silent"))
+       if (opt && strncmp(opt->option, "silent", sizeof("silent")) == 0)
                _D("Skip running poweroff animation.");
        else
                poweroff_start_animation();
@@ -658,7 +639,7 @@ static GVariant *remove_poweroff_time(GDBusConnection *conn,
        GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
 {
        struct poweroff_handle *handle;
-       GList *l;
+       GList *l, *l_next;
        int ret = 0;
        pid_t pid;
 
@@ -668,22 +649,16 @@ static GVariant *remove_poweroff_time(GDBusConnection *conn,
 
        pid = (pid_t)ret;
 
-       SYS_G_LIST_FOREACH(poweroff_handles, l, handle) {
-               if (handle->pid == pid)
+       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 (handle) {
-               if (handle->timeout_id)
-                       g_source_remove(handle->timeout_id);
-               handle->timeout = 0;
-               handle->timeout_id = g_timeout_add_seconds(handle->timeout,
-                               poweroff_wait_timeout_cb,
-                               (void *)((intptr_t)(handle->pid)));
-       } else {
-               _E("Invalid pid(%d).", pid);
-               ret = -1;
-       }
+       if (poweroff_stage == POWEROFF_WAIT_OTHERS && SYS_G_LIST_LENGTH(poweroff_handles) == 0)
+               poweroff_main();
 
 out:
        return g_variant_new("(i)", ret);
@@ -694,6 +669,9 @@ static const dbus_method_s dbus_methods[] = {
        { "PowerOffWithOption", "ss", "i", dbus_power_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 },
        /* Add methods here */
 };
@@ -723,9 +701,10 @@ static int add_poweroff_option(enum poweroff_type type, const char *option)
        }
 
        opt->type = type;
-       opt->option = (option ? strdup(option) : NULL);
+       if (option)
+               strncpy(opt->option, option, sizeof(opt->option) - 1);
 
-       SYS_G_LIST_APPEND(poweroff_options, opt);
+       SYS_G_LIST_APPEND(poweroff_options_list, opt);
 
        _D("Add %s option=%s", name, opt->option);
 
@@ -744,14 +723,10 @@ void poweroff_remove_wait(pid_t pid)
 
 static int load_config(struct parse_result *result, void *user_data)
 {
-       enum poweroff_type type;
-
        if (MATCH(result->section, "PowerOff") && MATCH(result->name, "Option")) {
-               type = POWEROFF_TYPE_DIRECT;
-               add_poweroff_option(type, result->value);
+               add_poweroff_option(POWEROFF_TYPE_POWEROFF, result->value);
        } else if (MATCH(result->section, "Reboot") && MATCH(result->name, "Option")) {
-               type = POWEROFF_TYPE_RESTART;
-               add_poweroff_option(type, result->value);
+               add_poweroff_option(POWEROFF_TYPE_REBOOT, result->value);
        } else if (MATCH(result->section, "PowerState") && MATCH(result->name, "PowerOffDelaySecond")) {
                sscanf(result->value, "%d", &poweroff_delay_second);
        }
@@ -794,10 +769,3 @@ void power_off_init(void)
 
        poweroff_stage = POWEROFF_DEFAULT;
 }
-
-static void __CONSTRUCTOR__ initialize(void)
-{
-       disp_plgn = get_var_display_plugin();
-       if (!disp_plgn)
-               _E("Failed to get display plugin variable.");
-}
index be605fa..c6f8ebf 100644 (file)
@@ -47,7 +47,7 @@ enum poweroff_type {
 
 struct power_option {
        enum poweroff_type type;
-       char *option;
+       char option[32];
 };
 
 struct poweroff_handle {
index 48c6716..badf4e7 100644 (file)
@@ -69,6 +69,7 @@ static const char *device_notifier_type_str[DEVICE_NOTIFIER_MAX] = {
        NOTIFY_STR(DEVICE_NOTIFIER_DISPLAY_AMBIENT_STATE),
        NOTIFY_STR(DEVICE_NOTIFIER_DISPLAY_LOCK),
        NOTIFY_STR(DEVICE_NOTIFIER_POWER_RESUME),
+       NOTIFY_STR(DEVICE_NOTIFIER_POWEROFF_TRIGGERED),
        NOTIFY_STR(DEVICE_NOTIFIER_POWEROFF),
        NOTIFY_STR(DEVICE_NOTIFIER_APPLICATION_BACKGROUND),
        NOTIFY_STR(DEVICE_NOTIFIER_APPLICATION_FOREGROUND),
index 1635b3d..3acf22e 100644 (file)
@@ -41,6 +41,7 @@ enum device_notifier_type {
        DEVICE_NOTIFIER_DISPLAY_AMBIENT_STATE,
        DEVICE_NOTIFIER_DISPLAY_LOCK,
        DEVICE_NOTIFIER_POWER_RESUME,
+       DEVICE_NOTIFIER_POWEROFF_TRIGGERED,
        DEVICE_NOTIFIER_POWEROFF,
        DEVICE_NOTIFIER_APPLICATION_BACKGROUND,
        DEVICE_NOTIFIER_APPLICATION_FOREGROUND,