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