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