Replacing tray with taskbar
[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 #include <ode/internal-encryption.h>
31
32 #include <aul.h>
33 #include <vconf.h>
34 #include <signal.h>
35
36 #include "starter.h"
37 #include "lock_mgr.h"
38 #include "home_mgr.h"
39 #include "hw_key.h"
40 #include "process_mgr.h"
41 #include "util.h"
42 #include "status.h"
43 #include "hw_key.h"
44 #include "dbus_util.h"
45
46 static void _set_starter_sequence(int val)
47 {
48         vconf_set_int(VCONFKEY_STARTER_SEQUENCE, val);
49 }
50
51
52
53 static void _signal_handler(int signum, siginfo_t *info, void *unused)
54 {
55         _D("_signal_handler : Terminated...");
56         elm_exit();
57 }
58
59
60
61 static int _power_off_cb(status_active_key_e key, void *data)
62 {
63         int val = status_active_get()->sysman_power_off_status;
64
65         if (val > VCONFKEY_SYSMAN_POWER_OFF_NONE) {
66             _D("_power_off_cb : Terminated...");
67             elm_exit();
68         }
69
70         return 1;
71 }
72
73
74
75 static void _language_changed_cb(keynode_t *node, void *data)
76 {
77         char *lang = NULL;
78
79         ret_if(!node);
80
81         lang = vconf_keynode_get_str(node);
82         ret_if(!lang);
83
84         _D("language is changed : %s", lang);
85
86         elm_language_set(lang);
87 }
88
89
90
91 static int _set_i18n(const char *domain, const char *dir)
92 {
93         char *r = NULL;
94
95         if (domain == NULL) {
96                 errno = EINVAL;
97                 return -1;
98         }
99
100         char *lang = vconf_get_str(VCONFKEY_LANGSET);
101         r = setlocale(LC_ALL, lang);
102         if (!r) {
103                 _E("setlocale() error");
104         }
105         if (lang) {
106                 free(lang);
107         }
108
109         r = bindtextdomain(domain, dir);
110         if (!r) {
111                 _E("bindtextdomain() error");
112         }
113
114         r = textdomain(domain);
115         if (!r) {
116                 _E("textdomain() error");
117         }
118
119         if (vconf_notify_key_changed(VCONFKEY_LANGSET, _language_changed_cb, NULL) < 0) {
120                 _E("Failed to register changed cb : %s", VCONFKEY_LANGSET);
121         }
122
123         return 0;
124 }
125
126
127
128 static int _check_dead_signal(int pid, void *data)
129 {
130         int home_pid = 0;
131         int volume_pid = 0;
132         int indicator_pid = 0;
133         int quickpanel_pid = 0;
134         int taskbar_pid = 0;
135         int lock_pid = 0;
136
137         _D("Process %d is termianted", pid);
138
139         if (pid < 0) {
140                 _E("pid : %d", pid);
141                 return 0;
142         }
143
144         /*
145          * starter try to re-launch these apps when the app is dead.
146          */
147         home_pid = home_mgr_get_home_pid();
148         volume_pid = home_mgr_get_volume_pid();
149         indicator_pid = home_mgr_get_indicator_pid();
150         quickpanel_pid = home_mgr_get_quickpanel_pid();
151         taskbar_pid = home_mgr_get_taskbar_pid();
152         lock_pid = lock_mgr_get_lock_pid();
153
154         if (pid == home_pid) {
155                 _D("Homescreen is dead");
156                 home_mgr_relaunch_homescreen();
157         } else if (pid == volume_pid) {
158                 _D("volume is dead");
159                 home_mgr_relaunch_volume();
160         } else if (pid == indicator_pid) {
161                 _D("indicator is dead");
162                 home_mgr_relaunch_indicator();
163         } else if (pid == quickpanel_pid) {
164                 _D("quickpanel is dead");
165                 home_mgr_relaunch_quickpanel();
166         } else if (pid == taskbar_pid) {
167                 _D("taskbar is dead");
168                 home_mgr_relaunch_taskbar();
169         } else if (pid == lock_pid) {
170                 _D("lockscreen is dead");
171                 lock_mgr_unlock();
172         } else {
173                 _D("Unknown process, ignore it");
174         }
175
176         return 0;
177 }
178
179
180
181 static void _launch_apps(void)
182 {
183         /* Tells the service manager that service startup is finished */
184         sd_notify(0, "READY=1");
185
186         /*
187          * After user data partition mount,
188          * launch lockscreen, homescreen, etc.
189          */
190         lock_mgr_init();
191         home_mgr_init(NULL);
192
193         /*
194          * Set the starter sequence vconfkey.
195          * '1' menas that booting seqeunce is done.
196          */
197         _set_starter_sequence(1);
198 }
199
200
201
202 static void _init(void)
203 {
204         struct sigaction act;
205         char err_buf[128] = { 0, };
206         int ret = 0;
207
208         memset(&act, 0x00, sizeof(struct sigaction));
209         act.sa_sigaction = _signal_handler;
210         act.sa_flags = SA_SIGINFO;
211
212         ret = sigemptyset(&act.sa_mask);
213         if (ret < 0) {
214                 if (strerror_r(errno, err_buf, sizeof(err_buf)) == 0) {
215                         _E("Failed to sigemptyset[%d / %s]", errno, err_buf);
216                 }
217         }
218         ret = sigaddset(&act.sa_mask, SIGTERM);
219         if (ret < 0) {
220                 if (strerror_r(errno, err_buf, sizeof(err_buf)) == 0) {
221                         _E("Failed to sigaddset[%d / %s]", errno, err_buf);
222                 }
223         }
224         ret = sigaction(SIGTERM, &act, NULL);
225         if (ret < 0) {
226                 if (strerror_r(errno, err_buf, sizeof(err_buf)) == 0) {
227                         _E("Failed to sigaction[%d / %s]", errno, err_buf);
228                 }
229         }
230
231         _set_i18n(PACKAGE, LOCALEDIR);
232
233         status_register();
234         status_active_register_cb(STATUS_ACTIVE_KEY_SYSMAN_POWER_OFF_STATUS, _power_off_cb, NULL);
235
236         e_dbus_init();
237
238         hw_key_create_window();
239
240         /*
241          * Initialize starter sequence vconfkey.
242          */
243         _set_starter_sequence(0);
244
245         ret = starter_execute_ode_process(BEFORE_LOCKSCREEN);
246         if (!ret) {
247                 _E("Failed to execute ode process");
248         }
249
250         aul_listen_app_dead_signal(_check_dead_signal, NULL);
251 }
252
253
254
255 static void _fini(void)
256 {
257         home_mgr_fini();
258         lock_mgr_fini();
259
260         hw_key_destroy_window();
261
262         e_dbus_shutdown();
263
264         status_active_unregister_cb(STATUS_ACTIVE_KEY_SYSMAN_POWER_OFF_STATUS, _power_off_cb);
265         status_unregister();
266
267         if (vconf_ignore_key_changed(VCONFKEY_LANGSET, _language_changed_cb) < 0) {
268                 _E("Failed to unregister changed cb : %s", VCONFKEY_LANGSET);
269         }
270 }
271
272
273
274 int main(int argc, char *argv[])
275 {
276         int ret = 0;
277         Ecore_Wl2_Display *display = NULL;
278         struct wl_display *displ = NULL;
279
280         _D("starter is launched..!!");
281
282         ret = elm_init(argc, argv);
283         if (!ret) {
284                 _E("elm_init() failed : %d", ret);
285                 return -1;
286         }
287
288         ret = ecore_wl2_init();
289         if (!ret) {
290                 _E("ecore_wl2_init() failed : %d", ret);
291                 elm_shutdown();
292                 return -1;
293         }
294
295         displ = ecore_wl2_display_get(NULL);
296         if (!displ) {
297                 _W("There's no display");
298                 display = ecore_wl2_display_connect(NULL);
299                 if (!display) {
300                         _E("Failed to connect display");
301                         return -1;
302                 }
303         }
304
305         _init();
306
307         malloc_trim(0);
308         elm_run();
309
310         _fini();
311
312         if (display) {
313                 ecore_wl2_display_disconnect(display);
314                 ecore_wl2_shutdown();
315         }
316
317         elm_shutdown();
318
319         return 0;
320 }
321
322
323
324 static void _mount_complete_cb(void *user_data)
325 {
326         _D("Mount is successfully completed");
327 }
328
329
330
331 int starter_execute_ode_process(int booting_state)
332 {
333         _D("This call is before or after Lockscreen: %d", booting_state);
334         int ret = ODE_ERROR_NONE;
335         int ode_state = 0;
336
337         ret = ode_internal_encryption_get_state(&ode_state);
338         if (ret != ODE_ERROR_NONE) {
339                 _E("Failed to get ODE state, ret: %d", ret);
340                 return 0;
341         }
342
343         if (booting_state == BEFORE_LOCKSCREEN) {
344                 if (ode_state == ODE_STATE_ENCRYPTED) {
345                         lock_mgr_init();
346
347                         ret = ode_internal_encryption_set_mount_event_cb(_mount_complete_cb, NULL);
348                         if (ret != ODE_ERROR_NONE) {
349                                 _E("Failed to set mount event cb");
350                         }
351                 } else {
352                         _launch_apps();
353                 }
354         } else if (booting_state == AFTER_LOCKSCREEN) {
355                 if (ode_state == ODE_STATE_ENCRYPTED) {
356                         _D("ODE state is: %d, and we should mount at this time", ode_state);
357
358                         ret = ode_internal_encryption_mount();
359                         if (ret != ODE_ERROR_NONE) {
360                                 _E("Failed to mount");
361                                 return 0;
362                         }
363
364                         sd_notify(0, "READY=1");
365                         home_mgr_init(NULL);
366
367                         vconf_set_int(VCONFKEY_STARTER_SEQUENCE, 1);
368                 } else {
369                         _D("ODE state is: %d, Do nothing", ode_state);
370                 }
371         }
372
373         return 1;
374 }