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