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