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