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