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) {
109 ret = vconf_notify_key_changed(VCONFKEY_MASTER_STARTED,
112 NOTIFICATION_ERR("failed to notify key(%s) : %d",
113 VCONFKEY_MASTER_STARTED, ret);
117 static inline void _unset_master_started_cb(vconf_callback_fn cb) {
120 ret = vconf_ignore_key_changed(VCONFKEY_MASTER_STARTED,
123 NOTIFICATION_ERR("failed to notify key(%s) : %d",
124 VCONFKEY_MASTER_STARTED, ret);
128 int notification_ipc_is_master_ready(void)
130 int ret = -1, is_master_started = 0;
132 ret = vconf_get_bool(VCONFKEY_MASTER_STARTED, &is_master_started);
133 if (ret == 0 && is_master_started == 1) {
134 NOTIFICATION_ERR("the master has been started");
136 is_master_started = 0;
137 NOTIFICATION_ERR("the master has been stopped");
140 return is_master_started;
144 notification_ipc_add_deffered_task(
145 void (*deferred_task_cb)(void *data),
148 task_list *list = NULL;
149 task_list *list_new = NULL;
152 (task_list *) malloc(sizeof(task_list));
154 if (list_new == NULL) {
155 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
158 if (s_info.is_started_cb_set_task == 0) {
159 _set_master_started_cb(_master_started_cb_task);
160 s_info.is_started_cb_set_task = 1;
163 list_new->next = NULL;
164 list_new->prev = NULL;
166 list_new->task_cb = deferred_task_cb;
167 list_new->data = user_data;
169 if (g_task_list == NULL) {
170 g_task_list = list_new;
174 while (list->next != NULL) {
178 list->next = list_new;
179 list_new->prev = list;
181 return NOTIFICATION_ERROR_NONE;
185 notification_ipc_del_deffered_task(
186 void (*deferred_task_cb)(void *data))
188 task_list *list_del = NULL;
189 task_list *list_prev = NULL;
190 task_list *list_next = NULL;
192 list_del = g_task_list;
194 if (list_del == NULL) {
195 return NOTIFICATION_ERROR_INVALID_PARAMETER;
198 while (list_del->prev != NULL) {
199 list_del = list_del->prev;
203 if (list_del->task_cb == deferred_task_cb) {
204 list_prev = list_del->prev;
205 list_next = list_del->next;
207 if (list_prev == NULL) {
208 g_task_list = list_next;
210 list_prev->next = list_next;
213 if (list_next == NULL) {
214 if (list_prev != NULL) {
215 list_prev->next = NULL;
218 list_next->prev = list_prev;
223 if (g_task_list == NULL) {
224 if (s_info.is_started_cb_set_task == 1) {
225 _unset_master_started_cb(_master_started_cb_task);
226 s_info.is_started_cb_set_task = 0;
230 return NOTIFICATION_ERROR_NONE;
232 list_del = list_del->next;
233 } while (list_del != NULL);
235 return NOTIFICATION_ERROR_INVALID_PARAMETER;
238 static void _do_deffered_task(void) {
239 task_list *list_do = NULL;
240 task_list *list_temp = NULL;
242 if (g_task_list == NULL) {
246 list_do = g_task_list;
248 if (s_info.is_started_cb_set_task == 1) {
249 _unset_master_started_cb(_master_started_cb_task);
250 s_info.is_started_cb_set_task = 0;
253 while (list_do->prev != NULL) {
254 list_do = list_do->prev;
257 while (list_do != NULL) {
258 if (list_do->task_cb != NULL) {
259 list_do->task_cb(list_do->data);
260 NOTIFICATION_DBG("called:%p", list_do->task_cb);
262 list_temp = list_do->next;
268 static void _master_started_cb_service(keynode_t *node,
270 int ret = NOTIFICATION_ERROR_NONE;
272 if (notification_ipc_is_master_ready()) {
273 NOTIFICATION_ERR("try to register a notification service");
274 ret = notification_ipc_monitor_deregister();
275 if (ret != NOTIFICATION_ERROR_NONE) {
276 NOTIFICATION_ERR("failed to unregister a monitor");
278 ret = notification_ipc_monitor_register();
279 if (ret != NOTIFICATION_ERROR_NONE) {
280 NOTIFICATION_ERR("failed to register a monitor");
283 NOTIFICATION_ERR("try to unregister a notification service");
284 ret = notification_ipc_monitor_deregister();
285 if (ret != NOTIFICATION_ERROR_NONE) {
286 NOTIFICATION_ERR("failed to deregister a monitor");
291 static void _master_started_cb_task(keynode_t *node,
294 if (notification_ipc_is_master_ready()) {
300 * functions to create operation list
302 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)
305 notification_op *op_list = NULL;
311 op_list = (notification_op *)malloc(sizeof(notification_op) * num_op);
313 if (op_list == NULL) {
314 NOTIFICATION_ERR("malloc failed");
318 memset(op_list, 0x0, sizeof(notification_op) * num_op);
320 for (i = 0; i < num_op; i++) {
321 (op_list + i)->type = type;
322 if (list_priv_id != NULL) {
323 (op_list + i)->priv_id = *(list_priv_id + i);
325 if (noti_list != NULL) {
326 (op_list + i)->noti = *(noti_list + i);
334 * utility functions creating notification packet
336 static inline char *_dup_string(const char *string)
340 if (string == NULL) {
343 if (string[0] == '\0') {
347 ret = strdup(string);
349 NOTIFICATION_ERR("Error: %s\n", strerror(errno));
354 static inline bundle *_create_bundle_from_string(unsigned char *string)
356 if (string == NULL) {
359 if (string[0] == '\0') {
363 return bundle_decode(string, strlen((char *)string));
367 * functions creating notification packet
369 EXPORT_API int notification_ipc_make_noti_from_packet(notification_h noti, const struct packet *packet)
376 int internal_group_id;
378 char *caller_pkgname = NULL;
379 char *launch_pkgname = NULL;
380 unsigned char *args = NULL;
381 unsigned char *group_args = NULL;
382 unsigned char *b_execute_option = NULL;
383 unsigned char *b_service_responding = NULL;
384 unsigned char *b_service_single_launch = NULL;
385 unsigned char *b_service_multi_launch = NULL;
386 unsigned char *b_event_handler[NOTIFICATION_EVENT_TYPE_MAX] = { NULL, };
389 unsigned char *b_text = NULL;
390 unsigned char *b_key = NULL;
391 unsigned char *b_format_args = NULL;
393 unsigned char *b_image_path = NULL;
395 char *sound_path = NULL;
397 char *vibration_path = NULL;
404 int flags_for_property;
406 double progress_size;
407 double progress_percentage;
408 char *app_icon_path = NULL;
409 char *app_name = NULL;
410 char *temp_title = NULL;
411 char *temp_content = NULL;
417 NOTIFICATION_ERR("invalid data");
418 return NOTIFICATION_ERROR_INVALID_PARAMETER;
421 ret = packet_get(packet,
422 "iiiiisssssssssssssssssssssisisisiiiiiiiiddsssssii",
433 &b_service_responding,
434 &b_service_single_launch,
435 &b_service_multi_launch,
436 &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_1],
437 &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_2],
438 &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_3],
439 &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_4],
440 &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_5],
441 &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_6],
442 &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_ICON],
443 &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_THUMBNAIL],
464 &progress_percentage,
474 NOTIFICATION_ERR("failed to create a noti from packet");
475 return NOTIFICATION_ERROR_INVALID_PARAMETER;
479 * This is already allocated from the notification_create function.
480 * Before reallocate string to here.
481 * We have to release old one first.
483 free(noti->caller_pkgname);
484 noti->caller_pkgname = _dup_string(caller_pkgname);
485 noti->launch_pkgname = _dup_string(launch_pkgname);
486 noti->args = _create_bundle_from_string(args);
487 noti->group_args = _create_bundle_from_string(group_args);
488 noti->b_execute_option = _create_bundle_from_string(b_execute_option);
489 noti->b_service_responding = _create_bundle_from_string(b_service_responding);
490 noti->b_service_single_launch = _create_bundle_from_string(b_service_single_launch);
491 noti->b_service_multi_launch = _create_bundle_from_string(b_service_multi_launch);
492 for (i = 0; i < NOTIFICATION_EVENT_TYPE_MAX; i++) {
493 noti->b_event_handler[i] = _create_bundle_from_string(b_event_handler[i]);
495 noti->domain = _dup_string(domain);
496 noti->dir = _dup_string(dir);
497 noti->b_text = _create_bundle_from_string(b_text);
498 noti->b_key = _create_bundle_from_string(b_key);
499 noti->b_format_args = _create_bundle_from_string(b_format_args);
500 noti->b_image_path = _create_bundle_from_string(b_image_path);
501 noti->sound_path = _dup_string(sound_path);
502 noti->vibration_path = _dup_string(vibration_path);
503 noti->app_icon_path = _dup_string(app_icon_path);
504 noti->app_name = _dup_string(app_name);
505 noti->temp_title = _dup_string(temp_title);
506 noti->temp_content = _dup_string(temp_content);
509 noti->layout = layout;
510 noti->group_id = group_id;
511 noti->internal_group_id = internal_group_id;
512 noti->priv_id = priv_id;
513 noti->num_format_args = num_format_args;
514 noti->sound_type = sound_type;
515 noti->vibration_type = vibration_type;
516 noti->led_operation = led_operation;
517 noti->led_argb = led_argb;
518 noti->led_on_ms = led_on_ms;
519 noti->led_off_ms = led_off_ms;
521 noti->insert_time = insert_time;
522 noti->flags_for_property = flags_for_property;
523 noti->display_applist = display_applist;
524 noti->progress_size = progress_size;
525 noti->progress_percentage = progress_percentage;
526 noti->tag = _dup_string(tag);
527 noti->ongoing_flag = ongoing_flag;
528 noti->auto_remove = auto_remove;
530 return NOTIFICATION_ERROR_NONE;
533 EXPORT_API struct packet *notification_ipc_make_packet_from_noti(notification_h noti, const char *command, int packet_type)
536 int b_encode_len = 0;
537 struct packet *result = NULL;
539 char *group_args = NULL;
540 char *b_image_path = NULL;
541 char *b_execute_option = NULL;
542 char *b_service_responding = NULL;
543 char *b_service_single_launch = NULL;
544 char *b_service_multi_launch = NULL;
545 char *b_event_handler[NOTIFICATION_EVENT_TYPE_MAX] = { NULL , };
548 char *b_format_args = NULL;
549 struct packet *(*func_to_create_packet)(const char *command, const char *fmt, ...);
550 char *title_key = NULL;
551 char buf_key[32] = { 0, };
553 /* Decode bundle to insert DB */
555 bundle_encode(noti->args, (bundle_raw **) & args, NULL);
557 if (noti->group_args) {
558 bundle_encode(noti->group_args, (bundle_raw **) & group_args,
562 if (noti->b_execute_option) {
563 bundle_encode(noti->b_execute_option,
564 (bundle_raw **) & b_execute_option, &b_encode_len);
566 if (noti->b_service_responding) {
567 bundle_encode(noti->b_service_responding,
568 (bundle_raw **) & b_service_responding, &b_encode_len);
570 if (noti->b_service_single_launch) {
571 bundle_encode(noti->b_service_single_launch,
572 (bundle_raw **) & b_service_single_launch, &b_encode_len);
574 if (noti->b_service_multi_launch) {
575 bundle_encode(noti->b_service_multi_launch,
576 (bundle_raw **) & b_service_multi_launch, &b_encode_len);
579 for (i = 0; i < NOTIFICATION_EVENT_TYPE_MAX; i++) {
580 if (noti->b_event_handler[i]) {
581 bundle_encode(noti->b_event_handler[i],
582 (bundle_raw **) & b_event_handler[i], &b_encode_len);
587 bundle_encode(noti->b_text, (bundle_raw **) & b_text, &b_encode_len);
590 bundle_encode(noti->b_key, (bundle_raw **) & b_key, &b_encode_len);
592 if (noti->b_format_args) {
593 bundle_encode(noti->b_format_args,
594 (bundle_raw **) & b_format_args, &b_encode_len);
597 if (noti->b_image_path) {
598 bundle_encode(noti->b_image_path,
599 (bundle_raw **) & b_image_path, &b_encode_len);
602 if (noti->b_key != NULL) {
603 snprintf(buf_key, sizeof(buf_key), "%d",
604 NOTIFICATION_TEXT_TYPE_TITLE);
606 bundle_get_str(noti->b_key, buf_key, &title_key);
609 if (title_key == NULL && noti->b_text != NULL) {
610 snprintf(buf_key, sizeof(buf_key), "%d",
611 NOTIFICATION_TEXT_TYPE_TITLE);
613 bundle_get_str(noti->b_text, buf_key, &title_key);
616 if (title_key == NULL) {
617 title_key = noti->caller_pkgname;
620 if (packet_type == 1)
621 func_to_create_packet = packet_create;
622 else if (packet_type == 2)
623 func_to_create_packet = packet_create_noack;
628 result = func_to_create_packet(command,
629 "iiiiisssssssssssssssssssssisisisiiiiiiiiddsssssii",
633 noti->internal_group_id,
635 NOTIFICATION_CHECK_STR(noti->caller_pkgname),
636 NOTIFICATION_CHECK_STR(noti->launch_pkgname),
637 NOTIFICATION_CHECK_STR(args),
638 NOTIFICATION_CHECK_STR(group_args),
639 NOTIFICATION_CHECK_STR(b_execute_option),
640 NOTIFICATION_CHECK_STR(b_service_responding),
641 NOTIFICATION_CHECK_STR(b_service_single_launch),
642 NOTIFICATION_CHECK_STR(b_service_multi_launch),
643 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_1]),
644 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_2]),
645 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_3]),
646 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_4]),
647 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_5]),
648 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_6]),
649 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_ICON]),
650 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_THUMBNAIL]),
651 NOTIFICATION_CHECK_STR(noti->domain),
652 NOTIFICATION_CHECK_STR(noti->dir),
653 NOTIFICATION_CHECK_STR(b_text),
654 NOTIFICATION_CHECK_STR(b_key),
655 NOTIFICATION_CHECK_STR(b_format_args),
656 noti->num_format_args,
657 NOTIFICATION_CHECK_STR(b_image_path),
659 NOTIFICATION_CHECK_STR(noti->sound_path),
660 noti->vibration_type,
661 NOTIFICATION_CHECK_STR(noti->vibration_path),
668 noti->flags_for_property,
669 noti->display_applist,
671 noti->progress_percentage,
672 NOTIFICATION_CHECK_STR(noti->app_icon_path),
673 NOTIFICATION_CHECK_STR(noti->app_name),
674 NOTIFICATION_CHECK_STR(noti->temp_title),
675 NOTIFICATION_CHECK_STR(noti->temp_content),
676 NOTIFICATION_CHECK_STR(noti->tag),
681 /* Free decoded data */
689 if (b_execute_option) {
690 free(b_execute_option);
692 if (b_service_responding) {
693 free(b_service_responding);
695 if (b_service_single_launch) {
696 free(b_service_single_launch);
698 if (b_service_multi_launch) {
699 free(b_service_multi_launch);
702 for (i = 0; i < NOTIFICATION_EVENT_TYPE_MAX; i++) {
703 if (b_event_handler[i]) {
704 free(b_event_handler[i]);
725 EXPORT_API struct packet *notification_ipc_make_reply_packet_from_noti(notification_h noti, struct packet *packet)
728 int b_encode_len = 0;
729 struct packet *result = NULL;
731 char *group_args = NULL;
732 char *b_image_path = NULL;
733 char *b_execute_option = NULL;
734 char *b_service_responding = NULL;
735 char *b_service_single_launch = NULL;
736 char *b_service_multi_launch = NULL;
737 char *b_event_handler[NOTIFICATION_EVENT_TYPE_MAX] = { NULL , };
740 char *b_format_args = NULL;
741 char *title_key = NULL;
742 char buf_key[32] = { 0, };
744 /* Decode bundle to insert DB */
746 bundle_encode(noti->args, (bundle_raw **) & args, &b_encode_len);
748 if (noti->group_args) {
749 bundle_encode(noti->group_args, (bundle_raw **) & group_args,
753 if (noti->b_execute_option) {
754 bundle_encode(noti->b_execute_option,
755 (bundle_raw **) & b_execute_option, &b_encode_len);
757 if (noti->b_service_responding) {
758 bundle_encode(noti->b_service_responding,
759 (bundle_raw **) & b_service_responding, &b_encode_len);
761 if (noti->b_service_single_launch) {
762 bundle_encode(noti->b_service_single_launch,
763 (bundle_raw **) & b_service_single_launch, &b_encode_len);
765 if (noti->b_service_multi_launch) {
766 bundle_encode(noti->b_service_multi_launch,
767 (bundle_raw **) & b_service_multi_launch, &b_encode_len);
770 for (i = 0; i < NOTIFICATION_EVENT_TYPE_MAX; i++) {
771 if (noti->b_event_handler[i]) {
772 bundle_encode(noti->b_event_handler[i],
773 (bundle_raw **) & b_event_handler[i], &b_encode_len);
778 bundle_encode(noti->b_text, (bundle_raw **) & b_text, &b_encode_len);
781 bundle_encode(noti->b_key, (bundle_raw **) & b_key, &b_encode_len);
783 if (noti->b_format_args) {
784 bundle_encode(noti->b_format_args,
785 (bundle_raw **) & b_format_args, &b_encode_len);
788 if (noti->b_image_path) {
789 bundle_encode(noti->b_image_path,
790 (bundle_raw **) & b_image_path, &b_encode_len);
793 if (noti->b_key != NULL) {
794 snprintf(buf_key, sizeof(buf_key), "%d",
795 NOTIFICATION_TEXT_TYPE_TITLE);
797 bundle_get_str(noti->b_key, buf_key, &title_key);
800 if (title_key == NULL && noti->b_text != NULL) {
801 snprintf(buf_key, sizeof(buf_key), "%d",
802 NOTIFICATION_TEXT_TYPE_TITLE);
804 bundle_get_str(noti->b_text, buf_key, &title_key);
807 if (title_key == NULL) {
808 title_key = noti->caller_pkgname;
811 result = packet_create_reply(packet,
812 "iiiiisssssssssssssssssssssisisisiiiiiiiiddsssssii",
816 noti->internal_group_id,
818 NOTIFICATION_CHECK_STR(noti->caller_pkgname),
819 NOTIFICATION_CHECK_STR(noti->launch_pkgname),
820 NOTIFICATION_CHECK_STR(args),
821 NOTIFICATION_CHECK_STR(group_args),
822 NOTIFICATION_CHECK_STR(b_execute_option),
823 NOTIFICATION_CHECK_STR(b_service_responding),
824 NOTIFICATION_CHECK_STR(b_service_single_launch),
825 NOTIFICATION_CHECK_STR(b_service_multi_launch),
826 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_1]),
827 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_2]),
828 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_3]),
829 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_4]),
830 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_5]),
831 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_6]),
832 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_ICON]),
833 NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_THUMBNAIL]),
834 NOTIFICATION_CHECK_STR(noti->domain),
835 NOTIFICATION_CHECK_STR(noti->dir),
836 NOTIFICATION_CHECK_STR(b_text),
837 NOTIFICATION_CHECK_STR(b_key),
838 NOTIFICATION_CHECK_STR(b_format_args),
839 noti->num_format_args,
840 NOTIFICATION_CHECK_STR(b_image_path),
842 NOTIFICATION_CHECK_STR(noti->sound_path),
843 noti->vibration_type,
844 NOTIFICATION_CHECK_STR(noti->vibration_path),
851 noti->flags_for_property,
852 noti->display_applist,
854 noti->progress_percentage,
855 NOTIFICATION_CHECK_STR(noti->app_icon_path),
856 NOTIFICATION_CHECK_STR(noti->app_name),
857 NOTIFICATION_CHECK_STR(noti->temp_title),
858 NOTIFICATION_CHECK_STR(noti->temp_content),
859 NOTIFICATION_CHECK_STR(noti->tag),
863 /* Free decoded data */
871 if (b_execute_option) {
872 free(b_execute_option);
874 if (b_service_responding) {
875 free(b_service_responding);
877 if (b_service_single_launch) {
878 free(b_service_single_launch);
880 if (b_service_multi_launch) {
881 free(b_service_multi_launch);
884 for (i = 0; i < NOTIFICATION_EVENT_TYPE_MAX; i++) {
885 if (b_event_handler[i]) {
886 free(b_event_handler[i]);
908 * functions to handler services
910 static struct packet *_handler_insert(pid_t pid, int handle, const struct packet *packet)
912 notification_h noti = NULL;
915 NOTIFICATION_ERR("a packet is null");
918 noti = notification_create(NOTIFICATION_TYPE_NOTI);
920 NOTIFICATION_ERR("failed to create a notification");
923 notification_ipc_make_noti_from_packet(noti, packet);
925 if (noti->flags_for_property
926 & NOTIFICATION_PROP_DISABLE_UPDATE_ON_INSERT) {
927 /* Disable changed cb */
929 /* Enable changed cb */
930 notification_op *noti_op = notification_ipc_create_op(NOTIFICATION_OP_INSERT, 1, &(noti->priv_id), 1, ¬i);
931 if (noti_op != NULL) {
932 notification_call_changed_cb(noti_op, 1);
936 notification_free(noti);
941 static struct packet *_handler_update(pid_t pid, int handle, const struct packet *packet)
943 notification_h noti = NULL;
946 NOTIFICATION_ERR("a packet is null");
950 noti = notification_create(NOTIFICATION_TYPE_NOTI);
952 NOTIFICATION_ERR("failed to create a notification");
956 notification_ipc_make_noti_from_packet(noti, packet);
958 notification_op *noti_op = notification_ipc_create_op(NOTIFICATION_OP_UPDATE, 1, &(noti->priv_id), 1, ¬i);
959 if (noti_op != NULL) {
960 notification_call_changed_cb(noti_op, 1);
964 notification_free(noti);
969 static struct packet *_handler_refresh(pid_t pid, int handle, const struct packet *packet)
972 NOTIFICATION_ERR("a packet is null");
975 notification_op *noti_op = notification_ipc_create_op(NOTIFICATION_OP_REFRESH, 1, NULL, 0, NULL);
976 if (noti_op != NULL) {
977 notification_call_changed_cb(noti_op, 1);
984 static struct packet *_handler_delete_single(pid_t pid, int handle, const struct packet *packet)
987 int priv_id = NOTIFICATION_PRIV_ID_NONE;
990 NOTIFICATION_ERR("a packet is null");
993 if (packet_get(packet, "ii", &num_deleted, &priv_id) == 2) {
994 notification_op *noti_op = notification_ipc_create_op(NOTIFICATION_OP_DELETE, 1, &priv_id, 1, NULL);
995 if (noti_op != NULL) {
996 notification_call_changed_cb(noti_op, 1);
1004 static struct packet *_handler_delete_multiple(pid_t pid, int handle, const struct packet *packet)
1008 int num_deleted = 0;
1010 NOTIFICATION_INFO("delete_noti_multiple");
1013 NOTIFICATION_ERR("a packet is null");
1016 ret = packet_get(packet, "iiiiiiiiiii", &num_deleted,
1028 NOTIFICATION_INFO("packet data count:%d", ret);
1029 NOTIFICATION_INFO("packet data num deleted:%d", num_deleted);
1032 for (i = 0 ; i < 10 ; i++) {
1033 NOTIFICATION_INFO("packet data[%d]:%d",i, buf[i]);
1037 notification_op *noti_op = notification_ipc_create_op(
1038 NOTIFICATION_OP_DELETE, num_deleted, buf, num_deleted, NULL);
1039 if (noti_op == NULL) {
1040 NOTIFICATION_ERR("notification_ipc_create_op failed");
1043 notification_call_changed_cb(noti_op, num_deleted);
1050 static int _handler_service_register(pid_t pid, int handle, const struct packet *packet, void *data)
1055 NOTIFICATION_ERR("Packet is not valid\n");
1056 ret = NOTIFICATION_ERROR_INVALID_PARAMETER;
1057 } else if (packet_get(packet, "i", &ret) != 1) {
1058 NOTIFICATION_ERR("Packet is not valid\n");
1059 ret = NOTIFICATION_ERROR_INVALID_PARAMETER;
1062 notification_op *noti_op = notification_ipc_create_op(NOTIFICATION_OP_SERVICE_READY, 1, NULL, 1, NULL);
1063 if (noti_op != NULL) {
1064 notification_call_changed_cb(noti_op, 1);
1073 * functions to initialize and register a monitor
1075 static int notification_ipc_monitor_register(void)
1078 struct packet *packet;
1079 static struct method service_table[] = {
1082 .handler = _handler_insert,
1085 .cmd = "update_noti",
1086 .handler = _handler_update,
1089 .cmd = "refresh_noti",
1090 .handler = _handler_refresh,
1093 .cmd = "del_noti_single",
1094 .handler = _handler_delete_single,
1097 .cmd = "del_noti_multiple",
1098 .handler = _handler_delete_multiple,
1106 if (s_info.initialized == 1) {
1107 return NOTIFICATION_ERROR_NONE;
1109 s_info.initialized = 1;
1112 NOTIFICATION_ERR("register a service\n");
1114 com_core_packet_use_thread(1);
1115 s_info.server_fd = com_core_packet_client_init(s_info.socket_file, 0, service_table);
1116 if (s_info.server_fd < 0) {
1117 NOTIFICATION_ERR("Failed to make a connection to the master\n");
1118 return NOTIFICATION_ERROR_IO_ERROR;
1121 packet = packet_create("service_register", "");
1123 NOTIFICATION_ERR("Failed to build a packet\n");
1124 com_core_packet_client_fini(s_info.server_fd);
1125 return NOTIFICATION_ERROR_IO_ERROR;
1128 ret = com_core_packet_async_send(s_info.server_fd, packet, 1.0, _handler_service_register, NULL);
1129 NOTIFICATION_DBG("Service register sent: %d\n", ret);
1130 packet_destroy(packet);
1132 com_core_packet_client_fini(s_info.server_fd);
1133 s_info.server_fd = NOTIFICATION_ERROR_INVALID_PARAMETER;
1134 ret = NOTIFICATION_ERROR_IO_ERROR;
1136 ret = NOTIFICATION_ERROR_NONE;
1139 NOTIFICATION_DBG("Server FD: %d\n", s_info.server_fd);
1143 int notification_ipc_monitor_deregister(void)
1145 if (s_info.initialized == 0) {
1146 return NOTIFICATION_ERROR_NONE;
1149 com_core_packet_client_fini(s_info.server_fd);
1150 s_info.server_fd = NOTIFICATION_ERROR_INVALID_PARAMETER;
1152 s_info.initialized = 0;
1154 return NOTIFICATION_ERROR_NONE;
1157 int notification_ipc_monitor_init(void)
1159 int ret = NOTIFICATION_ERROR_NONE;
1161 if (notification_ipc_is_master_ready()) {
1162 ret = notification_ipc_monitor_register();
1165 if (s_info.is_started_cb_set_svc == 0) {
1166 _set_master_started_cb(_master_started_cb_service);
1167 s_info.is_started_cb_set_svc = 1;
1173 int notification_ipc_monitor_fini(void)
1175 int ret = NOTIFICATION_ERROR_NONE;
1177 if (s_info.is_started_cb_set_svc == 1) {
1178 _unset_master_started_cb(_master_started_cb_service);
1179 s_info.is_started_cb_set_svc = 0;
1182 ret = notification_ipc_monitor_deregister();
1188 * functions to request the service
1190 int notification_ipc_request_insert(notification_h noti, int *priv_id)
1193 int id = NOTIFICATION_PRIV_ID_NONE;
1194 struct packet *packet;
1195 struct packet *result;
1197 /* Initialize private ID */
1198 noti->priv_id = NOTIFICATION_PRIV_ID_NONE;
1199 noti->group_id = NOTIFICATION_GROUP_ID_NONE;
1200 noti->internal_group_id = NOTIFICATION_GROUP_ID_NONE;
1202 packet = notification_ipc_make_packet_from_noti(noti, "add_noti", 1);
1203 result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1205 NOTIFICATION_IPC_TIMEOUT);
1206 packet_destroy(packet);
1208 if (result != NULL) {
1209 if (packet_get(result, "ii", &status, &id) != 2) {
1210 NOTIFICATION_ERR("Failed to get a result packet");
1211 packet_unref(result);
1212 return NOTIFICATION_ERROR_IO_ERROR;
1215 if (status != NOTIFICATION_ERROR_NONE) {
1216 packet_unref(result);
1219 packet_unref(result);
1221 NOTIFICATION_ERR("failed to receive answer(insert)");
1222 if (notification_ipc_is_master_ready() == 1) {
1223 return NOTIFICATION_ERROR_PERMISSION_DENIED;
1226 return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1230 if (priv_id != NULL) {
1234 return NOTIFICATION_ERROR_NONE;
1237 int notification_ipc_request_delete_single(notification_type_e type, char *pkgname, int priv_id)
1240 int id = NOTIFICATION_PRIV_ID_NONE;
1241 struct packet *packet;
1242 struct packet *result;
1244 packet = packet_create("del_noti_single", "si", pkgname, priv_id);
1245 result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1247 NOTIFICATION_IPC_TIMEOUT);
1248 packet_destroy(packet);
1250 if (result != NULL) {
1251 if (packet_get(result, "ii", &status, &id) != 2) {
1252 NOTIFICATION_ERR("Failed to get a result packet");
1253 packet_unref(result);
1254 return NOTIFICATION_ERROR_IO_ERROR;
1256 packet_unref(result);
1258 NOTIFICATION_ERR("failed to receive answer(delete)");
1259 if (notification_ipc_is_master_ready() == 1) {
1260 return NOTIFICATION_ERROR_PERMISSION_DENIED;
1263 return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1270 int notification_ipc_request_delete_multiple(notification_type_e type, char *pkgname)
1273 int num_deleted = 0;
1274 struct packet *packet;
1275 struct packet *result;
1277 packet = packet_create("del_noti_multiple", "si", pkgname, type);
1278 result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1280 NOTIFICATION_IPC_TIMEOUT);
1281 packet_destroy(packet);
1283 if (result != NULL) {
1284 if (packet_get(result, "ii", &status, &num_deleted) != 2) {
1285 NOTIFICATION_ERR("Failed to get a result packet");
1286 packet_unref(result);
1287 return NOTIFICATION_ERROR_IO_ERROR;
1289 NOTIFICATION_ERR("num deleted:%d", num_deleted);
1290 packet_unref(result);
1292 NOTIFICATION_ERR("failed to receive answer(delete multiple)");
1293 if (notification_ipc_is_master_ready() == 1) {
1294 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;
1330 return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1337 static int _notification_ipc_update_cb(pid_t pid, int handle, const struct packet *packet, void *data)
1340 int id = NOTIFICATION_PRIV_ID_NONE;
1341 result_cb_item *cb_item = (result_cb_item *)data;
1343 if (cb_item == NULL) {
1344 NOTIFICATION_ERR("Failed to get a callback item");
1345 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1347 s_info.server_cl_fd_ref_cnt = (s_info.server_cl_fd_ref_cnt <= 1) ? 0 : s_info.server_cl_fd_ref_cnt - 1;
1348 if (s_info.server_cl_fd_ref_cnt <= 0) {
1349 NOTIFICATION_DBG("REFCNT: %d (fd: %d)", s_info.server_cl_fd_ref_cnt, s_info.server_cl_fd);
1350 int fd_temp = s_info.server_cl_fd;
1351 s_info.server_cl_fd = -1;
1352 com_core_packet_client_fini(fd_temp);
1353 NOTIFICATION_DBG("FD(%d) finalized", fd_temp);
1356 if (packet != NULL) {
1357 if (packet_get(packet, "ii", &status, &id) != 2) {
1358 NOTIFICATION_ERR("Failed to get a result packet");
1359 status = NOTIFICATION_ERROR_IO_ERROR;
1363 if (cb_item->result_cb != NULL) {
1364 cb_item->result_cb(id, status, cb_item->data);
1371 int notification_ipc_request_update_async(notification_h noti,
1372 void (*result_cb)(int priv_id, int result, void *data), void *user_data)
1374 int ret = NOTIFICATION_ERROR_NONE;
1376 struct packet *packet = NULL;
1377 result_cb_item *cb_item = NULL;
1379 packet = notification_ipc_make_packet_from_noti(noti, "update_noti", 1);
1380 if (packet == NULL) {
1381 ret = NOTIFICATION_ERROR_INVALID_PARAMETER;
1385 cb_item = calloc(1, sizeof(result_cb_item));
1386 if (cb_item == NULL) {
1387 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
1391 if (s_info.server_cl_fd < 0) {
1392 com_core_packet_use_thread(1);
1393 s_info.server_cl_fd = com_core_packet_client_init(s_info.socket_file, 0, NULL);
1394 if (s_info.server_cl_fd < 0) {
1395 NOTIFICATION_DBG("Failed to init client: %d", s_info.server_cl_fd);
1396 if (notification_ipc_is_master_ready() == 1) {
1397 ret = NOTIFICATION_ERROR_PERMISSION_DENIED;
1400 ret = NOTIFICATION_ERROR_SERVICE_NOT_READY;
1404 s_info.server_cl_fd_ref_cnt = 1;
1406 s_info.server_cl_fd_ref_cnt++;
1409 cb_item->result_cb = result_cb;
1410 cb_item->data = user_data;
1412 NOTIFICATION_INFO("Connection count:%d, fd:%d", s_info.server_cl_fd_ref_cnt, s_info.server_cl_fd);
1414 ret_con = com_core_packet_async_send(s_info.server_cl_fd, packet, 0.0f,
1415 _notification_ipc_update_cb, cb_item);
1417 NOTIFICATION_ERR("Failed to request update, %d\n", ret_con);
1418 s_info.server_cl_fd_ref_cnt = (s_info.server_cl_fd_ref_cnt <= 1) ? 0 : s_info.server_cl_fd_ref_cnt - 1;
1419 if (s_info.server_cl_fd_ref_cnt <= 0) {
1420 int fd_temp = s_info.server_cl_fd;
1421 s_info.server_cl_fd = -1;
1422 com_core_packet_client_fini(fd_temp);
1423 NOTIFICATION_INFO("FD(%d) finalized", fd_temp);
1425 ret = NOTIFICATION_ERROR_IO_ERROR;
1428 ret = NOTIFICATION_ERROR_NONE;
1433 if (cb_item) free(cb_item);
1434 NOTIFICATION_ERR("Err: %d\n", ret);
1437 if (packet) packet_destroy(packet);
1442 int notification_ipc_request_refresh(void)
1445 struct packet *packet;
1446 struct packet *result;
1448 packet = packet_create("refresh_noti", "i", NOTIFICATION_OP_REFRESH);
1449 result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1451 NOTIFICATION_IPC_TIMEOUT);
1452 packet_destroy(packet);
1454 if (result != NULL) {
1455 if (packet_get(result, "i", &status) != 1) {
1456 NOTIFICATION_ERR("Failed to get a result packet");
1457 packet_unref(result);
1458 return NOTIFICATION_ERROR_IO_ERROR;
1460 packet_unref(result);
1462 NOTIFICATION_ERR("failed to receive answer(refresh)");
1463 if (notification_ipc_is_master_ready() == 1) {
1464 return NOTIFICATION_ERROR_PERMISSION_DENIED;
1467 return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1475 int notification_ipc_update_setting(notification_setting_h setting)
1479 struct packet *packet;
1480 struct packet *result;
1482 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));
1483 result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1485 NOTIFICATION_IPC_TIMEOUT);
1486 packet_destroy(packet);
1488 if (result != NULL) {
1489 if (packet_get(result, "ii", &status, &ret) != 2) {
1490 NOTIFICATION_ERR("Failed to get a result packet");
1491 packet_unref(result);
1492 return NOTIFICATION_ERROR_IO_ERROR;
1494 packet_unref(result);
1496 NOTIFICATION_ERR("failed to receive answer(delete)");
1497 if (notification_ipc_is_master_ready() == 1) {
1498 return NOTIFICATION_ERROR_PERMISSION_DENIED;
1501 return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1508 int notification_ipc_update_system_setting(notification_system_setting_h system_setting)
1512 struct packet *packet = NULL;
1513 struct packet *result = NULL;
1515 packet = packet_create("update_noti_sys_setting", "ii", (int)(system_setting->do_not_disturb), (int)(system_setting->visibility_class));
1516 if (packet == NULL) {
1517 NOTIFICATION_ERR("packet_create failed.");
1520 result = com_core_packet_oneshot_send(NOTIFICATION_ADDR, packet, NOTIFICATION_IPC_TIMEOUT);
1521 packet_destroy(packet);
1523 if (result != NULL) {
1524 if (packet_get(result, "ii", &status, &ret) != 2) {
1525 NOTIFICATION_ERR("Failed to get a result packet");
1526 status = NOTIFICATION_ERROR_IO_ERROR;
1531 NOTIFICATION_ERR("failed to receive answer(delete)");
1532 if (notification_ipc_is_master_ready() == 1) {
1533 status = NOTIFICATION_ERROR_PERMISSION_DENIED;
1537 status = NOTIFICATION_ERROR_SERVICE_NOT_READY;
1543 packet_unref(result);
1549 int notification_ipc_noti_setting_property_set(const char *pkgname, const char *property, const char *value)
1553 struct packet *packet;
1554 struct packet *result;
1556 packet = packet_create("set_noti_property", "sss", pkgname, property, value);
1557 result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1559 NOTIFICATION_IPC_TIMEOUT);
1560 packet_destroy(packet);
1562 if (result != NULL) {
1563 if (packet_get(result, "ii", &status, &ret) != 2) {
1564 NOTIFICATION_ERR("Failed to get a result packet");
1565 packet_unref(result);
1566 return NOTIFICATION_ERROR_IO_ERROR;
1568 packet_unref(result);
1570 NOTIFICATION_ERR("failed to receive answer(delete)");
1571 if (notification_ipc_is_master_ready() == 1) {
1572 return NOTIFICATION_ERROR_PERMISSION_DENIED;
1575 return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1582 int notification_ipc_noti_setting_property_get(const char *pkgname, const char *property, char **value)
1586 struct packet *packet;
1587 struct packet *result;
1589 packet = packet_create("get_noti_property", "ss", pkgname, property);
1590 result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1592 NOTIFICATION_IPC_TIMEOUT);
1593 packet_destroy(packet);
1595 if (result != NULL) {
1596 if (packet_get(result, "is", &status, &ret) != 2) {
1597 NOTIFICATION_ERR("Failed to get a result packet");
1598 packet_unref(result);
1599 return NOTIFICATION_ERROR_IO_ERROR;
1601 if (status == NOTIFICATION_ERROR_NONE && ret != NULL) {
1602 *value = strdup(ret);
1604 packet_unref(result);
1606 NOTIFICATION_ERR("failed to receive answer(delete)");
1607 if (notification_ipc_is_master_ready() == 1) {
1608 return NOTIFICATION_ERROR_PERMISSION_DENIED;
1611 return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1618 int notification_ipc_request_load_noti_by_tag(notification_h noti, const char *pkgname, const char *tag)
1620 struct packet *packet;
1621 struct packet *result;
1623 packet = packet_create("load_noti_by_tag", "ss", pkgname, tag);
1624 result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1626 NOTIFICATION_IPC_TIMEOUT);
1627 packet_destroy(packet);
1629 if (result != NULL) {
1630 if (notification_ipc_make_noti_from_packet(noti, result) != NOTIFICATION_ERROR_NONE) {
1631 NOTIFICATION_ERR("Failed to get a result packet");
1632 packet_unref(result);
1633 return NOTIFICATION_ERROR_IO_ERROR;
1636 packet_unref(result);
1638 NOTIFICATION_ERR("failed to receive answer(load noti by tag)");
1639 if (notification_ipc_is_master_ready() == 1) {
1640 return NOTIFICATION_ERROR_PERMISSION_DENIED;
1643 return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1647 return NOTIFICATION_ERROR_NONE;