Fixed the build error for gcc-14
[apps/native/starter.git] / src / mobile / starter.c
1 /*
2  * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <Elementary.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #include <fcntl.h>
23 #include <unistd.h>
24 #include <string.h>
25 #include <malloc.h>
26 #include <Ecore_Wl2.h>
27
28 #include <E_DBus.h>
29 #include <systemd/sd-daemon.h>
30
31 #include <aul.h>
32 #include <vconf.h>
33 #include <signal.h>
34
35 #include "starter.h"
36 #include "lock_mgr.h"
37 #include "home_mgr.h"
38 #include "hw_key.h"
39 #include "process_mgr.h"
40 #include "util.h"
41 #include "status.h"
42 #include "hw_key.h"
43 #include "dbus_util.h"
44
45 static void _set_starter_sequence(int val)
46 {
47         vconf_set_int(VCONFKEY_STARTER_SEQUENCE, val);
48 }
49
50
51
52 static void _signal_handler(int signum, siginfo_t *info, void *unused)
53 {
54         _D("_signal_handler : Terminated...");
55         elm_exit();
56 }
57
58
59
60 static int _power_off_cb(status_active_key_e key, void *data)
61 {
62         int val = status_active_get()->sysman_power_off_status;
63
64         if (val > VCONFKEY_SYSMAN_POWER_OFF_NONE) {
65             _D("_power_off_cb : Terminated...");
66             elm_exit();
67         }
68
69         return 1;
70 }
71
72
73
74 static void _language_changed_cb(keynode_t *node, void *data)
75 {
76         char *lang = NULL;
77
78         ret_if(!node);
79
80         lang = vconf_keynode_get_str(node);
81         ret_if(!lang);
82
83         _D("language is changed : %s", lang);
84
85         elm_language_set(lang);
86 }
87
88
89
90 static int _set_i18n(const char *domain, const char *dir)
91 {
92         char *r = NULL;
93
94         if (domain == NULL) {
95                 errno = EINVAL;
96                 return -1;
97         }
98
99         char *lang = vconf_get_str(VCONFKEY_LANGSET);
100         r = setlocale(LC_ALL, lang);
101         if (!r) {
102                 _E("setlocale() error");
103         }
104         if (lang) {
105                 free(lang);
106         }
107
108         r = bindtextdomain(domain, dir);
109         if (!r) {
110                 _E("bindtextdomain() error");
111         }
112
113         r = textdomain(domain);
114         if (!r) {
115                 _E("textdomain() error");
116         }
117
118         if (vconf_notify_key_changed(VCONFKEY_LANGSET, _language_changed_cb, NULL) < 0) {
119                 _E("Failed to register changed cb : %s", VCONFKEY_LANGSET);
120         }
121
122         return 0;
123 }
124
125
126
127 static int _check_dead_signal(int pid, void *data)
128 {
129         int home_pid = 0;
130         int volume_pid = 0;
131         int indicator_pid = 0;
132         int quickpanel_pid = 0;
133         int taskbar_pid = 0;
134         int lock_pid = 0;
135
136         _D("Process %d is termianted", pid);
137
138         if (pid < 0) {
139                 _E("pid : %d", pid);
140                 return 0;
141         }
142
143         /*
144          * starter try to re-launch these apps when the app is dead.
145          */
146         home_pid = home_mgr_get_home_pid();
147         volume_pid = home_mgr_get_volume_pid();
148         indicator_pid = home_mgr_get_indicator_pid();
149         quickpanel_pid = home_mgr_get_quickpanel_pid();
150         taskbar_pid = home_mgr_get_taskbar_pid();
151         lock_pid = lock_mgr_get_lock_pid();
152
153         if (pid == home_pid) {
154                 _D("Homescreen is dead");
155                 home_mgr_relaunch_homescreen();
156         } else if (pid == volume_pid) {
157                 _D("volume is dead");
158                 home_mgr_relaunch_volume();
159         } else if (pid == indicator_pid) {
160                 _D("indicator is dead");
161                 home_mgr_relaunch_indicator();
162         } else if (pid == quickpanel_pid) {
163                 _D("quickpanel is dead");
164                 home_mgr_relaunch_quickpanel();
165         } else if (pid == taskbar_pid) {
166                 _D("taskbar is dead");
167                 home_mgr_relaunch_taskbar();
168         } else if (pid == lock_pid) {
169                 _D("lockscreen is dead");
170                 lock_mgr_unlock();
171         } else {
172                 _D("Unknown process, ignore it");
173         }
174
175         return 0;
176 }
177
178
179
180 static void _launch_apps(void)
181 {
182         /* Tells the service manager that service startup is finished */
183         sd_notify(0, "READY=1");
184
185         /*
186          * After user data partition mount,
187          * launch lockscreen, homescreen, etc.
188          */
189         lock_mgr_init();
190         home_mgr_init(NULL);
191
192         /*
193          * Set the starter sequence vconfkey.
194          * '1' menas that booting seqeunce is done.
195          */
196         _set_starter_sequence(1);
197 }
198
199
200
201 static void _init(void)
202 {
203         struct sigaction act;
204         char err_buf[128] = { 0, };
205         int ret = 0;
206
207         memset(&act, 0x00, sizeof(struct sigaction));
208         act.sa_sigaction = _signal_handler;
209         act.sa_flags = SA_SIGINFO;
210
211         ret = sigemptyset(&act.sa_mask);
212         if (ret < 0) {
213                 if (strerror_r(errno, err_buf, sizeof(err_buf)) == 0) {
214                         _E("Failed to sigemptyset[%d / %s]", errno, err_buf);
215                 }
216         }
217         ret = sigaddset(&act.sa_mask, SIGTERM);
218         if (ret < 0) {
219                 if (strerror_r(errno, err_buf, sizeof(err_buf)) == 0) {
220                         _E("Failed to sigaddset[%d / %s]", errno, err_buf);
221                 }
222         }
223         ret = sigaction(SIGTERM, &act, NULL);
224         if (ret < 0) {
225                 if (strerror_r(errno, err_buf, sizeof(err_buf)) == 0) {
226                         _E("Failed to sigaction[%d / %s]", errno, err_buf);
227                 }
228         }
229
230         _set_i18n(PACKAGE, LOCALEDIR);
231
232         status_register();
233         status_active_register_cb(STATUS_ACTIVE_KEY_SYSMAN_POWER_OFF_STATUS, _power_off_cb, NULL);
234
235         e_dbus_init();
236
237         hw_key_create_window();
238
239         /*
240          * Initialize starter sequence vconfkey.
241          */
242         _set_starter_sequence(0);
243
244         aul_listen_app_dead_signal(_check_dead_signal, NULL);
245 }
246
247
248
249 static void _fini(void)
250 {
251         home_mgr_fini();
252         lock_mgr_fini();
253
254         hw_key_destroy_window();
255
256         e_dbus_shutdown();
257
258         status_active_unregister_cb(STATUS_ACTIVE_KEY_SYSMAN_POWER_OFF_STATUS, _power_off_cb);
259         status_unregister();
260
261         if (vconf_ignore_key_changed(VCONFKEY_LANGSET, _language_changed_cb) < 0) {
262                 _E("Failed to unregister changed cb : %s", VCONFKEY_LANGSET);
263         }
264 }
265
266
267
268 int main(int argc, char *argv[])
269 {
270         int ret = 0;
271         Ecore_Wl2_Display *display = NULL;
272         struct wl_display *displ = NULL;
273
274         _D("starter is launched..!!");
275
276         ret = elm_init(argc, argv);
277         if (!ret) {
278                 _E("elm_init() failed : %d", ret);
279                 return -1;
280         }
281
282         ret = ecore_wl2_init();
283         if (!ret) {
284                 _E("ecore_wl2_init() failed : %d", ret);
285                 elm_shutdown();
286                 return -1;
287         }
288
289         displ = ecore_wl2_display_get(NULL);
290         if (!displ) {
291                 _W("There's no display");
292                 display = ecore_wl2_display_connect(NULL);
293                 if (!display) {
294                         _E("Failed to connect display");
295                         return -1;
296                 }
297         }
298
299         _init();
300
301         malloc_trim(0);
302         elm_run();
303
304         _fini();
305
306         if (display) {
307                 ecore_wl2_display_disconnect(display);
308                 ecore_wl2_shutdown();
309         }
310
311         elm_shutdown();
312
313         return 0;
314 }
315
316
317
318 static void _mount_complete_cb(void *user_data)
319 {
320         _D("Mount is successfully completed");
321 }