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>
38 #include <notification_setting_internal.h>
40 #define NOTIFICATION_IPC_TIMEOUT 0.0
42 #if !defined(VCONFKEY_MASTER_STARTED)
43 #define VCONFKEY_MASTER_STARTED "memory/data-provider-master/started"
49 int server_cl_fd_ref_cnt;
51 const char *socket_file;
53 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);
57 int is_started_cb_set_svc;
58 int is_started_cb_set_task;
62 .server_cl_fd_ref_cnt = 0,
64 .socket_file = NOTIFICATION_ADDR,
66 .is_started_cb_set_svc = 0,
67 .is_started_cb_set_task = 0,
70 typedef struct _task_list task_list;
75 void (*task_cb) (void *data);
79 typedef struct _result_cb_item {
80 void (*result_cb)(int priv_id, int result, void *data);
84 static task_list *g_task_list;
86 static int notification_ipc_monitor_register(void);
87 static int notification_ipc_monitor_deregister(void);
88 static void _do_deffered_task(void);
89 static void _master_started_cb_task(keynode_t *node, void *data);
91 static inline char *_string_get(char *string)
96 if (string[0] == '\0')
103 * functions to check state of master
105 static inline void _set_master_started_cb(vconf_callback_fn cb)
109 ret = vconf_notify_key_changed(VCONFKEY_MASTER_STARTED, cb, NULL);
111 NOTIFICATION_ERR("failed to notify key(%s) : %d",
112 VCONFKEY_MASTER_STARTED, ret);
115 static inline void _unset_master_started_cb(vconf_callback_fn cb)
119 ret = vconf_ignore_key_changed(VCONFKEY_MASTER_STARTED, cb);
121 NOTIFICATION_ERR("failed to notify key(%s) : %d",
122 VCONFKEY_MASTER_STARTED, ret);
125 int notification_ipc_is_master_ready(void)
127 int ret = -1, is_master_started = 0;
129 ret = vconf_get_bool(VCONFKEY_MASTER_STARTED, &is_master_started);
130 if (ret == 0 && is_master_started == 1) {
131 NOTIFICATION_ERR("the master has been started");
133 is_master_started = 0;
134 NOTIFICATION_ERR("the master has been stopped");
137 return is_master_started;
140 int notification_ipc_add_deffered_task(
141 void (*deferred_task_cb)(void *data),
144 task_list *list = NULL;
145 task_list *list_new = NULL;
148 (task_list *) malloc(sizeof(task_list));
150 if (list_new == NULL)
151 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
153 if (s_info.is_started_cb_set_task == 0) {
154 _set_master_started_cb(_master_started_cb_task);
155 s_info.is_started_cb_set_task = 1;
158 list_new->next = NULL;
159 list_new->prev = NULL;
161 list_new->task_cb = deferred_task_cb;
162 list_new->data = user_data;
164 if (g_task_list == NULL) {
165 g_task_list = list_new;
169 while (list->next != NULL)
173 list->next = list_new;
174 list_new->prev = list;
176 return NOTIFICATION_ERROR_NONE;
180 notification_ipc_del_deffered_task(
181 void (*deferred_task_cb)(void *data))
183 task_list *list_del = NULL;
184 task_list *list_prev = NULL;
185 task_list *list_next = NULL;
187 list_del = g_task_list;
189 if (list_del == NULL)
190 return NOTIFICATION_ERROR_INVALID_PARAMETER;
193 while (list_del->prev != NULL)
194 list_del = list_del->prev;
198 if (list_del->task_cb == deferred_task_cb) {
199 list_prev = list_del->prev;
200 list_next = list_del->next;
202 if (list_prev == NULL)
203 g_task_list = list_next;
205 list_prev->next = list_next;
207 if (list_next == NULL) {
208 if (list_prev != NULL)
209 list_prev->next = NULL;
212 list_next->prev = list_prev;
217 if (g_task_list == NULL) {
218 if (s_info.is_started_cb_set_task == 1) {
219 _unset_master_started_cb(_master_started_cb_task);
220 s_info.is_started_cb_set_task = 0;
224 return NOTIFICATION_ERROR_NONE;
226 list_del = list_del->next;
227 } while (list_del != NULL);
229 return NOTIFICATION_ERROR_INVALID_PARAMETER;
232 static void _do_deffered_task(void)
234 task_list *list_do = NULL;
235 task_list *list_temp = NULL;
237 if (g_task_list == NULL)
240 list_do = g_task_list;
242 if (s_info.is_started_cb_set_task == 1) {
243 _unset_master_started_cb(_master_started_cb_task);
244 s_info.is_started_cb_set_task = 0;
247 while (list_do->prev != NULL)
248 list_do = list_do->prev;
251 while (list_do != NULL) {
252 if (list_do->task_cb != NULL) {
253 list_do->task_cb(list_do->data);
254 NOTIFICATION_DBG("called:%p", list_do->task_cb);
256 list_temp = list_do->next;
262 static void _master_started_cb_service(keynode_t *node,
264 int ret = NOTIFICATION_ERROR_NONE;
266 if (notification_ipc_is_master_ready()) {
267 NOTIFICATION_ERR("try to register a notification service");
268 ret = notification_ipc_monitor_deregister();
269 if (ret != NOTIFICATION_ERROR_NONE)
270 NOTIFICATION_ERR("failed to unregister a monitor");
272 ret = notification_ipc_monitor_register();
273 if (ret != NOTIFICATION_ERROR_NONE)
274 NOTIFICATION_ERR("failed to register a monitor");
277 NOTIFICATION_ERR("try to unregister a notification service");
278 ret = notification_ipc_monitor_deregister();
279 if (ret != NOTIFICATION_ERROR_NONE)
280 NOTIFICATION_ERR("failed to deregister a monitor");
285 static void _master_started_cb_task(keynode_t *node,
288 if (notification_ipc_is_master_ready())
293 * functions to create operation list
295 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)
298 notification_op *op_list = NULL;
303 op_list = (notification_op *)malloc(sizeof(notification_op) * num_op);
305 if (op_list == NULL) {
306 NOTIFICATION_ERR("malloc failed");
310 memset(op_list, 0x0, sizeof(notification_op) * num_op);
312 for (i = 0; i < num_op; i++) {
313 (op_list + i)->type = type;
314 if (list_priv_id != NULL)
315 (op_list + i)->priv_id = *(list_priv_id + i);
317 if (noti_list != NULL)
318 (op_list + i)->noti = *(noti_list + i);
325 * utility functions creating notification packet
327 static inline char *_dup_string(const char *string)
334 if (string[0] == '\0')
337 ret = strdup(string);
339 NOTIFICATION_ERR("Error: %s\n", strerror(errno));
344 static inline bundle *_create_bundle_from_string(unsigned char *string)
349 if (string[0] == '\0')
352 return bundle_decode(string, strlen((char *)string));
356 * functions creating notification packet
358 EXPORT_API int notification_ipc_make_noti_from_packet(notification_h noti, const struct packet *packet)
365 int internal_group_id;
367 char *caller_pkgname = NULL;
368 char *launch_pkgname = NULL;
369 unsigned char *args = NULL;
370 unsigned char *group_args = NULL;
371 unsigned char *b_execute_option = NULL;
372 unsigned char *b_service_responding = NULL;
373 unsigned char *b_service_single_launch = NULL;
374 unsigned char *b_service_multi_launch = NULL;
375 unsigned char *b_event_handler[NOTIFICATION_EVENT_TYPE_MAX] = { NULL, };
378 unsigned char *b_text = NULL;
379 unsigned char *b_key = NULL;
380 unsigned char *b_format_args = NULL;
382 unsigned char *b_image_path = NULL;
384 char *sound_path = NULL;
386 char *vibration_path = NULL;
393 int flags_for_property;
395 double progress_size;
396 double progress_percentage;
397 char *app_icon_path = NULL;
398 char *app_name = NULL;
399 char *temp_title = NULL;
400 char *temp_content = NULL;
406 NOTIFICATION_ERR("invalid data");
407 return NOTIFICATION_ERROR_INVALID_PARAMETER;
410 ret = packet_get(packet,
411 "iiiiisssssssssssssssssssssisisisiiiiiiiiddsssssii",
422 &b_service_responding,
423 &b_service_single_launch,
424 &b_service_multi_launch,
425 &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_1],
426 &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_2],
427 &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_3],
428 &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_4],
429 &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_5],
430 &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_6],
431 &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_ICON],
432 &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_THUMBNAIL],
453 &progress_percentage,
463 NOTIFICATION_ERR("failed to create a noti from packet");
464 return NOTIFICATION_ERROR_INVALID_PARAMETER;
468 * This is already allocated from the notification_create function.
469 * Before reallocate string to here.
470 * We have to release old one first.
472 free(noti->caller_pkgname);
473 noti->caller_pkgname = _dup_string(caller_pkgname);
474 noti->launch_pkgname = _dup_string(launch_pkgname);
475 noti->args = _create_bundle_from_string(args);
476 noti->group_args = _create_bundle_from_string(group_args);
477 noti->b_execute_option = _create_bundle_from_string(b_execute_option);
478 noti->b_service_responding = _create_bundle_from_string(b_service_responding);
479 noti->b_service_single_launch = _create_bundle_from_string(b_service_single_launch);
480 noti->b_service_multi_launch = _create_bundle_from_string(b_service_multi_launch);
481 for (i = 0; i < NOTIFICATION_EVENT_TYPE_MAX; i++)
482 noti->b_event_handler[i] = _create_bundle_from_string(b_event_handler[i]);
484 noti->domain = _dup_string(domain);
485 noti->dir = _dup_string(dir);
486 noti->b_text = _create_bundle_from_string(b_text);
487 noti->b_key = _create_bundle_from_string(b_key);
488 noti->b_format_args = _create_bundle_from_string(b_format_args);
489 noti->b_image_path = _create_bundle_from_string(b_image_path);
490 noti->sound_path = _dup_string(sound_path);
491 noti->vibration_path = _dup_string(vibration_path);
492 noti->app_icon_path = _dup_string(app_icon_path);
493 noti->app_name = _dup_string(app_name);
494 noti->temp_title = _dup_string(temp_title);
495 noti->temp_content = _dup_string(temp_content);
498 noti->layout = layout;
499 noti->group_id = group_id;
500 noti->internal_group_id = internal_group_id;
501 noti->priv_id = priv_id;
502 noti->num_format_args = num_format_args;
503 noti->sound_type = sound_type;
504 noti->vibration_type = vibration_type;
505 noti->led_operation = led_operation;
506 noti->led_argb = led_argb;
507 noti->led_on_ms = led_on_ms;
508 noti->led_off_ms = led_off_ms;
510 noti->insert_time = insert_time;
511 noti->flags_for_property = flags_for_property;
512 noti->display_applist = display_applist;
513 noti->progress_size = progress_size;
514 noti->progress_percentage = progress_percentage;
515 noti->tag = _dup_string(tag);
516 noti->ongoing_flag = ongoing_flag;
517 noti->auto_remove = auto_remove;
519 return NOTIFICATION_ERROR_NONE;
522 EXPORT_API struct packet *notification_ipc_make_packet_from_noti(notification_h noti, const char *command, int packet_type)
525 int b_encode_len = 0;
526 struct packet *result = NULL;
528 char *group_args = NULL;
529 char *b_image_path = NULL;
530 char *b_execute_option = NULL;
531 char *b_service_responding = NULL;
532 char *b_service_single_launch = NULL;
533 char *b_service_multi_launch = NULL;
534 char *b_event_handler[NOTIFICATION_EVENT_TYPE_MAX] = { NULL , };
537 char *b_format_args = NULL;
538 struct packet *(*func_to_create_packet)(const char *command, const char *fmt, ...);
539 char *title_key = NULL;
540 char buf_key[32] = { 0, };
542 /* Decode bundle to insert DB */
544 bundle_encode(noti->args, (bundle_raw **) & args, NULL);
546 if (noti->group_args)
547 bundle_encode(noti->group_args, (bundle_raw **) & group_args,
550 if (noti->b_execute_option)
551 bundle_encode(noti->b_execute_option,
552 (bundle_raw **) & b_execute_option, &b_encode_len);
554 if (noti->b_service_responding)
555 bundle_encode(noti->b_service_responding,
556 (bundle_raw **) & b_service_responding, &b_encode_len);
558 if (noti->b_service_single_launch)
559 bundle_encode(noti->b_service_single_launch,
560 (bundle_raw **) & b_service_single_launch, &b_encode_len);
562 if (noti->b_service_multi_launch)
563 bundle_encode(noti->b_service_multi_launch,
564 (bundle_raw **) & b_service_multi_launch, &b_encode_len);
566 for (i = 0; i < NOTIFICATION_EVENT_TYPE_MAX; i++) {
567 if (noti->b_event_handler[i])
568 bundle_encode(noti->b_event_handler[i],
569 (bundle_raw **) & b_event_handler[i], &b_encode_len);
574 bundle_encode(noti->b_text, (bundle_raw **) & b_text, &b_encode_len);
577 bundle_encode(noti->b_key, (bundle_raw **) & b_key, &b_encode_len);
579 if (noti->b_format_args)
580 bundle_encode(noti->b_format_args,
581 (bundle_raw **) & b_format_args, &b_encode_len);
583 if (noti->b_image_path)
584 bundle_encode(noti->b_image_path,
585 (bundle_raw **) & b_image_path, &b_encode_len);
587 if (noti->b_key != NULL) {
588 snprintf(buf_key, sizeof(buf_key), "%d",
589 NOTIFICATION_TEXT_TYPE_TITLE);
591 bundle_get_str(noti->b_key, buf_key, &title_key);
594 if (title_key == NULL && noti->b_text != NULL) {
595 snprintf(buf_key, sizeof(buf_key), "%d",
596 NOTIFICATION_TEXT_TYPE_TITLE);
598 bundle_get_str(noti->b_text, buf_key, &title_key);
601 if (title_key == NULL)
602 title_key = noti->caller_pkgname;
605 if (packet_type == 1)
606 func_to_create_packet = packet_create;
607 else if (packet_type == 2)
608 func_to_create_packet = packet_create_noack;
612 result = func_to_create_packet(command,
613 "iiiiisssssssssssssssssssssisisisiiiiiiiiddsssssii",
617 noti->internal_group_id,
619 NOTIFICATION_CHECK_STR(noti->caller_pkgname),
620 NOTIFICATION_CHECK_STR(noti->launch_pkgname),
621 NOTIFICATION_CHECK_STR(args),
622 NOTIFICATION_CHECK_STR(group_args),
623 NOTIFICATION_CHECK_STR(b_execute_option),
624 NOTIFICATION_CHECK_STR(b_service_responding),
625 NOTIFICATION_CHECK_STR(b_service_single_launch),
626 NOTIFICATION_CHECK_STR(b_service_multi_launch),
627 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_1]),
628 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_2]),
629 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_3]),
630 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_4]),
631 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_5]),
632 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_6]),
633 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_ICON]),
634 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_THUMBNAIL]),
635 NOTIFICATION_CHECK_STR(noti->domain),
636 NOTIFICATION_CHECK_STR(noti->dir),
637 NOTIFICATION_CHECK_STR(b_text),
638 NOTIFICATION_CHECK_STR(b_key),
639 NOTIFICATION_CHECK_STR(b_format_args),
640 noti->num_format_args,
641 NOTIFICATION_CHECK_STR(b_image_path),
643 NOTIFICATION_CHECK_STR(noti->sound_path),
644 noti->vibration_type,
645 NOTIFICATION_CHECK_STR(noti->vibration_path),
652 noti->flags_for_property,
653 noti->display_applist,
655 noti->progress_percentage,
656 NOTIFICATION_CHECK_STR(noti->app_icon_path),
657 NOTIFICATION_CHECK_STR(noti->app_name),
658 NOTIFICATION_CHECK_STR(noti->temp_title),
659 NOTIFICATION_CHECK_STR(noti->temp_content),
660 NOTIFICATION_CHECK_STR(noti->tag),
665 /* Free decoded data */
672 if (b_execute_option)
673 free(b_execute_option);
675 if (b_service_responding)
676 free(b_service_responding);
678 if (b_service_single_launch)
679 free(b_service_single_launch);
681 if (b_service_multi_launch)
682 free(b_service_multi_launch);
684 for (i = 0; i < NOTIFICATION_EVENT_TYPE_MAX; i++) {
685 if (b_event_handler[i])
686 free(b_event_handler[i]);
704 EXPORT_API struct packet *notification_ipc_make_reply_packet_from_noti(notification_h noti, struct packet *packet)
707 int b_encode_len = 0;
708 struct packet *result = NULL;
710 char *group_args = NULL;
711 char *b_image_path = NULL;
712 char *b_execute_option = NULL;
713 char *b_service_responding = NULL;
714 char *b_service_single_launch = NULL;
715 char *b_service_multi_launch = NULL;
716 char *b_event_handler[NOTIFICATION_EVENT_TYPE_MAX] = { NULL , };
719 char *b_format_args = NULL;
720 char *title_key = NULL;
721 char buf_key[32] = { 0, };
723 /* Decode bundle to insert DB */
725 bundle_encode(noti->args, (bundle_raw **) & args, &b_encode_len);
727 if (noti->group_args)
728 bundle_encode(noti->group_args, (bundle_raw **) & group_args,
731 if (noti->b_execute_option)
732 bundle_encode(noti->b_execute_option,
733 (bundle_raw **) & b_execute_option, &b_encode_len);
735 if (noti->b_service_responding)
736 bundle_encode(noti->b_service_responding,
737 (bundle_raw **) & b_service_responding, &b_encode_len);
739 if (noti->b_service_single_launch)
740 bundle_encode(noti->b_service_single_launch,
741 (bundle_raw **) & b_service_single_launch, &b_encode_len);
743 if (noti->b_service_multi_launch)
744 bundle_encode(noti->b_service_multi_launch,
745 (bundle_raw **) & b_service_multi_launch, &b_encode_len);
747 for (i = 0; i < NOTIFICATION_EVENT_TYPE_MAX; i++) {
748 if (noti->b_event_handler[i])
749 bundle_encode(noti->b_event_handler[i],
750 (bundle_raw **) & b_event_handler[i], &b_encode_len);
754 bundle_encode(noti->b_text, (bundle_raw **) & b_text, &b_encode_len);
757 bundle_encode(noti->b_key, (bundle_raw **) & b_key, &b_encode_len);
759 if (noti->b_format_args)
760 bundle_encode(noti->b_format_args,
761 (bundle_raw **) & b_format_args, &b_encode_len);
763 if (noti->b_image_path)
764 bundle_encode(noti->b_image_path,
765 (bundle_raw **) & b_image_path, &b_encode_len);
767 if (noti->b_key != NULL) {
768 snprintf(buf_key, sizeof(buf_key), "%d",
769 NOTIFICATION_TEXT_TYPE_TITLE);
771 bundle_get_str(noti->b_key, buf_key, &title_key);
774 if (title_key == NULL && noti->b_text != NULL) {
775 snprintf(buf_key, sizeof(buf_key), "%d",
776 NOTIFICATION_TEXT_TYPE_TITLE);
778 bundle_get_str(noti->b_text, buf_key, &title_key);
781 if (title_key == NULL)
782 title_key = noti->caller_pkgname;
784 result = packet_create_reply(packet,
785 "iiiiisssssssssssssssssssssisisisiiiiiiiiddsssssii",
789 noti->internal_group_id,
791 NOTIFICATION_CHECK_STR(noti->caller_pkgname),
792 NOTIFICATION_CHECK_STR(noti->launch_pkgname),
793 NOTIFICATION_CHECK_STR(args),
794 NOTIFICATION_CHECK_STR(group_args),
795 NOTIFICATION_CHECK_STR(b_execute_option),
796 NOTIFICATION_CHECK_STR(b_service_responding),
797 NOTIFICATION_CHECK_STR(b_service_single_launch),
798 NOTIFICATION_CHECK_STR(b_service_multi_launch),
799 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_1]),
800 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_2]),
801 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_3]),
802 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_4]),
803 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_5]),
804 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_6]),
805 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_ICON]),
806 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_THUMBNAIL]),
807 NOTIFICATION_CHECK_STR(noti->domain),
808 NOTIFICATION_CHECK_STR(noti->dir),
809 NOTIFICATION_CHECK_STR(b_text),
810 NOTIFICATION_CHECK_STR(b_key),
811 NOTIFICATION_CHECK_STR(b_format_args),
812 noti->num_format_args,
813 NOTIFICATION_CHECK_STR(b_image_path),
815 NOTIFICATION_CHECK_STR(noti->sound_path),
816 noti->vibration_type,
817 NOTIFICATION_CHECK_STR(noti->vibration_path),
824 noti->flags_for_property,
825 noti->display_applist,
827 noti->progress_percentage,
828 NOTIFICATION_CHECK_STR(noti->app_icon_path),
829 NOTIFICATION_CHECK_STR(noti->app_name),
830 NOTIFICATION_CHECK_STR(noti->temp_title),
831 NOTIFICATION_CHECK_STR(noti->temp_content),
832 NOTIFICATION_CHECK_STR(noti->tag),
836 /* Free decoded data */
843 if (b_execute_option)
844 free(b_execute_option);
846 if (b_service_responding)
847 free(b_service_responding);
849 if (b_service_single_launch)
850 free(b_service_single_launch);
852 if (b_service_multi_launch)
853 free(b_service_multi_launch);
856 for (i = 0; i < NOTIFICATION_EVENT_TYPE_MAX; i++) {
857 if (b_event_handler[i])
858 free(b_event_handler[i]);
877 * functions to handler services
879 static struct packet *_handler_insert(pid_t pid, int handle, const struct packet *packet)
881 notification_h noti = NULL;
882 notification_op *noti_op;
885 NOTIFICATION_ERR("a packet is null");
888 noti = notification_create(NOTIFICATION_TYPE_NOTI);
890 NOTIFICATION_ERR("failed to create a notification");
893 notification_ipc_make_noti_from_packet(noti, packet);
895 if (noti->flags_for_property
896 & NOTIFICATION_PROP_DISABLE_UPDATE_ON_INSERT) {
897 /* Disable changed cb */
899 /* Enable changed cb */
900 noti_op = notification_ipc_create_op(NOTIFICATION_OP_INSERT, 1, &(noti->priv_id), 1, ¬i);
901 if (noti_op != NULL) {
902 notification_call_changed_cb(noti_op, 1);
906 notification_free(noti);
911 static struct packet *_handler_update(pid_t pid, int handle, const struct packet *packet)
913 notification_h noti = NULL;
914 notification_op *noti_op;
917 NOTIFICATION_ERR("a packet is null");
921 noti = notification_create(NOTIFICATION_TYPE_NOTI);
923 NOTIFICATION_ERR("failed to create a notification");
927 notification_ipc_make_noti_from_packet(noti, packet);
929 noti_op = notification_ipc_create_op(NOTIFICATION_OP_UPDATE, 1, &(noti->priv_id), 1, ¬i);
930 if (noti_op != NULL) {
931 notification_call_changed_cb(noti_op, 1);
935 notification_free(noti);
940 static struct packet *_handler_refresh(pid_t pid, int handle, const struct packet *packet)
942 notification_op *noti_op;
945 NOTIFICATION_ERR("a packet is null");
949 noti_op = notification_ipc_create_op(NOTIFICATION_OP_REFRESH, 1, NULL, 0, NULL);
950 if (noti_op != NULL) {
951 notification_call_changed_cb(noti_op, 1);
958 static struct packet *_handler_delete_single(pid_t pid, int handle, const struct packet *packet)
961 int priv_id = NOTIFICATION_PRIV_ID_NONE;
962 notification_op *noti_op;
965 NOTIFICATION_ERR("a packet is null");
968 if (packet_get(packet, "ii", &num_deleted, &priv_id) == 2) {
969 noti_op = notification_ipc_create_op(NOTIFICATION_OP_DELETE, 1, &priv_id, 1, NULL);
970 if (noti_op != NULL) {
971 notification_call_changed_cb(noti_op, 1);
979 static struct packet *_handler_delete_multiple(pid_t pid, int handle, const struct packet *packet)
984 notification_op *noti_op;
986 NOTIFICATION_INFO("delete_noti_multiple");
989 NOTIFICATION_ERR("a packet is null");
992 ret = packet_get(packet, "iiiiiiiiiii", &num_deleted,
1004 NOTIFICATION_INFO("packet data count:%d", ret);
1005 NOTIFICATION_INFO("packet data num deleted:%d", num_deleted);
1008 for (i = 0 ; i < 10 ; i++)
1009 NOTIFICATION_INFO("packet data[%d]:%d", i, buf[i]);
1013 noti_op = notification_ipc_create_op(
1014 NOTIFICATION_OP_DELETE, num_deleted, buf, num_deleted, NULL);
1015 if (noti_op == NULL) {
1016 NOTIFICATION_ERR("notification_ipc_create_op failed");
1019 notification_call_changed_cb(noti_op, num_deleted);
1026 static int _handler_service_register(pid_t pid, int handle, const struct packet *packet, void *data)
1029 notification_op *noti_op;
1032 NOTIFICATION_ERR("Packet is not valid\n");
1033 ret = NOTIFICATION_ERROR_INVALID_PARAMETER;
1034 } else if (packet_get(packet, "i", &ret) != 1) {
1035 NOTIFICATION_ERR("Packet is not valid\n");
1036 ret = NOTIFICATION_ERROR_INVALID_PARAMETER;
1039 noti_op = notification_ipc_create_op(NOTIFICATION_OP_SERVICE_READY, 1, NULL, 1, NULL);
1040 if (noti_op != NULL) {
1041 notification_call_changed_cb(noti_op, 1);
1050 * functions to initialize and register a monitor
1052 static int notification_ipc_monitor_register(void)
1055 struct packet *packet;
1056 static struct method service_table[] = {
1059 .handler = _handler_insert,
1062 .cmd = "update_noti",
1063 .handler = _handler_update,
1066 .cmd = "refresh_noti",
1067 .handler = _handler_refresh,
1070 .cmd = "del_noti_single",
1071 .handler = _handler_delete_single,
1074 .cmd = "del_noti_multiple",
1075 .handler = _handler_delete_multiple,
1083 if (s_info.initialized == 1)
1084 return NOTIFICATION_ERROR_NONE;
1086 s_info.initialized = 1;
1088 NOTIFICATION_ERR("register a service\n");
1090 com_core_packet_use_thread(1);
1091 s_info.server_fd = com_core_packet_client_init(s_info.socket_file, 0, service_table);
1092 if (s_info.server_fd < 0) {
1093 NOTIFICATION_ERR("Failed to make a connection to the master\n");
1094 return NOTIFICATION_ERROR_IO_ERROR;
1097 packet = packet_create("service_register", "");
1099 NOTIFICATION_ERR("Failed to build a packet\n");
1100 com_core_packet_client_fini(s_info.server_fd);
1101 return NOTIFICATION_ERROR_IO_ERROR;
1104 ret = com_core_packet_async_send(s_info.server_fd, packet, 1.0, _handler_service_register, NULL);
1105 NOTIFICATION_DBG("Service register sent: %d\n", ret);
1106 packet_destroy(packet);
1108 com_core_packet_client_fini(s_info.server_fd);
1109 s_info.server_fd = NOTIFICATION_ERROR_INVALID_PARAMETER;
1110 ret = NOTIFICATION_ERROR_IO_ERROR;
1112 ret = NOTIFICATION_ERROR_NONE;
1115 NOTIFICATION_DBG("Server FD: %d\n", s_info.server_fd);
1119 int notification_ipc_monitor_deregister(void)
1121 if (s_info.initialized == 0)
1122 return NOTIFICATION_ERROR_NONE;
1124 com_core_packet_client_fini(s_info.server_fd);
1125 s_info.server_fd = NOTIFICATION_ERROR_INVALID_PARAMETER;
1127 s_info.initialized = 0;
1129 return NOTIFICATION_ERROR_NONE;
1132 int notification_ipc_monitor_init(void)
1134 int ret = NOTIFICATION_ERROR_NONE;
1136 if (notification_ipc_is_master_ready())
1137 ret = notification_ipc_monitor_register();
1139 if (s_info.is_started_cb_set_svc == 0) {
1140 _set_master_started_cb(_master_started_cb_service);
1141 s_info.is_started_cb_set_svc = 1;
1147 int notification_ipc_monitor_fini(void)
1149 int ret = NOTIFICATION_ERROR_NONE;
1151 if (s_info.is_started_cb_set_svc == 1) {
1152 _unset_master_started_cb(_master_started_cb_service);
1153 s_info.is_started_cb_set_svc = 0;
1156 ret = notification_ipc_monitor_deregister();
1162 * functions to request the service
1164 int notification_ipc_request_insert(notification_h noti, int *priv_id)
1167 int id = NOTIFICATION_PRIV_ID_NONE;
1168 struct packet *packet;
1169 struct packet *result;
1171 /* Initialize private ID */
1172 noti->priv_id = NOTIFICATION_PRIV_ID_NONE;
1173 noti->group_id = NOTIFICATION_GROUP_ID_NONE;
1174 noti->internal_group_id = NOTIFICATION_GROUP_ID_NONE;
1176 packet = notification_ipc_make_packet_from_noti(noti, "add_noti", 1);
1177 result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1179 NOTIFICATION_IPC_TIMEOUT);
1180 packet_destroy(packet);
1182 if (result != NULL) {
1183 if (packet_get(result, "ii", &status, &id) != 2) {
1184 NOTIFICATION_ERR("Failed to get a result packet");
1185 packet_unref(result);
1186 return NOTIFICATION_ERROR_IO_ERROR;
1189 if (status != NOTIFICATION_ERROR_NONE) {
1190 packet_unref(result);
1193 packet_unref(result);
1195 NOTIFICATION_ERR("failed to receive answer(insert)");
1196 if (notification_ipc_is_master_ready() == 1)
1197 return NOTIFICATION_ERROR_PERMISSION_DENIED;
1199 return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1202 if (priv_id != NULL)
1205 return NOTIFICATION_ERROR_NONE;
1208 int notification_ipc_request_delete_single(notification_type_e type, char *pkgname, int priv_id)
1211 int id = NOTIFICATION_PRIV_ID_NONE;
1212 struct packet *packet;
1213 struct packet *result;
1215 packet = packet_create("del_noti_single", "si", pkgname, priv_id);
1216 result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1218 NOTIFICATION_IPC_TIMEOUT);
1219 packet_destroy(packet);
1221 if (result != NULL) {
1222 if (packet_get(result, "ii", &status, &id) != 2) {
1223 NOTIFICATION_ERR("Failed to get a result packet");
1224 packet_unref(result);
1225 return NOTIFICATION_ERROR_IO_ERROR;
1227 packet_unref(result);
1229 NOTIFICATION_ERR("failed to receive answer(delete)");
1230 if (notification_ipc_is_master_ready() == 1)
1231 return NOTIFICATION_ERROR_PERMISSION_DENIED;
1233 return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1239 int notification_ipc_request_delete_multiple(notification_type_e type, char *pkgname)
1242 int num_deleted = 0;
1243 struct packet *packet;
1244 struct packet *result;
1246 packet = packet_create("del_noti_multiple", "si", pkgname, type);
1247 result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1249 NOTIFICATION_IPC_TIMEOUT);
1250 packet_destroy(packet);
1252 if (result != NULL) {
1253 if (packet_get(result, "ii", &status, &num_deleted) != 2) {
1254 NOTIFICATION_ERR("Failed to get a result packet");
1255 packet_unref(result);
1256 return NOTIFICATION_ERROR_IO_ERROR;
1258 NOTIFICATION_ERR("num deleted:%d", num_deleted);
1259 packet_unref(result);
1261 NOTIFICATION_ERR("failed to receive answer(delete multiple)");
1262 if (notification_ipc_is_master_ready() == 1)
1263 return NOTIFICATION_ERROR_PERMISSION_DENIED;
1265 return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1271 int notification_ipc_request_update(notification_h noti)
1274 int id = NOTIFICATION_PRIV_ID_NONE;
1275 struct packet *packet;
1276 struct packet *result;
1278 packet = notification_ipc_make_packet_from_noti(noti, "update_noti", 1);
1279 result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1281 NOTIFICATION_IPC_TIMEOUT);
1282 packet_destroy(packet);
1284 if (result != NULL) {
1285 if (packet_get(result, "ii", &status, &id) != 2) {
1286 NOTIFICATION_ERR("Failed to get a result packet");
1287 packet_unref(result);
1288 return NOTIFICATION_ERROR_IO_ERROR;
1290 packet_unref(result);
1292 NOTIFICATION_ERR("failed to receive answer(update)");
1293 if (notification_ipc_is_master_ready() == 1)
1294 return NOTIFICATION_ERROR_PERMISSION_DENIED;
1296 return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1302 static int _notification_ipc_update_cb(pid_t pid, int handle, const struct packet *packet, void *data)
1305 int id = NOTIFICATION_PRIV_ID_NONE;
1306 result_cb_item *cb_item = (result_cb_item *)data;
1308 if (cb_item == NULL) {
1309 NOTIFICATION_ERR("Failed to get a callback item");
1310 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1312 s_info.server_cl_fd_ref_cnt = (s_info.server_cl_fd_ref_cnt <= 1) ? 0 : s_info.server_cl_fd_ref_cnt - 1;
1313 if (s_info.server_cl_fd_ref_cnt <= 0) {
1314 NOTIFICATION_DBG("REFCNT: %d (fd: %d)", s_info.server_cl_fd_ref_cnt, s_info.server_cl_fd);
1315 int fd_temp = s_info.server_cl_fd;
1316 s_info.server_cl_fd = -1;
1317 com_core_packet_client_fini(fd_temp);
1318 NOTIFICATION_DBG("FD(%d) finalized", fd_temp);
1321 if (packet != NULL) {
1322 if (packet_get(packet, "ii", &status, &id) != 2) {
1323 NOTIFICATION_ERR("Failed to get a result packet");
1324 status = NOTIFICATION_ERROR_IO_ERROR;
1328 if (cb_item->result_cb != NULL)
1329 cb_item->result_cb(id, status, cb_item->data);
1336 int notification_ipc_request_update_async(notification_h noti,
1337 void (*result_cb)(int priv_id, int result, void *data), void *user_data)
1339 int ret = NOTIFICATION_ERROR_NONE;
1341 struct packet *packet = NULL;
1342 result_cb_item *cb_item = NULL;
1344 packet = notification_ipc_make_packet_from_noti(noti, "update_noti", 1);
1345 if (packet == NULL) {
1346 ret = NOTIFICATION_ERROR_INVALID_PARAMETER;
1350 cb_item = calloc(1, sizeof(result_cb_item));
1351 if (cb_item == NULL) {
1352 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
1356 if (s_info.server_cl_fd < 0) {
1357 com_core_packet_use_thread(1);
1358 s_info.server_cl_fd = com_core_packet_client_init(s_info.socket_file, 0, NULL);
1359 if (s_info.server_cl_fd < 0) {
1360 NOTIFICATION_DBG("Failed to init client: %d", s_info.server_cl_fd);
1361 if (notification_ipc_is_master_ready() == 1)
1362 ret = NOTIFICATION_ERROR_PERMISSION_DENIED;
1364 ret = NOTIFICATION_ERROR_SERVICE_NOT_READY;
1368 s_info.server_cl_fd_ref_cnt = 1;
1370 s_info.server_cl_fd_ref_cnt++;
1373 cb_item->result_cb = result_cb;
1374 cb_item->data = user_data;
1376 NOTIFICATION_INFO("Connection count:%d, fd:%d", s_info.server_cl_fd_ref_cnt, s_info.server_cl_fd);
1378 ret_con = com_core_packet_async_send(s_info.server_cl_fd, packet, 0.0f,
1379 _notification_ipc_update_cb, cb_item);
1381 NOTIFICATION_ERR("Failed to request update, %d\n", ret_con);
1382 s_info.server_cl_fd_ref_cnt = (s_info.server_cl_fd_ref_cnt <= 1) ? 0 : s_info.server_cl_fd_ref_cnt - 1;
1383 if (s_info.server_cl_fd_ref_cnt <= 0) {
1384 int fd_temp = s_info.server_cl_fd;
1385 s_info.server_cl_fd = -1;
1386 com_core_packet_client_fini(fd_temp);
1387 NOTIFICATION_INFO("FD(%d) finalized", fd_temp);
1389 ret = NOTIFICATION_ERROR_IO_ERROR;
1392 ret = NOTIFICATION_ERROR_NONE;
1397 if (cb_item) free(cb_item);
1398 NOTIFICATION_ERR("Err: %d\n", ret);
1401 if (packet) packet_destroy(packet);
1406 int notification_ipc_request_refresh(void)
1409 struct packet *packet;
1410 struct packet *result;
1412 packet = packet_create("refresh_noti", "i", NOTIFICATION_OP_REFRESH);
1413 result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1415 NOTIFICATION_IPC_TIMEOUT);
1416 packet_destroy(packet);
1418 if (result != NULL) {
1419 if (packet_get(result, "i", &status) != 1) {
1420 NOTIFICATION_ERR("Failed to get a result packet");
1421 packet_unref(result);
1422 return NOTIFICATION_ERROR_IO_ERROR;
1424 packet_unref(result);
1426 NOTIFICATION_ERR("failed to receive answer(refresh)");
1427 if (notification_ipc_is_master_ready() == 1)
1428 return NOTIFICATION_ERROR_PERMISSION_DENIED;
1430 return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1437 int notification_ipc_update_setting(notification_setting_h setting)
1441 struct packet *packet;
1442 struct packet *result;
1444 packet = packet_create("update_noti_setting", "siii", setting->package_name, (int)(setting->allow_to_notify), (int)(setting->do_not_disturb_except), (int)(setting->visibility_class));
1445 result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1447 NOTIFICATION_IPC_TIMEOUT);
1448 packet_destroy(packet);
1450 if (result != NULL) {
1451 if (packet_get(result, "ii", &status, &ret) != 2) {
1452 NOTIFICATION_ERR("Failed to get a result packet");
1453 packet_unref(result);
1454 return NOTIFICATION_ERROR_IO_ERROR;
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;
1462 return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1468 int notification_ipc_update_system_setting(notification_system_setting_h system_setting)
1472 struct packet *packet = NULL;
1473 struct packet *result = NULL;
1475 packet = packet_create("update_noti_sys_setting", "ii", (int)(system_setting->do_not_disturb), (int)(system_setting->visibility_class));
1476 if (packet == NULL) {
1477 NOTIFICATION_ERR("packet_create failed.");
1480 result = com_core_packet_oneshot_send(NOTIFICATION_ADDR, packet, NOTIFICATION_IPC_TIMEOUT);
1481 packet_destroy(packet);
1483 if (result != NULL) {
1484 if (packet_get(result, "ii", &status, &ret) != 2) {
1485 NOTIFICATION_ERR("Failed to get a result packet");
1486 status = NOTIFICATION_ERROR_IO_ERROR;
1491 NOTIFICATION_ERR("failed to receive answer(delete)");
1492 if (notification_ipc_is_master_ready() == 1) {
1493 status = NOTIFICATION_ERROR_PERMISSION_DENIED;
1496 status = NOTIFICATION_ERROR_SERVICE_NOT_READY;
1502 packet_unref(result);
1507 int notification_ipc_noti_setting_property_set(const char *pkgname, const char *property, const char *value)
1511 struct packet *packet;
1512 struct packet *result;
1514 packet = packet_create("set_noti_property", "sss", pkgname, property, value);
1515 result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1517 NOTIFICATION_IPC_TIMEOUT);
1518 packet_destroy(packet);
1520 if (result != NULL) {
1521 if (packet_get(result, "ii", &status, &ret) != 2) {
1522 NOTIFICATION_ERR("Failed to get a result packet");
1523 packet_unref(result);
1524 return NOTIFICATION_ERROR_IO_ERROR;
1526 packet_unref(result);
1528 NOTIFICATION_ERR("failed to receive answer(delete)");
1529 if (notification_ipc_is_master_ready() == 1)
1530 return NOTIFICATION_ERROR_PERMISSION_DENIED;
1532 return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1538 int notification_ipc_noti_setting_property_get(const char *pkgname, const char *property, char **value)
1542 struct packet *packet;
1543 struct packet *result;
1545 packet = packet_create("get_noti_property", "ss", pkgname, property);
1546 result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1548 NOTIFICATION_IPC_TIMEOUT);
1549 packet_destroy(packet);
1551 if (result != NULL) {
1552 if (packet_get(result, "is", &status, &ret) != 2) {
1553 NOTIFICATION_ERR("Failed to get a result packet");
1554 packet_unref(result);
1555 return NOTIFICATION_ERROR_IO_ERROR;
1557 if (status == NOTIFICATION_ERROR_NONE && ret != NULL)
1558 *value = strdup(ret);
1560 packet_unref(result);
1562 NOTIFICATION_ERR("failed to receive answer(delete)");
1563 if (notification_ipc_is_master_ready() == 1)
1564 return NOTIFICATION_ERROR_PERMISSION_DENIED;
1566 return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1572 int notification_ipc_request_load_noti_by_tag(notification_h noti, const char *pkgname, const char *tag)
1574 struct packet *packet;
1575 struct packet *result;
1577 packet = packet_create("load_noti_by_tag", "ss", pkgname, tag);
1578 result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1580 NOTIFICATION_IPC_TIMEOUT);
1581 packet_destroy(packet);
1583 if (result != NULL) {
1584 if (notification_ipc_make_noti_from_packet(noti, result) != NOTIFICATION_ERROR_NONE) {
1585 NOTIFICATION_ERR("Failed to get a result packet");
1586 packet_unref(result);
1587 return NOTIFICATION_ERROR_IO_ERROR;
1590 packet_unref(result);
1592 NOTIFICATION_ERR("failed to receive answer(load noti by tag)");
1593 if (notification_ipc_is_master_ready() == 1)
1594 return NOTIFICATION_ERROR_PERMISSION_DENIED;
1596 return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1599 return NOTIFICATION_ERROR_NONE;