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