4 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
6 * Licensed under the Apache License, Version 2.0 (the License);
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
22 #include <eventsystem.h>
23 #include <libsyscommon/libgdbus.h>
24 #include <libsyscommon/libsystemd.h>
25 #include <libsyscommon/list.h>
26 #include <libsyscommon/file.h>
27 #include <libsyscommon/ini-parser.h>
28 #include <hal/device/hal-board.h>
31 #include "shared/device-notifier.h"
32 #include "shared/common.h"
34 #include "display-ops.h"
35 #include "shared/plugin.h"
36 #include "power-doze.h"
39 #define SYSTEMD_DBUS_SIGNAL_SYSTEM_STARTUP_FINISHED "StartupFinished"
40 #define SYSTEMD_DBUS_SIGNAL_USER_STARTUP_FINISHED "UserSessionStartupFinished"
42 #define INIT_CONF_PATH "/etc/deviced/init.conf"
44 static struct trans_info init_ti = {
50 static struct boot_condition {
53 } bc = { "unknown", "normal" };
55 static guint sig_id[2] = {0, 0};
57 void remove_delayed_init_done_handler(void *data)
59 gdbus_signal_unsubscribe(NULL, sig_id[0]);
60 gdbus_signal_unsubscribe(NULL, sig_id[1]);
63 static void delayed_init_done_received(GDBusConnection *conn,
71 static int system_done = 0;
72 static int user_done = 0;
74 if (strcmp(name, SYSTEMD_DBUS_SIGNAL_SYSTEM_STARTUP_FINISHED) == 0) {
78 system_done = check_system_boot_finished();
79 if (system_done == 0) {
80 _E("System session is not ready yet.");
83 CRITICAL_LOG("System session is ready.");
84 syscommon_notifier_emit_notify_once(DEVICED_NOTIFIER_DELAYED_INIT, &system_done);
86 } else if (strcmp(name, SYSTEMD_DBUS_SIGNAL_USER_STARTUP_FINISHED) == 0) {
90 _I("User session is ready.");
93 if (!system_done || !user_done)
96 remove_delayed_init_done_handler(NULL);
101 void add_delayed_init_done_handler(void *data)
103 /* System Session is loaded completely */
105 sig_id[0] = gdbus_signal_subscribe(NULL,
107 SYSTEMD_DBUS_IFACE_MANAGER,
108 SYSTEMD_DBUS_SIGNAL_SYSTEM_STARTUP_FINISHED,
109 delayed_init_done_received,
113 _E("Failed to init dbus signal(%s).", SYSTEMD_DBUS_SIGNAL_SYSTEM_STARTUP_FINISHED);
115 /* User Session is loaded completely */
116 sig_id[1] = gdbus_signal_subscribe(NULL,
118 SYSTEMD_DBUS_IFACE_MANAGER,
119 SYSTEMD_DBUS_SIGNAL_USER_STARTUP_FINISHED,
120 delayed_init_done_received,
124 _E("Failed to init dbus signal(%s).", SYSTEMD_DBUS_SIGNAL_USER_STARTUP_FINISHED);
127 static void parse_transition_info(const char *action)
129 char curr[16] = { 0, };
130 char next[16] = { 0, };
132 if (sscanf(action, "%15[^,],%15s", curr, next) == 2) {
133 init_ti.curr = convert_action_string_to_power_state(curr);
134 init_ti.next = convert_action_string_to_power_state(next);
138 static void parse_init_ti(const struct parse_result *result)
141 struct section_property *prop;
143 SYS_G_LIST_FOREACH(result->props, elem, prop) {
144 if (MATCH(prop->key, "Enum"))
145 init_ti.reason = atoi(prop->value);
146 else if (MATCH(prop->key, "ActionChangeState"))
147 parse_transition_info(prop->value);
151 static int parse_matching_boot_condition(const struct parse_result *result, void *data)
154 struct section_property *prop;
155 struct boot_condition config_bc = { "", "normal" };
157 if (!MATCH(result->section, "EventAction"))
160 SYS_G_LIST_FOREACH(result->props, elem, prop) {
161 if (MATCH(prop->key, "BootReason"))
162 snprintf(config_bc.reason, sizeof(config_bc.reason), "%s", prop->value);
163 else if (MATCH(prop->key, "BootMode"))
164 snprintf(config_bc.mode, sizeof(config_bc.mode), "%s", prop->value);
167 if (MATCH(bc.reason, config_bc.reason) && MATCH(bc.mode, config_bc.mode))
168 parse_init_ti(result);
173 void initial_transition_by_boot_condition(void)
177 retval = hal_device_board_get_boot_reason(bc.reason, sizeof(bc.reason));
179 _I("Failed to get BootReason, %d. Default change state to normal.", retval);
180 power_request_change_state_strict(DEVICED_POWER_STATE_START, DEVICED_POWER_STATE_NORMAL, 1, NULL);
184 retval = hal_device_board_get_boot_mode(bc.mode, sizeof(bc.mode));
186 _I("Failed to get BootMode, %d", retval);
188 CRITICAL_LOG("BootReason=%s, BootMode=%s", bc.reason, bc.mode);
189 syscommon_config_parse_by_section(INIT_CONF_PATH, parse_matching_boot_condition, NULL);
191 power_request_change_state_strict(init_ti.curr, init_ti.next, init_ti.reason, NULL);