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