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