Update SMACK, Fix a crash of terminating sequence, etc, ...
[platform/framework/web/data-provider-master.git] / src / package.c
1 /*
2  * Copyright 2013  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.1 (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://floralicense.org/license/
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 <stdio.h>
18 #include <errno.h>
19 #include <string.h> /* strcmp */
20 #include <stdlib.h> /* free */
21
22 #include <dlog.h>
23 #include <Eina.h>
24 #include <Ecore_Evas.h>
25
26 #include <packet.h>
27 #include <livebox-errno.h>
28 #include <ail.h>
29
30 #include "critical_log.h"
31 #include "debug.h"
32 #include "util.h"
33 #include "parser.h"
34 #include "conf.h"
35 #include "slave_life.h"
36 #include "slave_rpc.h"
37 #include "client_life.h"
38 #include "package.h"
39 #include "fault_manager.h"
40 #include "instance.h"
41 #include "script_handler.h"
42 #include "group.h"
43 #include "abi.h"
44 #include "io.h"
45 #include "pkgmgr.h"
46 #include "xmonitor.h"
47
48 int errno;
49
50 struct fault_info {
51         double timestamp;
52         char *filename;
53         char *function;
54 };
55
56 /*!
57  * pkg_info describes the loaded package.
58  */
59
60 struct pkg_info {
61         char *pkgname;
62
63         struct {
64                 enum lb_type type;
65
66                 union {
67                         struct {
68                                 char *path;
69                                 char *group;
70                         } script;
71
72                         struct {
73                                 /*!< Reserved for future use */
74                         } file;
75
76                         struct {
77                                 /*!< Reserved for future use */
78                         } text;
79
80                         struct {
81                                 /*!< Reserved for future use */
82                         } buffer;
83                 } info;
84
85                 unsigned int size_list;
86                 char *auto_launch;
87                 int pinup;
88                 int timeout;
89                 double period;
90                 char *libexec;
91         } lb;
92
93         struct {
94                 enum pd_type type;
95
96                 union {
97                         struct {
98                                 char *path;
99                                 char *group;
100                         } script;
101
102                         struct {
103                                 /*!< Reserved for future use */
104                         } text;
105
106                         struct {
107                                 /*!< Reserved for future use */
108                         } buffer;
109                 } info;
110
111                 unsigned int width;
112                 unsigned int height;
113         } pd;
114
115         int network;
116         int secured;
117         char *script; /* script type: edje, ... */
118         char *abi;
119
120         int fault_count;
121         struct fault_info *fault_info;
122
123         struct slave_node *slave;
124         int refcnt;
125
126         Eina_List *inst_list;
127         Eina_List *ctx_list;
128
129         int is_uninstalled;
130 };
131
132 static struct {
133         Eina_List *pkg_list;
134 } s_info = {
135         .pkg_list = NULL,
136 };
137
138 static int slave_activated_cb(struct slave_node *slave, void *data)
139 {
140         struct pkg_info *info = data;
141         struct inst_info *inst;
142         Eina_List *l;
143         Eina_List *n;
144         int cnt;
145         int ret;
146
147         if (!slave_need_to_reactivate_instances(slave)) {
148                 DbgPrint("Do not need to reactivate instances\n");
149                 return 0;
150         }
151
152         cnt = 0;
153         EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
154                 ret = instance_recover_state(inst);
155                 if (!ret)
156                         continue;
157
158                 instance_thaw_updator(inst);
159                 cnt++;
160         }
161
162         DbgPrint("Recover state for %d instances of %s\n", cnt, package_name(info));
163         return 0;
164 }
165
166 static int slave_fault_cb(struct slave_node *slave, void *data)
167 {
168         Eina_List *l;
169         Eina_List *n;
170         struct inst_info *inst;
171         struct pkg_info *info = (struct pkg_info *)data;
172
173         if (package_is_fault(info)) {
174                 ErrPrint("Already faulted package: %s\n", package_name(info));
175                 return 0;
176         }
177
178         (void)package_set_fault_info(info, util_timestamp(), slave_name(slave), __func__);
179         fault_broadcast_info(package_name(info), slave_name(slave), __func__);
180
181         DbgPrint("Slave critical fault - package: %s (by slave fault %s\n", package_name(info), slave_name(slave));
182         EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
183                 DbgPrint("Destroy instance %p\n", inst);
184                 instance_destroyed(inst);
185         }
186
187         return 0;
188 }
189
190 static int slave_deactivated_cb(struct slave_node *slave, void *data)
191 {
192         struct pkg_info *info = data;
193         struct inst_info *inst;
194         Eina_List *l;
195         Eina_List *n;
196         int cnt = 0;
197
198         if (info->fault_info) {
199                 EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
200                         instance_destroyed(inst);
201                 }
202         } else {
203                 EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
204                         cnt += instance_need_slave(inst);
205                         /*!
206                          * instance_deactivated will call the slave_unload_instance.
207                          * if the loaded instance counter meets 0,
208                          * the slave will be deactivated.
209                          * so we should not call the instance activate function
210                          * from here.
211                          *
212                          * activate slave when the slave is reactivated
213                          */
214                 }
215         }
216
217         return cnt ? SLAVE_NEED_TO_REACTIVATE : 0;
218 }
219
220 static int xmonitor_paused_cb(void *data)
221 {
222         struct pkg_info *info = (struct pkg_info *)data;
223         struct inst_info *inst;
224         Eina_List *l;
225
226         if (slave_state(info->slave) != SLAVE_TERMINATED) {
227                 DbgPrint("Skip this\n");
228                 return 0;
229         }
230
231         EINA_LIST_FOREACH(info->inst_list, l, inst) {
232                 instance_freeze_updator(inst);
233         }
234
235         return 0;
236 }
237
238 static int xmonitor_resumed_cb(void *data)
239 {
240         struct pkg_info *info = data;
241         struct inst_info *inst;
242         Eina_List *l;
243
244         if (slave_state(info->slave) != SLAVE_TERMINATED) {
245                 DbgPrint("Skip this\n");
246                 return 0;
247         }
248
249         EINA_LIST_FOREACH(info->inst_list, l, inst) {
250                 instance_thaw_updator(inst);
251         }
252
253         return 0;
254 }
255
256 static int slave_paused_cb(struct slave_node *slave, void *data)
257 {
258         struct pkg_info *info = (struct pkg_info *)data;
259         struct inst_info *inst;
260         Eina_List *l;
261
262         EINA_LIST_FOREACH(info->inst_list, l, inst) {
263                 instance_freeze_updator(inst);
264         }
265
266         return 0;
267 }
268
269 static int slave_resumed_cb(struct slave_node *slave, void *data)
270 {
271         struct pkg_info *info = (struct pkg_info *)data;
272         struct inst_info *inst;
273         Eina_List *l;
274
275         EINA_LIST_FOREACH(info->inst_list, l, inst) {
276                 instance_thaw_updator(inst);
277         }
278
279         return 0;
280 }
281
282 static inline void destroy_package(struct pkg_info *info)
283 {
284         struct context_info *ctx_info;
285         EINA_LIST_FREE(info->ctx_list, ctx_info) {
286                 /* This items will be deleted from group_del_livebox */
287         }
288
289         group_del_livebox(info->pkgname);
290         package_clear_fault(info);
291
292         s_info.pkg_list = eina_list_remove(s_info.pkg_list, info);
293
294         if (info->lb.type == LB_TYPE_SCRIPT) {
295                 DbgFree(info->lb.info.script.path);
296                 DbgFree(info->lb.info.script.group);
297         }
298
299         if (info->pd.type == PD_TYPE_SCRIPT) {
300                 DbgFree(info->pd.info.script.path);
301                 DbgFree(info->pd.info.script.group);
302         }
303
304         DbgFree(info->script);
305         DbgFree(info->abi);
306         DbgFree(info->pkgname);
307         DbgFree(info->lb.libexec);
308         DbgFree(info->lb.auto_launch);
309
310         DbgFree(info);
311 }
312
313 static inline int load_conf(struct pkg_info *info)
314 {
315         struct parser *parser;
316         const char *str;
317         const char *group;
318
319         parser = parser_load(info->pkgname);
320         if (!parser) {
321                 info->lb.size_list = 0x01; /* Default */
322
323                 info->script = strdup(DEFAULT_SCRIPT);
324                 if (!info->script) {
325                         ErrPrint("Heap: %s\n", strerror(errno));
326                         return LB_STATUS_ERROR_MEMORY;
327                 }
328
329                 info->abi = strdup(DEFAULT_ABI);
330                 if (!info->abi) {
331                         ErrPrint("Heap: %s\n", strerror(errno));
332                         DbgFree(info->script);
333                         info->script = NULL;
334                         return LB_STATUS_ERROR_MEMORY;
335                 }
336
337                 info->pd.width = g_conf.width;
338                 info->pd.height = g_conf.height >> 2;
339                 info->lb.pinup = 1;
340                 return LB_STATUS_SUCCESS;
341         }
342
343         info->lb.type = LB_TYPE_FILE;
344         if (parser_text_lb(parser)) {
345                 info->lb.type = LB_TYPE_TEXT;
346         } else if (parser_buffer_lb(parser)) {
347                 info->lb.type = LB_TYPE_BUFFER;
348         } else {
349                 str = parser_lb_path(parser);
350                 if (str) {
351                         info->lb.type = LB_TYPE_SCRIPT;
352
353                         info->lb.info.script.path = strdup(str);
354                         if (!info->lb.info.script.path) {
355                                 ErrPrint("Heap: %s\n", strerror(errno));
356                                 parser_unload(parser);
357                                 return LB_STATUS_ERROR_MEMORY;
358                         }
359
360                         str = parser_lb_group(parser);
361                         if (str) {
362                                 info->lb.info.script.group = strdup(str);
363                                 if (!info->lb.info.script.group) {
364                                         ErrPrint("Heap: %s\n", strerror(errno));
365                                         DbgFree(info->lb.info.script.path);
366                                         parser_unload(parser);
367                                         return LB_STATUS_ERROR_MEMORY;
368                                 }
369                         }
370                 }
371         }
372
373         if (parser_text_pd(parser)) {
374                 info->pd.type = PD_TYPE_TEXT;
375         } else if (parser_buffer_pd(parser)) {
376                 info->pd.type = PD_TYPE_BUFFER;
377         } else {
378                 str = parser_pd_path(parser);
379                 if (str) {
380                         info->pd.type = PD_TYPE_SCRIPT;
381                         info->pd.info.script.path = strdup(str);
382                         if (!info->pd.info.script.path) {
383                                 ErrPrint("Heap: %s\n", strerror(errno));
384                                 if (info->lb.type == LB_TYPE_SCRIPT) {
385                                         DbgFree(info->lb.info.script.path);
386                                         DbgFree(info->lb.info.script.group);
387                                 }
388                                 parser_unload(parser);
389                                 return LB_STATUS_ERROR_MEMORY;
390                         }
391
392                         str = parser_pd_group(parser);
393                         if (str) {
394                                 info->pd.info.script.group = strdup(str);
395                                 if (!info->pd.info.script.group) {
396                                         ErrPrint("Heap: %s\n", strerror(errno));
397                                         DbgFree(info->pd.info.script.path);
398                                         if (info->lb.type == LB_TYPE_SCRIPT) {
399                                                 DbgFree(info->lb.info.script.path);
400                                                 DbgFree(info->lb.info.script.group);
401                                         }
402                                         parser_unload(parser);
403                                         return LB_STATUS_ERROR_MEMORY;
404                                 }
405                         }
406                 }
407         }
408
409         str = parser_script(parser);
410         str = str ? str : DEFAULT_SCRIPT;
411         info->script = strdup(str);
412         if (!info->script) {
413                 ErrPrint("Heap: %s\n", strerror(errno));
414                 if (info->pd.type == PD_TYPE_SCRIPT) {
415                         DbgFree(info->pd.info.script.path);
416                         DbgFree(info->pd.info.script.group);
417                 }
418
419                 if (info->lb.type == LB_TYPE_SCRIPT) {
420                         DbgFree(info->lb.info.script.path);
421                         DbgFree(info->lb.info.script.group);
422                 }
423
424                 parser_unload(parser);
425                 return LB_STATUS_ERROR_MEMORY;
426         }
427
428         str = parser_abi(parser);
429         str = str ? str : DEFAULT_ABI;
430         info->abi = strdup(str);
431         if (!info->abi) {
432                 ErrPrint("Heap: %s\n", strerror(errno));
433                 DbgFree(info->script);
434                 if (info->pd.type == PD_TYPE_SCRIPT) {
435                         DbgFree(info->pd.info.script.path);
436                         DbgFree(info->pd.info.script.group);
437                 }
438
439                 if (info->lb.type == LB_TYPE_SCRIPT) {
440                         DbgFree(info->lb.info.script.path);
441                         DbgFree(info->lb.info.script.group);
442                 }
443                 parser_unload(parser);
444                 return LB_STATUS_ERROR_MEMORY;
445         }
446
447         info->lb.timeout = parser_timeout(parser);
448         info->network = parser_network(parser);
449
450         info->lb.period = parser_period(parser);
451         if (info->lb.period < 0.0f)
452                 info->lb.period = 0.0f;
453         else if (info->lb.period > 0.0f && info->lb.period < MINIMUM_PERIOD)
454                 info->lb.period = MINIMUM_PERIOD;
455
456         info->lb.size_list = parser_size(parser);
457
458         str = parser_auto_launch(parser);
459         str = str ? str : "";
460         info->lb.auto_launch = strdup(str);
461         if (!info->lb.auto_launch) {
462                 ErrPrint("Heap: %s\n", strerror(errno));
463                 DbgFree(info->abi);
464                 DbgFree(info->script);
465                 if (info->pd.type == PD_TYPE_SCRIPT) {
466                         DbgFree(info->pd.info.script.path);
467                         DbgFree(info->pd.info.script.group);
468                 }
469
470                 if (info->lb.type == LB_TYPE_SCRIPT) {
471                         DbgFree(info->lb.info.script.path);
472                         DbgFree(info->lb.info.script.group);
473                 }
474                 parser_unload(parser);
475                 return LB_STATUS_ERROR_MEMORY;
476         }
477
478         info->secured = parser_secured(parser);
479         info->lb.pinup = parser_pinup(parser);
480
481         parser_get_pdsize(parser, &info->pd.width, &info->pd.height);
482
483         group = parser_group_str(parser);
484         if (group && group_add_livebox(group, info->pkgname) < 0)
485                 ErrPrint("Failed to build cluster tree for %s{%s}\n", info->pkgname, group);
486
487         parser_unload(parser);
488         return LB_STATUS_SUCCESS;
489 }
490
491 HAPI struct pkg_info *package_create(const char *pkgname)
492 {
493         struct pkg_info *pkginfo;
494
495         pkginfo = calloc(1, sizeof(*pkginfo));
496         if (!pkginfo) {
497                 ErrPrint("Heap: %s\n", strerror(errno));
498                 return NULL;
499         }
500
501         pkginfo->pkgname = io_livebox_pkgname(pkgname);
502         if (!pkginfo->pkgname) {
503                 ErrPrint("Failed to get pkgname, fallback to fs checker\n");
504                 if (util_validate_livebox_package(pkgname) < 0) {
505                         ErrPrint("Invalid package name: %s\n", pkgname);
506                         DbgFree(pkginfo);
507                         return NULL;
508                 }
509
510                 pkginfo->pkgname = strdup(pkgname);
511                 if (!pkginfo->pkgname) {
512                         ErrPrint("Heap: %s\n", strerror(errno));
513                         DbgFree(pkginfo);
514                         return NULL;
515                 }
516         }
517
518         if (io_load_package_db(pkginfo) < 0) {
519                 ErrPrint("Failed to load DB, fall back to conf file loader\n");
520                 if (load_conf(pkginfo) < 0) {
521                         ErrPrint("Failed to initiate the conf file loader\n");
522                         DbgFree(pkginfo->pkgname);
523                         DbgFree(pkginfo);
524                         return NULL;
525                 }
526         }
527
528         package_ref(pkginfo);
529
530         s_info.pkg_list = eina_list_append(s_info.pkg_list, pkginfo);
531
532         return pkginfo;
533 }
534
535 HAPI int package_destroy(struct pkg_info *info)
536 {
537         package_unref(info);
538         return LB_STATUS_SUCCESS;
539 }
540
541 HAPI Eina_List *package_ctx_info(struct pkg_info *pkginfo)
542 {
543         return pkginfo->ctx_list;
544 }
545
546 HAPI void package_add_ctx_info(struct pkg_info *pkginfo, struct context_info *info)
547 {
548         pkginfo->ctx_list = eina_list_append(pkginfo->ctx_list, info);
549 }
550
551 HAPI void package_del_ctx_info(struct pkg_info *pkginfo, struct context_info *info)
552 {
553         pkginfo->ctx_list = eina_list_remove(pkginfo->ctx_list, info);
554 }
555
556 HAPI char *package_lb_pkgname(const char *pkgname)
557 {
558         char *lb_pkgname;
559
560         lb_pkgname = io_livebox_pkgname(pkgname);
561         if (!lb_pkgname) {
562                 if (util_validate_livebox_package(pkgname) < 0)
563                         return NULL;
564
565                 lb_pkgname = strdup(pkgname);
566                 if (!lb_pkgname) {
567                         ErrPrint("Heap: %s\n", strerror(errno));
568                         return NULL;
569                 }
570         }
571
572         return lb_pkgname;
573 }
574
575 HAPI int package_is_lb_pkgname(const char *pkgname)
576 {
577         char *lb_pkgname;
578         int ret;
579
580         lb_pkgname = package_lb_pkgname(pkgname);
581         ret = !!lb_pkgname;
582         DbgFree(lb_pkgname);
583
584         return ret;
585 }
586
587 HAPI struct pkg_info *package_find(const char *pkgname)
588 {
589         Eina_List *l;
590         struct pkg_info *info;
591
592         if (!pkgname)
593                 return NULL;
594
595         EINA_LIST_FOREACH(s_info.pkg_list, l, info) {
596                 if (!strcmp(info->pkgname, pkgname))
597                         return info;
598         }
599
600         return NULL;
601 }
602
603 HAPI struct inst_info *package_find_instance_by_id(const char *pkgname, const char *id)
604 {
605         Eina_List *l;
606         struct inst_info *inst;
607         struct pkg_info *info;
608
609         info = package_find(pkgname);
610         if (!info) {
611                 ErrPrint("Package %s is not exists\n", pkgname);
612                 return NULL;
613         }
614
615         EINA_LIST_FOREACH(info->inst_list, l, inst) {
616                 if (!strcmp(instance_id(inst), id))
617                         return inst;
618         }
619
620         return NULL;
621 }
622
623 HAPI struct inst_info *package_find_instance_by_timestamp(const char *pkgname, double timestamp)
624 {
625         Eina_List *l;
626         struct inst_info *inst;
627         struct pkg_info *info;
628
629         info = package_find(pkgname);
630         if (!info) {
631                 ErrPrint("Package %s is not exists\n", pkgname);
632                 return NULL;
633         }
634
635         EINA_LIST_FOREACH(info->inst_list, l, inst) {
636                 if (instance_timestamp(inst) == timestamp)
637                         return inst;
638         }
639
640         return NULL;
641 }
642
643 HAPI int package_dump_fault_info(struct pkg_info *info)
644 {
645         if (!info->fault_info)
646                 return LB_STATUS_ERROR_NOT_EXIST;
647
648         CRITICAL_LOG("=============\n");
649         CRITICAL_LOG("faulted at %lf\n", info->fault_info->timestamp);
650         CRITICAL_LOG("Package: %s\n", info->pkgname);
651         CRITICAL_LOG("Function: %s\n", info->fault_info->function);
652         CRITICAL_LOG("InstanceID: %s\n", info->fault_info->filename);
653         return LB_STATUS_SUCCESS;
654 }
655
656 HAPI int package_get_fault_info(struct pkg_info *info, double *timestamp, const char **filename, const char **function)
657 {
658         if (!info->fault_info)
659                 return LB_STATUS_ERROR_NOT_EXIST;
660
661         *timestamp = info->fault_info->timestamp;
662         *filename = info->fault_info->filename;
663         *function = info->fault_info->function;
664         return LB_STATUS_SUCCESS;
665 }
666
667 HAPI int package_set_fault_info(struct pkg_info *info, double timestamp, const char *filename, const char *function)
668 {
669         struct fault_info *fault;
670
671         package_clear_fault(info);
672
673         fault = calloc(1, sizeof(*fault));
674         if (!fault) {
675                 ErrPrint("Heap: %s\n", strerror(errno));
676                 return LB_STATUS_ERROR_MEMORY;
677         }
678
679         fault->timestamp = timestamp;
680         if (!filename)
681                 filename = "unknown";
682         if (!function)
683                 function = "unknown";
684
685         fault->filename = strdup(filename);
686         if (!fault->filename) {
687                 ErrPrint("Heap: %s\n", strerror(errno));
688                 DbgFree(fault);
689                 return LB_STATUS_ERROR_MEMORY;
690         }
691
692         fault->function = strdup(function);
693         if (!fault->function) {
694                 ErrPrint("Heap: %s\n", strerror(errno));
695                 DbgFree(fault->filename);
696                 DbgFree(fault);
697                 return LB_STATUS_ERROR_MEMORY;
698         }
699
700         info->fault_info = fault;
701         info->fault_count++;
702         return LB_STATUS_SUCCESS;
703 }
704
705 HAPI int package_clear_fault(struct pkg_info *info)
706 {
707         if (!info->fault_info)
708                 return LB_STATUS_ERROR_INVALID;
709         
710         package_dump_fault_info(info);
711
712         DbgFree(info->fault_info->function);
713         DbgFree(info->fault_info->filename);
714         DbgFree(info->fault_info);
715         info->fault_info = NULL;
716         return LB_STATUS_SUCCESS;
717 }
718
719 HAPI const int const package_is_fault(const struct pkg_info *info)
720 {
721         return !!info->fault_info;
722 }
723
724 HAPI struct slave_node * const package_slave(const struct pkg_info *info)
725 {
726         return info->slave;
727 }
728
729 HAPI const int const package_timeout(const struct pkg_info *info)
730 {
731         return info->lb.timeout;
732 }
733
734 HAPI void package_set_timeout(struct pkg_info *info, int timeout)
735 {
736         info->lb.timeout = timeout;
737 }
738
739 HAPI const double const package_period(const struct pkg_info *info)
740 {
741         return info->lb.period;
742 }
743
744 HAPI void package_set_period(struct pkg_info *info, double period)
745 {
746         info->lb.period = period;
747 }
748
749 HAPI const int const package_secured(const struct pkg_info *info)
750 {
751         return info->secured;
752 }
753
754 HAPI void package_set_secured(struct pkg_info *info, int secured)
755 {
756         info->secured = secured;
757 }
758
759 HAPI const char * const package_script(const struct pkg_info *info)
760 {
761         return info->script;
762 }
763
764 HAPI int package_set_script(struct pkg_info *info, const char *script)
765 {
766         char *tmp;
767
768         tmp = strdup(script);
769         if (!tmp) {
770                 ErrPrint("Heap: %s\n", strerror(errno));
771                 return LB_STATUS_ERROR_MEMORY;
772         }
773
774         DbgFree(info->script);
775         info->script = tmp;
776         return LB_STATUS_SUCCESS;
777 }
778
779 HAPI const char * const package_abi(const struct pkg_info *info)
780 {
781         return info->abi;
782 }
783
784 HAPI int package_set_abi(struct pkg_info *info, const char *abi)
785 {
786         char *tmp;
787         tmp = strdup(abi);
788         if (!tmp) {
789                 ErrPrint("Heap: %s\n", strerror(errno));
790                 return LB_STATUS_ERROR_MEMORY;
791         }
792
793         DbgFree(info->abi);
794         info->abi = tmp;
795         return LB_STATUS_SUCCESS;
796 }
797
798 HAPI const char * const package_lb_path(const struct pkg_info *info)
799 {
800         if (info->lb.type != LB_TYPE_SCRIPT)
801                 return NULL;
802
803         return info->lb.info.script.path;
804 }
805
806 HAPI int package_set_lb_path(struct pkg_info *info, const char *path)
807 {
808         char *tmp;
809
810         if (info->lb.type != LB_TYPE_SCRIPT)
811                 return LB_STATUS_ERROR_INVALID;
812
813         tmp = strdup(path);
814         if (!tmp) {
815                 ErrPrint("Heap: %s\n", strerror(errno));
816                 return LB_STATUS_ERROR_MEMORY;
817         }
818
819         DbgFree(info->lb.info.script.path);
820         info->lb.info.script.path = tmp;
821         return LB_STATUS_SUCCESS;
822 }
823
824 HAPI const char * const package_lb_group(const struct pkg_info *info)
825 {
826         if (info->lb.type != LB_TYPE_SCRIPT)
827                 return NULL;
828
829         return info->lb.info.script.group;
830 }
831
832 HAPI int package_set_lb_group(struct pkg_info *info, const char *group)
833 {
834         char *tmp;
835
836         if (info->lb.type != LB_TYPE_SCRIPT)
837                 return LB_STATUS_ERROR_INVALID;
838
839         tmp = strdup(group);
840         if (!tmp) {
841                 ErrPrint("Heap: %s\n", strerror(errno));
842                 return LB_STATUS_ERROR_MEMORY;
843         }
844
845         DbgFree(info->lb.info.script.group);
846         info->lb.info.script.group = tmp;
847         return LB_STATUS_SUCCESS;
848 }
849
850 HAPI const char * const package_pd_path(const struct pkg_info *info)
851 {
852         if (info->pd.type != PD_TYPE_SCRIPT)
853                 return NULL;
854
855         return info->pd.info.script.path;
856 }
857
858 HAPI int package_set_pd_path(struct pkg_info *info, const char *path)
859 {
860         char *tmp;
861
862         if (info->pd.type != PD_TYPE_SCRIPT)
863                 return LB_STATUS_ERROR_INVALID;
864
865         tmp = strdup(path);
866         if (!tmp) {
867                 ErrPrint("Heap: %s\n", strerror(errno));
868                 return LB_STATUS_ERROR_MEMORY;
869         }
870
871         DbgFree(info->pd.info.script.path);
872         info->pd.info.script.path = tmp;
873         return LB_STATUS_SUCCESS;
874 }
875
876 HAPI const char * const package_pd_group(const struct pkg_info *info)
877 {
878         if (info->pd.type != PD_TYPE_SCRIPT)
879                 return NULL;
880
881         return info->pd.info.script.group;
882 }
883
884 HAPI int package_set_pd_group(struct pkg_info *info, const char *group)
885 {
886         char *tmp;
887
888         if (info->pd.type != PD_TYPE_SCRIPT)
889                 return LB_STATUS_ERROR_INVALID;
890
891         tmp = strdup(group);
892         if (!tmp) {
893                 ErrPrint("Heap: %s\n", strerror(errno));
894                 return LB_STATUS_ERROR_MEMORY;
895         }
896
897         DbgFree(info->pd.info.script.group);
898         info->pd.info.script.group = tmp;
899         return LB_STATUS_SUCCESS;
900 }
901
902 HAPI const int const package_pinup(const struct pkg_info *info)
903 {
904         return info->lb.pinup;
905 }
906
907 HAPI void package_set_pinup(struct pkg_info *info, int pinup)
908 {
909         info->lb.pinup = pinup;
910 }
911
912 HAPI const char * const package_auto_launch(const struct pkg_info *info)
913 {
914         return info->lb.auto_launch;
915 }
916
917 HAPI void package_set_auto_launch(struct pkg_info *info, const char *auto_launch)
918 {
919         if (!auto_launch)
920                 auto_launch = "";
921
922         info->lb.auto_launch = strdup(auto_launch);
923         if (!info->lb.auto_launch) {
924                 ErrPrint("Heap: %s\n", strerror(errno));
925                 return;
926         }
927 }
928
929 HAPI const unsigned int const package_size_list(const struct pkg_info *info)
930 {
931         return info->lb.size_list;
932 }
933
934 HAPI void package_set_size_list(struct pkg_info *info, unsigned int size_list)
935 {
936         info->lb.size_list = size_list;
937 }
938
939 HAPI const int const package_pd_width(const struct pkg_info *info)
940 {
941         return info->pd.width;
942 }
943
944 HAPI void package_set_pd_width(struct pkg_info *info, int width)
945 {
946         info->pd.width = width;
947 }
948
949 HAPI const int const package_pd_height(const struct pkg_info *info)
950 {
951         return info->pd.height;
952 }
953
954 HAPI void package_set_pd_height(struct pkg_info *info, int height)
955 {
956         info->pd.height = height;
957 }
958
959 HAPI struct pkg_info * const package_ref(struct pkg_info *info)
960 {
961         info->refcnt++;
962         return info;
963 }
964
965 HAPI struct pkg_info * const package_unref(struct pkg_info *info)
966 {
967         if (info->refcnt == 0) {
968                 ErrPrint("Invalid request\n");
969                 return NULL;
970         }
971
972         info->refcnt--;
973         if (info->refcnt == 0) {
974                 destroy_package(info);
975                 info = NULL;
976         }
977
978         return info;
979 }
980
981 HAPI const int const package_refcnt(const struct pkg_info *info)
982 {
983         return info->refcnt;
984 }
985
986 HAPI const enum lb_type package_lb_type(const struct pkg_info *info)
987 {
988         return info->lb.type;
989 }
990
991 HAPI void package_set_lb_type(struct pkg_info *info, enum lb_type type)
992 {
993         info->lb.type = type;
994 }
995
996 HAPI const char * const package_libexec(struct pkg_info *info)
997 {
998         return info->lb.libexec;
999 }
1000
1001 HAPI int package_set_libexec(struct pkg_info *info, const char *libexec)
1002 {
1003         char *tmp;
1004
1005         tmp = strdup(libexec);
1006         if (!tmp) {
1007                 ErrPrint("Heap: %s\n", strerror(errno));
1008                 return LB_STATUS_ERROR_MEMORY;
1009         }
1010
1011         DbgFree(info->lb.libexec);
1012         info->lb.libexec = tmp;
1013         return LB_STATUS_SUCCESS;
1014 }
1015
1016 HAPI int package_network(struct pkg_info *info)
1017 {
1018         return info->network;
1019 }
1020
1021 HAPI void package_set_network(struct pkg_info *info, int network)
1022 {
1023         info->network = network;
1024 }
1025
1026 HAPI const enum pd_type const package_pd_type(const struct pkg_info *info)
1027 {
1028         return info->pd.type;
1029 }
1030
1031 HAPI void package_set_pd_type(struct pkg_info *info, enum pd_type type)
1032 {
1033         info->pd.type = type;
1034 }
1035
1036 /*!
1037  * \note
1038  * Add the instance to the package info.
1039  * If a package has no slave, assign a new slave.
1040  */
1041 static inline int assign_new_slave(struct pkg_info *info)
1042 {
1043         char *s_name;
1044         char *s_pkgname;
1045         const char *tmp;
1046
1047         s_name = util_slavename();
1048         if (!s_name) {
1049                 ErrPrint("Failed to get a new slave name\n");
1050                 return LB_STATUS_ERROR_FAULT;
1051         }
1052
1053         tmp = abi_find_slave(info->abi);
1054         if (!tmp) {
1055                 DbgFree(s_name);
1056                 ErrPrint("Failed to find a proper pkgname of a slave\n");
1057                 return LB_STATUS_ERROR_INVALID;
1058         }
1059
1060         DbgPrint("Slave package: \"%s\" (abi: %s)\n", tmp, info->abi);
1061         s_pkgname = util_replace_string(tmp, REPLACE_TAG_APPID, info->pkgname);
1062         if (!s_pkgname) {
1063                 DbgPrint("Failed to get replaced string\n");
1064                 s_pkgname = strdup(tmp);
1065                 if (!s_pkgname) {
1066                         ErrPrint("Heap: %s\n", strerror(errno));
1067                         DbgFree(s_name);
1068                         return LB_STATUS_ERROR_MEMORY;
1069                 }
1070         }
1071
1072         DbgPrint("New slave name is %s, it is assigned for livebox %s (using %s)\n", s_name, info->pkgname, s_pkgname);
1073         info->slave = slave_create(s_name, info->secured, info->abi, s_pkgname, info->network);
1074
1075         DbgFree(s_name);
1076         DbgFree(s_pkgname);
1077
1078         if (!info->slave) {
1079                 /*!
1080                  * \note
1081                  * package_destroy will try to remove "info" from the pkg_list.
1082                  * but we didn't add this to it yet.
1083                  * If the list method couldn't find an "info" from the list,
1084                  * it just do nothing so I'll leave this.
1085                  */
1086                 return LB_STATUS_ERROR_FAULT;
1087         }
1088         /*!
1089          * \note
1090          * Slave is not activated yet.
1091          */
1092         return LB_STATUS_SUCCESS;
1093 }
1094
1095 HAPI int package_add_instance(struct pkg_info *info, struct inst_info *inst)
1096 {
1097         if (!info->inst_list) {
1098                 info->slave = slave_find_available(info->abi, info->secured, info->network);
1099
1100                 if (!info->slave) {
1101                         int ret;
1102
1103                         ret = assign_new_slave(info);
1104                         if (ret < 0)
1105                                 return ret;
1106                 } else {
1107                         DbgPrint("Slave %s is assigned for %s\n", slave_name(info->slave), info->pkgname);
1108                 }
1109
1110                 slave_ref(info->slave);
1111                 slave_load_package(info->slave);
1112                 slave_event_callback_add(info->slave, SLAVE_EVENT_DEACTIVATE, slave_deactivated_cb, info);
1113                 slave_event_callback_add(info->slave, SLAVE_EVENT_ACTIVATE, slave_activated_cb, info);
1114                 slave_event_callback_add(info->slave, SLAVE_EVENT_FAULT, slave_fault_cb, info);
1115
1116                 if (info->secured) {
1117                         slave_event_callback_add(info->slave, SLAVE_EVENT_PAUSE, slave_paused_cb, info);
1118                         slave_event_callback_add(info->slave, SLAVE_EVENT_RESUME, slave_resumed_cb, info);
1119
1120                         /*!
1121                          * \note
1122                          * In case of the slave is terminated because of expired TTL timer,
1123                          * Master should freeze the all update time.
1124                          * But the callback should check the slave's state to prevent from duplicated freezing.
1125                          *
1126                          * This callback will freeze the timer only if a slave doesn't running.
1127                          */
1128                         xmonitor_add_event_callback(XMONITOR_PAUSED, xmonitor_paused_cb, info);
1129                         xmonitor_add_event_callback(XMONITOR_RESUMED, xmonitor_resumed_cb, info);
1130                 }
1131         }
1132
1133         info->inst_list = eina_list_append(info->inst_list, inst);
1134         return LB_STATUS_SUCCESS;
1135 }
1136
1137 HAPI int package_del_instance(struct pkg_info *info, struct inst_info *inst)
1138 {
1139         info->inst_list = eina_list_remove(info->inst_list, inst);
1140
1141         if (info->inst_list)
1142                 return LB_STATUS_SUCCESS;
1143
1144         if (info->slave) {
1145                 slave_unload_package(info->slave);
1146
1147                 slave_event_callback_del(info->slave, SLAVE_EVENT_FAULT, slave_fault_cb, info);
1148                 slave_event_callback_del(info->slave, SLAVE_EVENT_DEACTIVATE, slave_deactivated_cb, info);
1149                 slave_event_callback_del(info->slave, SLAVE_EVENT_ACTIVATE, slave_activated_cb, info);
1150
1151                 if (info->secured) {
1152                         slave_event_callback_del(info->slave, SLAVE_EVENT_PAUSE, slave_paused_cb, info);
1153                         slave_event_callback_del(info->slave, SLAVE_EVENT_RESUME, slave_resumed_cb, info);
1154
1155                         xmonitor_del_event_callback(XMONITOR_PAUSED, xmonitor_paused_cb, info);
1156                         xmonitor_del_event_callback(XMONITOR_RESUMED, xmonitor_resumed_cb, info);
1157                 }
1158
1159                 slave_unref(info->slave);
1160                 info->slave = NULL;
1161         }
1162
1163         if (info->is_uninstalled)
1164                 package_destroy(info);
1165
1166         return LB_STATUS_SUCCESS;
1167 }
1168
1169 HAPI Eina_List *package_instance_list(struct pkg_info *info)
1170 {
1171         return info->inst_list;
1172 }
1173
1174 static int client_created_cb(struct client_node *client, void *data)
1175 {
1176         struct pkg_info *info;
1177         Eina_List *l;
1178
1179         struct inst_info *inst;
1180         Eina_List *i_l;
1181
1182         EINA_LIST_FOREACH(s_info.pkg_list, l, info) {
1183                 if (info->fault_info) {
1184                         fault_unicast_info(client, info->pkgname, info->fault_info->filename, info->fault_info->function);
1185                         continue;
1186                 }
1187
1188                 EINA_LIST_FOREACH(info->inst_list, i_l, inst) {
1189                         switch (instance_state(inst)) {
1190                         case INST_INIT:
1191                                 /* Will be send a created event after the instance gets created event */
1192                                 break;
1193                         case INST_ACTIVATED: /*!< This instance is actiavted, and used */
1194                         case INST_REQUEST_TO_REACTIVATE: /*!< This instance will be reactivated soon */
1195                         case INST_REQUEST_TO_DESTROY: /*!< This instance will be destroy soon */
1196                                 if (instance_client(inst) == client) {
1197                                         instance_unicast_created_event(inst, client);
1198                                 } else if (instance_client(inst) == NULL) {
1199                                         /*!
1200                                          * \note
1201                                          * Instances are lives in the system cluster/sub-cluster
1202                                          */
1203                                         if (client_is_subscribed(client, instance_cluster(inst), instance_category(inst))) {
1204                                                 instance_unicast_created_event(inst, client);
1205                                                 DbgPrint("(Subscribed) Created package: %s\n", info->pkgname);
1206                                         }
1207                                 }
1208
1209                                 break;
1210                         default:
1211                                 DbgPrint("%s(%s) is not activated (%d)\n",
1212                                                 package_name(info), instance_id(inst), instance_state(inst));
1213                                 break;
1214                         }
1215                 }
1216         }
1217
1218         return 0;
1219 }
1220
1221 static int io_uninstall_cb(const char *pkgname, int prime, void *data)
1222 {
1223         struct pkg_info *info;
1224         Eina_List *l;
1225         Eina_List *n;
1226         struct inst_info *inst;
1227
1228         DbgPrint("Livebox package %s is uninstalled\n", pkgname);
1229         info = package_find(pkgname);
1230         if (!info) {
1231                 DbgPrint("%s is not yet loaded\n", pkgname);
1232                 return 0;
1233         }
1234
1235         info->is_uninstalled = 1;
1236
1237         /*!
1238          * \NOTE
1239          * Don't delete an item from the inst_list.
1240          * destroy callback will use this list again.
1241          * So, Don't touch it from here.
1242          */
1243         if (info->inst_list) {
1244                 EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
1245                         instance_destroy(inst);
1246                 }
1247         } else {
1248                 package_destroy(info);
1249         }
1250
1251         return 0;
1252 }
1253
1254 static inline void reload_package_info(struct pkg_info *info)
1255 {
1256         Eina_List *l;
1257         Eina_List *n;
1258         struct inst_info *inst;
1259
1260         DbgPrint("Already exists, try to update it\n");
1261         /*!
1262          * \note
1263          * Without "is_uninstalled", the package will be kept
1264          */
1265         EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
1266                 instance_destroy(inst);
1267         }
1268
1269         group_del_livebox(info->pkgname);
1270         package_clear_fault(info);
1271
1272         /*!
1273          * \NOTE:
1274          * Nested DB I/O
1275          */
1276         io_load_package_db(info);
1277 }
1278
1279 static int io_install_cb(const char *pkgname, int prime, void *data)
1280 {
1281         struct pkg_info *info;
1282
1283         DbgPrint("Livebox package %s is installed\n", pkgname);
1284         info = package_find(pkgname);
1285         if (info) {
1286                 reload_package_info(info);
1287         } else {
1288                 info = package_create(pkgname);
1289                 DbgPrint("Package %s is%sbuilt\n", pkgname, info ? " " : " not ");
1290         }
1291
1292         return 0;
1293 }
1294
1295 static int install_cb(const char *pkgname, enum pkgmgr_status status, double value, void *data)
1296 {
1297         int ret;
1298
1299         if (status != PKGMGR_STATUS_END)
1300                 return 0;
1301
1302         ret = io_update_livebox_package(pkgname, io_install_cb, NULL);
1303         DbgPrint("Processed %d packages\n", ret);
1304         return 0;
1305 }
1306
1307 static int uninstall_cb(const char *pkgname, enum pkgmgr_status status, double value, void *data)
1308 {
1309         int ret;
1310
1311         if (status == PKGMGR_STATUS_START) {
1312                 ret = io_update_livebox_package(pkgname, io_uninstall_cb, NULL);
1313                 DbgPrint("Processed %d packages\n", ret);
1314                 if (ret == 0) {
1315                         /*! for keeping the old style */
1316                         (void)io_uninstall_cb(pkgname, -1, NULL);
1317                 }
1318         }
1319
1320         return 0;
1321 }
1322
1323 static int io_update_cb(const char *pkgname, int prime, void *data)
1324 {
1325         struct pkg_info *info;
1326
1327         DbgPrint("Livebox package %s is updated\n", pkgname);
1328         info = package_find(pkgname);
1329         if (!info)
1330                 return 0;
1331
1332         reload_package_info(info);
1333         return 0;
1334 }
1335
1336 static int update_cb(const char *pkgname, enum pkgmgr_status status, double value, void *data)
1337 {
1338         int ret;
1339         if (status != PKGMGR_STATUS_END)
1340                 return 0;
1341
1342         ret = io_update_livebox_package(pkgname, io_update_cb, NULL);
1343         DbgPrint("Processed %d packages\n", ret);
1344         return 0;
1345 }
1346
1347 static int crawling_liveboxes(const char *pkgname, int prime, void *data)
1348 {
1349         if (package_find(pkgname)) {
1350                 ErrPrint("Information of %s is already built\n", pkgname);
1351         } else {
1352                 struct pkg_info *info;
1353                 info = package_create(pkgname);
1354                 if (info)
1355                         DbgPrint("[%s] information is built prime(%d)\n", pkgname, prime);
1356         }
1357
1358         return 0;
1359 }
1360
1361 HAPI int package_init(void)
1362 {
1363         client_global_event_handler_add(CLIENT_GLOBAL_EVENT_CREATE, client_created_cb, NULL);
1364         pkgmgr_init();
1365
1366         pkgmgr_add_event_callback(PKGMGR_EVENT_INSTALL, install_cb, NULL);
1367         pkgmgr_add_event_callback(PKGMGR_EVENT_UNINSTALL, uninstall_cb, NULL);
1368         pkgmgr_add_event_callback(PKGMGR_EVENT_UPDATE, update_cb, NULL);
1369
1370         io_crawling_liveboxes(crawling_liveboxes, NULL);
1371         return 0;
1372 }
1373
1374 HAPI int package_fini(void)
1375 {
1376         Eina_List *p_l;
1377         Eina_List *p_n;
1378         Eina_List *i_l;
1379         Eina_List *i_n;
1380         struct pkg_info *info;
1381         struct inst_info *inst;
1382
1383         pkgmgr_del_event_callback(PKGMGR_EVENT_INSTALL, install_cb, NULL);
1384         pkgmgr_del_event_callback(PKGMGR_EVENT_UNINSTALL, uninstall_cb, NULL);
1385         pkgmgr_del_event_callback(PKGMGR_EVENT_UPDATE, update_cb, NULL);
1386         pkgmgr_fini();
1387         client_global_event_handler_del(CLIENT_GLOBAL_EVENT_CREATE, client_created_cb, NULL);
1388
1389         EINA_LIST_FOREACH_SAFE(s_info.pkg_list, p_l, p_n, info) {
1390                 EINA_LIST_FOREACH_SAFE(info->inst_list, i_l, i_n, inst) {
1391                         instance_state_reset(inst);
1392                         instance_destroy(inst);
1393                 }
1394
1395                 package_destroy(info);
1396         }
1397
1398         return 0;
1399 }
1400
1401 HAPI const char *package_find_by_secured_slave(struct slave_node *slave)
1402 {
1403         Eina_List *l;
1404         struct pkg_info *info;
1405
1406         if (!slave_is_secured(slave))
1407                 return NULL;
1408
1409         EINA_LIST_FOREACH(s_info.pkg_list, l, info) {
1410                 if (info->slave == slave)
1411                         return info->pkgname;
1412         }
1413
1414         return NULL;
1415 }
1416
1417 HAPI const char * const package_name(const struct pkg_info *info)
1418 {
1419         return info->pkgname;
1420 }
1421
1422 /*!
1423  * del_or_creat : 1 == create, 0 == delete
1424  */
1425 HAPI int package_alter_instances_to_client(struct client_node *client, enum alter_type alter)
1426 {
1427         struct pkg_info *info;
1428         Eina_List *l;
1429
1430         struct inst_info *inst;
1431         Eina_List *i_l;
1432
1433         EINA_LIST_FOREACH(s_info.pkg_list, l, info) {
1434                 EINA_LIST_FOREACH(info->inst_list, i_l, inst) {
1435                         if (instance_client(inst))
1436                                 continue;
1437
1438                         if (!client_is_subscribed(client, instance_cluster(inst), instance_category(inst)))
1439                                 continue;
1440
1441                         switch (instance_state(inst)) {
1442                         case INST_INIT:
1443                         case INST_REQUEST_TO_ACTIVATE:
1444                                 /* Will be send a created event after the instance gets created event */
1445                                 switch (alter) {
1446                                 case ALTER_CREATE:
1447                                         if (!instance_has_client(inst, client)) {
1448                                                 instance_add_client(inst, client);
1449                                         }
1450                                         break;
1451                                 case ALTER_DESTROY:
1452                                         if (instance_has_client(inst, client)) {
1453                                                 instance_del_client(inst, client);
1454                                         }
1455                                         break;
1456                                 default:
1457                                         break;
1458                                 }
1459                                 break;
1460                         case INST_ACTIVATED: /*!< This instance is actiavted, and used */
1461                         case INST_REQUEST_TO_REACTIVATE: /*!< This instance will be reactivated soon */
1462                         case INST_REQUEST_TO_DESTROY: /*!< This instance will be destroy soon */
1463                                 /*!
1464                                  * \note
1465                                  * Instances are lives in the system cluster/sub-cluster
1466                                  */
1467                                 switch (alter) {
1468                                 case ALTER_CREATE:
1469                                         if (!instance_has_client(inst, client)) {
1470                                                 instance_unicast_created_event(inst, client);
1471                                                 instance_add_client(inst, client);
1472                                                 DbgPrint("(Subscribed) Created package: %s\n", info->pkgname);
1473                                         }
1474                                         break;
1475                                 case ALTER_DESTROY:
1476                                         if (instance_has_client(inst, client)) {
1477                                                 instance_unicast_deleted_event(inst, client);
1478                                                 instance_del_client(inst, client);
1479                                         }
1480                                         break;
1481                                 default:
1482                                         break;
1483                                 }
1484
1485                                 break;
1486                         default:
1487                                 DbgPrint("%s(%s) is not activated (%d)\n",
1488                                                 package_name(info), instance_id(inst), instance_state(inst));
1489                                 break;
1490                         }
1491                 }
1492         }
1493
1494         return 0;
1495 }
1496
1497 HAPI const Eina_List *package_list(void)
1498 {
1499         return s_info.pkg_list;
1500 }
1501
1502 HAPI int const package_fault_count(struct pkg_info *info)
1503 {
1504         return info ? info->fault_count : 0;
1505 }
1506
1507 HAPI int package_is_enabled(const char *appid)
1508 {
1509         ail_appinfo_h ai;
1510         bool enabled;
1511         int ret;
1512
1513         ret = ail_get_appinfo(appid, &ai);
1514         if (ret != AIL_ERROR_OK) {
1515                 ErrPrint("Unable to get appinfo: %d\n", ret);
1516                 return 0;
1517         }
1518
1519         if (ail_appinfo_get_bool(ai, AIL_PROP_X_SLP_ENABLED_BOOL, &enabled) != AIL_ERROR_OK)
1520                 enabled = false;
1521
1522         ail_destroy_appinfo(ai);
1523
1524         return enabled == true;
1525 }
1526
1527 /* End of a file */