2a9277723056a21ef94b552e9dc310cc5586033d
[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
27 #include <aul.h>
28 #include <vconf.h>
29 #include <signal.h>
30
31 #include "starter.h"
32 #include "lock_mgr.h"
33 #include "home_mgr.h"
34 #include "hw_key.h"
35 #include "process_mgr.h"
36 #include "util.h"
37 #include "status.h"
38 #include "hw_key.h"
39
40
41
42 #if 0
43 static void _hide_home(void)
44 {
45         int seq = status_active_get()->starter_sequence;
46         ret_if(seq == 1);
47
48         vconf_set_int(VCONFKEY_STARTER_SEQUENCE, 0);
49 }
50 #endif
51
52
53
54 static void _show_home(void)
55 {
56         vconf_set_int(VCONFKEY_STARTER_SEQUENCE, 1);
57 }
58
59
60
61 static void _signal_handler(int signum, siginfo_t *info, void *unused)
62 {
63     _D("_signal_handler : Terminated...");
64     elm_exit();
65 }
66
67
68
69 static int _power_off_cb(status_active_key_e key, void *data)
70 {
71         int val = status_active_get()->sysman_power_off_status;
72
73         if (val == VCONFKEY_SYSMAN_POWER_OFF_DIRECT
74                 || val == VCONFKEY_SYSMAN_POWER_OFF_RESTART)
75         {
76             _D("_power_off_cb : Terminated...");
77             elm_exit();
78         }
79
80         return 1;
81 }
82
83
84
85 static void _language_changed_cb(keynode_t *node, void *data)
86 {
87         char *lang = NULL;
88
89         ret_if(!node);
90
91         lang = vconf_keynode_get_str(node);
92         ret_if(!lang);
93
94         _D("language is changed : %s", lang);
95
96         elm_language_set(lang);
97 }
98
99
100
101 static int _set_i18n(const char *domain, const char *dir)
102 {
103         char *r = NULL;
104
105         if (domain == NULL) {
106                 errno = EINVAL;
107                 return -1;
108         }
109
110         char *lang = vconf_get_str(VCONFKEY_LANGSET);
111         r = setlocale(LC_ALL, lang);
112         if (!r) {
113                 _E("setlocale() error");
114         }
115         if (lang) {
116                 free(lang);
117         }
118
119         r = bindtextdomain(domain, dir);
120         if (!r) {
121                 _E("bindtextdomain() error");
122         }
123
124         r = textdomain(domain);
125         if (!r) {
126                 _E("textdomain() error");
127         }
128
129         if (vconf_notify_key_changed(VCONFKEY_LANGSET, _language_changed_cb, NULL) < 0) {
130                 _E("Failed to register changed cb : %s", VCONFKEY_LANGSET);
131         }
132
133         return 0;
134 }
135
136
137
138 static int _check_dead_signal(int pid, void *data)
139 {
140 #ifndef TIZEN_ARCH_ARM64
141         int home_pid = 0;
142         int volume_pid = 0;
143         int indicator_pid = 0;
144         int quickpanel_pid = 0;
145         int lock_pid = 0;
146
147         _D("Process %d is termianted", pid);
148
149         if (pid < 0) {
150                 _E("pid : %d", pid);
151                 return 0;
152         }
153
154         /*
155          * If the architecture is not 64bit,
156          * starter try to re-launch these apps when the app is dead.
157          */
158         home_pid = home_mgr_get_home_pid();
159         volume_pid = home_mgr_get_volume_pid();
160         indicator_pid = home_mgr_get_indicator_pid();
161         quickpanel_pid = home_mgr_get_quickpanel_pid();
162         lock_pid = lock_mgr_get_lock_pid();
163
164         if (pid == home_pid) {
165                 _D("Homescreen is dead");
166                 home_mgr_relaunch_homescreen();
167         } else if (pid == volume_pid) {
168                 _D("volume is dead");
169                 home_mgr_relaunch_volume();
170         } else if (pid == indicator_pid) {
171                 _D("indicator is dead");
172                 home_mgr_relaunch_indicator();
173         } else if (pid == quickpanel_pid) {
174                 _D("quickpanel is dead");
175                 home_mgr_relaunch_quickpanel();
176         } else if (pid == lock_pid) {
177                 _D("lockscreen is dead");
178                 lock_mgr_unlock();
179         } else {
180                 _D("Unknown process, ignore it");
181         }
182 #else
183         _D("Process %d is termianted", pid);
184
185         if (pid < 0) {
186                 _E("pid : %d", pid);
187                 return 0;
188         }
189 #endif
190
191         return 0;
192 }
193
194
195
196 static void _init(struct appdata *ad)
197 {
198         struct sigaction act;
199         char err_buf[128] = {0,};
200
201         memset(&act,0x00,sizeof(struct sigaction));
202         act.sa_sigaction = _signal_handler;
203         act.sa_flags = SA_SIGINFO;
204
205         int ret = sigemptyset(&act.sa_mask);
206         if (ret < 0) {
207                 if (strerror_r(errno, err_buf, sizeof(err_buf)) == 0) {
208                         _E("Failed to sigemptyset[%d / %s]", errno, err_buf);
209                 }
210         }
211         ret = sigaddset(&act.sa_mask, SIGTERM);
212         if (ret < 0) {
213                 if (strerror_r(errno, err_buf, sizeof(err_buf)) == 0) {
214                         _E("Failed to sigaddset[%d / %s]", errno, err_buf);
215                 }
216         }
217         ret = sigaction(SIGTERM, &act, NULL);
218         if (ret < 0) {
219                 if (strerror_r(errno, err_buf, sizeof(err_buf)) == 0) {
220                         _E("Failed to sigaction[%d / %s]", errno, err_buf);
221                 }
222         }
223
224         _set_i18n(PACKAGE, LOCALEDIR);
225
226         status_register();
227         status_active_register_cb(STATUS_ACTIVE_KEY_SYSMAN_POWER_OFF_STATUS, _power_off_cb, NULL);
228
229         hw_key_create_window();
230
231         lock_mgr_init();
232         home_mgr_init(NULL);
233
234         _show_home();
235
236         aul_listen_app_dead_signal(_check_dead_signal, NULL);
237 }
238
239
240
241 static void _fini(struct appdata *ad)
242 {
243         hw_key_destroy_window();
244
245         home_mgr_fini();
246         lock_mgr_fini();
247
248         status_active_unregister_cb(STATUS_ACTIVE_KEY_SYSMAN_POWER_OFF_STATUS, _power_off_cb);
249         status_unregister();
250
251         if (vconf_ignore_key_changed(VCONFKEY_LANGSET, _language_changed_cb) < 0) {
252                 _E("Failed to unregister changed cb : %s", VCONFKEY_LANGSET);
253         }
254 }
255
256
257
258 int main(int argc, char *argv[])
259 {
260         struct appdata ad;
261
262         _D("starter is launched..!!");
263
264         elm_init(argc, argv);
265         _init(&ad);
266
267         malloc_trim(0);
268         elm_run();
269
270         _fini(&ad);
271         elm_shutdown();
272
273         return 0;
274 }