4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Seungtaek Chung <seungtaek.chung@samsung.com>, Mi-Ju Lee <miju52.lee@samsung.com>, Xi Zhichan <zhichan.xi@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
31 #include <com-core_packet.h>
33 #include <notification_ipc.h>
34 #include <notification_db.h>
35 #include <notification_type.h>
36 #include <notification_private.h>
37 #include <notification_debug.h>
39 #define NOTIFICATION_IPC_TIMEOUT 0.0
41 #if !defined(VCONFKEY_MASTER_STARTED)
42 #define VCONFKEY_MASTER_STARTED "memory/data-provider-master/started"
48 int server_cl_fd_ref_cnt;
50 const char *socket_file;
52 int (*request_cb)(const char *appid, const char *name, int type, const char *content, const char *icon, pid_t pid, double period, int allow_duplicate, void *data);
56 int is_started_cb_set_svc;
57 int is_started_cb_set_task;
61 .server_cl_fd_ref_cnt = 0,
63 .socket_file = NOTIFICATION_ADDR,
65 .is_started_cb_set_svc = 0,
66 .is_started_cb_set_task = 0,
69 typedef struct _task_list task_list;
74 void (*task_cb) (void *data);
78 typedef struct _result_cb_item {
79 void (*result_cb)(int priv_id, int result, void *data);
83 static task_list *g_task_list;
85 static int notification_ipc_monitor_register(void);
86 static int notification_ipc_monitor_deregister(void);
87 static void _do_deffered_task(void);
88 static void _master_started_cb_task(keynode_t *node, void *data);
90 static inline char *_string_get(char *string)
95 if (string[0] == '\0') {
103 * functions to check state of master
105 static inline void _set_master_started_cb(vconf_callback_fn cb) {
108 ret = vconf_notify_key_changed(VCONFKEY_MASTER_STARTED,
111 NOTIFICATION_ERR("failed to notify key(%s) : %d",
112 VCONFKEY_MASTER_STARTED, ret);
116 static inline void _unset_master_started_cb(vconf_callback_fn cb) {
119 ret = vconf_ignore_key_changed(VCONFKEY_MASTER_STARTED,
122 NOTIFICATION_ERR("failed to notify key(%s) : %d",
123 VCONFKEY_MASTER_STARTED, ret);
127 int notification_ipc_is_master_ready(void)
129 int ret = -1, is_master_started = 0;
131 ret = vconf_get_bool(VCONFKEY_MASTER_STARTED, &is_master_started);
132 if (ret == 0 && is_master_started == 1) {
133 NOTIFICATION_ERR("the master has been started");
135 is_master_started = 0;
136 NOTIFICATION_ERR("the master has been stopped");
139 return is_master_started;
143 notification_ipc_add_deffered_task(
144 void (*deferred_task_cb)(void *data),
147 task_list *list = NULL;
148 task_list *list_new = NULL;
151 (task_list *) malloc(sizeof(task_list));
153 if (list_new == NULL) {
154 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
157 if (s_info.is_started_cb_set_task == 0) {
158 _set_master_started_cb(_master_started_cb_task);
159 s_info.is_started_cb_set_task = 1;
162 list_new->next = NULL;
163 list_new->prev = NULL;
165 list_new->task_cb = deferred_task_cb;
166 list_new->data = user_data;
168 if (g_task_list == NULL) {
169 g_task_list = list_new;
173 while (list->next != NULL) {
177 list->next = list_new;
178 list_new->prev = list;
180 return NOTIFICATION_ERROR_NONE;
184 notification_ipc_del_deffered_task(
185 void (*deferred_task_cb)(void *data))
187 task_list *list_del = NULL;
188 task_list *list_prev = NULL;
189 task_list *list_next = NULL;
191 list_del = g_task_list;
193 if (list_del == NULL) {
194 return NOTIFICATION_ERROR_INVALID_PARAMETER;
197 while (list_del->prev != NULL) {
198 list_del = list_del->prev;
202 if (list_del->task_cb == deferred_task_cb) {
203 list_prev = list_del->prev;
204 list_next = list_del->next;
206 if (list_prev == NULL) {
207 g_task_list = list_next;
209 list_prev->next = list_next;
212 if (list_next == NULL) {
213 if (list_prev != NULL) {
214 list_prev->next = NULL;
217 list_next->prev = list_prev;
222 if (g_task_list == NULL) {
223 if (s_info.is_started_cb_set_task == 1) {
224 _unset_master_started_cb(_master_started_cb_task);
225 s_info.is_started_cb_set_task = 0;
229 return NOTIFICATION_ERROR_NONE;
231 list_del = list_del->next;
232 } while (list_del != NULL);
234 return NOTIFICATION_ERROR_INVALID_PARAMETER;
237 static void _do_deffered_task(void) {
238 task_list *list_do = NULL;
239 task_list *list_temp = NULL;
241 if (g_task_list == NULL) {
245 list_do = g_task_list;
247 if (s_info.is_started_cb_set_task == 1) {
248 _unset_master_started_cb(_master_started_cb_task);
249 s_info.is_started_cb_set_task = 0;
252 while (list_do->prev != NULL) {
253 list_do = list_do->prev;
256 while (list_do != NULL) {
257 if (list_do->task_cb != NULL) {
258 list_do->task_cb(list_do->data);
259 NOTIFICATION_DBG("called:%p", list_do->task_cb);
261 list_temp = list_do->next;
267 static void _master_started_cb_service(keynode_t *node,
269 int ret = NOTIFICATION_ERROR_NONE;
271 if (notification_ipc_is_master_ready()) {
272 NOTIFICATION_ERR("try to register a notification service");
273 ret = notification_ipc_monitor_deregister();
274 if (ret != NOTIFICATION_ERROR_NONE) {
275 NOTIFICATION_ERR("failed to unregister a monitor");
277 ret = notification_ipc_monitor_register();
278 if (ret != NOTIFICATION_ERROR_NONE) {
279 NOTIFICATION_ERR("failed to register a monitor");
282 NOTIFICATION_ERR("try to unregister a notification service");
283 ret = notification_ipc_monitor_deregister();
284 if (ret != NOTIFICATION_ERROR_NONE) {
285 NOTIFICATION_ERR("failed to deregister a monitor");
290 static void _master_started_cb_task(keynode_t *node,
293 if (notification_ipc_is_master_ready()) {
299 * functions to create operation list
301 notification_op *notification_ipc_create_op(notification_op_type_e type, int num_op, int *list_priv_id, int num_priv_id, notification_h *noti_list)
304 notification_op *op_list = NULL;
310 op_list = (notification_op *)malloc(sizeof(notification_op) * num_op);
312 if (op_list == NULL) {
316 memset(op_list, 0x0, sizeof(notification_op) * num_op);
318 for (i = 0; i < num_op; i++) {
319 (op_list + i)->type = type;
320 if (list_priv_id != NULL) {
321 (op_list + i)->priv_id = *(list_priv_id + i);
323 if (noti_list != NULL) {
324 (op_list + i)->noti = *(noti_list + i);
332 * utility functions creating notification packet
334 static inline char *_dup_string(const char *string)
338 if (string == NULL) {
341 if (string[0] == '\0') {
345 ret = strdup(string);
347 NOTIFICATION_ERR("Error: %d\n", errno);
352 static inline bundle *_create_bundle_from_string(unsigned char *string)
354 if (string == NULL) {
357 if (string[0] == '\0') {
361 return bundle_decode(string, strlen((char *)string));
365 * functions creating notification packet
367 EXPORT_API int notification_ipc_make_noti_from_packet(notification_h noti, const struct packet *packet)
373 int internal_group_id;
375 char *caller_pkgname = NULL;
376 char *launch_pkgname = NULL;
377 unsigned char *args = NULL;
378 unsigned char *group_args = NULL;
379 unsigned char *b_execute_option = NULL;
380 unsigned char *b_service_responding = NULL;
381 unsigned char *b_service_single_launch = NULL;
382 unsigned char *b_service_multi_launch = NULL;
385 unsigned char *b_text = NULL;
386 unsigned char *b_key = NULL;
387 unsigned char *b_format_args = NULL;
389 unsigned char *b_image_path = NULL;
391 char *sound_path = NULL;
393 char *vibration_path = NULL;
400 int flags_for_property;
402 double progress_size;
403 double progress_percentage;
404 char *app_icon_path = NULL;
405 char *app_name = NULL;
406 char *temp_title = NULL;
407 char *temp_content = NULL;
411 NOTIFICATION_ERR("invalid data");
412 return NOTIFICATION_ERROR_INVALID_PARAMETER;
415 ret = packet_get(packet,
416 "iiiiisssssssssssssisisisiiiiiiiiddsssss",
427 &b_service_responding,
428 &b_service_single_launch,
429 &b_service_multi_launch,
450 &progress_percentage,
458 NOTIFICATION_ERR("failed to create a noti from packet");
459 return NOTIFICATION_ERROR_INVALID_PARAMETER;
463 * This is already allocated from the notification_create function.
464 * Before reallocate string to here.
465 * We have to release old one first.
467 free(noti->caller_pkgname);
468 noti->caller_pkgname = _dup_string(caller_pkgname);
469 noti->launch_pkgname = _dup_string(launch_pkgname);
470 noti->args = _create_bundle_from_string(args);
471 noti->group_args = _create_bundle_from_string(group_args);
472 noti->b_execute_option = _create_bundle_from_string(b_execute_option);
473 noti->b_service_responding = _create_bundle_from_string(b_service_responding);
474 noti->b_service_single_launch = _create_bundle_from_string(b_service_single_launch);
475 noti->b_service_multi_launch = _create_bundle_from_string(b_service_multi_launch);
476 noti->domain = _dup_string(domain);
477 noti->dir = _dup_string(dir);
478 noti->b_text = _create_bundle_from_string(b_text);
479 noti->b_key = _create_bundle_from_string(b_key);
480 noti->b_format_args = _create_bundle_from_string(b_format_args);
481 noti->b_image_path = _create_bundle_from_string(b_image_path);
482 noti->sound_path = _dup_string(sound_path);
483 noti->vibration_path = _dup_string(vibration_path);
484 noti->app_icon_path = _dup_string(app_icon_path);
485 noti->app_name = _dup_string(app_name);
486 noti->temp_title = _dup_string(temp_title);
487 noti->temp_content = _dup_string(temp_content);
490 noti->layout = layout;
491 noti->group_id = group_id;
492 noti->internal_group_id = internal_group_id;
493 noti->priv_id = priv_id;
494 noti->num_format_args = num_format_args;
495 noti->sound_type = sound_type;
496 noti->vibration_type = vibration_type;
497 noti->led_operation = led_operation;
498 noti->led_argb = led_argb;
499 noti->led_on_ms = led_on_ms;
500 noti->led_off_ms = led_off_ms;
502 noti->insert_time = insert_time;
503 noti->flags_for_property = flags_for_property;
504 noti->display_applist = display_applist;
505 noti->progress_size = progress_size;
506 noti->progress_percentage = progress_percentage;
507 noti->tag = _dup_string(tag);
509 return NOTIFICATION_ERROR_NONE;
512 EXPORT_API struct packet *notification_ipc_make_packet_from_noti(notification_h noti, const char *command, int packet_type)
514 int b_encode_len = 0;
515 struct packet *result = NULL;
517 char *group_args = NULL;
518 char *b_image_path = NULL;
519 char *b_execute_option = NULL;
520 char *b_service_responding = NULL;
521 char *b_service_single_launch = NULL;
522 char *b_service_multi_launch = NULL;
525 char *b_format_args = NULL;
526 struct packet *(*func_to_create_packet)(const char *command, const char *fmt, ...);
527 const char *title_key = NULL;
528 char buf_key[32] = { 0, };
530 /* Decode bundle to insert DB */
532 bundle_encode(noti->args, (bundle_raw **) & args, NULL);
534 if (noti->group_args) {
535 bundle_encode(noti->group_args, (bundle_raw **) & group_args,
539 if (noti->b_execute_option) {
540 bundle_encode(noti->b_execute_option,
541 (bundle_raw **) & b_execute_option, &b_encode_len);
543 if (noti->b_service_responding) {
544 bundle_encode(noti->b_service_responding,
545 (bundle_raw **) & b_service_responding, &b_encode_len);
547 if (noti->b_service_single_launch) {
548 bundle_encode(noti->b_service_single_launch,
549 (bundle_raw **) & b_service_single_launch, &b_encode_len);
551 if (noti->b_service_multi_launch) {
552 bundle_encode(noti->b_service_multi_launch,
553 (bundle_raw **) & b_service_multi_launch, &b_encode_len);
557 bundle_encode(noti->b_text, (bundle_raw **) & b_text, &b_encode_len);
560 bundle_encode(noti->b_key, (bundle_raw **) & b_key, &b_encode_len);
562 if (noti->b_format_args) {
563 bundle_encode(noti->b_format_args,
564 (bundle_raw **) & b_format_args, &b_encode_len);
567 if (noti->b_image_path) {
568 bundle_encode(noti->b_image_path,
569 (bundle_raw **) & b_image_path, &b_encode_len);
572 if (noti->b_key != NULL) {
573 snprintf(buf_key, sizeof(buf_key), "%d",
574 NOTIFICATION_TEXT_TYPE_TITLE);
576 title_key = bundle_get_val(noti->b_key, buf_key);
579 if (title_key == NULL && noti->b_text != NULL) {
580 snprintf(buf_key, sizeof(buf_key), "%d",
581 NOTIFICATION_TEXT_TYPE_TITLE);
583 title_key = bundle_get_val(noti->b_text, buf_key);
586 if (title_key == NULL) {
587 title_key = noti->caller_pkgname;
590 if (packet_type == 1)
591 func_to_create_packet = packet_create;
592 else if (packet_type == 2)
593 func_to_create_packet = packet_create_noack;
598 result = func_to_create_packet(command,
599 "iiiiisssssssssssssisisisiiiiiiiiddsssss",
603 noti->internal_group_id,
605 NOTIFICATION_CHECK_STR(noti->caller_pkgname),
606 NOTIFICATION_CHECK_STR(noti->launch_pkgname),
607 NOTIFICATION_CHECK_STR(args),
608 NOTIFICATION_CHECK_STR(group_args),
609 NOTIFICATION_CHECK_STR(b_execute_option),
610 NOTIFICATION_CHECK_STR(b_service_responding),
611 NOTIFICATION_CHECK_STR(b_service_single_launch),
612 NOTIFICATION_CHECK_STR(b_service_multi_launch),
613 NOTIFICATION_CHECK_STR(noti->domain),
614 NOTIFICATION_CHECK_STR(noti->dir),
615 NOTIFICATION_CHECK_STR(b_text),
616 NOTIFICATION_CHECK_STR(b_key),
617 NOTIFICATION_CHECK_STR(b_format_args),
618 noti->num_format_args,
619 NOTIFICATION_CHECK_STR(b_image_path),
621 NOTIFICATION_CHECK_STR(noti->sound_path),
622 noti->vibration_type,
623 NOTIFICATION_CHECK_STR(noti->vibration_path),
630 noti->flags_for_property,
631 noti->display_applist,
633 noti->progress_percentage,
634 NOTIFICATION_CHECK_STR(noti->app_icon_path),
635 NOTIFICATION_CHECK_STR(noti->app_name),
636 NOTIFICATION_CHECK_STR(noti->temp_title),
637 NOTIFICATION_CHECK_STR(noti->temp_content),
638 NOTIFICATION_CHECK_STR(noti->tag));
641 /* Free decoded data */
649 if (b_execute_option) {
650 free(b_execute_option);
652 if (b_service_responding) {
653 free(b_service_responding);
655 if (b_service_single_launch) {
656 free(b_service_single_launch);
658 if (b_service_multi_launch) {
659 free(b_service_multi_launch);
679 EXPORT_API struct packet *notification_ipc_make_reply_packet_from_noti(notification_h noti, struct packet *packet)
681 int b_encode_len = 0;
682 struct packet *result = NULL;
684 char *group_args = NULL;
685 char *b_image_path = NULL;
686 char *b_execute_option = NULL;
687 char *b_service_responding = NULL;
688 char *b_service_single_launch = NULL;
689 char *b_service_multi_launch = NULL;
692 char *b_format_args = NULL;
693 const char *title_key = NULL;
694 char buf_key[32] = { 0, };
696 /* Decode bundle to insert DB */
698 bundle_encode(noti->args, (bundle_raw **) & args, &b_encode_len);
700 if (noti->group_args) {
701 bundle_encode(noti->group_args, (bundle_raw **) & group_args,
705 if (noti->b_execute_option) {
706 bundle_encode(noti->b_execute_option,
707 (bundle_raw **) & b_execute_option, &b_encode_len);
709 if (noti->b_service_responding) {
710 bundle_encode(noti->b_service_responding,
711 (bundle_raw **) & b_service_responding, &b_encode_len);
713 if (noti->b_service_single_launch) {
714 bundle_encode(noti->b_service_single_launch,
715 (bundle_raw **) & b_service_single_launch, &b_encode_len);
717 if (noti->b_service_multi_launch) {
718 bundle_encode(noti->b_service_multi_launch,
719 (bundle_raw **) & b_service_multi_launch, &b_encode_len);
723 bundle_encode(noti->b_text, (bundle_raw **) & b_text, &b_encode_len);
726 bundle_encode(noti->b_key, (bundle_raw **) & b_key, &b_encode_len);
728 if (noti->b_format_args) {
729 bundle_encode(noti->b_format_args,
730 (bundle_raw **) & b_format_args, &b_encode_len);
733 if (noti->b_image_path) {
734 bundle_encode(noti->b_image_path,
735 (bundle_raw **) & b_image_path, &b_encode_len);
738 if (noti->b_key != NULL) {
739 snprintf(buf_key, sizeof(buf_key), "%d",
740 NOTIFICATION_TEXT_TYPE_TITLE);
742 title_key = bundle_get_val(noti->b_key, buf_key);
745 if (title_key == NULL && noti->b_text != NULL) {
746 snprintf(buf_key, sizeof(buf_key), "%d",
747 NOTIFICATION_TEXT_TYPE_TITLE);
749 title_key = bundle_get_val(noti->b_text, buf_key);
752 if (title_key == NULL) {
753 title_key = noti->caller_pkgname;
756 result = packet_create_reply(packet,
757 "iiiiisssssssssssssisisisiiiiiiiiddsssss",
761 noti->internal_group_id,
763 NOTIFICATION_CHECK_STR(noti->caller_pkgname),
764 NOTIFICATION_CHECK_STR(noti->launch_pkgname),
765 NOTIFICATION_CHECK_STR(args),
766 NOTIFICATION_CHECK_STR(group_args),
767 NOTIFICATION_CHECK_STR(b_execute_option),
768 NOTIFICATION_CHECK_STR(b_service_responding),
769 NOTIFICATION_CHECK_STR(b_service_single_launch),
770 NOTIFICATION_CHECK_STR(b_service_multi_launch),
771 NOTIFICATION_CHECK_STR(noti->domain),
772 NOTIFICATION_CHECK_STR(noti->dir),
773 NOTIFICATION_CHECK_STR(b_text),
774 NOTIFICATION_CHECK_STR(b_key),
775 NOTIFICATION_CHECK_STR(b_format_args),
776 noti->num_format_args,
777 NOTIFICATION_CHECK_STR(b_image_path),
779 NOTIFICATION_CHECK_STR(noti->sound_path),
780 noti->vibration_type,
781 NOTIFICATION_CHECK_STR(noti->vibration_path),
788 noti->flags_for_property,
789 noti->display_applist,
791 noti->progress_percentage,
792 NOTIFICATION_CHECK_STR(noti->app_icon_path),
793 NOTIFICATION_CHECK_STR(noti->app_name),
794 NOTIFICATION_CHECK_STR(noti->temp_title),
795 NOTIFICATION_CHECK_STR(noti->temp_content),
796 NOTIFICATION_CHECK_STR(noti->tag));
798 /* Free decoded data */
806 if (b_execute_option) {
807 free(b_execute_option);
809 if (b_service_responding) {
810 free(b_service_responding);
812 if (b_service_single_launch) {
813 free(b_service_single_launch);
815 if (b_service_multi_launch) {
816 free(b_service_multi_launch);
837 * functions to handler services
839 static struct packet *_handler_insert(pid_t pid, int handle, const struct packet *packet)
841 notification_h noti = NULL;
844 NOTIFICATION_ERR("a packet is null");
847 noti = notification_create(NOTIFICATION_TYPE_NOTI);
849 NOTIFICATION_ERR("failed to create a notification");
852 notification_ipc_make_noti_from_packet(noti, packet);
854 if (noti->flags_for_property
855 & NOTIFICATION_PROP_DISABLE_UPDATE_ON_INSERT) {
856 /* Disable changed cb */
858 /* Enable changed cb */
859 notification_op *noti_op = notification_ipc_create_op(NOTIFICATION_OP_INSERT, 1, &(noti->priv_id), 1, ¬i);
860 if (noti_op != NULL) {
861 notification_call_changed_cb(noti_op, 1);
865 notification_free(noti);
870 static struct packet *_handler_update(pid_t pid, int handle, const struct packet *packet)
872 notification_h noti = NULL;
875 NOTIFICATION_ERR("a packet is null");
879 noti = notification_create(NOTIFICATION_TYPE_NOTI);
881 NOTIFICATION_ERR("failed to create a notification");
885 notification_ipc_make_noti_from_packet(noti, packet);
887 notification_op *noti_op = notification_ipc_create_op(NOTIFICATION_OP_UPDATE, 1, &(noti->priv_id), 1, ¬i);
888 if (noti_op != NULL) {
889 notification_call_changed_cb(noti_op, 1);
893 notification_free(noti);
898 static struct packet *_handler_refresh(pid_t pid, int handle, const struct packet *packet)
901 NOTIFICATION_ERR("a packet is null");
904 notification_op *noti_op = notification_ipc_create_op(NOTIFICATION_OP_REFRESH, 1, NULL, 0, NULL);
905 if (noti_op != NULL) {
906 notification_call_changed_cb(noti_op, 1);
913 static struct packet *_handler_delete_single(pid_t pid, int handle, const struct packet *packet)
916 int priv_id = NOTIFICATION_PRIV_ID_NONE;
919 NOTIFICATION_ERR("a packet is null");
922 if (packet_get(packet, "ii", &num_deleted, &priv_id) == 2) {
923 notification_op *noti_op = notification_ipc_create_op(NOTIFICATION_OP_DELETE, 1, &priv_id, 1, NULL);
924 if (noti_op != NULL) {
925 notification_call_changed_cb(noti_op, 1);
933 static struct packet *_handler_delete_multiple(pid_t pid, int handle, const struct packet *packet)
939 NOTIFICATION_ERR("delete_noti_multiple");
942 NOTIFICATION_ERR("a packet is null");
945 ret = packet_get(packet, "iiiiiiiiiii", &num_deleted,
957 NOTIFICATION_ERR("packet data count:%d", ret);
958 NOTIFICATION_ERR("packet data num deleted:%d", num_deleted);
961 for (i = 0 ; i < 10 ; i++) {
962 NOTIFICATION_ERR("packet data[%d]:%d",i, buf[i]);
966 notification_op *noti_op = notification_ipc_create_op(
967 NOTIFICATION_OP_DELETE, num_deleted, buf, num_deleted, NULL);
968 if (noti_op != NULL) {
969 notification_call_changed_cb(noti_op, num_deleted);
977 static int _handler_service_register(pid_t pid, int handle, const struct packet *packet, void *data)
982 NOTIFICATION_ERR("Packet is not valid\n");
983 ret = NOTIFICATION_ERROR_INVALID_PARAMETER;
984 } else if (packet_get(packet, "i", &ret) != 1) {
985 NOTIFICATION_ERR("Packet is not valid\n");
986 ret = NOTIFICATION_ERROR_INVALID_PARAMETER;
989 notification_op *noti_op = notification_ipc_create_op(NOTIFICATION_OP_SERVICE_READY, 1, NULL, 1, NULL);
990 if (noti_op != NULL) {
991 notification_call_changed_cb(noti_op, 1);
1000 * functions to initialize and register a monitor
1002 static int notification_ipc_monitor_register(void)
1005 struct packet *packet;
1006 static struct method service_table[] = {
1009 .handler = _handler_insert,
1012 .cmd = "update_noti",
1013 .handler = _handler_update,
1016 .cmd = "refresh_noti",
1017 .handler = _handler_refresh,
1020 .cmd = "del_noti_single",
1021 .handler = _handler_delete_single,
1024 .cmd = "del_noti_multiple",
1025 .handler = _handler_delete_multiple,
1033 if (s_info.initialized == 1) {
1034 return NOTIFICATION_ERROR_NONE;
1036 s_info.initialized = 1;
1039 NOTIFICATION_ERR("register a service\n");
1041 com_core_packet_use_thread(1);
1042 s_info.server_fd = com_core_packet_client_init(s_info.socket_file, 0, service_table);
1043 if (s_info.server_fd < 0) {
1044 NOTIFICATION_ERR("Failed to make a connection to the master\n");
1045 return NOTIFICATION_ERROR_IO_ERROR;
1048 packet = packet_create("service_register", "");
1050 NOTIFICATION_ERR("Failed to build a packet\n");
1051 com_core_packet_client_fini(s_info.server_fd);
1052 return NOTIFICATION_ERROR_IO_ERROR;
1055 ret = com_core_packet_async_send(s_info.server_fd, packet, 1.0, _handler_service_register, NULL);
1056 NOTIFICATION_DBG("Service register sent: %d\n", ret);
1057 packet_destroy(packet);
1059 com_core_packet_client_fini(s_info.server_fd);
1060 s_info.server_fd = NOTIFICATION_ERROR_INVALID_PARAMETER;
1061 ret = NOTIFICATION_ERROR_IO_ERROR;
1063 ret = NOTIFICATION_ERROR_NONE;
1066 NOTIFICATION_DBG("Server FD: %d\n", s_info.server_fd);
1070 int notification_ipc_monitor_deregister(void)
1072 if (s_info.initialized == 0) {
1073 return NOTIFICATION_ERROR_NONE;
1076 com_core_packet_client_fini(s_info.server_fd);
1077 s_info.server_fd = NOTIFICATION_ERROR_INVALID_PARAMETER;
1079 s_info.initialized = 0;
1081 return NOTIFICATION_ERROR_NONE;
1084 int notification_ipc_monitor_init(void)
1086 int ret = NOTIFICATION_ERROR_NONE;
1088 if (notification_ipc_is_master_ready()) {
1089 ret = notification_ipc_monitor_register();
1092 if (s_info.is_started_cb_set_svc == 0) {
1093 _set_master_started_cb(_master_started_cb_service);
1094 s_info.is_started_cb_set_svc = 1;
1100 int notification_ipc_monitor_fini(void)
1102 int ret = NOTIFICATION_ERROR_NONE;
1104 if (s_info.is_started_cb_set_svc == 1) {
1105 _unset_master_started_cb(_master_started_cb_service);
1106 s_info.is_started_cb_set_svc = 0;
1109 ret = notification_ipc_monitor_deregister();
1115 * functions to request the service
1117 int notification_ipc_request_insert(notification_h noti, int *priv_id)
1120 int id = NOTIFICATION_PRIV_ID_NONE;
1121 struct packet *packet;
1122 struct packet *result;
1124 /* Initialize private ID */
1125 noti->priv_id = NOTIFICATION_PRIV_ID_NONE;
1126 noti->group_id = NOTIFICATION_GROUP_ID_NONE;
1127 noti->internal_group_id = NOTIFICATION_GROUP_ID_NONE;
1129 packet = notification_ipc_make_packet_from_noti(noti, "add_noti", 1);
1130 result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1132 NOTIFICATION_IPC_TIMEOUT);
1133 packet_destroy(packet);
1135 if (result != NULL) {
1136 if (packet_get(result, "ii", &status, &id) != 2) {
1137 NOTIFICATION_ERR("Failed to get a result packet");
1138 packet_unref(result);
1139 return NOTIFICATION_ERROR_IO_ERROR;
1142 if (status != NOTIFICATION_ERROR_NONE) {
1143 packet_unref(result);
1146 packet_unref(result);
1148 NOTIFICATION_ERR("failed to receive answer(insert)");
1149 if (notification_ipc_is_master_ready() == 1) {
1150 return NOTIFICATION_ERROR_PERMISSION_DENIED;
1153 return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1157 if (priv_id != NULL) {
1161 return NOTIFICATION_ERROR_NONE;
1164 int notification_ipc_request_delete_single(notification_type_e type, char *pkgname, int priv_id)
1167 int id = NOTIFICATION_PRIV_ID_NONE;
1168 struct packet *packet;
1169 struct packet *result;
1171 packet = packet_create("del_noti_single", "si", pkgname, priv_id);
1172 result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1174 NOTIFICATION_IPC_TIMEOUT);
1175 packet_destroy(packet);
1177 if (result != NULL) {
1178 if (packet_get(result, "ii", &status, &id) != 2) {
1179 NOTIFICATION_ERR("Failed to get a result packet");
1180 packet_unref(result);
1181 return NOTIFICATION_ERROR_IO_ERROR;
1183 packet_unref(result);
1185 NOTIFICATION_ERR("failed to receive answer(delete)");
1186 if (notification_ipc_is_master_ready() == 1) {
1187 return NOTIFICATION_ERROR_PERMISSION_DENIED;
1190 return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1197 int notification_ipc_request_delete_multiple(notification_type_e type, char *pkgname)
1200 int num_deleted = 0;
1201 struct packet *packet;
1202 struct packet *result;
1204 packet = packet_create("del_noti_multiple", "si", pkgname, type);
1205 result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1207 NOTIFICATION_IPC_TIMEOUT);
1208 packet_destroy(packet);
1210 if (result != NULL) {
1211 if (packet_get(result, "ii", &status, &num_deleted) != 2) {
1212 NOTIFICATION_ERR("Failed to get a result packet");
1213 packet_unref(result);
1214 return NOTIFICATION_ERROR_IO_ERROR;
1216 NOTIFICATION_ERR("num deleted:%d", num_deleted);
1217 packet_unref(result);
1219 NOTIFICATION_ERR("failed to receive answer(delete multiple)");
1220 if (notification_ipc_is_master_ready() == 1) {
1221 return NOTIFICATION_ERROR_PERMISSION_DENIED;
1224 return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1231 int notification_ipc_request_update(notification_h noti)
1234 int id = NOTIFICATION_PRIV_ID_NONE;
1235 struct packet *packet;
1236 struct packet *result;
1238 packet = notification_ipc_make_packet_from_noti(noti, "update_noti", 1);
1239 result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1241 NOTIFICATION_IPC_TIMEOUT);
1242 packet_destroy(packet);
1244 if (result != NULL) {
1245 if (packet_get(result, "ii", &status, &id) != 2) {
1246 NOTIFICATION_ERR("Failed to get a result packet");
1247 packet_unref(result);
1248 return NOTIFICATION_ERROR_IO_ERROR;
1250 packet_unref(result);
1252 NOTIFICATION_ERR("failed to receive answer(update)");
1253 if (notification_ipc_is_master_ready() == 1) {
1254 return NOTIFICATION_ERROR_PERMISSION_DENIED;
1257 return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1264 static int _notification_ipc_update_cb(pid_t pid, int handle, const struct packet *packet, void *data)
1267 int id = NOTIFICATION_PRIV_ID_NONE;
1268 result_cb_item *cb_item = (result_cb_item *)data;
1270 if (cb_item == NULL) {
1271 NOTIFICATION_ERR("Failed to get a callback item");
1272 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1274 s_info.server_cl_fd_ref_cnt = (s_info.server_cl_fd_ref_cnt <= 1) ? 0 : s_info.server_cl_fd_ref_cnt - 1;
1275 if (s_info.server_cl_fd_ref_cnt <= 0) {
1276 NOTIFICATION_DBG("REFCNT: %d (fd: %d)", s_info.server_cl_fd_ref_cnt, s_info.server_cl_fd);
1277 int fd_temp = s_info.server_cl_fd;
1278 s_info.server_cl_fd = -1;
1279 com_core_packet_client_fini(fd_temp);
1280 NOTIFICATION_DBG("FD(%d) finalized", fd_temp);
1283 if (packet != NULL) {
1284 if (packet_get(packet, "ii", &status, &id) != 2) {
1285 NOTIFICATION_ERR("Failed to get a result packet");
1286 status = NOTIFICATION_ERROR_IO_ERROR;
1290 if (cb_item->result_cb != NULL) {
1291 cb_item->result_cb(id, status, cb_item->data);
1298 int notification_ipc_request_update_async(notification_h noti,
1299 void (*result_cb)(int priv_id, int result, void *data), void *user_data)
1301 int ret = NOTIFICATION_ERROR_NONE;
1303 struct packet *packet = NULL;
1304 result_cb_item *cb_item = NULL;
1306 packet = notification_ipc_make_packet_from_noti(noti, "update_noti", 1);
1307 if (packet == NULL) {
1308 ret = NOTIFICATION_ERROR_INVALID_PARAMETER;
1312 cb_item = calloc(1, sizeof(result_cb_item));
1313 if (cb_item == NULL) {
1314 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
1318 if (s_info.server_cl_fd < 0) {
1319 com_core_packet_use_thread(1);
1320 s_info.server_cl_fd = com_core_packet_client_init(s_info.socket_file, 0, NULL);
1321 if (s_info.server_cl_fd < 0) {
1322 NOTIFICATION_DBG("Failed to init client: %d", s_info.server_cl_fd);
1323 if (notification_ipc_is_master_ready() == 1) {
1324 ret = NOTIFICATION_ERROR_PERMISSION_DENIED;
1327 ret = NOTIFICATION_ERROR_SERVICE_NOT_READY;
1331 s_info.server_cl_fd_ref_cnt = 1;
1333 s_info.server_cl_fd_ref_cnt++;
1336 cb_item->result_cb = result_cb;
1337 cb_item->data = user_data;
1339 NOTIFICATION_INFO("Connection count:%d, fd:%d", s_info.server_cl_fd_ref_cnt, s_info.server_cl_fd);
1341 ret_con = com_core_packet_async_send(s_info.server_cl_fd, packet, 0.0f,
1342 _notification_ipc_update_cb, cb_item);
1344 NOTIFICATION_ERR("Failed to request update, %d\n", ret_con);
1345 s_info.server_cl_fd_ref_cnt = (s_info.server_cl_fd_ref_cnt <= 1) ? 0 : s_info.server_cl_fd_ref_cnt - 1;
1346 if (s_info.server_cl_fd_ref_cnt <= 0) {
1347 int fd_temp = s_info.server_cl_fd;
1348 s_info.server_cl_fd = -1;
1349 com_core_packet_client_fini(fd_temp);
1350 NOTIFICATION_INFO("FD(%d) finalized", fd_temp);
1352 ret = NOTIFICATION_ERROR_IO_ERROR;
1355 ret = NOTIFICATION_ERROR_NONE;
1360 if (cb_item) free(cb_item);
1361 NOTIFICATION_ERR("Err: %d\n", ret);
1364 if (packet) packet_destroy(packet);
1369 int notification_ipc_request_refresh(void)
1372 struct packet *packet;
1373 struct packet *result;
1375 packet = packet_create("refresh_noti", "i", NOTIFICATION_OP_REFRESH);
1376 result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1378 NOTIFICATION_IPC_TIMEOUT);
1379 packet_destroy(packet);
1381 if (result != NULL) {
1382 if (packet_get(result, "i", &status) != 1) {
1383 NOTIFICATION_ERR("Failed to get a result packet");
1384 packet_unref(result);
1385 return NOTIFICATION_ERROR_IO_ERROR;
1387 packet_unref(result);
1389 NOTIFICATION_ERR("failed to receive answer(refresh)");
1390 if (notification_ipc_is_master_ready() == 1) {
1391 return NOTIFICATION_ERROR_PERMISSION_DENIED;
1394 return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1401 int notification_ipc_noti_setting_property_set(const char *pkgname, const char *property, const char *value)
1405 struct packet *packet;
1406 struct packet *result;
1408 packet = packet_create("set_noti_property", "sss", pkgname, property, value);
1409 result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1411 NOTIFICATION_IPC_TIMEOUT);
1412 packet_destroy(packet);
1414 if (result != NULL) {
1415 if (packet_get(result, "ii", &status, &ret) != 2) {
1416 NOTIFICATION_ERR("Failed to get a result packet");
1417 packet_unref(result);
1418 return NOTIFICATION_ERROR_IO_ERROR;
1420 packet_unref(result);
1422 NOTIFICATION_ERR("failed to receive answer(delete)");
1423 if (notification_ipc_is_master_ready() == 1) {
1424 return NOTIFICATION_ERROR_PERMISSION_DENIED;
1427 return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1434 int notification_ipc_noti_setting_property_get(const char *pkgname, const char *property, char **value)
1438 struct packet *packet;
1439 struct packet *result;
1441 packet = packet_create("get_noti_property", "ss", pkgname, property);
1442 result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1444 NOTIFICATION_IPC_TIMEOUT);
1445 packet_destroy(packet);
1447 if (result != NULL) {
1448 if (packet_get(result, "is", &status, &ret) != 2) {
1449 NOTIFICATION_ERR("Failed to get a result packet");
1450 packet_unref(result);
1451 return NOTIFICATION_ERROR_IO_ERROR;
1453 if (status == NOTIFICATION_ERROR_NONE && ret != NULL) {
1454 *value = strdup(ret);
1456 packet_unref(result);
1458 NOTIFICATION_ERR("failed to receive answer(delete)");
1459 if (notification_ipc_is_master_ready() == 1) {
1460 return NOTIFICATION_ERROR_PERMISSION_DENIED;
1463 return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1470 int notification_ipc_request_load_noti_by_tag(notification_h noti, const char *pkgname, const char *tag)
1472 struct packet *packet;
1473 struct packet *result;
1475 packet = packet_create("load_noti_by_tag", "ss", pkgname, tag);
1476 result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1478 NOTIFICATION_IPC_TIMEOUT);
1479 packet_destroy(packet);
1481 if (result != NULL) {
1482 if (notification_ipc_make_noti_from_packet(noti, result) != NOTIFICATION_ERROR_NONE) {
1483 NOTIFICATION_ERR("Failed to get a result packet");
1484 packet_unref(result);
1485 return NOTIFICATION_ERROR_IO_ERROR;
1488 packet_unref(result);
1490 NOTIFICATION_ERR("failed to receive answer(load noti by tag)");
1491 if (notification_ipc_is_master_ready() == 1) {
1492 return NOTIFICATION_ERROR_PERMISSION_DENIED;
1495 return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1499 return NOTIFICATION_ERROR_NONE;