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