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