Remove Wayland,X11 and EFL dependencies
[platform/core/appfw/aul-1.git] / src / launch.c
1 /*
2  *  aul
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <sys/time.h>
26 #include <fcntl.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <dirent.h>
31 #include <glib.h>
32
33 #include "aul.h"
34 #include "aul_api.h"
35 #include "app_sock.h"
36 #include "perf.h"
37 #include "simple_util.h"
38 #include "launch.h"
39 #include "key.h"
40 #include "aul_util.h"
41
42 static int aul_initialized = 0;
43 static int aul_fd;
44
45 static int (*_aul_handler) (aul_type type, bundle *kb, void *data) = NULL;
46 static void *_aul_data;
47
48
49
50 static int __call_aul_handler(aul_type type, bundle *kb);
51 static int app_resume();
52 static int app_terminate();
53 static void __clear_internal_key(bundle *kb);
54 static inline void __set_stime(bundle *kb);
55 static int __app_start_internal(gpointer data);
56 static int __app_launch_local(bundle *b);
57 static int __send_result_to_launchpad(int fd, int res);
58
59 extern  int aul_launch_fini();
60
61 int aul_is_initialized()
62 {
63         return aul_initialized;
64 }
65
66 static int __call_aul_handler(aul_type type, bundle *kb)
67 {
68         if (_aul_handler)
69                 _aul_handler(type, kb, _aul_data);
70         return 0;
71 }
72
73 int app_start(bundle *kb)
74 {
75         _app_start_res_prepare(kb);
76         __call_aul_handler(AUL_START, kb);
77         return 0;
78 }
79
80 static int app_resume()
81 {
82         __call_aul_handler(AUL_RESUME, NULL);
83         return 0;
84 }
85
86 static int app_terminate()
87 {
88         __call_aul_handler(AUL_TERMINATE, NULL);
89         return 0;
90 }
91
92
93
94
95 /**
96  * @brief       encode kb and send it to 'pid'
97  * @param[in]   pid             receiver's pid
98  * @param[in]   cmd             message's status (APP_START | APP_RESULT)
99  * @param[in]   kb              data
100  */
101 SLPAPI int app_agent_send_cmd(int uid, int cmd, bundle *kb)
102 {
103         int datalen;
104         bundle_raw *kb_data;
105         int res;
106
107         bundle_encode(kb, &kb_data, &datalen);
108         if ((res = __app_agent_send_raw(uid, cmd, kb_data, datalen)) < 0) {
109                 switch (res) {
110                 case -EINVAL:
111                         res = AUL_R_EINVAL;
112                         break;
113                 case -ECOMM:
114                         res = AUL_R_ECOMM;
115                         break;
116                 case -EAGAIN:
117                         res = AUL_R_ETIMEOUT;
118                         break;
119                 case -ELOCALLAUNCH_ID:
120                         res = AUL_R_LOCAL;
121                         break;
122                 case -EILLEGALACCESS:
123                         res = AUL_R_EILLACC;
124                         break;
125                 case -ETERMINATING:
126                         res = AUL_R_ETERMINATING;
127                         break;
128                 case -ENOLAUNCHPAD:
129                         res = AUL_R_ENOLAUNCHPAD;
130                         break;
131                 default:
132                         res = AUL_R_ERROR;
133                 }
134         }
135         free(kb_data);
136
137         return res;
138 }
139
140 SLPAPI int app_agent_send_cmd_with_noreply(int uid, int cmd, bundle *kb)
141 {
142         int datalen;
143         bundle_raw *kb_data;
144         int res;
145
146         bundle_encode(kb, &kb_data, &datalen);
147         if ((res = __app_send_raw_with_noreply(uid, cmd, kb_data, datalen)) < 0) {
148                 switch (res) {
149                 case -EINVAL:
150                         res = AUL_R_EINVAL;
151                         break;
152                 case -ECOMM:
153                         res = AUL_R_ECOMM;
154                         break;
155                 case -EAGAIN:
156                         res = AUL_R_ETIMEOUT;
157                         break;
158                 case -ELOCALLAUNCH_ID:
159                         res = AUL_R_LOCAL;
160                         break;
161                 case -EILLEGALACCESS:
162                         res = AUL_R_EILLACC;
163                         break;
164                 default:
165                         res = AUL_R_ERROR;
166                 }
167         }
168         free(kb_data);
169
170         return res;
171 }
172
173
174
175
176
177
178
179
180
181 /**
182  * @brief       encode kb and send it to 'pid'
183  * @param[in]   pid             receiver's pid
184  * @param[in]   cmd             message's status (APP_START | APP_RESULT)
185  * @param[in]   kb              data
186  */
187 SLPAPI int app_send_cmd(int pid, int cmd, bundle *kb)
188 {
189         int datalen;
190         bundle_raw *kb_data;
191         int res;
192
193         bundle_encode(kb, &kb_data, &datalen);
194         if ((res = __app_send_raw(pid, cmd, kb_data, datalen)) < 0) {
195                 switch (res) {
196                 case -EINVAL:
197                         res = AUL_R_EINVAL;
198                         break;
199                 case -ECOMM:
200                         res = AUL_R_ECOMM;
201                         break;
202                 case -EAGAIN:
203                         res = AUL_R_ETIMEOUT;
204                         break;
205                 case -ELOCALLAUNCH_ID:
206                         res = AUL_R_LOCAL;
207                         break;
208                 case -EILLEGALACCESS:
209                         res = AUL_R_EILLACC;
210                         break;
211                 case -ETERMINATING:
212                         res = AUL_R_ETERMINATING;
213                         break;
214                 case -ENOLAUNCHPAD:
215                         res = AUL_R_ENOLAUNCHPAD;
216                         break;
217                 default:
218                         res = AUL_R_ERROR;
219                 }
220         }
221         free(kb_data);
222
223         return res;
224 }
225
226 SLPAPI int app_send_cmd_with_noreply(int pid, int cmd, bundle *kb)
227 {
228         int datalen;
229         bundle_raw *kb_data;
230         int res;
231
232         bundle_encode(kb, &kb_data, &datalen);
233         if ((res = __app_send_raw_with_noreply(pid, cmd, kb_data, datalen)) < 0) {
234                 switch (res) {
235                 case -EINVAL:
236                         res = AUL_R_EINVAL;
237                         break;
238                 case -ECOMM:
239                         res = AUL_R_ECOMM;
240                         break;
241                 case -EAGAIN:
242                         res = AUL_R_ETIMEOUT;
243                         break;
244                 case -ELOCALLAUNCH_ID:
245                         res = AUL_R_LOCAL;
246                         break;
247                 case -EILLEGALACCESS:
248                         res = AUL_R_EILLACC;
249                         break;
250                 default:
251                         res = AUL_R_ERROR;
252                 }
253         }
254         free(kb_data);
255
256         return res;
257 }
258
259 static void __clear_internal_key(bundle *kb)
260 {
261         bundle_del(kb, AUL_K_CALLER_PID);
262         bundle_del(kb, AUL_K_PKG_NAME);
263         bundle_del(kb, AUL_K_WAIT_RESULT);
264         bundle_del(kb, AUL_K_SEND_RESULT);
265         bundle_del(kb, AUL_K_ARGV0);
266 }
267
268 static inline void __set_stime(bundle *kb)
269 {
270         struct timeval tv;
271         char tmp[MAX_LOCAL_BUFSZ];
272
273         gettimeofday(&tv, NULL);
274         snprintf(tmp, MAX_LOCAL_BUFSZ, "%ld/%ld", tv.tv_sec, tv.tv_usec);
275         bundle_add(kb, AUL_K_STARTTIME, tmp);
276 }
277
278 static int __app_start_internal(gpointer data)
279 {
280         bundle *kb;
281
282         kb = (bundle *) data;
283         app_start(kb);
284         bundle_free(kb);
285
286         return 0;
287 }
288
289 static int __app_launch_local(bundle *b)
290 {
291         if (!aul_is_initialized())
292                 return AUL_R_ENOINIT;
293
294         if (b == NULL) {
295                 _E("bundle for APP_START is NULL");
296         }
297         if (g_idle_add(__app_start_internal, b) > 0)
298                 return AUL_R_OK;
299         else
300                 return AUL_R_ERROR;
301 }
302
303 static int __app_resume_local()
304 {
305         if (!aul_is_initialized())
306                 return AUL_R_ENOINIT;
307
308         app_resume();
309
310         return 0;
311 }
312
313 /**
314  * @brief       start caller with kb
315  * @return      callee's pid
316  */
317 int app_request_to_launchpad(int cmd, const char *pkgname, bundle *kb)
318 {
319         int must_free = 0;
320         int ret = 0;
321
322         SECURE_LOGD("launch request : %s", pkgname);
323         if (kb == NULL) {
324                 kb = bundle_create();
325                 must_free = 1;
326         } else
327                 __clear_internal_key(kb);
328
329         bundle_add(kb, AUL_K_PKG_NAME, pkgname);
330         __set_stime(kb);
331         ret = app_send_cmd(AUL_UTIL_PID, cmd, kb);
332
333         _D("launch request result : %d", ret);
334         if (ret == AUL_R_LOCAL) {
335                 _E("app_request_to_launchpad : Same Process Send Local");
336                 bundle *b;
337
338                 switch (cmd) {
339                         case APP_START:
340                         case APP_START_RES:
341                                 b = bundle_dup(kb);
342                                 ret = __app_launch_local(b);
343                                 break;
344                         case APP_OPEN:
345                         case APP_RESUME:
346                         case APP_RESUME_BY_PID:
347                                 ret = __app_resume_local();
348                                 break;
349                         default:
350                                 _E("no support packet");
351                 }
352
353         }
354
355         /* cleanup */
356         if (must_free)
357                 bundle_free(kb);
358
359         return ret;
360 }
361
362 static int __send_result_to_launchpad(int fd, int res)
363 {
364         if (send(fd, &res, sizeof(int), MSG_NOSIGNAL) < 0) {
365                 if (errno == EPIPE) {
366                         _E("send failed due to EPIPE.\n");
367                         close(fd);
368                         return -1;
369                 }
370                 _E("send fail to client");
371         }
372         close(fd);
373         return 0;
374 }
375
376 /**
377  * @brief       caller & callee's sock handler
378  */
379 int aul_sock_handler(int fd)
380 {
381         app_pkt_t *pkt;
382         bundle *kbundle;
383         int clifd;
384         struct ucred cr;
385
386         const char *pid_str;
387         int pid;
388         int ret;
389
390         if ((pkt = __app_recv_raw(fd, &clifd, &cr)) == NULL) {
391                 _E("recv error");
392                 return -1;
393         }
394
395         if (pkt->cmd != APP_RESULT && pkt->cmd != APP_CANCEL && cr.uid != 0) {
396                 _E("security error");
397                 __send_result_to_launchpad(clifd, -1);
398                 free(pkt);
399                 return -1;
400         }
401
402         if (pkt->cmd != APP_RESULT && pkt->cmd != APP_CANCEL) {
403                 ret = __send_result_to_launchpad(clifd, 0);
404                 if (ret < 0) {
405                         free(pkt);
406                         return -1;
407                 }
408         } else {
409                 close(clifd);
410         }
411
412         switch (pkt->cmd) {
413         case APP_START: /* run in callee */
414         case APP_START_RES:
415                 kbundle = bundle_decode(pkt->data, pkt->len);
416                 if (kbundle == NULL)
417                         goto err;
418                 app_start(kbundle);
419                 bundle_free(kbundle);
420                 break;
421
422         case APP_OPEN:  /* run in callee */
423         case APP_RESUME:
424         case APP_RESUME_BY_PID:
425                 app_resume();
426                 break;
427
428         case APP_TERM_BY_PID:   /* run in callee */
429                 app_terminate();
430                 break;
431
432         case APP_TERM_REQ_BY_PID:       /* run in callee */
433                 app_subapp_terminate_request();
434                 break;
435
436         case APP_RESULT:        /* run in caller */
437         case APP_CANCEL:
438                 kbundle = bundle_decode(pkt->data, pkt->len);
439                 if (kbundle == NULL)
440                         goto err;
441
442                 pid_str = bundle_get_val(kbundle, AUL_K_CALLEE_PID);
443                 pid = atoi(pid_str);
444
445                 app_result(pkt->cmd, kbundle, pid);
446                 bundle_free(kbundle);
447                 break;
448
449         case APP_KEY_EVENT:     /* run in caller */
450                 kbundle = bundle_decode(pkt->data, pkt->len);
451                 if (kbundle == NULL)
452                         goto err;
453                 app_key_event(kbundle);
454                 bundle_free(kbundle);
455                 break;
456
457         default:
458                 _E("no support packet");
459         }
460
461         free(pkt);
462         return 0;
463
464 err:
465         free(pkt);
466         return -1;
467 }
468
469 int aul_make_bundle_from_argv(int argc, char **argv, bundle **kb)
470 {
471         int ac = 1;
472
473         char *buf = NULL;
474
475         *kb = bundle_create();
476         if (*kb == NULL)
477                 return AUL_R_ERROR;
478
479         if (argv == NULL)
480                 return AUL_R_OK;
481
482         if ((argv != NULL) && (argv[0] != NULL)) {
483                 buf = strdup(argv[0]);
484                 if (NULL == buf) {
485                         _E("Malloc failed");
486                         return AUL_R_ERROR;
487                 }
488
489                 bundle_add(*kb, AUL_K_ARGV0, buf);
490         }
491         if (buf) {              /*Prevent FIX: ID 38717 */
492                 free(buf);
493                 buf = NULL;
494         }
495
496         while (ac < argc) {
497                 if (ac + 1 == argc) {
498                         if (bundle_add(*kb, argv[ac], "") < 0) {
499                                 _E("bundle add error pos - %d", ac);
500                                 return AUL_R_ECANCELED;
501                         }
502                 } else {
503                         if (bundle_add(*kb, argv[ac], argv[ac + 1]) < 0) {
504                                 _E("bundle add error pos - %d", ac);
505                                 return AUL_R_ECANCELED;
506                         }
507                 }
508                 ac = ac + 2;
509         }
510
511         return AUL_R_OK;
512 }
513
514 int aul_register_init_callback(
515         int (*aul_handler) (aul_type type, bundle *, void *), void *data)
516 {
517         /* Save start handler function in static var */
518         _aul_handler = aul_handler;
519         _aul_data = data;
520         return 0;
521 }
522
523 int aul_initialize()
524 {
525         if (aul_initialized) {
526                 //_E("aul already initialized");
527                 return AUL_R_ECANCELED;
528         }
529
530         aul_fd = __create_server_sock(getpid());
531         if (aul_fd < 0) {
532                 _E("aul_init create sock failed");
533                 return AUL_R_ECOMM;
534         }
535         aul_initialized = 1;
536
537         return aul_fd;
538 }
539
540 SLPAPI void aul_finalize()
541 {
542
543         aul_launch_fini();
544
545         if (aul_initialized) {
546                 close(aul_fd);
547         }
548
549         return;
550 }
551
552
553 SLPAPI int aul_launch_app(const char *appid, bundle *kb)
554 {
555         int ret;
556
557         if (appid == NULL)
558                 return AUL_R_EINVAL;
559
560         ret = app_request_to_launchpad(APP_START, appid, kb);
561         return ret;
562 }
563
564 SLPAPI int aul_open_app(const char *appid)
565 {
566         int ret;
567
568         if (appid == NULL)
569                 return AUL_R_EINVAL;
570
571         ret = app_request_to_launchpad(APP_OPEN, appid, NULL);
572         return ret;
573 }
574
575 SLPAPI int aul_resume_app(const char *appid)
576 {
577         int ret;
578
579         if (appid == NULL)
580                 return AUL_R_EINVAL;
581
582         ret = app_request_to_launchpad(APP_RESUME, appid, NULL);
583         return ret;
584 }
585
586 SLPAPI int aul_resume_pid(int pid)
587 {
588         char pkgname[MAX_PID_STR_BUFSZ];
589         int ret;
590
591         if (pid <= 0)
592                 return AUL_R_EINVAL;
593
594         snprintf(pkgname, MAX_PID_STR_BUFSZ, "%d", pid);
595         ret = app_request_to_launchpad(APP_RESUME_BY_PID, pkgname, NULL);
596         return ret;
597 }
598
599 SLPAPI int aul_terminate_pid(int pid)
600 {
601         char pkgname[MAX_PID_STR_BUFSZ];
602         int ret;
603
604         if (pid <= 0)
605                 return AUL_R_EINVAL;
606
607         snprintf(pkgname, MAX_PID_STR_BUFSZ, "%d", pid);
608         ret = app_request_to_launchpad(APP_TERM_BY_PID, pkgname, NULL);
609         return ret;
610 }
611
612 SLPAPI int aul_kill_pid(int pid)
613 {
614         char pkgname[MAX_PID_STR_BUFSZ];
615         int ret;
616
617         if (pid <= 0)
618                 return AUL_R_EINVAL;
619
620         snprintf(pkgname, MAX_PID_STR_BUFSZ, "%d", pid);
621         ret = app_request_to_launchpad(APP_KILL_BY_PID, pkgname, NULL);
622         return ret;
623 }
624
625 /* vi: set ts=8 sts=8 sw=8: */
626