If the box is deleted while creating, and the delete reason is SUCCESS, change it...
[platform/framework/web/livebox-viewer.git] / src / client.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 <unistd.h>
19 #include <errno.h>
20 #include <string.h>
21 #include <stdlib.h>
22 #include <pthread.h>
23
24 #include <dlog.h>
25 #include <glib.h>
26
27 #include <vconf.h>
28 #include <vconf-keys.h>
29
30 #include <packet.h>
31 #include <com-core.h>
32 #include <com-core_packet.h>
33 #include <livebox-errno.h>
34 #include <secure_socket.h>
35
36 #include "debug.h"
37 #include "client.h"
38 #include "livebox.h"
39 #include "livebox_internal.h"
40 #include "desc_parser.h"
41 #include "fb.h"
42 #include "util.h"
43 #include "master_rpc.h"
44 #include "conf.h"
45 #include "critical_log.h"
46 #include "file_service.h"
47
48 int errno;
49
50 static struct info {
51         int fd;
52         guint timer_id;
53         char *client_addr;
54 } s_info = {
55         .fd = -1,
56         .timer_id = 0,
57         .client_addr = NULL,
58 };
59
60 static struct packet *master_fault_package(pid_t pid, int handle, const struct packet *packet)
61 {
62         const char *pkgname;
63         const char *id;
64         const char *function;
65
66         if (packet_get(packet, "sss", &pkgname, &id, &function) != 3) {
67                 ErrPrint("Invalid arguments\n");
68                 return NULL;
69         }
70
71         master_rpc_clear_fault_package(pkgname);
72         lb_invoke_fault_handler(LB_FAULT_DEACTIVATED, pkgname, id, function);
73         return NULL;
74 }
75
76 static struct packet *master_hold_scroll(pid_t pid, int handle, const struct packet *packet)
77 {
78         struct livebox *handler;
79         const char *pkgname;
80         const char *id;
81         int seize;
82         int ret;
83
84         ret = packet_get(packet, "ssi", &pkgname, &id, &seize);
85         if (ret != 3) {
86                 ErrPrint("Invalid argument\n");
87                 goto out;
88         }
89
90         handler = lb_find_livebox(pkgname, id);
91         if (!handler) {
92                 ErrPrint("Instance(%s) is not exists\n", id);
93                 goto out;
94         }
95
96         DbgPrint("HOLD: %s %d\n", id, seize);
97         lb_invoke_event_handler(handler, seize ? LB_EVENT_HOLD_SCROLL : LB_EVENT_RELEASE_SCROLL);
98
99 out:
100         return NULL;
101 }
102
103 static struct packet *master_pinup(pid_t pid, int handle, const struct packet *packet)
104 {
105         const char *pkgname;
106         const char *id;
107         const char *content;
108         struct livebox *handler;
109         char *new_content;
110         int ret;
111         int status;
112         int pinup;
113
114         ret = packet_get(packet, "iisss", &status, &pinup, &pkgname, &id, &content);
115         if (ret != 5) {
116                 ErrPrint("Invalid argument\n");
117                 goto out;
118         }
119
120         handler = lb_find_livebox(pkgname, id);
121         if (!handler) {
122                 ErrPrint("Instance (%s) is not exists\n", id);
123                 goto out;
124         }
125
126         if (status == 0) {
127                 new_content = strdup(content);
128                 if (new_content) {
129                         free(handler->content);
130                         handler->content = new_content;
131                         handler->is_pinned_up = pinup;
132                 } else {
133                         ErrPrint("Heap: %s\n", strerror(errno));
134                         status = LB_STATUS_ERROR_MEMORY;
135                 }
136         }
137
138         if (handler->pinup_cb) {
139                 ret_cb_t cb;
140                 void *cbdata;
141
142                 /* Make sure that user can call pinup API in its result callback */
143                 cb = handler->pinup_cb;
144                 cbdata = handler->pinup_cbdata;
145
146                 handler->pinup_cb = NULL;
147                 handler->pinup_cbdata = NULL;
148
149                 cb(handler, status, cbdata);
150         } else if (status == 0) {
151                 lb_invoke_event_handler(handler, LB_EVENT_PINUP_CHANGED);
152         }
153
154 out:
155         return NULL;
156 }
157
158 static struct packet *master_deleted(pid_t pid, int handle, const struct packet *packet)
159 {
160         const char *pkgname;
161         const char *id;
162         double timestamp;
163         struct livebox *handler;
164         int reason;
165
166         if (packet_get(packet, "ssdi", &pkgname, &id, &timestamp, &reason) != 4) {
167                 ErrPrint("Invalid arguemnt\n");
168                 goto out;
169         }
170
171         handler = lb_find_livebox_by_timestamp(timestamp);
172         if (!handler) {
173                 /*!
174                  * \note
175                  * This can be happens only if the user delete a livebox
176                  * right after create it before receive created event.
177                  */
178                 goto out;
179         }
180
181         /*!< Check validity of this "handler" */
182         if (handler->state != CREATE) {
183                 if (handler->state != DELETE) {
184                         /*!
185                          * \note
186                          * This is not possible
187                          */
188                         CRITICAL_LOG("Already deleted handler (%s - %s)\n", pkgname, id);
189                         return NULL;
190                 }
191         }
192
193         if (handler->created_cb) {
194                 ret_cb_t cb;
195                 void *cbdata;
196                 /*!
197                  * \note
198                  *
199                  * "if (handler->id == NULL) {"
200                  *
201                  * The instance is not created yet.
202                  * But the master forcely destroy it and send destroyed event to this
203                  * without the created event.
204                  *
205                  * It could be destroyed when a slave has critical error(fault)
206                  * before creating an instance successfully.
207                  */
208                 if (handler->created_cb == handler->deleted_cb) {
209                         if (handler->created_cbdata != handler->deleted_cbdata) {
210                                 DbgPrint("cb is same but cbdata is different (%s - %s)\n", pkgname, id);
211                         }
212
213                         handler->deleted_cb = NULL;
214                         handler->deleted_cbdata = NULL;
215                 }
216
217                 cb = handler->created_cb;
218                 cbdata = handler->created_cbdata;
219
220                 handler->created_cb = NULL;
221                 handler->created_cbdata = NULL;
222
223                 if (reason == LB_STATUS_SUCCESS) {
224                         reason = LB_STATUS_ERROR_CANCEL;
225                 }
226                 cb(handler, reason, cbdata);
227         } else if (handler->id) {
228                 if (handler->deleted_cb) {
229                         ret_cb_t cb;
230                         void *cbdata;
231
232                         cb = handler->deleted_cb;
233                         cbdata = handler->deleted_cbdata;
234
235                         handler->deleted_cb = NULL;
236                         handler->deleted_cbdata = NULL;
237
238                         cb(handler, reason, cbdata);
239                 } else {
240                         lb_invoke_event_handler(handler, LB_EVENT_DELETED);
241                 }
242         }
243
244         /* Just try to delete it, if a user didn't remove it from the live box list */
245         lb_unref(handler);
246
247 out:
248         return NULL;
249 }
250
251 static struct packet *master_lb_update_begin(pid_t pid, int handle, const struct packet *packet)
252 {
253         struct livebox *handler;
254         const char *pkgname;
255         const char *id;
256         const char *content;
257         const char *title;
258         const char *fbfile;
259         double priority;
260         int ret;
261
262         ret = packet_get(packet, "ssdsss", &pkgname, &id, &priority, &content, &title, &fbfile);
263         if (ret != 6) {
264                 ErrPrint("Invalid argument\n");
265                 goto out;
266         }
267
268         handler = lb_find_livebox(pkgname, id);
269         if (!handler) {
270                 ErrPrint("Instance[%s] is not exists\n", id);
271                 goto out;
272         }
273
274         if (handler->state != CREATE) {
275                 ErrPrint("(%s) is not created\n", id);
276                 goto out;
277         }
278
279         lb_set_priority(handler, priority);
280         lb_set_content(handler, content);
281         lb_set_title(handler, title);
282
283         /*!
284          * \NOTE
285          * Width & Height is not changed in this case.
286          * If the active update is began, the size should not be changed,
287          * And if the size is changed, the provider should finish the updating first.
288          * And then begin updating again after change its size.
289          */
290         if (lb_get_lb_fb(handler)) {
291                 (void)lb_set_lb_fb(handler, fbfile);
292
293                 ret = fb_sync(lb_get_lb_fb(handler));
294                 if (ret != LB_STATUS_SUCCESS) {
295                         ErrPrint("Failed to do sync FB (%s - %s) (%d)\n", pkgname, fbfile, ret);
296                 } else {
297                         lb_invoke_event_handler(handler, LB_EVENT_LB_UPDATE_BEGIN);
298                 }
299         } else {
300                 ErrPrint("Invalid request[%s], %s\n", id, fbfile);
301         }
302
303 out:
304         return NULL;
305 }
306
307 static struct packet *master_pd_update_begin(pid_t pid, int handle, const struct packet *packet)
308 {
309         struct livebox *handler;
310         const char *pkgname;
311         const char *id;
312         const char *fbfile;
313         int ret;
314
315         ret = packet_get(packet, "sss", &pkgname, &id, &fbfile);
316         if (ret != 2) {
317                 ErrPrint("Invalid argument\n");
318                 goto out;
319         }
320
321         handler = lb_find_livebox(pkgname, id);
322         if (!handler) {
323                 ErrPrint("Instance[%s] is not exists\n", id);
324                 goto out;
325         }
326
327         if (handler->state != CREATE) {
328                 ErrPrint("[%s] is not created\n", id);
329                 goto out;
330         }
331
332         if (lb_get_pd_fb(handler)) {
333                 (void)lb_set_lb_fb(handler, fbfile);
334
335                 ret = fb_sync(lb_get_lb_fb(handler));
336                 if (ret != LB_STATUS_SUCCESS) {
337                         ErrPrint("Failed to do sync FB (%s - %s) (%d)\n", pkgname, fbfile, ret);
338                 } else {
339                         lb_invoke_event_handler(handler, LB_EVENT_PD_UPDATE_BEGIN);
340                 }
341         } else {
342                 ErrPrint("Invalid request[%s], %s\n", id, fbfile);
343         }
344
345 out:
346         return NULL;
347 }
348
349 static struct packet *master_lb_update_end(pid_t pid, int handle, const struct packet *packet)
350 {
351         struct livebox *handler;
352         const char *pkgname;
353         const char *id;
354         int ret;
355
356         ret = packet_get(packet, "ss", &pkgname, &id);
357         if (ret != 2) {
358                 ErrPrint("Invalid argument\n");
359                 goto out;
360         }
361
362         handler = lb_find_livebox(pkgname, id);
363         if (!handler) {
364                 ErrPrint("Instance[%s] is not exists\n", id);
365                 goto out;
366         }
367
368         if (handler->state != CREATE) {
369                 ErrPrint("[%s] is not created\n", id);
370                 goto out;
371         }
372
373         if (lb_get_lb_fb(handler)) {
374                 lb_invoke_event_handler(handler, LB_EVENT_LB_UPDATE_END);
375         } else {
376                 ErrPrint("Invalid request[%s]\n", id);
377         }
378
379 out:
380         return NULL;
381 }
382
383 static struct packet *master_access_status(pid_t pid, int handle, const struct packet *packet)
384 {
385         struct livebox *handler;
386         const char *pkgname;
387         const char *id;
388         int ret;
389         int status;
390
391         ret = packet_get(packet, "ssi", &pkgname, &id, &status);
392         if (ret != 3) {
393                 ErrPrint("Invalid argument\n");
394                 goto out;
395         }
396
397         handler = lb_find_livebox(pkgname, id);
398         if (!handler) {
399                 ErrPrint("Instance[%s] is not exists\n", id);
400                 goto out;
401         }
402
403         if (handler->state != CREATE) {
404                 ErrPrint("[%s] is not created\n", id);
405                 goto out;
406         }
407
408         if (handler->access_event_cb) {
409                 ret_cb_t cb;
410                 void *cbdata;
411
412                 cb = handler->access_event_cb;
413                 cbdata = handler->access_event_cbdata;
414
415                 handler->access_event_cb = NULL;
416                 handler->access_event_cbdata = NULL;
417
418                 cb(handler, status, cbdata);
419         } else {
420                 ErrPrint("Invalid event[%s]\n", id);
421         }
422 out:
423         return NULL;
424 }
425
426 static struct packet *master_pd_update_end(pid_t pid, int handle, const struct packet *packet)
427 {
428         struct livebox *handler;
429         const char *pkgname;
430         const char *id;
431         int ret;
432
433         ret = packet_get(packet, "ss", &pkgname, &id);
434         if (ret != 2) {
435                 ErrPrint("Invalid argument\n");
436                 goto out;
437         }
438
439         handler = lb_find_livebox(pkgname, id);
440         if (!handler) {
441                 ErrPrint("Instance[%s] is not exists\n", id);
442                 goto out;
443         }
444
445         if (handler->state != CREATE) {
446                 ErrPrint("[%s] is not created\n", id);
447                 goto out;
448         }
449
450         if (lb_get_lb_fb(handler)) {
451                 lb_invoke_event_handler(handler, LB_EVENT_PD_UPDATE_END);
452         } else {
453                 ErrPrint("Invalid request[%s]", id);
454         }
455
456 out:
457         return NULL;
458 }
459
460 static struct packet *master_lb_updated(pid_t pid, int handle, const struct packet *packet)
461 {
462         const char *pkgname;
463         const char *id;
464         const char *fbfile;
465         const char *content;
466         const char *title;
467         const char *safe_file;
468         struct livebox *handler;
469         int lb_w;
470         int lb_h;
471         double priority;
472         int ret;
473
474         ret = packet_get(packet, "sssiidsss",
475                                 &pkgname, &id,
476                                 &fbfile, &lb_w, &lb_h,
477                                 &priority, &content, &title,
478                                 &safe_file);
479         if (ret != 9) {
480                 ErrPrint("Invalid argument\n");
481                 goto out;
482         }
483
484         handler = lb_find_livebox(pkgname, id);
485         if (!handler) {
486                 ErrPrint("instance(%s) is not exists\n", id);
487                 goto out;
488         }
489
490         if (handler->state != CREATE) {
491                 /*!
492                  * \note
493                  * Already deleted by the user.
494                  * Don't try to notice anything with this, Just ignore all events
495                  * Beacuse the user doesn't wants know about this anymore
496                  */
497                 ErrPrint("(%s) is not exists, but updated\n", id);
498                 goto out;
499         }
500
501         lb_set_priority(handler, priority);
502         lb_set_content(handler, content);
503         lb_set_title(handler, title);
504         lb_set_size(handler, lb_w, lb_h);
505         lb_set_filename(handler, safe_file);
506
507         if (lb_text_lb(handler)) {
508                 (void)parse_desc(handler, livebox_filename(handler), 0);
509                 /*!
510                  * \note
511                  * DESC parser will call the "text event callback".
512                  * Don't need to call global event callback in this case.
513                  */
514                 goto out;
515         } else if (lb_get_lb_fb(handler)) {
516                 if (conf_frame_drop_for_resizing() && handler->size_changed_cb) {
517                         /* Just for skipping the update event callback call, After request to resize buffer, update event will be discarded */
518                         DbgPrint("Discards obsoloted update event\n");
519                         ret = LB_STATUS_ERROR_BUSY;
520                 } else {
521                         (void)lb_set_lb_fb(handler, fbfile);
522
523                         if (!conf_manual_sync()) {
524                                 ret = fb_sync(lb_get_lb_fb(handler));
525                                 if (ret != LB_STATUS_SUCCESS) {
526                                         ErrPrint("Failed to do sync FB (%s - %s) (%d)\n", pkgname, util_basename(util_uri_to_path(id)), ret);
527                                 }
528                         } else {
529                                 ret = LB_STATUS_SUCCESS;
530                         }
531                 }
532         } else {
533                 ret = LB_STATUS_SUCCESS;
534         }
535
536         if (ret == LB_STATUS_SUCCESS) {
537                 lb_invoke_event_handler(handler, LB_EVENT_LB_UPDATED);
538         }
539
540 out:
541         return NULL;
542 }
543
544 static struct packet *master_pd_created(pid_t pid, int handle, const struct packet *packet)
545 {
546         struct livebox *handler;
547         const char *pkgname;
548         const char *id;
549         const char *buf_id;
550         int width;
551         int height;
552         int ret;
553         int status;
554
555         ret = packet_get(packet, "sssiii", &pkgname, &id, &buf_id, &width, &height, &status);
556         if (ret != 6) {
557                 ErrPrint("Invalid argument\n");
558                 goto out;
559         }
560
561         handler = lb_find_livebox(pkgname, id);
562         if (!handler) {
563                 ErrPrint("Instance(%s) is not exists\n", id);
564                 goto out;
565         }
566
567         if (handler->state != CREATE) {
568                 ErrPrint("Instance(%s) is not created\n", id);
569                 goto out;
570         }
571
572         lb_set_pdsize(handler, width, height);
573         if (lb_text_pd(handler)) {
574                 DbgPrint("Text TYPE does not need to handle this\n");
575         } else {
576                 (void)lb_set_pd_fb(handler, buf_id);
577                 ret = fb_sync(lb_get_pd_fb(handler));
578                 if (ret < 0) {
579                         ErrPrint("Failed to do sync FB (%s - %s)\n", pkgname, util_basename(util_uri_to_path(id)));
580                 }
581         }
582
583         handler->is_pd_created = (status == 0);
584
585         if (handler->pd_created_cb) {
586                 ret_cb_t cb;
587                 void *cbdata;
588
589                 cb = handler->pd_created_cb;
590                 cbdata = handler->pd_created_cbdata;
591
592                 handler->pd_created_cb = NULL;
593                 handler->pd_created_cbdata = NULL;
594
595                 /*!
596                  * Before call the Callback function,
597                  * pd_create_cb must be reset.
598                  * Because, in the create callback, user can call create_pd function again.
599                  */
600                 DbgPrint("PERF_DBOX\n");
601                 cb(handler, status, cbdata);
602         } else if (handler->is_pd_created) {
603                 lb_invoke_event_handler(handler, LB_EVENT_PD_CREATED);
604         }
605
606 out:
607         return NULL;
608 }
609
610 static struct packet *master_pd_destroyed(pid_t pid, int handle, const struct packet *packet)
611 {
612         struct livebox *handler;
613         const char *pkgname;
614         const char *id;
615         int ret;
616         int status;
617
618         ret = packet_get(packet, "ssi", &pkgname, &id, &status);
619         if (ret != 3) {
620                 ErrPrint("Invalid argument\n");
621                 goto out;
622         }
623
624         handler = lb_find_livebox(pkgname, id);
625         if (!handler) {
626                 ErrPrint("Instance(%s) is not exists\n", id);
627                 goto out;
628         }
629
630         if (handler->state != CREATE) {
631                 ErrPrint("Instance(%s) is not created\n", id);
632                 goto out;
633         }
634
635         handler->is_pd_created = 0;
636
637         if (handler->pd_destroyed_cb) {
638                 ret_cb_t cb;
639                 void *cbdata;
640
641                 cb = handler->pd_destroyed_cb;
642                 cbdata = handler->pd_destroyed_cbdata;
643
644                 handler->pd_destroyed_cb = NULL;
645                 handler->pd_destroyed_cbdata = NULL;
646
647                 /*!
648                  * Before call the Callback function,
649                  * pd_destroyed_cb must be reset.
650                  * Because, in the create callback, user can call destroy_pd function again.
651                  */
652                 cb(handler, status, cbdata);
653         } else if (status == 0) {
654                 lb_invoke_event_handler(handler, LB_EVENT_PD_DESTROYED);
655         }
656
657 out:
658         return NULL;
659 }
660
661 static struct packet *master_pd_updated(pid_t pid, int handle, const struct packet *packet)
662 {
663         const char *pkgname;
664         const char *id;
665         const char *descfile;
666         const char *fbfile;
667         int ret;
668         struct livebox *handler;
669         int pd_w;
670         int pd_h;
671
672         ret = packet_get(packet, "ssssii",
673                                 &pkgname, &id,
674                                 &descfile, &fbfile,
675                                 &pd_w, &pd_h);
676         if (ret != 6) {
677                 ErrPrint("Invalid argument\n");
678                 goto out;
679         }
680
681         handler = lb_find_livebox(pkgname, id);
682         if (!handler) {
683                 ErrPrint("Instance(%s) is not exists\n", id);
684                 goto out;
685         }
686
687         if (handler->state != CREATE) {
688                 /*!
689                  * \note
690                  * This handler is already deleted by the user.
691                  * So don't try to notice anything about this anymore.
692                  * Just ignore all events.
693                  */
694                 ErrPrint("Instance(%s) is not created\n", id);
695                 goto out;
696         }
697
698         lb_set_pdsize(handler, pd_w, pd_h);
699
700         if (lb_text_pd(handler)) {
701                 (void)parse_desc(handler, descfile, 1);
702         } else {
703                 if (conf_frame_drop_for_resizing() && handler->size_changed_cb) {
704                         /* Just for skipping the update event callback call, After request to resize buffer, update event will be discarded */
705                         DbgPrint("Discards obsoloted update event\n");
706                 } else {
707                         (void)lb_set_pd_fb(handler, fbfile);
708
709                          if (!conf_manual_sync()) {
710                                 ret = fb_sync(lb_get_pd_fb(handler));
711                                 if (ret < 0) {
712                                         ErrPrint("Failed to do sync FB (%s - %s), %d\n", pkgname, util_basename(util_uri_to_path(id)), ret);
713                                 } else {
714                                         lb_invoke_event_handler(handler, LB_EVENT_PD_UPDATED);
715                                 }
716                         } else {
717                                 lb_invoke_event_handler(handler, LB_EVENT_PD_UPDATED);
718                         }
719                 }
720         }
721
722 out:
723         return NULL;
724 }
725
726 static struct packet *master_update_mode(pid_t pid, int handle, const struct packet *packet)
727 {
728         struct livebox *handler;
729         const char *pkgname;
730         const char *id;
731         int active_mode;
732         int status;
733         int ret;
734
735         if (!packet) {
736                 ErrPrint("Invalid packet\n");
737                 goto out;
738         }
739
740         ret = packet_get(packet, "ssii", &pkgname, &id, &status, &active_mode);
741         if (ret != 4) {
742                 ErrPrint("Invalid argument\n");
743                 goto out;
744         }
745
746         handler = lb_find_livebox(pkgname, id);
747         if (!handler) {
748                 ErrPrint("Livebox(%s) is not found\n", id);
749                 goto out;
750         }
751
752         if (handler->state != CREATE) {
753                 ErrPrint("Livebox(%s) is not created yet\n", id);
754                 goto out;
755         }
756
757         if (status == LB_STATUS_SUCCESS) {
758                 lb_set_update_mode(handler, active_mode);
759         }
760
761         if (handler->update_mode_cb) {
762                 ret_cb_t cb;
763                 void *cbdata;
764
765                 cb = handler->update_mode_cb;
766                 cbdata = handler->update_mode_cbdata;
767
768                 handler->update_mode_cb = NULL;
769                 handler->update_mode_cbdata = NULL;
770
771                 cb(handler, status, cbdata);
772         } else {
773                 lb_invoke_event_handler(handler, LB_EVENT_UPDATE_MODE_CHANGED);
774         }
775
776 out:
777         return NULL;
778 }
779
780 static struct packet *master_size_changed(pid_t pid, int handle, const struct packet *packet)
781 {
782         struct livebox *handler;
783         const char *pkgname;
784         const char *id;
785         const char *fbfile;
786         int status;
787         int ret;
788         int w;
789         int h;
790         int is_pd;
791
792         if (!packet) {
793                 ErrPrint("Invalid packet\n");
794                 goto out;
795         }
796
797         ret = packet_get(packet, "sssiiii", &pkgname, &id, &fbfile, &is_pd, &w, &h, &status);
798         if (ret != 7) {
799                 ErrPrint("Invalid argument\n");
800                 goto out;
801         }
802
803         handler = lb_find_livebox(pkgname, id);
804         if (!handler) {
805                 ErrPrint("Livebox(%s) is not found\n", id);
806                 goto out;
807         }
808
809         if (handler->state != CREATE) {
810                 ErrPrint("Livebox(%s) is not created yet\n", id);
811                 goto out;
812         }
813
814         if (is_pd) {
815                 /*!
816                  * \NOTE
817                  * PD is not able to resized by the client.
818                  * PD is only can be managed by the provider.
819                  * So the PD has no private resized event handler.
820                  * Notify it via global event handler only.
821                  */
822                 if (status == 0) {
823                         lb_set_pdsize(handler, w, h);
824                         lb_invoke_event_handler(handler, LB_EVENT_PD_SIZE_CHANGED);
825                 } else {
826                         ErrPrint("This is not possible. PD Size is changed but the return value is not ZERO (%d)\n", status);
827                 }
828         } else {
829                 if (status == 0) {
830                         lb_set_size(handler, w, h);
831
832                         /*!
833                          * \NOTE
834                          * If there is a created LB FB, 
835                          * Update it too.
836                          */
837                         if (lb_get_lb_fb(handler)) {
838                                 (void)lb_set_lb_fb(handler, fbfile);
839
840                                 ret = fb_sync(lb_get_lb_fb(handler));
841                                 if (ret < 0) {
842                                         ErrPrint("Failed to do sync FB (%s - %s)\n", pkgname, util_basename(util_uri_to_path(id)));
843                                 }
844
845                                 /* Just update the size info only. */
846                         }
847
848                         /*!
849                          * \NOTE
850                          * I cannot believe client.
851                          * So I added some log before & after call the user callback.
852                          */
853                         if (handler->size_changed_cb) {
854                                 ret_cb_t cb;
855                                 void *cbdata;
856
857                                 cb = handler->size_changed_cb;
858                                 cbdata = handler->size_cbdata;
859
860                                 handler->size_changed_cb = NULL;
861                                 handler->size_cbdata = NULL;
862
863                                 cb(handler, status, cbdata);
864                         } else {
865                                 lb_invoke_event_handler(handler, LB_EVENT_LB_SIZE_CHANGED);
866                         }
867                 } else {
868                         if (handler->size_changed_cb) {
869                                 ret_cb_t cb;
870                                 void *cbdata;
871
872                                 cb = handler->size_changed_cb;
873                                 cbdata = handler->size_cbdata;
874
875                                 handler->size_changed_cb = NULL;
876                                 handler->size_cbdata = NULL;
877
878                                 cb(handler, status, cbdata);
879                         }
880                 }
881         }
882
883 out:
884         return NULL;
885 }
886
887 static struct packet *master_period_changed(pid_t pid, int handle, const struct packet *packet)
888 {
889         struct livebox *handler;
890         const char *pkgname;
891         const char *id;
892         int ret;
893         double period;
894         int status;
895
896         ret = packet_get(packet, "idss", &status, &period, &pkgname, &id);
897         if (ret != 4) {
898                 ErrPrint("Invalid argument\n");
899                 goto out;
900         }
901
902         handler = lb_find_livebox(pkgname, id);
903         if (!handler) {
904                 ErrPrint("Livebox(%s) is not found\n", id);
905                 goto out;
906         }
907
908         if (handler->state != CREATE) {
909                 ErrPrint("Livebox(%s) is not created\n", id);
910                 goto out;
911         }
912
913         if (status == 0) {
914                 lb_set_period(handler, period);
915         }
916
917         if (handler->period_changed_cb) {
918                 ret_cb_t cb;
919                 void *cbdata;
920
921                 cb = handler->period_changed_cb;
922                 cbdata = handler->period_cbdata;
923
924                 handler->period_changed_cb = NULL;
925                 handler->period_cbdata = NULL;
926
927                 cb(handler, status, cbdata);
928         } else if (status == 0) {
929                 lb_invoke_event_handler(handler, LB_EVENT_PERIOD_CHANGED);
930         }
931
932 out:
933         return NULL;
934 }
935
936 static struct packet *master_group_changed(pid_t pid, int handle, const struct packet *packet)
937 {
938         struct livebox *handler;
939         const char *pkgname;
940         const char *id;
941         int ret;
942         const char *cluster;
943         const char *category;
944         int status;
945
946         ret = packet_get(packet, "ssiss", &pkgname, &id, &status, &cluster, &category);
947         if (ret != 5) {
948                 ErrPrint("Invalid argument\n");
949                 goto out;
950         }
951
952         handler = lb_find_livebox(pkgname, id);
953         if (!handler) {
954                 ErrPrint("Livebox(%s) is not exists\n", id);
955                 goto out;
956         }
957
958         if (handler->state != CREATE) {
959                 /*!
960                  * \note
961                  * Do no access this handler,
962                  * You cannot believe this handler anymore.
963                  */
964                 ErrPrint("Livebox(%s) is not created\n", id);
965                 goto out;
966         }
967
968         if (status == 0) {
969                 (void)lb_set_group(handler, cluster, category);
970         }
971
972         if (handler->group_changed_cb) {
973                 ret_cb_t cb;
974                 void *cbdata;
975
976                 cb = handler->group_changed_cb;
977                 cbdata = handler->group_cbdata;
978
979                 handler->group_changed_cb = NULL;
980                 handler->group_cbdata = NULL;
981
982                 cb(handler, status, cbdata);
983         } else if (status == 0) {
984                 lb_invoke_event_handler(handler, LB_EVENT_GROUP_CHANGED);
985         }
986
987 out:
988         return NULL;
989 }
990
991 static struct packet *master_created(pid_t pid, int handle, const struct packet *packet)
992 {
993         struct livebox *handler;
994
995         int lb_w;
996         int lb_h;
997         int pd_w;
998         int pd_h;
999         const char *pkgname;
1000         const char *id;
1001
1002         const char *content;
1003         const char *cluster;
1004         const char *category;
1005         const char *lb_fname;
1006         const char *pd_fname;
1007         const char *title;
1008
1009         double timestamp;
1010         const char *auto_launch;
1011         double priority;
1012         int size_list;
1013         int user;
1014         int pinup_supported;
1015         enum lb_type lb_type;
1016         enum pd_type pd_type;
1017         double period;
1018         int is_pinned_up;
1019
1020         int old_state = DESTROYED;
1021
1022         int ret;
1023
1024         ret = packet_get(packet, "dsssiiiisssssdiiiiidsi",
1025                         &timestamp,
1026                         &pkgname, &id, &content,
1027                         &lb_w, &lb_h, &pd_w, &pd_h,
1028                         &cluster, &category, &lb_fname, &pd_fname,
1029                         &auto_launch, &priority, &size_list, &user, &pinup_supported,
1030                         &lb_type, &pd_type, &period, &title, &is_pinned_up);
1031         if (ret != 22) {
1032                 ErrPrint("Invalid argument\n");
1033                 ret = LB_STATUS_ERROR_INVALID;
1034                 goto out;
1035         }
1036
1037         ErrPrint("[%lf] pkgname: %s, id: %s, content: %s, "
1038                 "pd_w: %d, pd_h: %d, lb_w: %d, lb_h: %d, "
1039                 "cluster: %s, category: %s, lb_fname: \"%s\", pd_fname: \"%s\", "
1040                 "auto_launch: %s, priority: %lf, size_list: %d, user: %d, pinup: %d, "
1041                 "lb_type: %d, pd_type: %d, period: %lf, title: [%s], is_pinned_up: %d\n",
1042                 timestamp, pkgname, id, content,
1043                 pd_w, pd_h, lb_w, lb_h,
1044                 cluster, category, lb_fname, pd_fname,
1045                 auto_launch, priority, size_list, user, pinup_supported,
1046                 lb_type, pd_type, period, title, is_pinned_up);
1047
1048         handler = lb_find_livebox_by_timestamp(timestamp);
1049         if (!handler) {
1050                 handler = lb_new_livebox(pkgname, id, timestamp);
1051                 if (!handler) {
1052                         ErrPrint("Failed to create a new livebox\n");
1053                         ret = LB_STATUS_ERROR_FAULT;
1054                         goto out;
1055                 }
1056
1057                 old_state = handler->state;
1058         } else {
1059                 if (handler->state != CREATE) {
1060                         if (handler->state != DELETE) {
1061                                 /*!
1062                                  * \note
1063                                  * This is not possible!!!
1064                                  */
1065                                 ErrPrint("Invalid handler\n");
1066                                 ret = LB_STATUS_ERROR_INVALID;
1067                                 goto out;
1068                         }
1069
1070                         /*!
1071                          * \note
1072                          * After get the delete states,
1073                          * call the create callback with deleted result.
1074                          */
1075                 }
1076
1077                 old_state = handler->state;
1078
1079                 if (handler->id) {
1080                         ErrPrint("Already created: timestamp[%lf] "
1081                                 "pkgname[%s], id[%s] content[%s] "
1082                                 "cluster[%s] category[%s] lb_fname[%s] pd_fname[%s]\n",
1083                                         timestamp, pkgname, id,
1084                                         content, cluster, category,
1085                                         lb_fname, pd_fname);
1086
1087                         ret = LB_STATUS_ERROR_ALREADY;
1088                         goto out;
1089                 }
1090
1091                 lb_set_id(handler, id);
1092         }
1093
1094         lb_set_size(handler, lb_w, lb_h);
1095         handler->lb.type = lb_type;
1096         handler->is_pinned_up = is_pinned_up;
1097
1098         switch (lb_type) {
1099         case _LB_TYPE_FILE:
1100                 break;
1101         case _LB_TYPE_SCRIPT:
1102         case _LB_TYPE_BUFFER:
1103                 if (!strlen(lb_fname)) {
1104                         break;
1105                 }
1106                 (void)lb_set_lb_fb(handler, lb_fname);
1107
1108                 ret = fb_sync(lb_get_lb_fb(handler));
1109                 if (ret < 0) {
1110                         ErrPrint("Failed to do sync FB (%s - %s)\n", pkgname, util_basename(util_uri_to_path(id)));
1111                 }
1112                 break;
1113         case _LB_TYPE_TEXT:
1114                 lb_set_text_lb(handler);
1115                 break;
1116         default:
1117                 break;
1118         }
1119
1120         handler->pd.type = pd_type;
1121         lb_set_pdsize(handler, pd_w, pd_h);
1122         lb_set_default_pdsize(handler, pd_w, pd_h);
1123         switch (pd_type) {
1124         case _PD_TYPE_SCRIPT:
1125         case _PD_TYPE_BUFFER:
1126                 if (!strlen(pd_fname)) {
1127                         break;
1128                 }
1129
1130                 lb_set_pd_fb(handler, pd_fname);
1131                 ret = fb_sync(lb_get_pd_fb(handler));
1132                 if (ret < 0) {
1133                         ErrPrint("Failed to do sync FB (%s - %s)\n", pkgname, util_basename(util_uri_to_path(id)));
1134                 }
1135                 break;
1136         case _PD_TYPE_TEXT:
1137                 lb_set_text_pd(handler);
1138                 break;
1139         default:
1140                 break;
1141         }
1142
1143         lb_set_priority(handler, priority);
1144
1145         lb_set_size_list(handler, size_list);
1146         lb_set_group(handler, cluster, category);
1147
1148         lb_set_content(handler, content);
1149         lb_set_title(handler, title);
1150
1151         lb_set_user(handler, user);
1152
1153         lb_set_auto_launch(handler, auto_launch);
1154         lb_set_pinup(handler, pinup_supported);
1155
1156         lb_set_period(handler, period);
1157
1158         ret = 0;
1159
1160         if (handler->state == CREATE) {
1161                 /*!
1162                  * \note
1163                  * These callback can change the handler->state.
1164                  * So we have to use the "old_state" which stored state before call these callbacks
1165                  */
1166
1167                 if (handler->created_cb) {
1168                         ret_cb_t cb;
1169                         void *cbdata;
1170
1171                         cb = handler->created_cb;
1172                         cbdata = handler->created_cbdata;
1173
1174                         handler->created_cb = NULL;
1175                         handler->created_cbdata = NULL;
1176
1177                         cb(handler, ret, cbdata);
1178                 } else {
1179                         lb_invoke_event_handler(handler, LB_EVENT_CREATED);
1180                 }
1181         }
1182
1183 out:
1184         if (ret == 0 && old_state == DELETE) {
1185                 lb_send_delete(handler, handler->created_cb, handler->created_cbdata);
1186
1187                 /*!
1188                  * \note
1189                  * handler->created_cb = NULL;
1190                  * handler->created_cbdata = NULL;
1191                  *
1192                  * Do not clear this to use this from the deleted event callback.
1193                  * if this value is not cleared when the deleted event callback check it,
1194                  * it means that the created function is not called yet.
1195                  * Then the call the deleted event callback with LB_STATUS_ERROR_CANCEL errno.
1196                  */
1197         }
1198
1199         return NULL;
1200 }
1201
1202 static struct method s_table[] = {
1203         {
1204                 .cmd = "lb_updated", /* pkgname, id, lb_w, lb_h, priority, ret */
1205                 .handler = master_lb_updated,
1206         },
1207         {
1208                 .cmd = "pd_updated", /* pkgname, id, descfile, pd_w, pd_h, ret */
1209                 .handler = master_pd_updated,
1210         },
1211         {
1212                 .cmd = "pd_created",
1213                 .handler = master_pd_created,
1214         },
1215         {
1216                 .cmd = "pd_destroyed",
1217                 .handler = master_pd_destroyed,
1218         },
1219         {
1220                 .cmd = "fault_package", /* pkgname, id, function, ret */
1221                 .handler = master_fault_package,
1222         },
1223         {
1224                 .cmd = "deleted", /* pkgname, id, timestamp, ret */
1225                 .handler = master_deleted,
1226         },
1227         {
1228                 .cmd = "created", /* timestamp, pkgname, id, content, lb_w, lb_h, pd_w, pd_h, cluster, category, lb_file, pd_file, auto_launch, priority, size_list, is_user, pinup_supported, text_lb, text_pd, period, ret */
1229                 .handler = master_created,
1230         },
1231         {
1232                 .cmd = "group_changed",
1233                 .handler = master_group_changed,
1234         },
1235         {
1236                 .cmd = "period_changed",
1237                 .handler = master_period_changed,
1238         },
1239         {
1240                 .cmd = "size_changed",
1241                 .handler = master_size_changed,
1242         },
1243         {
1244                 .cmd = "pinup",
1245                 .handler = master_pinup,
1246         },
1247         {
1248                 .cmd = "scroll",
1249                 .handler = master_hold_scroll,
1250         },
1251
1252         {
1253                 .cmd = "update_mode",
1254                 .handler = master_update_mode,
1255         },
1256
1257         {
1258                 .cmd = "lb_update_begin",
1259                 .handler = master_lb_update_begin,
1260         },
1261         {
1262                 .cmd = "lb_update_end",
1263                 .handler = master_lb_update_end,
1264         },
1265
1266         {
1267                 .cmd = "pd_update_begin",
1268                 .handler = master_pd_update_begin,
1269         },
1270         {
1271                 .cmd = "pd_update_end",
1272                 .handler = master_pd_update_end,
1273         },
1274
1275         {
1276                 .cmd = "access_status",
1277                 .handler = master_access_status,
1278         },
1279
1280         {
1281                 .cmd = NULL,
1282                 .handler = NULL,
1283         },
1284 };
1285
1286 static void acquire_cb(struct livebox *handler, const struct packet *result, void *data)
1287 {
1288         if (!result) {
1289                 DbgPrint("Result packet is not valid\n");
1290         } else {
1291                 int ret;
1292
1293                 if (packet_get(result, "i", &ret) != 1) {
1294                         ErrPrint("Invalid argument\n");
1295                 } else {
1296                         DbgPrint("Acquire returns: %d\n", ret);
1297                 }
1298         }
1299
1300         return;
1301 }
1302
1303 static inline int make_connection(void)
1304 {
1305         struct packet *packet;
1306         int ret;
1307
1308         DbgPrint("Let's making connection!\n");
1309
1310         s_info.fd = com_core_packet_client_init(client_addr(), 0, s_table);
1311         if (s_info.fd < 0) {
1312                 ErrPrint("Try this again later\n");
1313                 return LB_STATUS_ERROR_IO;
1314         }
1315
1316         packet = packet_create("acquire", "d", util_timestamp());
1317         if (!packet) {
1318                 com_core_packet_client_fini(s_info.fd);
1319                 s_info.fd = -1;
1320                 return LB_STATUS_ERROR_FAULT;
1321         }
1322
1323         ret = master_rpc_async_request(NULL, packet, 1, acquire_cb, NULL);
1324         if (ret < 0) {
1325                 ErrPrint("Master RPC returns %d\n", ret);
1326                 com_core_packet_client_fini(s_info.fd);
1327                 s_info.fd = -1;
1328                 return LB_STATUS_ERROR_IO;
1329         }
1330
1331         return LB_STATUS_SUCCESS;
1332 }
1333
1334 static int connected_cb(int handle, void *data)
1335 {
1336         master_rpc_check_and_fire_consumer();
1337         return 0;
1338 }
1339
1340 static void master_started_cb(keynode_t *node, void *data)
1341 {
1342         int state = 0;
1343
1344         if (vconf_get_bool(VCONFKEY_MASTER_STARTED, &state) < 0) {
1345                 ErrPrint("Unable to get [%s]\n", VCONFKEY_MASTER_STARTED);
1346         }
1347
1348         DbgPrint("Master state: %d\n", state);
1349         if (state == 1 && make_connection() == LB_STATUS_SUCCESS) {
1350                 int ret;
1351                 ret = vconf_ignore_key_changed(VCONFKEY_MASTER_STARTED, master_started_cb);
1352                 DbgPrint("master_started vconf key de-registered [%d]\n", ret);
1353         }
1354 }
1355
1356 static gboolean timeout_cb(gpointer data)
1357 {
1358         if (vconf_notify_key_changed(VCONFKEY_MASTER_STARTED, master_started_cb, NULL) < 0) {
1359                 ErrPrint("Failed to add vconf for monitoring service state\n");
1360         } else {
1361                 DbgPrint("vconf event callback is registered\n");
1362         }
1363
1364         master_started_cb(NULL, NULL);
1365
1366         s_info.timer_id = 0;
1367         return FALSE;
1368 }
1369
1370 static int disconnected_cb(int handle, void *data)
1371 {
1372         if (s_info.fd != handle) {
1373                 /*!< This handle is not my favor */
1374                 return 0;
1375         }
1376
1377         s_info.fd = -1; /*!< Disconnected */
1378
1379         master_rpc_clear_all_request();
1380         lb_invoke_fault_handler(LB_FAULT_PROVIDER_DISCONNECTED, MASTER_PKGNAME, "default", "disconnected");
1381
1382         lb_delete_all();
1383
1384         /* Try to reconnect after 1 sec later */
1385         if (!s_info.timer_id) {
1386                 DbgPrint("Reconnecting timer is added\n");
1387                 s_info.timer_id = g_timeout_add(1000, timeout_cb, NULL);
1388                 if (s_info.timer_id == 0) {
1389                         ErrPrint("Unable to add reconnecting timer\n");
1390                         return 0;
1391                 }
1392         } else {
1393                 ErrPrint("Reconnecting timer is already exists\n");
1394         }
1395
1396         return 0;
1397 }
1398
1399 int client_init(void)
1400 {
1401         s_info.client_addr = vconf_get_str(VCONFKEY_MASTER_CLIENT_ADDR);
1402         if (!s_info.client_addr) {
1403                 s_info.client_addr = strdup(CLIENT_SOCKET);
1404                 if (!s_info.client_addr) {
1405                         ErrPrint("Heap: %s\n", strerror(errno));
1406                         return -ENOMEM;
1407                 }
1408         }
1409
1410         (void)file_service_init();
1411
1412         DbgPrint("Server Address: %s\n", s_info.client_addr);
1413
1414         com_core_add_event_callback(CONNECTOR_DISCONNECTED, disconnected_cb, NULL);
1415         com_core_add_event_callback(CONNECTOR_CONNECTED, connected_cb, NULL);
1416         if (vconf_notify_key_changed(VCONFKEY_MASTER_STARTED, master_started_cb, NULL) < 0) {
1417                 ErrPrint("Failed to add vconf for service state\n");
1418         } else {
1419                 DbgPrint("vconf event callback is registered\n");
1420         }
1421
1422         master_started_cb(NULL, NULL);
1423         return 0;
1424 }
1425
1426 int client_fd(void)
1427 {
1428         return s_info.fd;
1429 }
1430
1431 const char *client_addr(void)
1432 {
1433         return s_info.client_addr;
1434 }
1435
1436 int client_fini(void)
1437 {
1438         int ret;
1439
1440         (void)file_service_fini();
1441
1442         ret = vconf_ignore_key_changed(VCONFKEY_MASTER_STARTED, master_started_cb);
1443         if (ret < 0) {
1444                 DbgPrint("Ignore vconf key: %d\n", ret);
1445         }
1446
1447         com_core_del_event_callback(CONNECTOR_DISCONNECTED, disconnected_cb, NULL);
1448         com_core_del_event_callback(CONNECTOR_CONNECTED, connected_cb, NULL);
1449         com_core_packet_client_fini(s_info.fd);
1450         s_info.fd = -1;
1451         free(s_info.client_addr);
1452         s_info.client_addr = NULL;
1453         return LB_STATUS_SUCCESS;
1454 }
1455
1456 /* End of a file */