Fix functions related to attach/detach window
[platform/core/appfw/aul-1.git] / src / pkginfo.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 #define _GNU_SOURCE
18 #include <stdio.h>
19 #include <string.h>
20 #include <stdlib.h>
21 #include <bundle_internal.h>
22
23 #include "aul.h"
24 #include "aul_api.h"
25 #include "menu_db_util.h"
26 #include "aul_sock.h"
27 #include "aul_util.h"
28 #include "aul_proc.h"
29 #include "aul_error.h"
30
31 typedef struct _internal_param_t {
32         aul_app_info_iter_fn iter_fn;
33         void *user_data;
34 } internal_param_t;
35
36 static const char *__appid;
37 static const char *__pkgid;
38 static const char *__root_path;
39
40 API int aul_app_get_pid(const char *appid)
41 {
42         return aul_app_get_pid_for_uid(appid, getuid());
43 }
44
45 API int aul_app_get_pid_for_uid(const char *appid, uid_t uid)
46 {
47         int ret;
48         char buf[MAX_PID_STR_BUFSZ];
49         bundle *b;
50
51         if (appid == NULL)
52                 return -1;
53
54         b = bundle_create();
55         if (b == NULL) {
56                 _E("out of memory");
57                 return -1;
58         }
59
60         snprintf(buf, sizeof(buf), "%d", uid);
61         bundle_add(b, AUL_K_APPID, appid);
62         bundle_add(b, AUL_K_TARGET_UID, buf);
63
64         ret = aul_sock_send_bundle(AUL_UTIL_PID, uid, APP_GET_PID,
65                         b, AUL_SOCK_NONE);
66         bundle_free(b);
67
68         return ret;
69 }
70
71 API int aul_app_is_running(const char *appid)
72 {
73         return aul_app_is_running_for_uid(appid, getuid());
74 }
75
76 API int aul_app_is_running_for_uid(const char *appid, uid_t uid)
77 {
78         int ret;
79         char buf[MAX_PID_STR_BUFSZ];
80         bundle *b;
81
82         if (appid == NULL)
83                 return 0;
84
85         b = bundle_create();
86         if (b == NULL) {
87                 _E("out of memory");
88                 return 0;
89         }
90
91         snprintf(buf, sizeof(buf), "%d", uid);
92         bundle_add(b, AUL_K_APPID, appid);
93         bundle_add(b, AUL_K_TARGET_UID, buf);
94
95         ret = aul_sock_send_bundle(AUL_UTIL_PID, uid, APP_IS_RUNNING,
96                         b, AUL_SOCK_NONE);
97         bundle_free(b);
98         if (ret > 0)
99                 return true;
100
101         return 0;
102 }
103
104 static void __running_app_info_cb(app_pkt_t *pkt, void *user_data)
105 {
106         internal_param_t *param = (internal_param_t *)user_data;
107         bundle *b = NULL;
108         aul_app_info info;
109         const char *val;
110
111         if (pkt == NULL || param == NULL) {
112                 _E("Invalid parameter");
113                 return;
114         }
115
116         if (pkt->cmd == APP_GET_INFO_ERROR) {
117                 _E("Failed to get app info");
118                 return;
119         }
120
121         if (pkt->opt & AUL_SOCK_BUNDLE)
122                 b = bundle_decode(pkt->data, pkt->len);
123
124         if (b == NULL)
125                 return;
126
127         val = bundle_get_val(b, AUL_K_PID);
128         if (val == NULL) {
129                 bundle_free(b);
130                 return;
131         }
132         info.pid = atoi(val);
133
134         info.appid = (char *)bundle_get_val(b, AUL_K_APPID);
135         info.app_path = (char *)bundle_get_val(b, AUL_K_EXEC);
136         info.pkgid = (char *)bundle_get_val(b, AUL_K_PKGID);
137         info.instance_id = (char *)bundle_get_val(b, AUL_K_INSTANCE_ID);
138
139         val = bundle_get_val(b, AUL_K_STATUS);
140         if (val == NULL) {
141                 bundle_free(b);
142                 return;
143         }
144         info.status = atoi(val);
145
146         val = bundle_get_val(b, AUL_K_IS_SUBAPP);
147         if (val == NULL) {
148                 bundle_free(b);
149                 return;
150         }
151         info.is_sub_app = atoi(val);
152
153         info.pkg_name = info.appid;
154         param->iter_fn(&info, param->user_data);
155         bundle_free(b);
156 }
157
158 static int __get_running_app_info(int cmd, aul_app_info_iter_fn iter_fn,
159                 void *user_data, uid_t uid)
160 {
161         int ret;
162         int fd;
163         bundle *b;
164         char buf[MAX_PID_STR_BUFSZ];
165         internal_param_t param = {iter_fn, user_data};
166
167         if (iter_fn == NULL)
168                 return AUL_R_EINVAL;
169
170         b = bundle_create();
171         if (b == NULL) {
172                 _E("out of memory");
173                 return AUL_R_ERROR;
174         }
175
176         snprintf(buf, sizeof(buf), "%d", uid);
177         bundle_add(b, AUL_K_TARGET_UID, buf);
178
179         fd = aul_sock_send_bundle(AUL_UTIL_PID, uid, cmd, b, AUL_SOCK_ASYNC);
180         bundle_free(b);
181         if (fd < 0)
182                 return aul_error_convert(fd);
183
184         ret = aul_sock_recv_pkt_with_cb(fd, __running_app_info_cb, &param);
185         if (ret < 0)
186                 return aul_error_convert(ret);
187
188         return AUL_R_OK;
189 }
190
191 API int aul_app_get_running_app_info(aul_app_info_iter_fn iter_fn,
192                 void *user_data)
193 {
194         return aul_app_get_running_app_info_for_uid(iter_fn,
195                         user_data, getuid());
196 }
197
198 API int aul_app_get_running_app_info_for_uid(aul_app_info_iter_fn iter_fn,
199                 void *user_data, uid_t uid)
200 {
201         return __get_running_app_info(APP_RUNNING_INFO, iter_fn,
202                         user_data, uid);
203 }
204
205 API int aul_app_get_all_running_app_info(aul_app_info_iter_fn iter_fn,
206                 void *user_data)
207 {
208         return aul_app_get_all_running_app_info_for_uid(iter_fn,
209                         user_data, getuid());
210 }
211
212 API int aul_app_get_all_running_app_info_for_uid(aul_app_info_iter_fn iter_fn,
213                 void *user_data, uid_t uid)
214 {
215         return __get_running_app_info(APP_ALL_RUNNING_INFO, iter_fn,
216                         user_data, uid);
217 }
218
219 API int aul_app_get_running_app_instance_info(aul_app_info_iter_fn iter_fn,
220                 void *user_data)
221 {
222         return aul_app_get_running_app_instance_info_for_uid(iter_fn,
223                         user_data, getuid());
224 }
225
226 API int aul_app_get_running_app_instance_info_for_uid(
227                 aul_app_info_iter_fn iter_fn, void *user_data, uid_t uid)
228 {
229         return __get_running_app_info(APP_RUNNING_INSTANCE_INFO, iter_fn,
230                         user_data, uid);
231 }
232
233 API void aul_set_preinit_appid(const char *appid)
234 {
235         __appid = appid;
236 }
237
238 const char *__get_preinit_appid(void)
239 {
240         if (!__appid)
241                 __appid = getenv("AUL_APPID");
242
243         return __appid;
244 }
245
246 API void aul_set_preinit_pkgid(const char *pkgid)
247 {
248         __pkgid = pkgid;
249 }
250
251 const char *__get_preinit_pkgid(void)
252 {
253         if (!__pkgid)
254                 __pkgid = getenv("AUL_PKGID");
255
256         return __pkgid;
257 }
258
259 API void aul_set_preinit_root_path(const char *root_path)
260 {
261         __root_path = root_path;
262 }
263
264 API const char *aul_get_preinit_root_path(void)
265 {
266         if (!__root_path)
267                 __root_path = getenv("AUL_ROOT_PATH");
268
269         return __root_path;
270 }
271
272 API int aul_app_get_pkgname_bypid(int pid, char *pkgname, int len)
273 {
274         return aul_app_get_appid_bypid(pid, pkgname, len);
275 }
276
277 API int aul_app_get_appid_bypid_for_uid(int pid, char *appid, int len,
278                 uid_t uid)
279 {
280         app_pkt_t *pkt = NULL;
281         int fd;
282         int ret;
283         const char *preinit_appid;
284         bundle *b;
285         char buf[MAX_PID_STR_BUFSZ];
286
287         if (pid <= 0 || appid == NULL) {
288                 _E("Invalid parameter");
289                 return AUL_R_EINVAL;
290         }
291
292         if (getpid() == pid) {
293                 preinit_appid = __get_preinit_appid();
294                 if (preinit_appid) {
295                         snprintf(appid, len, "%s", preinit_appid);
296                         return AUL_R_OK;
297                 }
298         }
299
300         b = bundle_create();
301         if (b == NULL) {
302                 _E("out of memory");
303                 return AUL_R_ERROR;
304         }
305
306         snprintf(buf, sizeof(buf), "%d", pid);
307         bundle_add(b, AUL_K_PID, buf);
308         snprintf(buf, sizeof(buf), "%d", uid);
309         bundle_add(b, AUL_K_TARGET_UID, buf);
310
311         fd = aul_sock_send_bundle(AUL_UTIL_PID, uid, APP_GET_APPID_BYPID,
312                         b, AUL_SOCK_ASYNC);
313         bundle_free(b);
314         if (fd <= 0)
315                 return AUL_R_ERROR;
316
317         ret = aul_sock_recv_reply_pkt(fd, &pkt);
318         if (ret < 0 || pkt == NULL)
319                 return AUL_R_ERROR;
320
321         if (pkt->cmd == APP_GET_INFO_OK) {
322                 snprintf(appid, len, "%s", pkt->data);
323                 free(pkt);
324                 return AUL_R_OK;
325         }
326         free(pkt);
327
328         return AUL_R_ERROR;
329 }
330
331 API int aul_app_get_appid_bypid(int pid, char *appid, int len)
332 {
333         return aul_app_get_appid_bypid_for_uid(pid, appid, len, getuid());
334 }
335
336 static int __get_pkginfo(int pid, char *buf, int len, uid_t uid)
337 {
338         const char *appid;
339         app_info_from_db *menu_info;
340
341         appid = __get_preinit_appid();
342         if (appid == NULL) {
343                 _E("Failed to get preinit appid - %d", pid);
344                 return -1;
345         }
346
347         menu_info = _get_app_info_from_db_by_appid_user(appid, uid);
348         if (menu_info == NULL) {
349                 _E("Failed to get app info - %s", appid);
350                 return -1;
351         }
352
353         snprintf(buf, len, "%s", _get_pkgid(menu_info));
354         _free_app_info_from_db(menu_info);
355
356         return 0;
357 }
358
359 API int aul_app_get_pkgid_bypid_for_uid(int pid, char *pkgid, int len,
360                 uid_t uid)
361 {
362         app_pkt_t *pkt = NULL;
363         int fd;
364         int ret;
365         const char *preinit_pkgid;
366         bundle *b;
367         char buf[MAX_PID_STR_BUFSZ];
368
369         if (pid <= 0 || pkgid == NULL) {
370                 _E("Invalid parameter");
371                 return AUL_R_EINVAL;
372         }
373
374         if (getpid() == pid) {
375                 preinit_pkgid = __get_preinit_pkgid();
376                 if (preinit_pkgid) {
377                         snprintf(pkgid, len, "%s", preinit_pkgid);
378                         return AUL_R_OK;
379                 } else {
380                         /* fallback (for debugging) */
381                         ret = __get_pkginfo(pid, pkgid, len, uid);
382                         if (ret == 0)
383                                 return AUL_R_OK;
384                 }
385         }
386
387         b = bundle_create();
388         if (b == NULL) {
389                 _E("out of memory");
390                 return AUL_R_ERROR;
391         }
392
393         snprintf(buf, sizeof(buf), "%d", pid);
394         bundle_add(b, AUL_K_PID, buf);
395         snprintf(buf, sizeof(buf), "%d", uid);
396         bundle_add(b, AUL_K_TARGET_UID, buf);
397
398         fd = aul_sock_send_bundle(AUL_UTIL_PID, uid, APP_GET_PKGID_BYPID,
399                         b, AUL_SOCK_ASYNC);
400         bundle_free(b);
401         if (fd <= 0)
402                 return AUL_R_ERROR;
403
404         ret = aul_sock_recv_reply_pkt(fd, &pkt);
405         if (ret < 0 || pkt == NULL)
406                 return AUL_R_ERROR;
407
408         if (pkt->cmd == APP_GET_INFO_OK) {
409                 snprintf(pkgid, len, "%s", pkt->data);
410                 free(pkt);
411                 return AUL_R_OK;
412         }
413         free(pkt);
414
415         return AUL_R_ERROR;
416 }
417
418 API int aul_app_get_pkgid_bypid(int pid, char *pkgid, int len)
419 {
420         return aul_app_get_pkgid_bypid_for_uid(pid, pkgid, len, getuid());
421 }
422
423 API int aul_update_rua_stat_for_uid(bundle *b, uid_t uid)
424 {
425         int ret;
426         char buf[MAX_PID_STR_BUFSZ];
427
428         if (b == NULL) {
429                 _E("Invalid parameter");
430                 return AUL_R_EINVAL;
431         }
432
433         snprintf(buf, sizeof(buf), "%d", uid);
434         bundle_del(b, AUL_K_TARGET_UID);
435         bundle_add(b, AUL_K_TARGET_UID, buf);
436
437         ret = aul_sock_send_bundle(AUL_UTIL_PID, uid,
438                         APP_UPDATE_RUA_STAT, b, AUL_SOCK_NONE);
439         return ret;
440 }
441
442 API int aul_add_rua_history_for_uid(bundle *b, uid_t uid)
443 {
444         int ret;
445         char buf[MAX_PID_STR_BUFSZ];
446
447         if (b == NULL) {
448                 SECURE_LOGE("invalid param");
449                 return AUL_R_EINVAL;
450         }
451
452         snprintf(buf, sizeof(buf), "%d", uid);
453         bundle_del(b, AUL_K_TARGET_UID);
454         bundle_add(b, AUL_K_TARGET_UID, buf);
455
456         ret = aul_sock_send_bundle(AUL_UTIL_PID, uid,
457                         APP_ADD_HISTORY, b, AUL_SOCK_NONE);
458         return ret;
459 }
460
461 API int aul_delete_rua_history_for_uid(bundle *b, uid_t uid)
462 {
463         int ret;
464         char buf[MAX_PID_STR_BUFSZ];
465         bundle *kb = NULL;
466
467         if (b == NULL) {
468                 kb = bundle_create();
469                 if (kb == NULL) {
470                         _E("out of memory");
471                         return AUL_R_ERROR;
472                 }
473
474                 b = kb;
475         }
476
477         snprintf(buf, sizeof(buf), "%d", uid);
478         bundle_del(b, AUL_K_TARGET_UID);
479         bundle_add(b, AUL_K_TARGET_UID, buf);
480
481         ret = aul_sock_send_bundle(AUL_UTIL_PID, uid, APP_REMOVE_HISTORY,
482                         b, AUL_SOCK_NONE);
483         if (kb)
484                 bundle_free(kb);
485
486         return ret;
487 }
488
489 API int aul_set_default_app_by_operation(bundle *b)
490 {
491         int ret;
492
493         if (b == NULL)
494                 return AUL_R_EINVAL;
495
496         ret = aul_sock_send_bundle(AUL_UTIL_PID, getuid(),
497                         APP_SET_APP_CONTROL_DEFAULT_APP, b, AUL_SOCK_NONE);
498         if (ret != 0) {
499                 if (ret == -EILLEGALACCESS)
500                         return AUL_R_EILLACC;
501                 else
502                         return AUL_R_ERROR;
503         }
504
505         return AUL_R_OK;
506 }
507
508 API int aul_unset_default_app_by_operation(const char *app_id)
509 {
510         int ret;
511
512         if (app_id == NULL)
513                 return AUL_R_EINVAL;
514
515         ret = aul_sock_send_raw(AUL_UTIL_PID, getuid(), APP_UNSET_APP_CONTROL_DEFAULT_APP,
516                         (unsigned char *)app_id, strlen(app_id), AUL_SOCK_NONE);
517         if (ret != 0) {
518                 if (ret == -EILLEGALACCESS)
519                         return AUL_R_EILLACC;
520                 else
521                         return AUL_R_ERROR;
522         }
523
524         return AUL_R_OK;
525 }
526
527 API int aul_app_get_last_caller_pid(int pid)
528 {
529         return aul_app_get_last_caller_pid_for_uid(pid, getuid());
530 }
531
532 API int aul_app_get_last_caller_pid_for_uid(int pid, uid_t uid)
533 {
534         int ret;
535         char buf[MAX_PID_STR_BUFSZ];
536         bundle *b;
537
538         if (pid < 0) {
539                 _E("Invalid parameter");
540                 return AUL_R_EINVAL;
541         }
542
543         b = bundle_create();
544         if (b == NULL) {
545                 _E("Failed to create bundle");
546                 return AUL_R_ERROR;
547         }
548
549         snprintf(buf, sizeof(buf), "%d", pid);
550         bundle_add(b, AUL_K_PID, buf);
551         snprintf(buf, sizeof(buf), "%d", uid);
552         bundle_add(b, AUL_K_TARGET_UID, buf);
553
554         ret = aul_sock_send_bundle(AUL_UTIL_PID, uid, APP_GET_LAST_CALLER_PID,
555                         b, AUL_SOCK_NONE);
556         bundle_free(b);
557         if (ret < 0)
558                 return aul_error_convert(ret);
559
560         return ret;
561 }
562
563 API int aul_set_alias_appid(const char *alias_appid, const char *appid)
564 {
565         int ret;
566         bundle *b;
567
568         if (alias_appid == NULL || appid == NULL) {
569                 _E("Invalid parameters");
570                 return AUL_R_EINVAL;
571         }
572
573         b = bundle_create();
574         if (b == NULL) {
575                 _E("out of memory");
576                 return AUL_R_ERROR;
577         }
578         bundle_add(b, AUL_K_ALIAS_APPID, alias_appid);
579         bundle_add(b, AUL_K_APPID, appid);
580
581         ret = aul_sock_send_bundle(AUL_UTIL_PID, getuid(),
582                         APP_SET_ALIAS_APPID, b, AUL_SOCK_NONE);
583         bundle_free(b);
584         if (ret != AUL_R_OK)
585                 return aul_error_convert(ret);
586
587         return AUL_R_OK;
588 }
589
590 API int aul_unset_alias_appid(const char *alias_appid)
591 {
592         int ret;
593         bundle *b;
594
595         if (alias_appid == NULL) {
596                 _E("Invalid parameter");
597                 return AUL_R_EINVAL;
598         }
599
600         b = bundle_create();
601         if (b == NULL) {
602                 _E("out of memory");
603                 return AUL_R_ERROR;
604         }
605         bundle_add(b, AUL_K_ALIAS_APPID, alias_appid);
606
607         ret = aul_sock_send_bundle(AUL_UTIL_PID, getuid(),
608                         APP_UNSET_ALIAS_APPID, b, AUL_SOCK_NONE);
609         bundle_free(b);
610         if (ret != AUL_R_OK)
611                 return aul_error_convert(ret);
612
613         return AUL_R_OK;
614 }
615
616 API int aul_enable_alias_info(const char *appid)
617 {
618         int ret;
619         bundle *b;
620
621         if (appid == NULL) {
622                 _E("Invalid parameter");
623                 return AUL_R_EINVAL;
624         }
625
626         b = bundle_create();
627         if (b == NULL) {
628                 _E("out of memory");
629                 return AUL_R_ERROR;
630         }
631         bundle_add(b, AUL_K_APPID, appid);
632
633         ret = aul_sock_send_bundle(AUL_UTIL_PID, getuid(),
634                         APP_ENABLE_ALIAS_INFO, b, AUL_SOCK_NONE);
635         bundle_free(b);
636         if (ret != AUL_R_OK)
637                 return aul_error_convert(ret);
638
639         return AUL_R_OK;
640 }
641
642 API int aul_disable_alias_info(const char *appid)
643 {
644         int ret;
645         bundle *b;
646
647         if (appid == NULL) {
648                 _E("Invalid parameter");
649                 return AUL_R_EINVAL;
650         }
651
652         b = bundle_create();
653         if (b == NULL) {
654                 _E("out of memory");
655                 return AUL_R_ERROR;
656         }
657         bundle_add(b, AUL_K_APPID, appid);
658
659         ret = aul_sock_send_bundle(AUL_UTIL_PID, getuid(),
660                         APP_DISABLE_ALIAS_INFO, b, AUL_SOCK_NONE);
661         bundle_free(b);
662         if (ret != AUL_R_OK)
663                 return aul_error_convert(ret);
664
665         return AUL_R_OK;
666 }
667
668 API int aul_app_get_instance_id_bypid_for_uid(int pid, char *instance_id,
669                 int len, uid_t uid)
670 {
671         app_pkt_t *pkt = NULL;
672         bundle *b;
673         int ret;
674         int fd;
675         char buf[MAX_PID_STR_BUFSZ];
676
677         if (pid <= 0 || instance_id == NULL) {
678                 _E("Invalid parameter");
679                 return AUL_R_EINVAL;
680         }
681
682         b = bundle_create();
683         if (b == NULL) {
684                 _E("Out of memory");
685                 return AUL_R_ERROR;
686         }
687
688         snprintf(buf, sizeof(buf), "%d", pid);
689         bundle_add(b, AUL_K_PID, buf);
690         snprintf(buf, sizeof(buf), "%d", uid);
691         bundle_add(b, AUL_K_TARGET_UID, buf);
692
693         fd = aul_sock_send_bundle(AUL_UTIL_PID, uid,
694                         APP_GET_INSTANCE_ID_BYPID, b,
695                         AUL_SOCK_ASYNC);
696         bundle_free(b);
697         if (fd <= 0)
698                 return AUL_R_ERROR;
699
700         ret = aul_sock_recv_reply_pkt(fd, &pkt);
701         if (ret < 0 || pkt == NULL)
702                 return  AUL_R_ERROR;
703
704         if (pkt->cmd == APP_GET_INFO_OK) {
705                 snprintf(instance_id, len, "%s", pkt->data);
706                 free(pkt);
707                 return AUL_R_OK;
708         }
709
710         free(pkt);
711
712         return AUL_R_ERROR;
713 }
714
715 API int aul_app_get_instance_id_bypid(int pid, char *instance_id, int len)
716 {
717         return aul_app_get_instance_id_bypid_for_uid(pid,
718                         instance_id, len, getuid());
719 }
720
721 API int aul_app_is_running_with_instance_id(const char *appid,
722                 const char *instance_id, bool *running)
723 {
724         bundle *b;
725         int ret;
726
727         if (!appid || !instance_id) {
728                 _E("Invalid parameter");
729                 return AUL_R_EINVAL;
730         }
731
732         b = bundle_create();
733         if (!b) {
734                 _E("out of memory");
735                 return AUL_R_ENOMEM;
736         }
737
738         bundle_add(b, AUL_K_APPID, appid);
739         bundle_add(b, AUL_K_INSTANCE_ID, instance_id);
740
741         ret = aul_sock_send_bundle(AUL_UTIL_PID, getuid(), APP_IS_RUNNING,
742                         b, AUL_SOCK_NONE);
743         bundle_free(b);
744         if (ret < 0)
745                 return aul_error_convert(ret);
746
747         *running = (bool)ret;
748
749         return AUL_R_OK;
750 }