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') {
104 * functions to check state of master
106 static inline void _set_master_started_cb(vconf_callback_fn cb)
110 ret = vconf_notify_key_changed(VCONFKEY_MASTER_STARTED,
113 NOTIFICATION_ERR("failed to notify key(%s) : %d",
114 VCONFKEY_MASTER_STARTED, ret);
118 static inline void _unset_master_started_cb(vconf_callback_fn cb)
122 ret = vconf_ignore_key_changed(VCONFKEY_MASTER_STARTED,
125 NOTIFICATION_ERR("failed to notify key(%s) : %d",
126 VCONFKEY_MASTER_STARTED, ret);
130 int notification_ipc_is_master_ready(void)
132 int ret = -1, is_master_started = 0;
134 ret = vconf_get_bool(VCONFKEY_MASTER_STARTED, &is_master_started);
135 if (ret == 0 && is_master_started == 1) {
136 NOTIFICATION_ERR("the master has been started");
138 is_master_started = 0;
139 NOTIFICATION_ERR("the master has been stopped");
142 return is_master_started;
146 notification_ipc_add_deffered_task(
147 void (*deferred_task_cb)(void *data),
150 task_list *list = NULL;
151 task_list *list_new = NULL;
154 (task_list *) malloc(sizeof(task_list));
156 if (list_new == NULL) {
157 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
160 if (s_info.is_started_cb_set_task == 0) {
161 _set_master_started_cb(_master_started_cb_task);
162 s_info.is_started_cb_set_task = 1;
165 list_new->next = NULL;
166 list_new->prev = NULL;
168 list_new->task_cb = deferred_task_cb;
169 list_new->data = user_data;
171 if (g_task_list == NULL) {
172 g_task_list = list_new;
176 while (list->next != NULL) {
180 list->next = list_new;
181 list_new->prev = list;
183 return NOTIFICATION_ERROR_NONE;
187 notification_ipc_del_deffered_task(
188 void (*deferred_task_cb)(void *data))
190 task_list *list_del = NULL;
191 task_list *list_prev = NULL;
192 task_list *list_next = NULL;
194 list_del = g_task_list;
196 if (list_del == NULL) {
197 return NOTIFICATION_ERROR_INVALID_PARAMETER;
200 while (list_del->prev != NULL) {
201 list_del = list_del->prev;
205 if (list_del->task_cb == deferred_task_cb) {
206 list_prev = list_del->prev;
207 list_next = list_del->next;
209 if (list_prev == NULL) {
210 g_task_list = list_next;
212 list_prev->next = list_next;
215 if (list_next == NULL) {
216 if (list_prev != NULL) {
217 list_prev->next = NULL;
220 list_next->prev = list_prev;
225 if (g_task_list == NULL) {
226 if (s_info.is_started_cb_set_task == 1) {
227 _unset_master_started_cb(_master_started_cb_task);
228 s_info.is_started_cb_set_task = 0;
232 return NOTIFICATION_ERROR_NONE;
234 list_del = list_del->next;
235 } while (list_del != NULL);
237 return NOTIFICATION_ERROR_INVALID_PARAMETER;
240 static void _do_deffered_task(void)
242 task_list *list_do = NULL;
243 task_list *list_temp = NULL;
245 if (g_task_list == NULL) {
249 list_do = g_task_list;
251 if (s_info.is_started_cb_set_task == 1) {
252 _unset_master_started_cb(_master_started_cb_task);
253 s_info.is_started_cb_set_task = 0;
256 while (list_do->prev != NULL) {
257 list_do = list_do->prev;
260 while (list_do != NULL) {
261 if (list_do->task_cb != NULL) {
262 list_do->task_cb(list_do->data);
263 NOTIFICATION_DBG("called:%p", list_do->task_cb);
265 list_temp = list_do->next;
271 static void _master_started_cb_service(keynode_t *node,
273 int ret = NOTIFICATION_ERROR_NONE;
275 if (notification_ipc_is_master_ready()) {
276 NOTIFICATION_ERR("try to register a notification service");
277 ret = notification_ipc_monitor_deregister();
278 if (ret != NOTIFICATION_ERROR_NONE) {
279 NOTIFICATION_ERR("failed to unregister a monitor");
281 ret = notification_ipc_monitor_register();
282 if (ret != NOTIFICATION_ERROR_NONE) {
283 NOTIFICATION_ERR("failed to register a monitor");
286 NOTIFICATION_ERR("try to unregister a notification service");
287 ret = notification_ipc_monitor_deregister();
288 if (ret != NOTIFICATION_ERROR_NONE) {
289 NOTIFICATION_ERR("failed to deregister a monitor");
294 static void _master_started_cb_task(keynode_t *node,
297 if (notification_ipc_is_master_ready()) {
303 * functions to create operation list
305 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)
308 notification_op *op_list = NULL;
314 op_list = (notification_op *)malloc(sizeof(notification_op) * num_op);
316 if (op_list == NULL) {
317 NOTIFICATION_ERR("malloc failed");
321 memset(op_list, 0x0, sizeof(notification_op) * num_op);
323 for (i = 0; i < num_op; i++) {
324 (op_list + i)->type = type;
325 if (list_priv_id != NULL) {
326 (op_list + i)->priv_id = *(list_priv_id + i);
328 if (noti_list != NULL) {
329 (op_list + i)->noti = *(noti_list + i);
337 * utility functions creating notification packet
339 static inline char *_dup_string(const char *string)
343 if (string == NULL) {
346 if (string[0] == '\0') {
350 ret = strdup(string);
352 NOTIFICATION_ERR("Error: %s\n", strerror(errno));
357 static inline bundle *_create_bundle_from_string(unsigned char *string)
359 if (string == NULL) {
362 if (string[0] == '\0') {
366 return bundle_decode(string, strlen((char *)string));
370 * functions creating notification packet
372 EXPORT_API int notification_ipc_make_noti_from_packet(notification_h noti, const struct packet *packet)
379 int internal_group_id;
381 char *caller_pkgname = NULL;
382 char *launch_pkgname = NULL;
383 unsigned char *args = NULL;
384 unsigned char *group_args = NULL;
385 unsigned char *b_execute_option = NULL;
386 unsigned char *b_service_responding = NULL;
387 unsigned char *b_service_single_launch = NULL;
388 unsigned char *b_service_multi_launch = NULL;
389 unsigned char *b_event_handler[NOTIFICATION_EVENT_TYPE_MAX] = { NULL, };
392 unsigned char *b_text = NULL;
393 unsigned char *b_key = NULL;
394 unsigned char *b_format_args = NULL;
396 unsigned char *b_image_path = NULL;
398 char *sound_path = NULL;
400 char *vibration_path = NULL;
407 int flags_for_property;
409 double progress_size;
410 double progress_percentage;
411 char *app_icon_path = NULL;
412 char *app_name = NULL;
413 char *temp_title = NULL;
414 char *temp_content = NULL;
420 NOTIFICATION_ERR("invalid data");
421 return NOTIFICATION_ERROR_INVALID_PARAMETER;
424 ret = packet_get(packet,
425 "iiiiisssssssssssssssssssssisisisiiiiiiiiddsssssii",
436 &b_service_responding,
437 &b_service_single_launch,
438 &b_service_multi_launch,
439 &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_1],
440 &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_2],
441 &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_3],
442 &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_4],
443 &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_5],
444 &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_6],
445 &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_ICON],
446 &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_THUMBNAIL],
467 &progress_percentage,
477 NOTIFICATION_ERR("failed to create a noti from packet");
478 return NOTIFICATION_ERROR_INVALID_PARAMETER;
482 * This is already allocated from the notification_create function.
483 * Before reallocate string to here.
484 * We have to release old one first.
486 free(noti->caller_pkgname);
487 noti->caller_pkgname = _dup_string(caller_pkgname);
488 noti->launch_pkgname = _dup_string(launch_pkgname);
489 noti->args = _create_bundle_from_string(args);
490 noti->group_args = _create_bundle_from_string(group_args);
491 noti->b_execute_option = _create_bundle_from_string(b_execute_option);
492 noti->b_service_responding = _create_bundle_from_string(b_service_responding);
493 noti->b_service_single_launch = _create_bundle_from_string(b_service_single_launch);
494 noti->b_service_multi_launch = _create_bundle_from_string(b_service_multi_launch);
495 for (i = 0; i < NOTIFICATION_EVENT_TYPE_MAX; i++) {
496 noti->b_event_handler[i] = _create_bundle_from_string(b_event_handler[i]);
498 noti->domain = _dup_string(domain);
499 noti->dir = _dup_string(dir);
500 noti->b_text = _create_bundle_from_string(b_text);
501 noti->b_key = _create_bundle_from_string(b_key);
502 noti->b_format_args = _create_bundle_from_string(b_format_args);
503 noti->b_image_path = _create_bundle_from_string(b_image_path);
504 noti->sound_path = _dup_string(sound_path);
505 noti->vibration_path = _dup_string(vibration_path);
506 noti->app_icon_path = _dup_string(app_icon_path);
507 noti->app_name = _dup_string(app_name);
508 noti->temp_title = _dup_string(temp_title);
509 noti->temp_content = _dup_string(temp_content);
512 noti->layout = layout;
513 noti->group_id = group_id;
514 noti->internal_group_id = internal_group_id;
515 noti->priv_id = priv_id;
516 noti->num_format_args = num_format_args;
517 noti->sound_type = sound_type;
518 noti->vibration_type = vibration_type;
519 noti->led_operation = led_operation;
520 noti->led_argb = led_argb;
521 noti->led_on_ms = led_on_ms;
522 noti->led_off_ms = led_off_ms;
524 noti->insert_time = insert_time;
525 noti->flags_for_property = flags_for_property;
526 noti->display_applist = display_applist;
527 noti->progress_size = progress_size;
528 noti->progress_percentage = progress_percentage;
529 noti->tag = _dup_string(tag);
530 noti->ongoing_flag = ongoing_flag;
531 noti->auto_remove = auto_remove;
533 return NOTIFICATION_ERROR_NONE;
536 EXPORT_API struct packet *notification_ipc_make_packet_from_noti(notification_h noti, const char *command, int packet_type)
539 int b_encode_len = 0;
540 struct packet *result = NULL;
542 char *group_args = NULL;
543 char *b_image_path = NULL;
544 char *b_execute_option = NULL;
545 char *b_service_responding = NULL;
546 char *b_service_single_launch = NULL;
547 char *b_service_multi_launch = NULL;
548 char *b_event_handler[NOTIFICATION_EVENT_TYPE_MAX] = { NULL , };
551 char *b_format_args = NULL;
552 struct packet *(*func_to_create_packet)(const char *command, const char *fmt, ...);
553 char *title_key = NULL;
554 char buf_key[32] = { 0, };
556 /* Decode bundle to insert DB */
558 bundle_encode(noti->args, (bundle_raw **) & args, NULL);
560 if (noti->group_args) {
561 bundle_encode(noti->group_args, (bundle_raw **) & group_args,
565 if (noti->b_execute_option) {
566 bundle_encode(noti->b_execute_option,
567 (bundle_raw **) & b_execute_option, &b_encode_len);
569 if (noti->b_service_responding) {
570 bundle_encode(noti->b_service_responding,
571 (bundle_raw **) & b_service_responding, &b_encode_len);
573 if (noti->b_service_single_launch) {
574 bundle_encode(noti->b_service_single_launch,
575 (bundle_raw **) & b_service_single_launch, &b_encode_len);
577 if (noti->b_service_multi_launch) {
578 bundle_encode(noti->b_service_multi_launch,
579 (bundle_raw **) & b_service_multi_launch, &b_encode_len);
582 for (i = 0; i < NOTIFICATION_EVENT_TYPE_MAX; i++) {
583 if (noti->b_event_handler[i]) {
584 bundle_encode(noti->b_event_handler[i],
585 (bundle_raw **) & b_event_handler[i], &b_encode_len);
590 bundle_encode(noti->b_text, (bundle_raw **) & b_text, &b_encode_len);
593 bundle_encode(noti->b_key, (bundle_raw **) & b_key, &b_encode_len);
595 if (noti->b_format_args) {
596 bundle_encode(noti->b_format_args,
597 (bundle_raw **) & b_format_args, &b_encode_len);
600 if (noti->b_image_path) {
601 bundle_encode(noti->b_image_path,
602 (bundle_raw **) & b_image_path, &b_encode_len);
605 if (noti->b_key != NULL) {
606 snprintf(buf_key, sizeof(buf_key), "%d",
607 NOTIFICATION_TEXT_TYPE_TITLE);
609 bundle_get_str(noti->b_key, buf_key, &title_key);
612 if (title_key == NULL && noti->b_text != NULL) {
613 snprintf(buf_key, sizeof(buf_key), "%d",
614 NOTIFICATION_TEXT_TYPE_TITLE);
616 bundle_get_str(noti->b_text, buf_key, &title_key);
619 if (title_key == NULL) {
620 title_key = noti->caller_pkgname;
623 if (packet_type == 1)
624 func_to_create_packet = packet_create;
625 else if (packet_type == 2)
626 func_to_create_packet = packet_create_noack;
631 result = func_to_create_packet(command,
632 "iiiiisssssssssssssssssssssisisisiiiiiiiiddsssssii",
636 noti->internal_group_id,
638 NOTIFICATION_CHECK_STR(noti->caller_pkgname),
639 NOTIFICATION_CHECK_STR(noti->launch_pkgname),
640 NOTIFICATION_CHECK_STR(args),
641 NOTIFICATION_CHECK_STR(group_args),
642 NOTIFICATION_CHECK_STR(b_execute_option),
643 NOTIFICATION_CHECK_STR(b_service_responding),
644 NOTIFICATION_CHECK_STR(b_service_single_launch),
645 NOTIFICATION_CHECK_STR(b_service_multi_launch),
646 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_1]),
647 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_2]),
648 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_3]),
649 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_4]),
650 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_5]),
651 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_6]),
652 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_ICON]),
653 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_THUMBNAIL]),
654 NOTIFICATION_CHECK_STR(noti->domain),
655 NOTIFICATION_CHECK_STR(noti->dir),
656 NOTIFICATION_CHECK_STR(b_text),
657 NOTIFICATION_CHECK_STR(b_key),
658 NOTIFICATION_CHECK_STR(b_format_args),
659 noti->num_format_args,
660 NOTIFICATION_CHECK_STR(b_image_path),
662 NOTIFICATION_CHECK_STR(noti->sound_path),
663 noti->vibration_type,
664 NOTIFICATION_CHECK_STR(noti->vibration_path),
671 noti->flags_for_property,
672 noti->display_applist,
674 noti->progress_percentage,
675 NOTIFICATION_CHECK_STR(noti->app_icon_path),
676 NOTIFICATION_CHECK_STR(noti->app_name),
677 NOTIFICATION_CHECK_STR(noti->temp_title),
678 NOTIFICATION_CHECK_STR(noti->temp_content),
679 NOTIFICATION_CHECK_STR(noti->tag),
684 /* Free decoded data */
692 if (b_execute_option) {
693 free(b_execute_option);
695 if (b_service_responding) {
696 free(b_service_responding);
698 if (b_service_single_launch) {
699 free(b_service_single_launch);
701 if (b_service_multi_launch) {
702 free(b_service_multi_launch);
705 for (i = 0; i < NOTIFICATION_EVENT_TYPE_MAX; i++) {
706 if (b_event_handler[i]) {
707 free(b_event_handler[i]);
728 EXPORT_API struct packet *notification_ipc_make_reply_packet_from_noti(notification_h noti, struct packet *packet)
731 int b_encode_len = 0;
732 struct packet *result = NULL;
734 char *group_args = NULL;
735 char *b_image_path = NULL;
736 char *b_execute_option = NULL;
737 char *b_service_responding = NULL;
738 char *b_service_single_launch = NULL;
739 char *b_service_multi_launch = NULL;
740 char *b_event_handler[NOTIFICATION_EVENT_TYPE_MAX] = { NULL , };
743 char *b_format_args = NULL;
744 char *title_key = NULL;
745 char buf_key[32] = { 0, };
747 /* Decode bundle to insert DB */
749 bundle_encode(noti->args, (bundle_raw **) & args, &b_encode_len);
751 if (noti->group_args) {
752 bundle_encode(noti->group_args, (bundle_raw **) & group_args,
756 if (noti->b_execute_option) {
757 bundle_encode(noti->b_execute_option,
758 (bundle_raw **) & b_execute_option, &b_encode_len);
760 if (noti->b_service_responding) {
761 bundle_encode(noti->b_service_responding,
762 (bundle_raw **) & b_service_responding, &b_encode_len);
764 if (noti->b_service_single_launch) {
765 bundle_encode(noti->b_service_single_launch,
766 (bundle_raw **) & b_service_single_launch, &b_encode_len);
768 if (noti->b_service_multi_launch) {
769 bundle_encode(noti->b_service_multi_launch,
770 (bundle_raw **) & b_service_multi_launch, &b_encode_len);
773 for (i = 0; i < NOTIFICATION_EVENT_TYPE_MAX; i++) {
774 if (noti->b_event_handler[i]) {
775 bundle_encode(noti->b_event_handler[i],
776 (bundle_raw **) & b_event_handler[i], &b_encode_len);
781 bundle_encode(noti->b_text, (bundle_raw **) & b_text, &b_encode_len);
784 bundle_encode(noti->b_key, (bundle_raw **) & b_key, &b_encode_len);
786 if (noti->b_format_args) {
787 bundle_encode(noti->b_format_args,
788 (bundle_raw **) & b_format_args, &b_encode_len);
791 if (noti->b_image_path) {
792 bundle_encode(noti->b_image_path,
793 (bundle_raw **) & b_image_path, &b_encode_len);
796 if (noti->b_key != NULL) {
797 snprintf(buf_key, sizeof(buf_key), "%d",
798 NOTIFICATION_TEXT_TYPE_TITLE);
800 bundle_get_str(noti->b_key, buf_key, &title_key);
803 if (title_key == NULL && noti->b_text != NULL) {
804 snprintf(buf_key, sizeof(buf_key), "%d",
805 NOTIFICATION_TEXT_TYPE_TITLE);
807 bundle_get_str(noti->b_text, buf_key, &title_key);
810 if (title_key == NULL) {
811 title_key = noti->caller_pkgname;
814 result = packet_create_reply(packet,
815 "iiiiisssssssssssssssssssssisisisiiiiiiiiddsssssii",
819 noti->internal_group_id,
821 NOTIFICATION_CHECK_STR(noti->caller_pkgname),
822 NOTIFICATION_CHECK_STR(noti->launch_pkgname),
823 NOTIFICATION_CHECK_STR(args),
824 NOTIFICATION_CHECK_STR(group_args),
825 NOTIFICATION_CHECK_STR(b_execute_option),
826 NOTIFICATION_CHECK_STR(b_service_responding),
827 NOTIFICATION_CHECK_STR(b_service_single_launch),
828 NOTIFICATION_CHECK_STR(b_service_multi_launch),
829 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_1]),
830 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_2]),
831 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_3]),
832 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_4]),
833 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_5]),
834 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_6]),
835 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_ICON]),
836 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_THUMBNAIL]),
837 NOTIFICATION_CHECK_STR(noti->domain),
838 NOTIFICATION_CHECK_STR(noti->dir),
839 NOTIFICATION_CHECK_STR(b_text),
840 NOTIFICATION_CHECK_STR(b_key),
841 NOTIFICATION_CHECK_STR(b_format_args),
842 noti->num_format_args,
843 NOTIFICATION_CHECK_STR(b_image_path),
845 NOTIFICATION_CHECK_STR(noti->sound_path),
846 noti->vibration_type,
847 NOTIFICATION_CHECK_STR(noti->vibration_path),
854 noti->flags_for_property,
855 noti->display_applist,
857 noti->progress_percentage,
858 NOTIFICATION_CHECK_STR(noti->app_icon_path),
859 NOTIFICATION_CHECK_STR(noti->app_name),
860 NOTIFICATION_CHECK_STR(noti->temp_title),
861 NOTIFICATION_CHECK_STR(noti->temp_content),
862 NOTIFICATION_CHECK_STR(noti->tag),
866 /* Free decoded data */
874 if (b_execute_option) {
875 free(b_execute_option);
877 if (b_service_responding) {
878 free(b_service_responding);
880 if (b_service_single_launch) {
881 free(b_service_single_launch);
883 if (b_service_multi_launch) {
884 free(b_service_multi_launch);
887 for (i = 0; i < NOTIFICATION_EVENT_TYPE_MAX; i++) {
888 if (b_event_handler[i]) {
889 free(b_event_handler[i]);
911 * functions to handler services
913 static struct packet *_handler_insert(pid_t pid, int handle, const struct packet *packet)
915 notification_h noti = NULL;
918 NOTIFICATION_ERR("a packet is null");
921 noti = notification_create(NOTIFICATION_TYPE_NOTI);
923 NOTIFICATION_ERR("failed to create a notification");
926 notification_ipc_make_noti_from_packet(noti, packet);
928 if (noti->flags_for_property
929 & NOTIFICATION_PROP_DISABLE_UPDATE_ON_INSERT) {
930 /* Disable changed cb */
932 /* Enable changed cb */
933 notification_op *noti_op = notification_ipc_create_op(NOTIFICATION_OP_INSERT, 1, &(noti->priv_id), 1, ¬i);
934 if (noti_op != NULL) {
935 notification_call_changed_cb(noti_op, 1);
939 notification_free(noti);
944 static struct packet *_handler_update(pid_t pid, int handle, const struct packet *packet)
946 notification_h noti = NULL;
949 NOTIFICATION_ERR("a packet is null");
953 noti = notification_create(NOTIFICATION_TYPE_NOTI);
955 NOTIFICATION_ERR("failed to create a notification");
959 notification_ipc_make_noti_from_packet(noti, packet);
961 notification_op *noti_op = notification_ipc_create_op(NOTIFICATION_OP_UPDATE, 1, &(noti->priv_id), 1, ¬i);
962 if (noti_op != NULL) {
963 notification_call_changed_cb(noti_op, 1);
967 notification_free(noti);
972 static struct packet *_handler_refresh(pid_t pid, int handle, const struct packet *packet)
975 NOTIFICATION_ERR("a packet is null");
978 notification_op *noti_op = notification_ipc_create_op(NOTIFICATION_OP_REFRESH, 1, NULL, 0, NULL);
979 if (noti_op != NULL) {
980 notification_call_changed_cb(noti_op, 1);
987 static struct packet *_handler_delete_single(pid_t pid, int handle, const struct packet *packet)
990 int priv_id = NOTIFICATION_PRIV_ID_NONE;
993 NOTIFICATION_ERR("a packet is null");
996 if (packet_get(packet, "ii", &num_deleted, &priv_id) == 2) {
997 notification_op *noti_op = notification_ipc_create_op(NOTIFICATION_OP_DELETE, 1, &priv_id, 1, NULL);
998 if (noti_op != NULL) {
999 notification_call_changed_cb(noti_op, 1);
1007 static struct packet *_handler_delete_multiple(pid_t pid, int handle, const struct packet *packet)
1011 int num_deleted = 0;
1013 NOTIFICATION_INFO("delete_noti_multiple");
1016 NOTIFICATION_ERR("a packet is null");
1019 ret = packet_get(packet, "iiiiiiiiiii", &num_deleted,
1031 NOTIFICATION_INFO("packet data count:%d", ret);
1032 NOTIFICATION_INFO("packet data num deleted:%d", num_deleted);
1035 for (i = 0 ; i < 10 ; i++) {
1036 NOTIFICATION_INFO("packet data[%d]:%d", i, buf[i]);
1040 notification_op *noti_op = notification_ipc_create_op(
1041 NOTIFICATION_OP_DELETE, num_deleted, buf, num_deleted, NULL);
1042 if (noti_op == NULL) {
1043 NOTIFICATION_ERR("notification_ipc_create_op failed");
1046 notification_call_changed_cb(noti_op, num_deleted);
1053 static int _handler_service_register(pid_t pid, int handle, const struct packet *packet, void *data)
1058 NOTIFICATION_ERR("Packet is not valid\n");
1059 ret = NOTIFICATION_ERROR_INVALID_PARAMETER;
1060 } else if (packet_get(packet, "i", &ret) != 1) {
1061 NOTIFICATION_ERR("Packet is not valid\n");
1062 ret = NOTIFICATION_ERROR_INVALID_PARAMETER;
1065 notification_op *noti_op = notification_ipc_create_op(NOTIFICATION_OP_SERVICE_READY, 1, NULL, 1, NULL);
1066 if (noti_op != NULL) {
1067 notification_call_changed_cb(noti_op, 1);
1076 * functions to initialize and register a monitor
1078 static int notification_ipc_monitor_register(void)
1081 struct packet *packet;
1082 static struct method service_table[] = {
1085 .handler = _handler_insert,
1088 .cmd = "update_noti",
1089 .handler = _handler_update,
1092 .cmd = "refresh_noti",
1093 .handler = _handler_refresh,
1096 .cmd = "del_noti_single",
1097 .handler = _handler_delete_single,
1100 .cmd = "del_noti_multiple",
1101 .handler = _handler_delete_multiple,
1109 if (s_info.initialized == 1) {
1110 return NOTIFICATION_ERROR_NONE;
1112 s_info.initialized = 1;
1115 NOTIFICATION_ERR("register a service\n");
1117 com_core_packet_use_thread(1);
1118 s_info.server_fd = com_core_packet_client_init(s_info.socket_file, 0, service_table);
1119 if (s_info.server_fd < 0) {
1120 NOTIFICATION_ERR("Failed to make a connection to the master\n");
1121 return NOTIFICATION_ERROR_IO_ERROR;
1124 packet = packet_create("service_register", "");
1126 NOTIFICATION_ERR("Failed to build a packet\n");
1127 com_core_packet_client_fini(s_info.server_fd);
1128 return NOTIFICATION_ERROR_IO_ERROR;
1131 ret = com_core_packet_async_send(s_info.server_fd, packet, 1.0, _handler_service_register, NULL);
1132 NOTIFICATION_DBG("Service register sent: %d\n", ret);
1133 packet_destroy(packet);
1135 com_core_packet_client_fini(s_info.server_fd);
1136 s_info.server_fd = NOTIFICATION_ERROR_INVALID_PARAMETER;
1137 ret = NOTIFICATION_ERROR_IO_ERROR;
1139 ret = NOTIFICATION_ERROR_NONE;
1142 NOTIFICATION_DBG("Server FD: %d\n", s_info.server_fd);
1146 int notification_ipc_monitor_deregister(void)
1148 if (s_info.initialized == 0) {
1149 return NOTIFICATION_ERROR_NONE;
1152 com_core_packet_client_fini(s_info.server_fd);
1153 s_info.server_fd = NOTIFICATION_ERROR_INVALID_PARAMETER;
1155 s_info.initialized = 0;
1157 return NOTIFICATION_ERROR_NONE;
1160 int notification_ipc_monitor_init(void)
1162 int ret = NOTIFICATION_ERROR_NONE;
1164 if (notification_ipc_is_master_ready()) {
1165 ret = notification_ipc_monitor_register();
1168 if (s_info.is_started_cb_set_svc == 0) {
1169 _set_master_started_cb(_master_started_cb_service);
1170 s_info.is_started_cb_set_svc = 1;
1176 int notification_ipc_monitor_fini(void)
1178 int ret = NOTIFICATION_ERROR_NONE;
1180 if (s_info.is_started_cb_set_svc == 1) {
1181 _unset_master_started_cb(_master_started_cb_service);
1182 s_info.is_started_cb_set_svc = 0;
1185 ret = notification_ipc_monitor_deregister();
1191 * functions to request the service
1193 int notification_ipc_request_insert(notification_h noti, int *priv_id)
1196 int id = NOTIFICATION_PRIV_ID_NONE;
1197 struct packet *packet;
1198 struct packet *result;
1200 /* Initialize private ID */
1201 noti->priv_id = NOTIFICATION_PRIV_ID_NONE;
1202 noti->group_id = NOTIFICATION_GROUP_ID_NONE;
1203 noti->internal_group_id = NOTIFICATION_GROUP_ID_NONE;
1205 packet = notification_ipc_make_packet_from_noti(noti, "add_noti", 1);
1206 result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1208 NOTIFICATION_IPC_TIMEOUT);
1209 packet_destroy(packet);
1211 if (result != NULL) {
1212 if (packet_get(result, "ii", &status, &id) != 2) {
1213 NOTIFICATION_ERR("Failed to get a result packet");
1214 packet_unref(result);
1215 return NOTIFICATION_ERROR_IO_ERROR;
1218 if (status != NOTIFICATION_ERROR_NONE) {
1219 packet_unref(result);
1222 packet_unref(result);
1224 NOTIFICATION_ERR("failed to receive answer(insert)");
1225 if (notification_ipc_is_master_ready() == 1) {
1226 return NOTIFICATION_ERROR_PERMISSION_DENIED;
1228 return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1232 if (priv_id != NULL) {
1236 return NOTIFICATION_ERROR_NONE;
1239 int notification_ipc_request_delete_single(notification_type_e type, char *pkgname, int priv_id)
1242 int id = NOTIFICATION_PRIV_ID_NONE;
1243 struct packet *packet;
1244 struct packet *result;
1246 packet = packet_create("del_noti_single", "si", pkgname, priv_id);
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, &id) != 2) {
1254 NOTIFICATION_ERR("Failed to get a result packet");
1255 packet_unref(result);
1256 return NOTIFICATION_ERROR_IO_ERROR;
1258 packet_unref(result);
1260 NOTIFICATION_ERR("failed to receive answer(delete)");
1261 if (notification_ipc_is_master_ready() == 1) {
1262 return NOTIFICATION_ERROR_PERMISSION_DENIED;
1264 return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1271 int notification_ipc_request_delete_multiple(notification_type_e type, char *pkgname)
1274 int num_deleted = 0;
1275 struct packet *packet;
1276 struct packet *result;
1278 packet = packet_create("del_noti_multiple", "si", pkgname, type);
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, &num_deleted) != 2) {
1286 NOTIFICATION_ERR("Failed to get a result packet");
1287 packet_unref(result);
1288 return NOTIFICATION_ERROR_IO_ERROR;
1290 NOTIFICATION_ERR("num deleted:%d", num_deleted);
1291 packet_unref(result);
1293 NOTIFICATION_ERR("failed to receive answer(delete multiple)");
1294 if (notification_ipc_is_master_ready() == 1) {
1295 return NOTIFICATION_ERROR_PERMISSION_DENIED;
1297 return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1304 int notification_ipc_request_update(notification_h noti)
1307 int id = NOTIFICATION_PRIV_ID_NONE;
1308 struct packet *packet;
1309 struct packet *result;
1311 packet = notification_ipc_make_packet_from_noti(noti, "update_noti", 1);
1312 result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1314 NOTIFICATION_IPC_TIMEOUT);
1315 packet_destroy(packet);
1317 if (result != NULL) {
1318 if (packet_get(result, "ii", &status, &id) != 2) {
1319 NOTIFICATION_ERR("Failed to get a result packet");
1320 packet_unref(result);
1321 return NOTIFICATION_ERROR_IO_ERROR;
1323 packet_unref(result);
1325 NOTIFICATION_ERR("failed to receive answer(update)");
1326 if (notification_ipc_is_master_ready() == 1) {
1327 return NOTIFICATION_ERROR_PERMISSION_DENIED;
1329 return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1336 static int _notification_ipc_update_cb(pid_t pid, int handle, const struct packet *packet, void *data)
1339 int id = NOTIFICATION_PRIV_ID_NONE;
1340 result_cb_item *cb_item = (result_cb_item *)data;
1342 if (cb_item == NULL) {
1343 NOTIFICATION_ERR("Failed to get a callback item");
1344 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1346 s_info.server_cl_fd_ref_cnt = (s_info.server_cl_fd_ref_cnt <= 1) ? 0 : s_info.server_cl_fd_ref_cnt - 1;
1347 if (s_info.server_cl_fd_ref_cnt <= 0) {
1348 NOTIFICATION_DBG("REFCNT: %d (fd: %d)", s_info.server_cl_fd_ref_cnt, s_info.server_cl_fd);
1349 int fd_temp = s_info.server_cl_fd;
1350 s_info.server_cl_fd = -1;
1351 com_core_packet_client_fini(fd_temp);
1352 NOTIFICATION_DBG("FD(%d) finalized", fd_temp);
1355 if (packet != NULL) {
1356 if (packet_get(packet, "ii", &status, &id) != 2) {
1357 NOTIFICATION_ERR("Failed to get a result packet");
1358 status = NOTIFICATION_ERROR_IO_ERROR;
1362 if (cb_item->result_cb != NULL) {
1363 cb_item->result_cb(id, status, cb_item->data);
1370 int notification_ipc_request_update_async(notification_h noti,
1371 void (*result_cb)(int priv_id, int result, void *data), void *user_data)
1373 int ret = NOTIFICATION_ERROR_NONE;
1375 struct packet *packet = NULL;
1376 result_cb_item *cb_item = NULL;
1378 packet = notification_ipc_make_packet_from_noti(noti, "update_noti", 1);
1379 if (packet == NULL) {
1380 ret = NOTIFICATION_ERROR_INVALID_PARAMETER;
1384 cb_item = calloc(1, sizeof(result_cb_item));
1385 if (cb_item == NULL) {
1386 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
1390 if (s_info.server_cl_fd < 0) {
1391 com_core_packet_use_thread(1);
1392 s_info.server_cl_fd = com_core_packet_client_init(s_info.socket_file, 0, NULL);
1393 if (s_info.server_cl_fd < 0) {
1394 NOTIFICATION_DBG("Failed to init client: %d", s_info.server_cl_fd);
1395 if (notification_ipc_is_master_ready() == 1) {
1396 ret = NOTIFICATION_ERROR_PERMISSION_DENIED;
1398 ret = NOTIFICATION_ERROR_SERVICE_NOT_READY;
1402 s_info.server_cl_fd_ref_cnt = 1;
1404 s_info.server_cl_fd_ref_cnt++;
1407 cb_item->result_cb = result_cb;
1408 cb_item->data = user_data;
1410 NOTIFICATION_INFO("Connection count:%d, fd:%d", s_info.server_cl_fd_ref_cnt, s_info.server_cl_fd);
1412 ret_con = com_core_packet_async_send(s_info.server_cl_fd, packet, 0.0f,
1413 _notification_ipc_update_cb, cb_item);
1415 NOTIFICATION_ERR("Failed to request update, %d\n", ret_con);
1416 s_info.server_cl_fd_ref_cnt = (s_info.server_cl_fd_ref_cnt <= 1) ? 0 : s_info.server_cl_fd_ref_cnt - 1;
1417 if (s_info.server_cl_fd_ref_cnt <= 0) {
1418 int fd_temp = s_info.server_cl_fd;
1419 s_info.server_cl_fd = -1;
1420 com_core_packet_client_fini(fd_temp);
1421 NOTIFICATION_INFO("FD(%d) finalized", fd_temp);
1423 ret = NOTIFICATION_ERROR_IO_ERROR;
1426 ret = NOTIFICATION_ERROR_NONE;
1431 if (cb_item) free(cb_item);
1432 NOTIFICATION_ERR("Err: %d\n", ret);
1435 if (packet) packet_destroy(packet);
1440 int notification_ipc_request_refresh(void)
1443 struct packet *packet;
1444 struct packet *result;
1446 packet = packet_create("refresh_noti", "i", NOTIFICATION_OP_REFRESH);
1447 result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1449 NOTIFICATION_IPC_TIMEOUT);
1450 packet_destroy(packet);
1452 if (result != NULL) {
1453 if (packet_get(result, "i", &status) != 1) {
1454 NOTIFICATION_ERR("Failed to get a result packet");
1455 packet_unref(result);
1456 return NOTIFICATION_ERROR_IO_ERROR;
1458 packet_unref(result);
1460 NOTIFICATION_ERR("failed to receive answer(refresh)");
1461 if (notification_ipc_is_master_ready() == 1) {
1462 return NOTIFICATION_ERROR_PERMISSION_DENIED;
1464 return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1472 int notification_ipc_update_setting(notification_setting_h setting)
1476 struct packet *packet;
1477 struct packet *result;
1479 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));
1480 result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1482 NOTIFICATION_IPC_TIMEOUT);
1483 packet_destroy(packet);
1485 if (result != NULL) {
1486 if (packet_get(result, "ii", &status, &ret) != 2) {
1487 NOTIFICATION_ERR("Failed to get a result packet");
1488 packet_unref(result);
1489 return NOTIFICATION_ERROR_IO_ERROR;
1491 packet_unref(result);
1493 NOTIFICATION_ERR("failed to receive answer(delete)");
1494 if (notification_ipc_is_master_ready() == 1) {
1495 return NOTIFICATION_ERROR_PERMISSION_DENIED;
1497 return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1504 int notification_ipc_update_system_setting(notification_system_setting_h system_setting)
1508 struct packet *packet = NULL;
1509 struct packet *result = NULL;
1511 packet = packet_create("update_noti_sys_setting", "ii", (int)(system_setting->do_not_disturb), (int)(system_setting->visibility_class));
1512 if (packet == NULL) {
1513 NOTIFICATION_ERR("packet_create failed.");
1516 result = com_core_packet_oneshot_send(NOTIFICATION_ADDR, packet, NOTIFICATION_IPC_TIMEOUT);
1517 packet_destroy(packet);
1519 if (result != NULL) {
1520 if (packet_get(result, "ii", &status, &ret) != 2) {
1521 NOTIFICATION_ERR("Failed to get a result packet");
1522 status = NOTIFICATION_ERROR_IO_ERROR;
1527 NOTIFICATION_ERR("failed to receive answer(delete)");
1528 if (notification_ipc_is_master_ready() == 1) {
1529 status = NOTIFICATION_ERROR_PERMISSION_DENIED;
1532 status = NOTIFICATION_ERROR_SERVICE_NOT_READY;
1538 packet_unref(result);
1544 int notification_ipc_noti_setting_property_set(const char *pkgname, const char *property, const char *value)
1548 struct packet *packet;
1549 struct packet *result;
1551 packet = packet_create("set_noti_property", "sss", pkgname, property, value);
1552 result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1554 NOTIFICATION_IPC_TIMEOUT);
1555 packet_destroy(packet);
1557 if (result != NULL) {
1558 if (packet_get(result, "ii", &status, &ret) != 2) {
1559 NOTIFICATION_ERR("Failed to get a result packet");
1560 packet_unref(result);
1561 return NOTIFICATION_ERROR_IO_ERROR;
1563 packet_unref(result);
1565 NOTIFICATION_ERR("failed to receive answer(delete)");
1566 if (notification_ipc_is_master_ready() == 1) {
1567 return NOTIFICATION_ERROR_PERMISSION_DENIED;
1569 return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1576 int notification_ipc_noti_setting_property_get(const char *pkgname, const char *property, char **value)
1580 struct packet *packet;
1581 struct packet *result;
1583 packet = packet_create("get_noti_property", "ss", pkgname, property);
1584 result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1586 NOTIFICATION_IPC_TIMEOUT);
1587 packet_destroy(packet);
1589 if (result != NULL) {
1590 if (packet_get(result, "is", &status, &ret) != 2) {
1591 NOTIFICATION_ERR("Failed to get a result packet");
1592 packet_unref(result);
1593 return NOTIFICATION_ERROR_IO_ERROR;
1595 if (status == NOTIFICATION_ERROR_NONE && ret != NULL) {
1596 *value = strdup(ret);
1598 packet_unref(result);
1600 NOTIFICATION_ERR("failed to receive answer(delete)");
1601 if (notification_ipc_is_master_ready() == 1) {
1602 return NOTIFICATION_ERROR_PERMISSION_DENIED;
1604 return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1611 int notification_ipc_request_load_noti_by_tag(notification_h noti, const char *pkgname, const char *tag)
1613 struct packet *packet;
1614 struct packet *result;
1616 packet = packet_create("load_noti_by_tag", "ss", pkgname, tag);
1617 result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1619 NOTIFICATION_IPC_TIMEOUT);
1620 packet_destroy(packet);
1622 if (result != NULL) {
1623 if (notification_ipc_make_noti_from_packet(noti, result) != NOTIFICATION_ERROR_NONE) {
1624 NOTIFICATION_ERR("Failed to get a result packet");
1625 packet_unref(result);
1626 return NOTIFICATION_ERROR_IO_ERROR;
1629 packet_unref(result);
1631 NOTIFICATION_ERR("failed to receive answer(load noti by tag)");
1632 if (notification_ipc_is_master_ready() == 1) {
1633 return NOTIFICATION_ERROR_PERMISSION_DENIED;
1635 return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1639 return NOTIFICATION_ERROR_NONE;