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