2 * Copyright 2013 Samsung Electronics Co., Ltd
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
8 * http://floralicense.org/license/
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.
28 #include <vconf-keys.h>
32 #include <com-core_packet.h>
33 #include <livebox-errno.h>
34 #include <livebox-service.h>
35 #include <secure_socket.h>
40 #include "livebox_internal.h"
41 #include "desc_parser.h"
44 #include "master_rpc.h"
46 #include "file_service.h"
48 #include <tzplatform_config.h>
62 static struct packet *master_fault_package(pid_t pid, int handle, const struct packet *packet)
68 if (packet_get(packet, "sss", &pkgname, &id, &function) != 3) {
69 ErrPrint("Invalid arguments\n");
73 DbgPrint("[%s]\n", pkgname);
74 master_rpc_clear_fault_package(pkgname);
75 lb_invoke_fault_handler(LB_FAULT_DEACTIVATED, pkgname, id, function);
79 static struct packet *master_hold_scroll(pid_t pid, int handle, const struct packet *packet)
81 struct livebox_common *common;
82 struct livebox *livebox;
89 ret = packet_get(packet, "ssi", &pkgname, &id, &seize);
91 ErrPrint("Invalid argument\n");
95 common = lb_find_common_handle(pkgname, id);
97 ErrPrint("Instance(%s) is not exists\n", id);
101 DbgPrint("HOLD: [%s] seize(%d)\n", id, seize);
102 seize = seize ? LB_EVENT_HOLD_SCROLL : LB_EVENT_RELEASE_SCROLL;
103 dlist_foreach(common->livebox_list, l, livebox) {
104 lb_invoke_event_handler(livebox, seize);
111 static struct packet *master_pinup(pid_t pid, int handle, const struct packet *packet)
116 struct livebox *handler;
119 struct livebox_common *common;
125 ret = packet_get(packet, "iisss", &status, &pinup, &pkgname, &id, &content);
127 ErrPrint("Invalid argument\n");
131 common = lb_find_common_handle(pkgname, id);
133 ErrPrint("Instance (%s) is not exists\n", id);
137 if (status == (int)LB_STATUS_SUCCESS) {
138 new_content = strdup(content);
140 free(common->content);
141 common->content = new_content;
142 common->is_pinned_up = pinup;
144 ErrPrint("Heap: %s\n", strerror(errno));
145 status = LB_STATUS_ERROR_MEMORY;
149 common->request.pinup = 0;
151 dlist_foreach_safe(common->livebox_list, l, n, handler) {
152 if (handler->cbs.pinup.cb) {
156 /* Make sure that user can call pinup API in its result callback */
157 cb = handler->cbs.pinup.cb;
158 cbdata = handler->cbs.pinup.data;
160 handler->cbs.pinup.cb = NULL;
161 handler->cbs.pinup.data = NULL;
163 cb(handler, status, cbdata);
164 } else if (status == (int)LB_STATUS_SUCCESS) {
165 lb_invoke_event_handler(handler, LB_EVENT_PINUP_CHANGED);
173 static struct packet *master_deleted(pid_t pid, int handle, const struct packet *packet)
178 struct livebox *handler;
179 struct livebox_common *common;
184 if (packet_get(packet, "ssdi", &pkgname, &id, ×tamp, &reason) != 4) {
185 ErrPrint("Invalid arguemnt\n");
189 DbgPrint("[%s]\n", pkgname);
190 common = lb_find_common_handle_by_timestamp(timestamp);
194 * This can be happens only if the user delete a livebox
195 * right after create it before receive created event.
200 /*!< Check validity of this "handler" */
201 if (common->state != CREATE) {
202 if (common->state != DELETE) {
205 * This is not possible
207 ErrPrint("Already deleted handler (%s - %s)\n", pkgname, id);
212 common->request.deleted = 0;
214 * We should change the state of "common handler' before handling the callbacks.
215 * Because if user tries to create a new handle in the callbacks,
216 * find_sharable_common_handle will returns destroying object.
217 * Then we will get panic.
218 * To prevent it, we should change its state first.
220 common->state = DELETE;
222 dlist_foreach_safe(common->livebox_list, l, n, handler) {
223 if (handler->cbs.created.cb) {
229 * "if (handler->id == NULL) {"
231 * The instance is not created yet.
232 * But the master forcely destroy it and send destroyed event to this
233 * without the created event.
235 * It could be destroyed when a slave has critical error(fault)
236 * before creating an instance successfully.
238 if (handler->cbs.created.cb == handler->cbs.deleted.cb) {
239 if (handler->cbs.created.data != handler->cbs.deleted.data) {
240 DbgPrint("cb is same but cbdata is different (%s - %s)\n", pkgname, id);
243 handler->cbs.deleted.cb = NULL;
244 handler->cbs.deleted.data = NULL;
247 cb = handler->cbs.created.cb;
248 cbdata = handler->cbs.created.data;
250 handler->cbs.created.cb = NULL;
251 handler->cbs.created.data = NULL;
253 if (reason == (int)LB_STATUS_SUCCESS) {
254 reason = LB_STATUS_ERROR_CANCEL;
257 cb(handler, reason, cbdata);
258 } else if (common->id) {
259 if (handler->cbs.deleted.cb) {
263 cb = handler->cbs.deleted.cb;
264 cbdata = handler->cbs.deleted.data;
266 handler->cbs.deleted.cb = NULL;
267 handler->cbs.deleted.data = NULL;
269 cb(handler, reason, cbdata);
271 lb_invoke_event_handler(handler, LB_EVENT_DELETED);
275 /* Just try to delete it, if a user didn't remove it from the live box list */
276 lb_unref(handler, 1);
283 static struct packet *master_lb_update_begin(pid_t pid, int handle, const struct packet *packet)
285 struct livebox *handler;
286 struct livebox_common *common;
295 ret = packet_get(packet, "ssdsss", &pkgname, &id, &priority, &content, &title, &fbfile);
297 ErrPrint("Invalid argument\n");
301 common = lb_find_common_handle(pkgname, id);
303 ErrPrint("Instance[%s] is not exists\n", id);
307 if (common->state != CREATE) {
308 ErrPrint("(%s) is not created\n", id);
312 lb_set_priority(common, priority);
313 lb_set_content(common, content);
314 lb_set_title(common, title);
318 * Width & Height is not changed in this case.
319 * If the active update is began, the size should not be changed,
320 * And if the size is changed, the provider should finish the updating first.
321 * And then begin updating again after change its size.
323 if (lb_get_lb_fb(common)) {
324 (void)lb_set_lb_fb(common, fbfile);
326 ret = lb_sync_lb_fb(common);
328 if (ret != (int)LB_STATUS_SUCCESS) {
329 ErrPrint("Failed to do sync FB (%s - %s) (%d)\n", pkgname, fbfile, ret);
332 dlist_foreach(common->livebox_list, l, handler) {
333 lb_invoke_event_handler(handler, LB_EVENT_LB_UPDATE_BEGIN);
337 ErrPrint("Invalid request[%s], %s\n", id, fbfile);
344 static struct packet *master_pd_update_begin(pid_t pid, int handle, const struct packet *packet)
346 struct livebox *handler;
347 struct livebox_common *common;
353 ret = packet_get(packet, "sss", &pkgname, &id, &fbfile);
355 ErrPrint("Invalid argument\n");
359 common = lb_find_common_handle(pkgname, id);
361 ErrPrint("Instance[%s] is not exists\n", id);
365 if (common->state != CREATE) {
366 ErrPrint("[%s] is not created\n", id);
370 if (lb_get_pd_fb(common)) {
371 (void)lb_set_pd_fb(common, fbfile);
373 ret = lb_sync_pd_fb(common);
374 if (ret != (int)LB_STATUS_SUCCESS) {
375 ErrPrint("Failed to do sync FB (%s - %s) (%d)\n", pkgname, fbfile, ret);
378 dlist_foreach(common->livebox_list, l, handler) {
379 lb_invoke_event_handler(handler, LB_EVENT_PD_UPDATE_BEGIN);
383 ErrPrint("Invalid request[%s], %s\n", id, fbfile);
390 static struct packet *master_lb_update_end(pid_t pid, int handle, const struct packet *packet)
392 struct livebox *handler;
393 struct livebox_common *common;
398 ret = packet_get(packet, "ss", &pkgname, &id);
400 ErrPrint("Invalid argument\n");
404 common = lb_find_common_handle(pkgname, id);
406 ErrPrint("Instance[%s] is not exists\n", id);
410 if (common->state != CREATE) {
411 ErrPrint("[%s] is not created\n", id);
415 if (lb_get_lb_fb(common)) {
417 dlist_foreach(common->livebox_list, l, handler) {
418 lb_invoke_event_handler(handler, LB_EVENT_LB_UPDATE_END);
421 ErrPrint("Invalid request[%s]\n", id);
428 static struct packet *master_key_status(pid_t pid, int handle, const struct packet *packet)
430 struct livebox *handler;
431 struct livebox_common *common;
438 ret = packet_get(packet, "ssi", &pkgname, &id, &status);
440 ErrPrint("Invalid argument\n");
444 common = lb_find_common_handle(pkgname, id);
446 ErrPrint("Instance[%s] is not exists\n", id);
450 if (common->state != CREATE) {
451 ErrPrint("[%s] is not created\n", id);
455 common->request.key_event = 0;
456 dlist_foreach(common->livebox_list, l, handler) {
457 if (handler->cbs.key_event.cb) {
461 cb = handler->cbs.key_event.cb;
462 cbdata = handler->cbs.key_event.data;
464 handler->cbs.key_event.cb = NULL;
465 handler->cbs.key_event.data = NULL;
467 cb(handler, status, cbdata);
469 ErrPrint("Invalid event[%s]\n", id);
477 static struct packet *master_request_close_pd(pid_t pid, int handle, const struct packet *packet)
479 struct livebox *handler;
480 struct livebox_common *common;
487 ret = packet_get(packet, "ssi", &pkgname, &id, &reason);
489 ErrPrint("Invalid argument\n");
493 common = lb_find_common_handle(pkgname, id);
495 ErrPrint("Instance[%s] is not exists\n", id);
499 if (common->state != CREATE) {
500 ErrPrint("[%s] is not created\n", id);
504 if (!common->is_pd_created) {
505 DbgPrint("PD is not created, closing what?(%s)\n", id);
509 DbgPrint("Reason: %d\n", reason);
511 dlist_foreach(common->livebox_list, l, handler) {
512 lb_invoke_event_handler(handler, LB_EVENT_REQUEST_CLOSE_PD);
518 static struct packet *master_access_status(pid_t pid, int handle, const struct packet *packet)
520 struct livebox *handler;
521 struct livebox_common *common;
528 ret = packet_get(packet, "ssi", &pkgname, &id, &status);
530 ErrPrint("Invalid argument\n");
534 common = lb_find_common_handle(pkgname, id);
536 ErrPrint("Instance[%s] is not exists\n", id);
540 if (common->state != CREATE) {
541 ErrPrint("[%s] is not created\n", id);
545 common->request.access_event = 0;
546 dlist_foreach(common->livebox_list, l, handler) {
547 if (handler->cbs.access_event.cb) {
551 cb = handler->cbs.access_event.cb;
552 cbdata = handler->cbs.access_event.data;
554 handler->cbs.access_event.cb = NULL;
555 handler->cbs.access_event.data = NULL;
557 cb(handler, status, cbdata);
564 static struct packet *master_pd_update_end(pid_t pid, int handle, const struct packet *packet)
566 struct livebox *handler;
567 struct livebox_common *common;
572 ret = packet_get(packet, "ss", &pkgname, &id);
574 ErrPrint("Invalid argument\n");
578 common = lb_find_common_handle(pkgname, id);
580 ErrPrint("Instance[%s] is not exists\n", id);
584 if (common->state != CREATE) {
585 ErrPrint("[%s] is not created\n", id);
589 if (lb_get_lb_fb(common)) {
592 dlist_foreach(common->livebox_list, l, handler) {
593 lb_invoke_event_handler(handler, LB_EVENT_PD_UPDATE_END);
596 ErrPrint("Invalid request[%s]", id);
603 static struct packet *master_lb_updated(pid_t pid, int handle, const struct packet *packet)
610 const char *safe_file;
613 struct livebox *handler;
614 struct livebox_common *common;
620 ret = packet_get(packet, "sssiidsssss",
622 &fbfile, &lb_w, &lb_h,
623 &priority, &content, &title,
624 &safe_file, &icon, &name);
626 ErrPrint("Invalid argument\n");
630 common = lb_find_common_handle(pkgname, id);
632 ErrPrint("instance(%s) is not exists\n", id);
636 if (common->state != CREATE) {
639 * Already deleted by the user.
640 * Don't try to notice anything with this, Just ignore all events
641 * Beacuse the user doesn't wants know about this anymore
643 ErrPrint("(%s) is not exists, but updated\n", id);
647 lb_set_priority(common, priority);
648 lb_set_content(common, content);
649 lb_set_title(common, title);
650 lb_set_size(common, lb_w, lb_h);
651 lb_set_filename(common, safe_file);
653 if (lb_text_lb(common)) {
654 const char *common_filename;
656 common_filename = common->filename ? common->filename : util_uri_to_path(common->id);
658 (void)parse_desc(common, common_filename, 0);
661 * DESC parser will call the "text event callback".
662 * Don't need to call global event callback in this case.
665 } else if (lb_get_lb_fb(common)) {
668 * replace this with "flag" instead of "callback address"
670 if (conf_frame_drop_for_resizing() && common->request.size_changed) {
671 /* Just for skipping the update event callback call, After request to resize buffer, update event will be discarded */
672 DbgPrint("Discards obsoloted update event\n");
673 ret = LB_STATUS_ERROR_BUSY;
675 (void)lb_set_lb_fb(common, fbfile);
677 if (!conf_manual_sync()) {
678 ret = lb_sync_lb_fb(common);
679 if (ret != (int)LB_STATUS_SUCCESS) {
680 ErrPrint("Failed to do sync FB (%s - %s) (%d)\n", pkgname, util_basename(util_uri_to_path(id)), ret);
683 ret = LB_STATUS_SUCCESS;
687 ret = LB_STATUS_SUCCESS;
690 if (ret == (int)LB_STATUS_SUCCESS) {
694 dlist_foreach_safe(common->livebox_list, l, n, handler) {
695 lb_invoke_event_handler(handler, LB_EVENT_LB_UPDATED);
703 static struct packet *master_pd_created(pid_t pid, int handle, const struct packet *packet)
705 struct livebox *handler;
706 struct livebox_common *common;
717 ret = packet_get(packet, "sssiii", &pkgname, &id, &buf_id, &width, &height, &status);
719 ErrPrint("Invalid argument\n");
723 DbgPrint("[%s]\n", pkgname);
724 common = lb_find_common_handle(pkgname, id);
726 ErrPrint("Instance(%s) is not exists\n", id);
730 if (common->state != CREATE) {
731 ErrPrint("Instance(%s) is not created\n", id);
735 if (!common->request.pd_created) {
736 ErrPrint("PD create request is canceled\n");
740 common->is_pd_created = (status == (int)LB_STATUS_SUCCESS);
741 common->request.pd_created = 0;
743 if (common->is_pd_created) {
744 lb_set_pdsize(common, width, height);
745 if (lb_text_pd(common)) {
746 DbgPrint("Text TYPE does not need to handle this\n");
748 (void)lb_set_pd_fb(common, buf_id);
750 switch (common->pd.type) {
751 case _PD_TYPE_SCRIPT:
752 case _PD_TYPE_BUFFER:
753 switch (fb_type(lb_get_pd_fb(common))) {
754 case BUFFER_TYPE_FILE:
755 case BUFFER_TYPE_SHM:
756 lb_create_lock_file(common, 1);
758 case BUFFER_TYPE_PIXMAP:
759 case BUFFER_TYPE_ERROR:
769 ret = lb_sync_pd_fb(common);
771 ErrPrint("Failed to do sync FB (%s - %s)\n", pkgname, util_basename(util_uri_to_path(id)));
776 DbgPrint("PERF_DBOX\n");
777 dlist_foreach_safe(common->livebox_list, l, n, handler) {
778 if (handler->cbs.pd_created.cb) {
782 cb = handler->cbs.pd_created.cb;
783 cbdata = handler->cbs.pd_created.data;
785 handler->cbs.pd_created.cb = NULL;
786 handler->cbs.pd_created.data = NULL;
789 * Before call the Callback function,
790 * pd_create_cb must be reset.
791 * Because, in the create callback, user can call create_pd function again.
793 cb(handler, status, cbdata);
794 } else if (status == (int)LB_STATUS_SUCCESS) {
795 lb_invoke_event_handler(handler, LB_EVENT_PD_CREATED);
803 static struct packet *master_pd_destroyed(pid_t pid, int handle, const struct packet *packet)
805 struct livebox *handler;
807 struct livebox_common *common;
813 ret = packet_get(packet, "ssi", &pkgname, &id, &status);
815 ErrPrint("Invalid argument\n");
819 DbgPrint("[%s]\n", pkgname);
820 common = lb_find_common_handle(pkgname, id);
822 ErrPrint("Instance(%s) is not exists\n", id);
826 if (common->state != CREATE) {
827 ErrPrint("Instance(%s) is not created\n", id);
831 if (common->is_pd_created == 0) {
832 ErrPrint("PD is not created, event is ignored\n");
836 common->is_pd_created = 0;
837 common->request.pd_destroyed = 0;
839 dlist_foreach(common->livebox_list, l, handler) {
840 if (handler->cbs.pd_destroyed.cb) {
844 cb = handler->cbs.pd_destroyed.cb;
845 cbdata = handler->cbs.pd_destroyed.data;
847 handler->cbs.pd_destroyed.cb = NULL;
848 handler->cbs.pd_destroyed.data = NULL;
851 * Before call the Callback function,
852 * pd_destroyed_cb must be reset.
853 * Because, in the create callback, user can call destroy_pd function again.
855 cb(handler, status, cbdata);
856 } else if (status == (int)LB_STATUS_SUCCESS) {
857 lb_invoke_event_handler(handler, LB_EVENT_PD_DESTROYED);
863 * Lock file should be deleted after all callbacks are processed.
865 switch (common->pd.type) {
866 case _PD_TYPE_SCRIPT:
867 case _PD_TYPE_BUFFER:
868 switch (fb_type(lb_get_pd_fb(common))) {
869 case BUFFER_TYPE_FILE:
870 case BUFFER_TYPE_SHM:
871 lb_destroy_lock_file(common, 1);
873 case BUFFER_TYPE_PIXMAP:
874 case BUFFER_TYPE_ERROR:
888 static struct packet *master_pd_updated(pid_t pid, int handle, const struct packet *packet)
892 const char *descfile;
895 struct livebox *handler;
896 struct livebox_common *common;
901 ret = packet_get(packet, "ssssii",
906 ErrPrint("Invalid argument\n");
910 DbgPrint("[%s]\n", pkgname);
911 common = lb_find_common_handle(pkgname, id);
913 ErrPrint("Instance(%s) is not exists\n", id);
917 if (common->state != CREATE) {
920 * This handler is already deleted by the user.
921 * So don't try to notice anything about this anymore.
922 * Just ignore all events.
924 ErrPrint("Instance(%s) is not created\n", id);
928 lb_set_pdsize(common, pd_w, pd_h);
930 if (lb_text_pd(common)) {
931 (void)parse_desc(common, descfile, 1);
933 if (conf_frame_drop_for_resizing() && common->request.size_changed) {
934 /* Just for skipping the update event callback call, After request to resize buffer, update event will be discarded */
935 DbgPrint("Discards obsoloted update event\n");
937 (void)lb_set_pd_fb(common, fbfile);
939 if (!conf_manual_sync()) {
940 ret = lb_sync_pd_fb(common);
942 ErrPrint("Failed to do sync FB (%s - %s), %d\n", pkgname, util_basename(util_uri_to_path(id)), ret);
944 dlist_foreach(common->livebox_list, l, handler) {
945 lb_invoke_event_handler(handler, LB_EVENT_PD_UPDATED);
949 dlist_foreach(common->livebox_list, l, handler) {
950 lb_invoke_event_handler(handler, LB_EVENT_PD_UPDATED);
960 static struct packet *master_update_mode(pid_t pid, int handle, const struct packet *packet)
962 struct livebox *handler;
963 struct livebox_common *common;
973 ErrPrint("Invalid packet\n");
977 ret = packet_get(packet, "ssii", &pkgname, &id, &status, &active_mode);
979 ErrPrint("Invalid argument\n");
983 common = lb_find_common_handle(pkgname, id);
985 ErrPrint("Livebox(%s) is not found\n", id);
989 if (common->state != CREATE) {
990 ErrPrint("Livebox(%s) is not created yet\n", id);
994 if (status == (int)LB_STATUS_SUCCESS) {
995 lb_set_update_mode(common, active_mode);
998 common->request.update_mode = 0;
999 dlist_foreach_safe(common->livebox_list, l, n, handler) {
1000 if (handler->cbs.update_mode.cb) {
1004 cb = handler->cbs.update_mode.cb;
1005 cbdata = handler->cbs.update_mode.data;
1007 handler->cbs.update_mode.cb = NULL;
1008 handler->cbs.update_mode.data = NULL;
1010 cb(handler, status, cbdata);
1011 } else if (status == (int)LB_STATUS_SUCCESS) {
1012 lb_invoke_event_handler(handler, LB_EVENT_UPDATE_MODE_CHANGED);
1020 static struct packet *master_size_changed(pid_t pid, int handle, const struct packet *packet)
1022 struct livebox *handler;
1023 struct livebox_common *common;
1024 const char *pkgname;
1034 ErrPrint("Invalid packet\n");
1038 ret = packet_get(packet, "sssiiii", &pkgname, &id, &fbfile, &is_pd, &w, &h, &status);
1040 ErrPrint("Invalid argument\n");
1044 common = lb_find_common_handle(pkgname, id);
1046 ErrPrint("Livebox(%s) is not found\n", id);
1050 if (common->state != CREATE) {
1051 ErrPrint("Livebox(%s) is not created yet\n", id);
1055 common->request.size_changed = 0;
1059 * PD is not able to resized by the client.
1060 * PD is only can be managed by the provider.
1061 * So the PD has no private resized event handler.
1062 * Notify it via global event handler only.
1064 if (status == (int)LB_STATUS_SUCCESS) {
1067 lb_set_pdsize(common, w, h);
1068 dlist_foreach(common->livebox_list, l, handler) {
1069 lb_invoke_event_handler(handler, LB_EVENT_PD_SIZE_CHANGED);
1072 ErrPrint("This is not possible. PD Size is changed but the return value is not ZERO (%d)\n", status);
1078 if (status == (int)LB_STATUS_SUCCESS) {
1079 lb_set_size(common, w, h);
1083 * If there is a created LB FB,
1086 if (lb_get_lb_fb(common)) {
1087 (void)lb_set_lb_fb(common, fbfile);
1089 ret = lb_sync_lb_fb(common);
1091 ErrPrint("Failed to do sync FB (%s - %s)\n", pkgname, util_basename(util_uri_to_path(id)));
1094 /* Just update the size info only. */
1100 * I cannot believe client.
1101 * So I added some log before & after call the user callback.
1103 dlist_foreach_safe(common->livebox_list, l, n, handler) {
1104 if (handler->cbs.size_changed.cb) {
1108 cb = handler->cbs.size_changed.cb;
1109 cbdata = handler->cbs.size_changed.data;
1111 handler->cbs.size_changed.cb = NULL;
1112 handler->cbs.size_changed.data = NULL;
1114 cb(handler, status, cbdata);
1115 } else if (status == (int)LB_STATUS_SUCCESS) {
1116 lb_invoke_event_handler(handler, LB_EVENT_LB_SIZE_CHANGED);
1125 static struct packet *master_period_changed(pid_t pid, int handle, const struct packet *packet)
1127 struct livebox *handler;
1128 struct livebox_common *common;
1131 const char *pkgname;
1137 ret = packet_get(packet, "idss", &status, &period, &pkgname, &id);
1139 ErrPrint("Invalid argument\n");
1143 common = lb_find_common_handle(pkgname, id);
1145 ErrPrint("Livebox(%s) is not found\n", id);
1149 if (common->state != CREATE) {
1150 ErrPrint("Livebox(%s) is not created\n", id);
1154 if (status == (int)LB_STATUS_SUCCESS) {
1155 lb_set_period(common, period);
1158 common->request.period_changed = 0;
1160 dlist_foreach_safe(common->livebox_list, l, n, handler) {
1161 if (handler->cbs.period_changed.cb) {
1165 cb = handler->cbs.period_changed.cb;
1166 cbdata = handler->cbs.period_changed.data;
1168 handler->cbs.period_changed.cb = NULL;
1169 handler->cbs.period_changed.data = NULL;
1171 cb(handler, status, cbdata);
1172 } else if (status == (int)LB_STATUS_SUCCESS) {
1173 lb_invoke_event_handler(handler, LB_EVENT_PERIOD_CHANGED);
1181 static struct packet *master_group_changed(pid_t pid, int handle, const struct packet *packet)
1183 struct livebox *handler;
1184 struct livebox_common *common;
1187 const char *pkgname;
1190 const char *cluster;
1191 const char *category;
1194 ret = packet_get(packet, "ssiss", &pkgname, &id, &status, &cluster, &category);
1196 ErrPrint("Invalid argument\n");
1200 common = lb_find_common_handle(pkgname, id);
1202 ErrPrint("Livebox(%s) is not exists\n", id);
1206 if (common->state != CREATE) {
1209 * Do no access this handler,
1210 * You cannot believe this handler anymore.
1212 ErrPrint("Livebox(%s) is not created\n", id);
1216 if (status == (int)LB_STATUS_SUCCESS) {
1217 (void)lb_set_group(common, cluster, category);
1220 common->request.group_changed = 0;
1222 dlist_foreach_safe(common->livebox_list, l, n, handler) {
1223 if (handler->cbs.group_changed.cb) {
1227 cb = handler->cbs.group_changed.cb;
1228 cbdata = handler->cbs.group_changed.data;
1230 handler->cbs.group_changed.cb = NULL;
1231 handler->cbs.group_changed.data = NULL;
1233 cb(handler, status, cbdata);
1234 } else if (status == (int)LB_STATUS_SUCCESS) {
1235 lb_invoke_event_handler(handler, LB_EVENT_GROUP_CHANGED);
1243 static struct packet *master_created(pid_t pid, int handle, const struct packet *packet)
1245 struct livebox *handler;
1246 struct livebox_common *common;
1253 const char *pkgname;
1256 const char *content;
1257 const char *cluster;
1258 const char *category;
1259 const char *lb_fname;
1260 const char *pd_fname;
1264 const char *auto_launch;
1268 int pinup_supported;
1269 enum lb_type lb_type;
1270 enum pd_type pd_type;
1274 int old_state = DESTROYED;
1278 ret = packet_get(packet, "dsssiiiisssssdiiiiidsi",
1280 &pkgname, &id, &content,
1281 &lb_w, &lb_h, &pd_w, &pd_h,
1282 &cluster, &category, &lb_fname, &pd_fname,
1283 &auto_launch, &priority, &size_list, &user, &pinup_supported,
1284 &lb_type, &pd_type, &period, &title, &is_pinned_up);
1286 ErrPrint("Invalid argument\n");
1287 ret = LB_STATUS_ERROR_INVALID;
1291 ErrPrint("[%lf] pkgname: %s, id: %s, content: %s, "
1292 "pd_w: %d, pd_h: %d, lb_w: %d, lb_h: %d, "
1293 "cluster: %s, category: %s, lb_fname: \"%s\", pd_fname: \"%s\", "
1294 "auto_launch: %s, priority: %lf, size_list: %d, user: %d, pinup: %d, "
1295 "lb_type: %d, pd_type: %d, period: %lf, title: [%s], is_pinned_up: %d\n",
1296 timestamp, pkgname, id, content,
1297 pd_w, pd_h, lb_w, lb_h,
1298 cluster, category, lb_fname, pd_fname,
1299 auto_launch, priority, size_list, user, pinup_supported,
1300 lb_type, pd_type, period, title, is_pinned_up);
1302 common = lb_find_common_handle_by_timestamp(timestamp);
1304 handler = lb_new_livebox(pkgname, id, timestamp, cluster, category);
1306 ErrPrint("Failed to create a new livebox\n");
1307 ret = LB_STATUS_ERROR_FAULT;
1310 common = handler->common;
1311 old_state = common->state;
1313 if (common->state != CREATE) {
1314 if (common->state != DELETE) {
1317 * This is not possible!!!
1319 ErrPrint("Invalid handler\n");
1320 ret = LB_STATUS_ERROR_INVALID;
1326 * After get the delete states,
1327 * call the create callback with deleted result.
1331 old_state = common->state;
1334 ErrPrint("Already created: timestamp[%lf] "
1335 "pkgname[%s], id[%s] content[%s] "
1336 "cluster[%s] category[%s] lb_fname[%s] pd_fname[%s]\n",
1337 timestamp, pkgname, id,
1338 content, cluster, category,
1339 lb_fname, pd_fname);
1341 ret = LB_STATUS_ERROR_ALREADY;
1345 lb_set_id(common, id);
1348 common->request.created = 0;
1349 lb_set_size(common, lb_w, lb_h);
1350 common->lb.type = lb_type;
1351 common->is_pinned_up = is_pinned_up;
1356 case _LB_TYPE_SCRIPT:
1357 case _LB_TYPE_BUFFER:
1358 if (!strlen(lb_fname)) {
1361 (void)lb_set_lb_fb(common, lb_fname);
1365 * Livebox should create the lock file from here.
1366 * Even if the old_state == DELETE,
1367 * the lock file will be deleted from deleted event callback.
1369 switch (fb_type(lb_get_lb_fb(common))) {
1370 case BUFFER_TYPE_FILE:
1371 case BUFFER_TYPE_SHM:
1372 lb_create_lock_file(common, 0);
1374 case BUFFER_TYPE_PIXMAP:
1375 case BUFFER_TYPE_ERROR:
1380 ret = lb_sync_lb_fb(common);
1382 ErrPrint("Failed to do sync FB (%s - %s)\n", pkgname, util_basename(util_uri_to_path(id)));
1386 lb_set_text_lb(common);
1392 common->pd.type = pd_type;
1393 lb_set_pdsize(common, pd_w, pd_h);
1394 lb_set_default_pdsize(common, pd_w, pd_h);
1396 case _PD_TYPE_SCRIPT:
1397 case _PD_TYPE_BUFFER:
1398 if (!strlen(pd_fname)) {
1402 lb_set_pd_fb(common, pd_fname);
1404 ret = lb_sync_pd_fb(common);
1406 ErrPrint("Failed to do sync FB (%s - %s)\n", pkgname, util_basename(util_uri_to_path(id)));
1411 * PD doesn't need to create the lock file from here.
1412 * Just create it from PD_CREATED event.
1417 lb_set_text_pd(common);
1423 lb_set_priority(common, priority);
1425 lb_set_size_list(common, size_list);
1426 lb_set_group(common, cluster, category);
1428 lb_set_content(common, content);
1429 lb_set_title(common, title);
1431 lb_set_user(common, user);
1433 lb_set_auto_launch(common, auto_launch);
1434 lb_set_pinup(common, pinup_supported);
1436 lb_set_period(common, period);
1440 if (common->state == CREATE) {
1441 dlist_foreach(common->livebox_list, l, handler) {
1444 * These callback can change the handler->state.
1445 * So we have to use the "old_state" which stored state before call these callbacks
1448 if (handler->cbs.created.cb) {
1452 cb = handler->cbs.created.cb;
1453 cbdata = handler->cbs.created.data;
1455 handler->cbs.created.cb = NULL;
1456 handler->cbs.created.data = NULL;
1458 cb(handler, ret, cbdata);
1460 lb_invoke_event_handler(handler, LB_EVENT_CREATED);
1466 if (ret == 0 && old_state == DELETE) {
1469 DbgPrint("Take place an unexpected case [%d]\n", common->refcnt);
1470 dlist_foreach_safe(common->livebox_list, l, n, handler) {
1471 if (handler->cbs.created.cb) {
1472 if (!handler->common->request.deleted) {
1473 if (lb_send_delete(handler, common->delete_type, handler->cbs.created.cb, handler->cbs.created.data) < 0) {
1476 * Already sent or something else happens.
1477 * Callback will be called in any cases
1480 } else if (handler->state != DELETE) {
1481 handler->cbs.created.cb(handler, LB_STATUS_ERROR_CANCEL, handler->cbs.created.data);
1482 lb_unref(handler, 1);
1485 lb_invoke_event_handler(handler, LB_EVENT_DELETED);
1486 lb_unref(handler, 1);
1492 * handler->cbs.created.cb = NULL;
1493 * handler->cbs.created.data = NULL;
1495 * Do not clear this to use this from the deleted event callback.
1496 * if this value is not cleared when the deleted event callback check it,
1497 * it means that the created function is not called yet.
1498 * Then the call the deleted event callback with LB_STATUS_ERROR_CANCEL errno.
1505 static struct method s_table[] = {
1507 .cmd = "lb_updated", /* pkgname, id, lb_w, lb_h, priority, ret */
1508 .handler = master_lb_updated,
1511 .cmd = "pd_updated", /* pkgname, id, descfile, pd_w, pd_h, ret */
1512 .handler = master_pd_updated,
1515 .cmd = "pd_created",
1516 .handler = master_pd_created,
1519 .cmd = "pd_destroyed",
1520 .handler = master_pd_destroyed,
1523 .cmd = "fault_package", /* pkgname, id, function, ret */
1524 .handler = master_fault_package,
1527 .cmd = "deleted", /* pkgname, id, timestamp, ret */
1528 .handler = master_deleted,
1531 .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 */
1532 .handler = master_created,
1535 .cmd = "group_changed",
1536 .handler = master_group_changed,
1539 .cmd = "period_changed",
1540 .handler = master_period_changed,
1543 .cmd = "size_changed",
1544 .handler = master_size_changed,
1548 .handler = master_pinup,
1552 .handler = master_hold_scroll,
1556 .cmd = "update_mode",
1557 .handler = master_update_mode,
1561 .cmd = "lb_update_begin",
1562 .handler = master_lb_update_begin,
1565 .cmd = "lb_update_end",
1566 .handler = master_lb_update_end,
1570 .cmd = "pd_update_begin",
1571 .handler = master_pd_update_begin,
1574 .cmd = "pd_update_end",
1575 .handler = master_pd_update_end,
1579 .cmd = "access_status",
1580 .handler = master_access_status,
1583 .cmd = "key_status",
1584 .handler = master_key_status,
1588 .handler = master_request_close_pd,
1597 static void acquire_cb(struct livebox *handler, const struct packet *result, void *data)
1600 DbgPrint("Result packet is not valid\n");
1604 if (packet_get(result, "i", &ret) != 1) {
1605 ErrPrint("Invalid argument\n");
1607 DbgPrint("Acquire returns: %d\n", ret);
1614 static inline int make_connection(void)
1616 struct packet *packet;
1619 DbgPrint("Let's making connection!\n");
1621 s_info.fd = com_core_packet_client_init(client_addr(), 0, s_table);
1622 if (s_info.fd < 0) {
1623 ErrPrint("Try this again later\n");
1624 return LB_STATUS_ERROR_IO;
1627 packet = packet_create("acquire", "d", util_timestamp());
1629 com_core_packet_client_fini(s_info.fd);
1631 return LB_STATUS_ERROR_FAULT;
1634 ret = master_rpc_async_request(NULL, packet, 1, acquire_cb, NULL);
1636 ErrPrint("Master RPC returns %d\n", ret);
1637 com_core_packet_client_fini(s_info.fd);
1639 return LB_STATUS_ERROR_IO;
1642 return LB_STATUS_SUCCESS;
1645 static int connected_cb(int handle, void *data)
1647 master_rpc_check_and_fire_consumer();
1651 static void master_started_cb(keynode_t *node, void *data)
1655 if (vconf_get_bool(VCONFKEY_MASTER_STARTED, &state) < 0) {
1656 ErrPrint("Unable to get [%s]\n", VCONFKEY_MASTER_STARTED);
1659 DbgPrint("Master state: %d\n", state);
1660 if (state == 1 && make_connection() == (int)LB_STATUS_SUCCESS) {
1662 ret = vconf_ignore_key_changed(VCONFKEY_MASTER_STARTED, master_started_cb);
1664 DbgPrint("master_started vconf key de-registered [%d]\n", ret);
1669 static gboolean timeout_cb(gpointer data)
1671 if (vconf_notify_key_changed(VCONFKEY_MASTER_STARTED, master_started_cb, NULL) < 0) {
1672 ErrPrint("Failed to add vconf for monitoring service state\n");
1674 DbgPrint("vconf event callback is registered\n");
1677 master_started_cb(NULL, NULL);
1679 s_info.timer_id = 0;
1683 static int disconnected_cb(int handle, void *data)
1685 if (s_info.fd != handle) {
1686 /*!< This handle is not my favor */
1690 s_info.fd = -1; /*!< Disconnected */
1692 master_rpc_clear_all_request();
1693 lb_invoke_fault_handler(LB_FAULT_PROVIDER_DISCONNECTED, MASTER_PKGNAME, "default", "disconnected");
1697 /* Try to reconnect after 1 sec later */
1698 if (!s_info.timer_id) {
1699 DbgPrint("Reconnecting timer is added\n");
1700 s_info.timer_id = g_timeout_add(1000, timeout_cb, NULL);
1701 if (s_info.timer_id == 0) {
1702 ErrPrint("Unable to add reconnecting timer\n");
1706 ErrPrint("Reconnecting timer is already exists\n");
1712 int client_init(int use_thread)
1714 com_core_packet_use_thread(use_thread);
1716 s_info.client_addr = vconf_get_str(VCONFKEY_MASTER_CLIENT_ADDR);
1717 if (!s_info.client_addr) {
1718 s_info.client_addr = strdup(CLIENT_SOCKET);
1719 if (!s_info.client_addr) {
1720 ErrPrint("Heap: %s\n", strerror(errno));
1725 (void)file_service_init();
1727 DbgPrint("Server Address: %s\n", s_info.client_addr);
1729 com_core_add_event_callback(CONNECTOR_DISCONNECTED, disconnected_cb, NULL);
1730 com_core_add_event_callback(CONNECTOR_CONNECTED, connected_cb, NULL);
1731 if (vconf_notify_key_changed(VCONFKEY_MASTER_STARTED, master_started_cb, NULL) < 0) {
1732 ErrPrint("Failed to add vconf for service state\n");
1734 DbgPrint("vconf event callback is registered\n");
1737 master_started_cb(NULL, NULL);
1746 const char *client_addr(void)
1748 return s_info.client_addr;
1751 int client_fini(void)
1755 (void)file_service_fini();
1757 ret = vconf_ignore_key_changed(VCONFKEY_MASTER_STARTED, master_started_cb);
1759 DbgPrint("Ignore vconf key: %d\n", ret);
1762 com_core_del_event_callback(CONNECTOR_DISCONNECTED, disconnected_cb, NULL);
1763 com_core_del_event_callback(CONNECTOR_CONNECTED, connected_cb, NULL);
1764 com_core_packet_client_fini(s_info.fd);
1766 free(s_info.client_addr);
1767 s_info.client_addr = NULL;
1768 return LB_STATUS_SUCCESS;