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_internal.h>
37 #include <notification_debug.h>
39 #define NOTIFICATION_IPC_TIMEOUT 0.0
41 #if !defined(VCONFKEY_MASTER_STARTED)
42 #define VCONFKEY_MASTER_STARTED "memory/data-provider-master/started"
48 int server_cl_fd_ref_cnt;
50 const char *socket_file;
52 int (*request_cb)(const char *appid, const char *name, int type, const char *content, const char *icon, pid_t pid, double period, int allow_duplicate, void *data);
56 int is_started_cb_set_svc;
57 int is_started_cb_set_task;
61 .server_cl_fd_ref_cnt = 0,
63 .socket_file = NOTIFICATION_ADDR,
65 .is_started_cb_set_svc = 0,
66 .is_started_cb_set_task = 0,
69 typedef struct _task_list task_list;
74 void (*task_cb) (void *data);
78 typedef struct _result_cb_item {
79 void (*result_cb)(int priv_id, int result, void *data);
83 static task_list *g_task_list;
85 static notification_error_e notification_ipc_monitor_register(void);
86 static notification_error_e notification_ipc_monitor_deregister(void);
87 static void _do_deffered_task(void);
88 static void _master_started_cb_task(keynode_t *node, void *data);
91 * functions to check state of master
93 static inline void _set_master_started_cb(vconf_callback_fn cb) {
96 ret = vconf_notify_key_changed(VCONFKEY_MASTER_STARTED,
99 NOTIFICATION_ERR("failed to notify key(%s) : %d",
100 VCONFKEY_MASTER_STARTED, ret);
104 static inline void _unset_master_started_cb(vconf_callback_fn cb) {
107 ret = vconf_ignore_key_changed(VCONFKEY_MASTER_STARTED,
110 NOTIFICATION_ERR("failed to notify key(%s) : %d",
111 VCONFKEY_MASTER_STARTED, ret);
115 int notification_ipc_is_master_ready(void)
117 int ret = -1, is_master_started = 0;
119 ret = vconf_get_bool(VCONFKEY_MASTER_STARTED, &is_master_started);
120 if (ret == 0 && is_master_started == 1) {
121 NOTIFICATION_ERR("the master has been started");
123 is_master_started = 0;
124 NOTIFICATION_ERR("the master has been stopped");
127 return is_master_started;
131 notification_ipc_add_deffered_task(
132 void (*deffered_task_cb)(void *data),
135 task_list *list = NULL;
136 task_list *list_new = NULL;
139 (task_list *) malloc(sizeof(task_list));
141 if (list_new == NULL) {
142 return NOTIFICATION_ERROR_NO_MEMORY;
145 if (s_info.is_started_cb_set_task == 0) {
146 _set_master_started_cb(_master_started_cb_task);
147 s_info.is_started_cb_set_task = 1;
150 list_new->next = NULL;
151 list_new->prev = NULL;
153 list_new->task_cb = deffered_task_cb;
154 list_new->data = user_data;
156 if (g_task_list == NULL) {
157 g_task_list = list_new;
161 while (list->next != NULL) {
165 list->next = list_new;
166 list_new->prev = list;
168 return NOTIFICATION_ERROR_NONE;
172 notification_ipc_del_deffered_task(
173 void (*deffered_task_cb)(void *data))
175 task_list *list_del = NULL;
176 task_list *list_prev = NULL;
177 task_list *list_next = NULL;
179 list_del = g_task_list;
181 if (list_del == NULL) {
182 return NOTIFICATION_ERROR_INVALID_DATA;
185 while (list_del->prev != NULL) {
186 list_del = list_del->prev;
190 if (list_del->task_cb == deffered_task_cb) {
191 list_prev = list_del->prev;
192 list_next = list_del->next;
194 if (list_prev == NULL) {
195 g_task_list = list_next;
197 list_prev->next = list_next;
200 if (list_next == NULL) {
201 if (list_prev != NULL) {
202 list_prev->next = NULL;
205 list_next->prev = list_prev;
210 if (g_task_list == NULL) {
211 if (s_info.is_started_cb_set_task == 1) {
212 _unset_master_started_cb(_master_started_cb_task);
213 s_info.is_started_cb_set_task = 0;
217 return NOTIFICATION_ERROR_NONE;
219 list_del = list_del->next;
220 } while (list_del != NULL);
222 return NOTIFICATION_ERROR_INVALID_DATA;
225 static void _do_deffered_task(void) {
226 task_list *list_do = NULL;
227 task_list *list_temp = NULL;
229 if (g_task_list == NULL) {
233 list_do = g_task_list;
235 if (s_info.is_started_cb_set_task == 1) {
236 _unset_master_started_cb(_master_started_cb_task);
237 s_info.is_started_cb_set_task = 0;
240 while (list_do->prev != NULL) {
241 list_do = list_do->prev;
244 while (list_do != NULL) {
245 if (list_do->task_cb != NULL) {
246 list_do->task_cb(list_do->data);
247 NOTIFICATION_DBG("called:%p", list_do->task_cb);
249 list_temp = list_do->next;
255 static void _master_started_cb_service(keynode_t *node,
257 int ret = NOTIFICATION_ERROR_NONE;
259 if (notification_ipc_is_master_ready()) {
260 ret = notification_ipc_monitor_register();
261 if (ret != NOTIFICATION_ERROR_NONE) {
262 NOTIFICATION_ERR("failed to register a monitor");
265 ret = notification_ipc_monitor_deregister();
266 if (ret != NOTIFICATION_ERROR_NONE) {
267 NOTIFICATION_ERR("failed to deregister a monitor");
272 static void _master_started_cb_task(keynode_t *node,
275 if (notification_ipc_is_master_ready()) {
281 * functions to create operation list
283 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)
286 notification_op *op_list = NULL;
292 op_list = (notification_op *)malloc(sizeof(notification_op) * num_op);
293 memset(op_list, 0x0, sizeof(notification_op) * num_op);
295 for (i = 0; i < num_op; i++) {
296 (op_list + i)->type = type;
297 if (list_priv_id != NULL) {
298 (op_list + i)->priv_id = *(list_priv_id + i);
300 if (noti_list != NULL) {
301 (op_list + i)->noti = *(noti_list + i);
309 * utility functions creating notification packet
311 static inline char *_dup_string(const char *string)
315 if (string == NULL) {
318 if (string[0] == '\0') {
322 ret = strdup(string);
324 NOTIFICATION_ERR("Error: %s\n", strerror(errno));
329 static inline bundle *_create_bundle_from_string(unsigned char *string)
331 if (string == NULL) {
334 if (string[0] == '\0') {
338 return bundle_decode(string, strlen((char *)string));
342 * functions creating notification packet
344 EXPORT_API notification_error_e notification_ipc_make_noti_from_packet(notification_h noti, const struct packet *packet)
350 int internal_group_id;
352 char *caller_pkgname = NULL;
353 char *launch_pkgname = NULL;
354 unsigned char *args = NULL;
355 unsigned char *group_args = NULL;
356 unsigned char *b_execute_option = NULL;
357 unsigned char *b_service_responding = NULL;
358 unsigned char *b_service_single_launch = NULL;
359 unsigned char *b_service_multi_launch = NULL;
362 unsigned char *b_text = NULL;
363 unsigned char *b_key = NULL;
364 unsigned char *b_format_args = NULL;
366 unsigned char *b_image_path = NULL;
368 char *sound_path = NULL;
370 char *vibration_path = NULL;
377 int flags_for_property;
379 double progress_size;
380 double progress_percentage;
381 char *app_icon_path = NULL;
382 char *app_name = NULL;
383 char *temp_title = NULL;
384 char *temp_content = NULL;
387 NOTIFICATION_ERR("invalid data");
388 return NOTIFICATION_ERROR_INVALID_DATA;
391 ret = packet_get(packet,
392 "iiiiisssssssssssssisisisiiiiiiiiddssss",
403 &b_service_responding,
404 &b_service_single_launch,
405 &b_service_multi_launch,
426 &progress_percentage,
433 NOTIFICATION_ERR("failed to create a noti from packet");
434 return NOTIFICATION_ERROR_INVALID_DATA;
438 * This is already allocated from the notification_create function.
439 * Before reallocate string to here.
440 * We have to release old one first.
442 free(noti->caller_pkgname);
443 noti->caller_pkgname = _dup_string(caller_pkgname);
444 noti->launch_pkgname = _dup_string(launch_pkgname);
445 noti->args = _create_bundle_from_string(args);
446 noti->group_args = _create_bundle_from_string(group_args);
447 noti->b_execute_option = _create_bundle_from_string(b_execute_option);
448 noti->b_service_responding = _create_bundle_from_string(b_service_responding);
449 noti->b_service_single_launch = _create_bundle_from_string(b_service_single_launch);
450 noti->b_service_multi_launch = _create_bundle_from_string(b_service_multi_launch);
451 noti->domain = _dup_string(domain);
452 noti->dir = _dup_string(dir);
453 noti->b_text = _create_bundle_from_string(b_text);
454 noti->b_key = _create_bundle_from_string(b_key);
455 noti->b_format_args = _create_bundle_from_string(b_format_args);
456 noti->b_image_path = _create_bundle_from_string(b_image_path);
457 noti->sound_path = _dup_string(sound_path);
458 noti->vibration_path = _dup_string(vibration_path);
459 noti->app_icon_path = _dup_string(app_icon_path);
460 noti->app_name = _dup_string(app_name);
461 noti->temp_title = _dup_string(temp_title);
462 noti->temp_content = _dup_string(temp_content);
465 noti->layout = layout;
466 noti->group_id = group_id;
467 noti->internal_group_id = internal_group_id;
468 noti->priv_id = priv_id;
469 noti->num_format_args = num_format_args;
470 noti->sound_type = sound_type;
471 noti->vibration_type = vibration_type;
472 noti->led_operation = led_operation;
473 noti->led_argb = led_argb;
474 noti->led_on_ms = led_on_ms;
475 noti->led_off_ms = led_off_ms;
477 noti->insert_time = insert_time;
478 noti->flags_for_property = flags_for_property;
479 noti->display_applist = display_applist;
480 noti->progress_size = progress_size;
481 noti->progress_percentage = progress_percentage;
483 return NOTIFICATION_ERROR_NONE;
486 EXPORT_API struct packet *notification_ipc_make_packet_from_noti(notification_h noti, const char *command, int packet_type)
488 struct packet *result = NULL;
490 char *group_args = NULL;
491 char *b_image_path = NULL;
492 char *b_execute_option = NULL;
493 char *b_service_responding = NULL;
494 char *b_service_single_launch = NULL;
495 char *b_service_multi_launch = NULL;
498 char *b_format_args = NULL;
499 int flag_simmode = 0;
500 struct packet *(*func_to_create_packet)(const char *command, const char *fmt, ...);
501 const char *title_key = NULL;
502 char buf_key[32] = { 0, };
504 /* Decode bundle to insert DB */
506 bundle_encode(noti->args, (bundle_raw **) & args, NULL);
508 if (noti->group_args) {
509 bundle_encode(noti->group_args, (bundle_raw **) & group_args,
513 if (noti->b_execute_option) {
514 bundle_encode(noti->b_execute_option,
515 (bundle_raw **) & b_execute_option, NULL);
517 if (noti->b_service_responding) {
518 bundle_encode(noti->b_service_responding,
519 (bundle_raw **) & b_service_responding, NULL);
521 if (noti->b_service_single_launch) {
522 bundle_encode(noti->b_service_single_launch,
523 (bundle_raw **) & b_service_single_launch, NULL);
525 if (noti->b_service_multi_launch) {
526 bundle_encode(noti->b_service_multi_launch,
527 (bundle_raw **) & b_service_multi_launch, NULL);
531 bundle_encode(noti->b_text, (bundle_raw **) & b_text, NULL);
534 bundle_encode(noti->b_key, (bundle_raw **) & b_key, NULL);
536 if (noti->b_format_args) {
537 bundle_encode(noti->b_format_args,
538 (bundle_raw **) & b_format_args, NULL);
541 if (noti->b_image_path) {
542 bundle_encode(noti->b_image_path,
543 (bundle_raw **) & b_image_path, NULL);
546 /* Check only simmode property is enable */
547 if (noti->flags_for_property & NOTIFICATION_PROP_DISPLAY_ONLY_SIMMODE) {
551 if (noti->b_key != NULL) {
552 snprintf(buf_key, sizeof(buf_key), "%d",
553 NOTIFICATION_TEXT_TYPE_TITLE);
555 title_key = bundle_get_val(noti->b_key, buf_key);
558 if (title_key == NULL && noti->b_text != NULL) {
559 snprintf(buf_key, sizeof(buf_key), "%d",
560 NOTIFICATION_TEXT_TYPE_TITLE);
562 title_key = bundle_get_val(noti->b_text, buf_key);
565 if (title_key == NULL) {
566 title_key = noti->caller_pkgname;
569 if (packet_type == 1)
570 func_to_create_packet = packet_create;
571 else if (packet_type == 2)
572 func_to_create_packet = packet_create_noack;
577 result = func_to_create_packet(command,
578 "iiiiisssssssssssssisisisiiiiiiiiddssss",
582 noti->internal_group_id,
584 NOTIFICATION_CHECK_STR(noti->caller_pkgname),
585 NOTIFICATION_CHECK_STR(noti->launch_pkgname),
586 NOTIFICATION_CHECK_STR(args),
587 NOTIFICATION_CHECK_STR(group_args),
588 NOTIFICATION_CHECK_STR(b_execute_option),
589 NOTIFICATION_CHECK_STR(b_service_responding),
590 NOTIFICATION_CHECK_STR(b_service_single_launch),
591 NOTIFICATION_CHECK_STR(b_service_multi_launch),
592 NOTIFICATION_CHECK_STR(noti->domain),
593 NOTIFICATION_CHECK_STR(noti->dir),
594 NOTIFICATION_CHECK_STR(b_text),
595 NOTIFICATION_CHECK_STR(b_key),
596 NOTIFICATION_CHECK_STR(b_format_args),
597 noti->num_format_args,
598 NOTIFICATION_CHECK_STR(b_image_path),
600 NOTIFICATION_CHECK_STR(noti->sound_path),
601 noti->vibration_type,
602 NOTIFICATION_CHECK_STR(noti->vibration_path),
609 noti->flags_for_property,
610 noti->display_applist,
612 noti->progress_percentage,
613 NOTIFICATION_CHECK_STR(noti->app_icon_path),
614 NOTIFICATION_CHECK_STR(noti->app_name),
615 NOTIFICATION_CHECK_STR(noti->temp_title),
616 NOTIFICATION_CHECK_STR(noti->temp_content));
619 /* Free decoded data */
627 if (b_execute_option) {
628 free(b_execute_option);
630 if (b_service_responding) {
631 free(b_service_responding);
633 if (b_service_single_launch) {
634 free(b_service_single_launch);
636 if (b_service_multi_launch) {
637 free(b_service_multi_launch);
658 * functions to handler services
660 static struct packet *_handler_insert(pid_t pid, int handle, const struct packet *packet)
662 notification_h noti = NULL;
665 NOTIFICATION_ERR("a packet is null");
668 noti = notification_create(NOTIFICATION_TYPE_NOTI);
670 NOTIFICATION_ERR("failed to create a notification");
673 notification_ipc_make_noti_from_packet(noti, packet);
675 if (noti->flags_for_property
676 & NOTIFICATION_PROP_DISABLE_UPDATE_ON_INSERT) {
677 /* Disable changed cb */
679 /* Enable changed cb */
680 notification_op *noti_op = notification_ipc_create_op(NOTIFICATION_OP_INSERT, 1, &(noti->priv_id), 1, ¬i);
681 if (noti_op != NULL) {
682 notification_call_changed_cb(noti_op, 1);
686 notification_free(noti);
691 static struct packet *_handler_update(pid_t pid, int handle, const struct packet *packet)
693 notification_h noti = NULL;
696 NOTIFICATION_ERR("a packet is null");
700 noti = notification_create(NOTIFICATION_TYPE_NOTI);
702 NOTIFICATION_ERR("failed to create a notification");
706 notification_ipc_make_noti_from_packet(noti, packet);
708 notification_op *noti_op = notification_ipc_create_op(NOTIFICATION_OP_UPDATE, 1, &(noti->priv_id), 1, ¬i);
709 if (noti_op != NULL) {
710 notification_call_changed_cb(noti_op, 1);
714 notification_free(noti);
719 static struct packet *_handler_refresh(pid_t pid, int handle, const struct packet *packet)
722 NOTIFICATION_ERR("a packet is null");
725 notification_op *noti_op = notification_ipc_create_op(NOTIFICATION_OP_REFRESH, 1, NULL, 0, NULL);
726 if (noti_op != NULL) {
727 notification_call_changed_cb(noti_op, 1);
734 static struct packet *_handler_delete_single(pid_t pid, int handle, const struct packet *packet)
737 int priv_id = NOTIFICATION_PRIV_ID_NONE;
740 NOTIFICATION_ERR("a packet is null");
743 if (packet_get(packet, "ii", &num_deleted, &priv_id) == 2) {
744 notification_op *noti_op = notification_ipc_create_op(NOTIFICATION_OP_DELETE, 1, &priv_id, 1, NULL);
745 if (noti_op != NULL) {
746 notification_call_changed_cb(noti_op, 1);
754 static struct packet *_handler_delete_multiple(pid_t pid, int handle, const struct packet *packet)
760 NOTIFICATION_ERR("delete_noti_multiple");
763 NOTIFICATION_ERR("a packet is null");
766 ret = packet_get(packet, "iiiiiiiiiii", &num_deleted,
778 NOTIFICATION_ERR("packet data count:%d", ret);
779 NOTIFICATION_ERR("packet data num deleted:%d", num_deleted);
782 for (i = 0 ; i < 10 ; i++) {
783 NOTIFICATION_ERR("packet data[%d]:%d",i, buf[i]);
787 notification_op *noti_op = notification_ipc_create_op(
788 NOTIFICATION_OP_DELETE, num_deleted, buf, num_deleted, NULL);
789 if (noti_op != NULL) {
790 notification_call_changed_cb(noti_op, num_deleted);
798 static int _handler_service_register(pid_t pid, int handle, const struct packet *packet, void *data)
803 NOTIFICATION_ERR("Packet is not valid\n");
804 ret = NOTIFICATION_ERROR_INVALID_DATA;
805 } else if (packet_get(packet, "i", &ret) != 1) {
806 NOTIFICATION_ERR("Packet is not valid\n");
807 ret = NOTIFICATION_ERROR_INVALID_DATA;
810 notification_op *noti_op = notification_ipc_create_op(NOTIFICATION_OP_SERVICE_READY, 1, NULL, 1, NULL);
811 if (noti_op != NULL) {
812 notification_call_changed_cb(noti_op, 1);
821 * functions to initialize and register a monitor
823 static notification_error_e notification_ipc_monitor_register(void)
826 struct packet *packet;
827 static struct method service_table[] = {
830 .handler = _handler_insert,
833 .cmd = "update_noti",
834 .handler = _handler_update,
837 .cmd = "refresh_noti",
838 .handler = _handler_refresh,
841 .cmd = "del_noti_single",
842 .handler = _handler_delete_single,
845 .cmd = "del_noti_multiple",
846 .handler = _handler_delete_multiple,
854 if (s_info.initialized == 1) {
855 return NOTIFICATION_ERROR_NONE;
857 s_info.initialized = 1;
860 NOTIFICATION_ERR("register a service\n");
862 s_info.server_fd = com_core_packet_client_init(s_info.socket_file, 0, service_table);
863 if (s_info.server_fd < 0) {
864 NOTIFICATION_ERR("Failed to make a connection to the master\n");
865 return NOTIFICATION_ERROR_IO;
868 packet = packet_create("service_register", "");
870 NOTIFICATION_ERR("Failed to build a packet\n");
871 return NOTIFICATION_ERROR_IO;
874 ret = com_core_packet_async_send(s_info.server_fd, packet, 1.0, _handler_service_register, NULL);
875 NOTIFICATION_DBG("Service register sent: %d\n", ret);
876 packet_destroy(packet);
878 com_core_packet_client_fini(s_info.server_fd);
879 s_info.server_fd = NOTIFICATION_ERROR_INVALID_DATA;
880 ret = NOTIFICATION_ERROR_IO;
882 ret = NOTIFICATION_ERROR_NONE;
885 NOTIFICATION_DBG("Server FD: %d\n", s_info.server_fd);
889 notification_error_e notification_ipc_monitor_deregister(void)
891 if (s_info.initialized == 0) {
892 return NOTIFICATION_ERROR_NONE;
895 com_core_packet_client_fini(s_info.server_fd);
896 s_info.server_fd = NOTIFICATION_ERROR_INVALID_DATA;
898 s_info.initialized = 0;
900 return NOTIFICATION_ERROR_NONE;
903 notification_error_e notification_ipc_monitor_init(void)
905 int ret = NOTIFICATION_ERROR_NONE;
907 if (notification_ipc_is_master_ready()) {
908 ret = notification_ipc_monitor_register();
911 if (s_info.is_started_cb_set_svc == 0) {
912 _set_master_started_cb(_master_started_cb_service);
913 s_info.is_started_cb_set_svc = 1;
919 notification_error_e notification_ipc_monitor_fini(void)
921 int ret = NOTIFICATION_ERROR_NONE;
923 if (s_info.is_started_cb_set_svc == 1) {
924 _unset_master_started_cb(_master_started_cb_service);
925 s_info.is_started_cb_set_svc = 0;
928 ret = notification_ipc_monitor_deregister();
934 * functions to request the service
936 notification_error_e notification_ipc_request_insert(notification_h noti, int *priv_id)
939 int id = NOTIFICATION_PRIV_ID_NONE;
940 struct packet *packet;
941 struct packet *result;
943 /* Initialize private ID */
944 noti->priv_id = NOTIFICATION_PRIV_ID_NONE;
945 noti->group_id = NOTIFICATION_GROUP_ID_NONE;
946 noti->internal_group_id = NOTIFICATION_GROUP_ID_NONE;
948 packet = notification_ipc_make_packet_from_noti(noti, "add_noti", 1);
949 result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
951 NOTIFICATION_IPC_TIMEOUT);
952 packet_destroy(packet);
954 if (result != NULL) {
955 if (packet_get(result, "ii", &status, &id) != 2) {
956 NOTIFICATION_ERR("Failed to get a result packet");
957 packet_unref(result);
958 return NOTIFICATION_ERROR_IO;
961 if (status != NOTIFICATION_ERROR_NONE) {
962 packet_unref(result);
965 packet_unref(result);
967 NOTIFICATION_ERR("failed to receive answer(insert)");
968 return NOTIFICATION_ERROR_SERVICE_NOT_READY;
971 if (priv_id != NULL) {
975 return NOTIFICATION_ERROR_NONE;
978 notification_error_e notification_ipc_request_delete_single(notification_type_e type, char *pkgname, int priv_id)
981 int id = NOTIFICATION_PRIV_ID_NONE;
982 struct packet *packet;
983 struct packet *result;
985 packet = packet_create("del_noti_single", "si", pkgname, priv_id);
986 result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
988 NOTIFICATION_IPC_TIMEOUT);
989 packet_destroy(packet);
991 if (result != NULL) {
992 if (packet_get(result, "ii", &status, &id) != 2) {
993 NOTIFICATION_ERR("Failed to get a result packet");
994 packet_unref(result);
995 return NOTIFICATION_ERROR_IO;
997 packet_unref(result);
999 NOTIFICATION_ERR("failed to receive answer(delete)");
1000 return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1006 notification_error_e notification_ipc_request_delete_multiple(notification_type_e type, char *pkgname)
1009 int num_deleted = 0;
1010 struct packet *packet;
1011 struct packet *result;
1013 packet = packet_create("del_noti_multiple", "si", pkgname, type);
1014 result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1016 NOTIFICATION_IPC_TIMEOUT);
1017 packet_destroy(packet);
1019 if (result != NULL) {
1020 if (packet_get(result, "ii", &status, &num_deleted) != 2) {
1021 NOTIFICATION_ERR("Failed to get a result packet");
1022 packet_unref(result);
1023 return NOTIFICATION_ERROR_IO;
1025 NOTIFICATION_ERR("num deleted:%d", num_deleted);
1026 packet_unref(result);
1028 NOTIFICATION_ERR("failed to receive answer(delete multiple)");
1029 return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1035 notification_error_e notification_ipc_request_update(notification_h noti)
1038 int id = NOTIFICATION_PRIV_ID_NONE;
1039 struct packet *packet;
1040 struct packet *result;
1042 packet = notification_ipc_make_packet_from_noti(noti, "update_noti", 1);
1043 result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1045 NOTIFICATION_IPC_TIMEOUT);
1046 packet_destroy(packet);
1048 if (result != NULL) {
1049 if (packet_get(result, "ii", &status, &id) != 2) {
1050 NOTIFICATION_ERR("Failed to get a result packet");
1051 packet_unref(result);
1052 return NOTIFICATION_ERROR_IO;
1054 packet_unref(result);
1056 NOTIFICATION_ERR("failed to receive answer(update)");
1057 return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1063 static int _notification_ipc_update_cb(pid_t pid, int handle, const struct packet *packet, void *data)
1066 int id = NOTIFICATION_PRIV_ID_NONE;
1067 result_cb_item *cb_item = (result_cb_item *)data;
1069 if (cb_item == NULL) {
1070 NOTIFICATION_ERR("Failed to get a callback item");
1071 return NOTIFICATION_ERROR_INVALID_DATA;
1073 s_info.server_cl_fd_ref_cnt = (s_info.server_cl_fd_ref_cnt <= 1) ? 0 : s_info.server_cl_fd_ref_cnt - 1;
1074 if (s_info.server_cl_fd_ref_cnt <= 0) {
1075 NOTIFICATION_DBG("REFCNT: %d (fd: %d)", s_info.server_cl_fd_ref_cnt, s_info.server_cl_fd);
1076 int fd_temp = s_info.server_cl_fd;
1077 s_info.server_cl_fd = -1;
1078 com_core_packet_client_fini(fd_temp);
1079 NOTIFICATION_DBG("FD(%d) finalized", fd_temp);
1082 if (packet != NULL) {
1083 if (packet_get(packet, "ii", &status, &id) != 2) {
1084 NOTIFICATION_ERR("Failed to get a result packet");
1085 status = NOTIFICATION_ERROR_IO;
1089 if (cb_item->result_cb != NULL) {
1090 cb_item->result_cb(id, status, cb_item->data);
1097 notification_error_e notification_ipc_request_update_async(notification_h noti,
1098 void (*result_cb)(int priv_id, int result, void *data), void *user_data)
1100 int ret = NOTIFICATION_ERROR_NONE;
1102 struct packet *packet = NULL;
1103 result_cb_item *cb_item = NULL;
1105 packet = notification_ipc_make_packet_from_noti(noti, "update_noti", 1);
1106 if (packet == NULL) {
1107 ret = NOTIFICATION_ERROR_INVALID_DATA;
1111 cb_item = calloc(1, sizeof(result_cb_item));
1112 if (cb_item == NULL) {
1113 ret = NOTIFICATION_ERROR_NO_MEMORY;
1117 if (s_info.server_cl_fd < 0) {
1118 com_core_packet_use_thread(1);
1119 s_info.server_cl_fd = com_core_packet_client_init(s_info.socket_file, 0, NULL);
1120 if (s_info.server_cl_fd < 0) {
1121 NOTIFICATION_DBG("Failed to init client: %d", s_info.server_cl_fd);
1122 ret = NOTIFICATION_ERROR_SERVICE_NOT_READY;
1125 s_info.server_cl_fd_ref_cnt = 1;
1127 s_info.server_cl_fd_ref_cnt++;
1130 cb_item->result_cb = result_cb;
1131 cb_item->data = user_data;
1133 NOTIFICATION_INFO("Connection count:%d, fd:%d", s_info.server_cl_fd_ref_cnt, s_info.server_cl_fd);
1135 ret_con = com_core_packet_async_send(s_info.server_cl_fd, packet, 0.0f,
1136 _notification_ipc_update_cb, cb_item);
1138 NOTIFICATION_ERR("Failed to request update, %d\n", ret_con);
1139 s_info.server_cl_fd_ref_cnt = (s_info.server_cl_fd_ref_cnt <= 1) ? 0 : s_info.server_cl_fd_ref_cnt - 1;
1140 if (s_info.server_cl_fd_ref_cnt <= 0) {
1141 int fd_temp = s_info.server_cl_fd;
1142 s_info.server_cl_fd = -1;
1143 com_core_packet_client_fini(fd_temp);
1144 NOTIFICATION_INFO("FD(%d) finalized", fd_temp);
1146 ret = NOTIFICATION_ERROR_IO;
1149 ret = NOTIFICATION_ERROR_NONE;
1154 if (cb_item) free(cb_item);
1155 NOTIFICATION_ERR("Err: %d\n", ret);
1158 if (packet) packet_destroy(packet);
1163 notification_error_e notification_ipc_request_refresh(void)
1166 struct packet *packet;
1167 struct packet *result;
1169 packet = packet_create("refresh_noti", "i", NOTIFICATION_OP_REFRESH);
1170 result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1172 NOTIFICATION_IPC_TIMEOUT);
1173 packet_destroy(packet);
1175 if (result != NULL) {
1176 if (packet_get(result, "i", &status) != 1) {
1177 NOTIFICATION_ERR("Failed to get a result packet");
1178 packet_unref(result);
1179 return NOTIFICATION_ERROR_IO;
1181 packet_unref(result);
1183 NOTIFICATION_ERR("failed to receive answer(refresh)");
1184 return NOTIFICATION_ERROR_SERVICE_NOT_READY;