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 NOTIFICATION_ERR("try to register a notification service");
261 ret = notification_ipc_monitor_deregister();
262 if (ret != NOTIFICATION_ERROR_NONE) {
263 NOTIFICATION_ERR("failed to unregister a monitor");
265 ret = notification_ipc_monitor_register();
266 if (ret != NOTIFICATION_ERROR_NONE) {
267 NOTIFICATION_ERR("failed to register a monitor");
270 NOTIFICATION_ERR("try to unregister a notification service");
271 ret = notification_ipc_monitor_deregister();
272 if (ret != NOTIFICATION_ERROR_NONE) {
273 NOTIFICATION_ERR("failed to deregister a monitor");
278 static void _master_started_cb_task(keynode_t *node,
281 if (notification_ipc_is_master_ready()) {
287 * functions to create operation list
289 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)
292 notification_op *op_list = NULL;
298 op_list = (notification_op *)malloc(sizeof(notification_op) * num_op);
299 memset(op_list, 0x0, sizeof(notification_op) * num_op);
301 for (i = 0; i < num_op; i++) {
302 (op_list + i)->type = type;
303 if (list_priv_id != NULL) {
304 (op_list + i)->priv_id = *(list_priv_id + i);
306 if (noti_list != NULL) {
307 (op_list + i)->noti = *(noti_list + i);
315 * utility functions creating notification packet
317 static inline char *_dup_string(const char *string)
321 if (string == NULL) {
324 if (string[0] == '\0') {
328 ret = strdup(string);
330 NOTIFICATION_ERR("Error: %s\n", strerror(errno));
335 static inline bundle *_create_bundle_from_string(unsigned char *string)
337 if (string == NULL) {
340 if (string[0] == '\0') {
344 return bundle_decode(string, strlen((char *)string));
348 * functions creating notification packet
350 EXPORT_API notification_error_e notification_ipc_make_noti_from_packet(notification_h noti, const struct packet *packet)
356 int internal_group_id;
358 char *caller_pkgname = NULL;
359 char *launch_pkgname = NULL;
360 unsigned char *args = NULL;
361 unsigned char *group_args = NULL;
362 unsigned char *b_execute_option = NULL;
363 unsigned char *b_service_responding = NULL;
364 unsigned char *b_service_single_launch = NULL;
365 unsigned char *b_service_multi_launch = NULL;
368 unsigned char *b_text = NULL;
369 unsigned char *b_key = NULL;
370 unsigned char *b_format_args = NULL;
372 unsigned char *b_image_path = NULL;
374 char *sound_path = NULL;
376 char *vibration_path = NULL;
383 int flags_for_property;
385 double progress_size;
386 double progress_percentage;
387 char *app_icon_path = NULL;
388 char *app_name = NULL;
389 char *temp_title = NULL;
390 char *temp_content = NULL;
393 NOTIFICATION_ERR("invalid data");
394 return NOTIFICATION_ERROR_INVALID_DATA;
397 ret = packet_get(packet,
398 "iiiiisssssssssssssisisisiiiiiiiiddssss",
409 &b_service_responding,
410 &b_service_single_launch,
411 &b_service_multi_launch,
432 &progress_percentage,
439 NOTIFICATION_ERR("failed to create a noti from packet");
440 return NOTIFICATION_ERROR_INVALID_DATA;
444 * This is already allocated from the notification_create function.
445 * Before reallocate string to here.
446 * We have to release old one first.
448 free(noti->caller_pkgname);
449 noti->caller_pkgname = _dup_string(caller_pkgname);
450 noti->launch_pkgname = _dup_string(launch_pkgname);
451 noti->args = _create_bundle_from_string(args);
452 noti->group_args = _create_bundle_from_string(group_args);
453 noti->b_execute_option = _create_bundle_from_string(b_execute_option);
454 noti->b_service_responding = _create_bundle_from_string(b_service_responding);
455 noti->b_service_single_launch = _create_bundle_from_string(b_service_single_launch);
456 noti->b_service_multi_launch = _create_bundle_from_string(b_service_multi_launch);
457 noti->domain = _dup_string(domain);
458 noti->dir = _dup_string(dir);
459 noti->b_text = _create_bundle_from_string(b_text);
460 noti->b_key = _create_bundle_from_string(b_key);
461 noti->b_format_args = _create_bundle_from_string(b_format_args);
462 noti->b_image_path = _create_bundle_from_string(b_image_path);
463 noti->sound_path = _dup_string(sound_path);
464 noti->vibration_path = _dup_string(vibration_path);
465 noti->app_icon_path = _dup_string(app_icon_path);
466 noti->app_name = _dup_string(app_name);
467 noti->temp_title = _dup_string(temp_title);
468 noti->temp_content = _dup_string(temp_content);
471 noti->layout = layout;
472 noti->group_id = group_id;
473 noti->internal_group_id = internal_group_id;
474 noti->priv_id = priv_id;
475 noti->num_format_args = num_format_args;
476 noti->sound_type = sound_type;
477 noti->vibration_type = vibration_type;
478 noti->led_operation = led_operation;
479 noti->led_argb = led_argb;
480 noti->led_on_ms = led_on_ms;
481 noti->led_off_ms = led_off_ms;
483 noti->insert_time = insert_time;
484 noti->flags_for_property = flags_for_property;
485 noti->display_applist = display_applist;
486 noti->progress_size = progress_size;
487 noti->progress_percentage = progress_percentage;
489 return NOTIFICATION_ERROR_NONE;
492 EXPORT_API struct packet *notification_ipc_make_packet_from_noti(notification_h noti, const char *command, int packet_type)
494 struct packet *result = NULL;
496 char *group_args = NULL;
497 char *b_image_path = NULL;
498 char *b_execute_option = NULL;
499 char *b_service_responding = NULL;
500 char *b_service_single_launch = NULL;
501 char *b_service_multi_launch = NULL;
504 char *b_format_args = NULL;
505 int flag_simmode = 0;
506 struct packet *(*func_to_create_packet)(const char *command, const char *fmt, ...);
507 const char *title_key = NULL;
508 char buf_key[32] = { 0, };
510 /* Decode bundle to insert DB */
512 bundle_encode(noti->args, (bundle_raw **) & args, NULL);
514 if (noti->group_args) {
515 bundle_encode(noti->group_args, (bundle_raw **) & group_args,
519 if (noti->b_execute_option) {
520 bundle_encode(noti->b_execute_option,
521 (bundle_raw **) & b_execute_option, NULL);
523 if (noti->b_service_responding) {
524 bundle_encode(noti->b_service_responding,
525 (bundle_raw **) & b_service_responding, NULL);
527 if (noti->b_service_single_launch) {
528 bundle_encode(noti->b_service_single_launch,
529 (bundle_raw **) & b_service_single_launch, NULL);
531 if (noti->b_service_multi_launch) {
532 bundle_encode(noti->b_service_multi_launch,
533 (bundle_raw **) & b_service_multi_launch, NULL);
537 bundle_encode(noti->b_text, (bundle_raw **) & b_text, NULL);
540 bundle_encode(noti->b_key, (bundle_raw **) & b_key, NULL);
542 if (noti->b_format_args) {
543 bundle_encode(noti->b_format_args,
544 (bundle_raw **) & b_format_args, NULL);
547 if (noti->b_image_path) {
548 bundle_encode(noti->b_image_path,
549 (bundle_raw **) & b_image_path, NULL);
552 /* Check only simmode property is enable */
553 if (noti->flags_for_property & NOTIFICATION_PROP_DISPLAY_ONLY_SIMMODE) {
557 if (noti->b_key != NULL) {
558 snprintf(buf_key, sizeof(buf_key), "%d",
559 NOTIFICATION_TEXT_TYPE_TITLE);
561 title_key = bundle_get_val(noti->b_key, buf_key);
564 if (title_key == NULL && noti->b_text != NULL) {
565 snprintf(buf_key, sizeof(buf_key), "%d",
566 NOTIFICATION_TEXT_TYPE_TITLE);
568 title_key = bundle_get_val(noti->b_text, buf_key);
571 if (title_key == NULL) {
572 title_key = noti->caller_pkgname;
575 if (packet_type == 1)
576 func_to_create_packet = packet_create;
577 else if (packet_type == 2)
578 func_to_create_packet = packet_create_noack;
583 result = func_to_create_packet(command,
584 "iiiiisssssssssssssisisisiiiiiiiiddssss",
588 noti->internal_group_id,
590 NOTIFICATION_CHECK_STR(noti->caller_pkgname),
591 NOTIFICATION_CHECK_STR(noti->launch_pkgname),
592 NOTIFICATION_CHECK_STR(args),
593 NOTIFICATION_CHECK_STR(group_args),
594 NOTIFICATION_CHECK_STR(b_execute_option),
595 NOTIFICATION_CHECK_STR(b_service_responding),
596 NOTIFICATION_CHECK_STR(b_service_single_launch),
597 NOTIFICATION_CHECK_STR(b_service_multi_launch),
598 NOTIFICATION_CHECK_STR(noti->domain),
599 NOTIFICATION_CHECK_STR(noti->dir),
600 NOTIFICATION_CHECK_STR(b_text),
601 NOTIFICATION_CHECK_STR(b_key),
602 NOTIFICATION_CHECK_STR(b_format_args),
603 noti->num_format_args,
604 NOTIFICATION_CHECK_STR(b_image_path),
606 NOTIFICATION_CHECK_STR(noti->sound_path),
607 noti->vibration_type,
608 NOTIFICATION_CHECK_STR(noti->vibration_path),
615 noti->flags_for_property,
616 noti->display_applist,
618 noti->progress_percentage,
619 NOTIFICATION_CHECK_STR(noti->app_icon_path),
620 NOTIFICATION_CHECK_STR(noti->app_name),
621 NOTIFICATION_CHECK_STR(noti->temp_title),
622 NOTIFICATION_CHECK_STR(noti->temp_content));
625 /* Free decoded data */
633 if (b_execute_option) {
634 free(b_execute_option);
636 if (b_service_responding) {
637 free(b_service_responding);
639 if (b_service_single_launch) {
640 free(b_service_single_launch);
642 if (b_service_multi_launch) {
643 free(b_service_multi_launch);
664 * functions to handler services
666 static struct packet *_handler_insert(pid_t pid, int handle, const struct packet *packet)
668 notification_h noti = NULL;
671 NOTIFICATION_ERR("a packet is null");
674 noti = notification_create(NOTIFICATION_TYPE_NOTI);
676 NOTIFICATION_ERR("failed to create a notification");
679 notification_ipc_make_noti_from_packet(noti, packet);
681 if (noti->flags_for_property
682 & NOTIFICATION_PROP_DISABLE_UPDATE_ON_INSERT) {
683 /* Disable changed cb */
685 /* Enable changed cb */
686 notification_op *noti_op = notification_ipc_create_op(NOTIFICATION_OP_INSERT, 1, &(noti->priv_id), 1, ¬i);
687 if (noti_op != NULL) {
688 notification_call_changed_cb(noti_op, 1);
692 notification_free(noti);
697 static struct packet *_handler_update(pid_t pid, int handle, const struct packet *packet)
699 notification_h noti = NULL;
702 NOTIFICATION_ERR("a packet is null");
706 noti = notification_create(NOTIFICATION_TYPE_NOTI);
708 NOTIFICATION_ERR("failed to create a notification");
712 notification_ipc_make_noti_from_packet(noti, packet);
714 notification_op *noti_op = notification_ipc_create_op(NOTIFICATION_OP_UPDATE, 1, &(noti->priv_id), 1, ¬i);
715 if (noti_op != NULL) {
716 notification_call_changed_cb(noti_op, 1);
720 notification_free(noti);
725 static struct packet *_handler_refresh(pid_t pid, int handle, const struct packet *packet)
728 NOTIFICATION_ERR("a packet is null");
731 notification_op *noti_op = notification_ipc_create_op(NOTIFICATION_OP_REFRESH, 1, NULL, 0, NULL);
732 if (noti_op != NULL) {
733 notification_call_changed_cb(noti_op, 1);
740 static struct packet *_handler_delete_single(pid_t pid, int handle, const struct packet *packet)
743 int priv_id = NOTIFICATION_PRIV_ID_NONE;
746 NOTIFICATION_ERR("a packet is null");
749 if (packet_get(packet, "ii", &num_deleted, &priv_id) == 2) {
750 notification_op *noti_op = notification_ipc_create_op(NOTIFICATION_OP_DELETE, 1, &priv_id, 1, NULL);
751 if (noti_op != NULL) {
752 notification_call_changed_cb(noti_op, 1);
760 static struct packet *_handler_delete_multiple(pid_t pid, int handle, const struct packet *packet)
766 NOTIFICATION_ERR("delete_noti_multiple");
769 NOTIFICATION_ERR("a packet is null");
772 ret = packet_get(packet, "iiiiiiiiiii", &num_deleted,
784 NOTIFICATION_ERR("packet data count:%d", ret);
785 NOTIFICATION_ERR("packet data num deleted:%d", num_deleted);
788 for (i = 0 ; i < 10 ; i++) {
789 NOTIFICATION_ERR("packet data[%d]:%d",i, buf[i]);
793 notification_op *noti_op = notification_ipc_create_op(
794 NOTIFICATION_OP_DELETE, num_deleted, buf, num_deleted, NULL);
795 if (noti_op != NULL) {
796 notification_call_changed_cb(noti_op, num_deleted);
804 static int _handler_service_register(pid_t pid, int handle, const struct packet *packet, void *data)
809 NOTIFICATION_ERR("Packet is not valid\n");
810 ret = NOTIFICATION_ERROR_INVALID_DATA;
811 } else if (packet_get(packet, "i", &ret) != 1) {
812 NOTIFICATION_ERR("Packet is not valid\n");
813 ret = NOTIFICATION_ERROR_INVALID_DATA;
816 notification_op *noti_op = notification_ipc_create_op(NOTIFICATION_OP_SERVICE_READY, 1, NULL, 1, NULL);
817 if (noti_op != NULL) {
818 notification_call_changed_cb(noti_op, 1);
827 * functions to initialize and register a monitor
829 static notification_error_e notification_ipc_monitor_register(void)
832 struct packet *packet;
833 static struct method service_table[] = {
836 .handler = _handler_insert,
839 .cmd = "update_noti",
840 .handler = _handler_update,
843 .cmd = "refresh_noti",
844 .handler = _handler_refresh,
847 .cmd = "del_noti_single",
848 .handler = _handler_delete_single,
851 .cmd = "del_noti_multiple",
852 .handler = _handler_delete_multiple,
860 if (s_info.initialized == 1) {
861 return NOTIFICATION_ERROR_NONE;
863 s_info.initialized = 1;
866 NOTIFICATION_ERR("register a service\n");
868 com_core_packet_use_thread(1);
869 s_info.server_fd = com_core_packet_client_init(s_info.socket_file, 0, service_table);
870 if (s_info.server_fd < 0) {
871 NOTIFICATION_ERR("Failed to make a connection to the master\n");
872 return NOTIFICATION_ERROR_IO;
875 packet = packet_create("service_register", "");
877 NOTIFICATION_ERR("Failed to build a packet\n");
878 com_core_packet_client_fini(s_info.server_fd);
879 return NOTIFICATION_ERROR_IO;
882 ret = com_core_packet_async_send(s_info.server_fd, packet, 1.0, _handler_service_register, NULL);
883 NOTIFICATION_DBG("Service register sent: %d\n", ret);
884 packet_destroy(packet);
886 com_core_packet_client_fini(s_info.server_fd);
887 s_info.server_fd = NOTIFICATION_ERROR_INVALID_DATA;
888 ret = NOTIFICATION_ERROR_IO;
890 ret = NOTIFICATION_ERROR_NONE;
893 NOTIFICATION_DBG("Server FD: %d\n", s_info.server_fd);
897 notification_error_e notification_ipc_monitor_deregister(void)
899 if (s_info.initialized == 0) {
900 return NOTIFICATION_ERROR_NONE;
903 com_core_packet_client_fini(s_info.server_fd);
904 s_info.server_fd = NOTIFICATION_ERROR_INVALID_DATA;
906 s_info.initialized = 0;
908 return NOTIFICATION_ERROR_NONE;
911 notification_error_e notification_ipc_monitor_init(void)
913 int ret = NOTIFICATION_ERROR_NONE;
915 if (notification_ipc_is_master_ready()) {
916 ret = notification_ipc_monitor_register();
919 if (s_info.is_started_cb_set_svc == 0) {
920 _set_master_started_cb(_master_started_cb_service);
921 s_info.is_started_cb_set_svc = 1;
927 notification_error_e notification_ipc_monitor_fini(void)
929 int ret = NOTIFICATION_ERROR_NONE;
931 if (s_info.is_started_cb_set_svc == 1) {
932 _unset_master_started_cb(_master_started_cb_service);
933 s_info.is_started_cb_set_svc = 0;
936 ret = notification_ipc_monitor_deregister();
942 * functions to request the service
944 notification_error_e notification_ipc_request_insert(notification_h noti, int *priv_id)
947 int id = NOTIFICATION_PRIV_ID_NONE;
948 struct packet *packet;
949 struct packet *result;
951 /* Initialize private ID */
952 noti->priv_id = NOTIFICATION_PRIV_ID_NONE;
953 noti->group_id = NOTIFICATION_GROUP_ID_NONE;
954 noti->internal_group_id = NOTIFICATION_GROUP_ID_NONE;
956 packet = notification_ipc_make_packet_from_noti(noti, "add_noti", 1);
957 result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
959 NOTIFICATION_IPC_TIMEOUT);
960 packet_destroy(packet);
962 if (result != NULL) {
963 if (packet_get(result, "ii", &status, &id) != 2) {
964 NOTIFICATION_ERR("Failed to get a result packet");
965 packet_unref(result);
966 return NOTIFICATION_ERROR_IO;
969 if (status != NOTIFICATION_ERROR_NONE) {
970 packet_unref(result);
973 packet_unref(result);
975 NOTIFICATION_ERR("failed to receive answer(insert)");
976 return NOTIFICATION_ERROR_SERVICE_NOT_READY;
979 if (priv_id != NULL) {
983 return NOTIFICATION_ERROR_NONE;
986 notification_error_e notification_ipc_request_delete_single(notification_type_e type, char *pkgname, int priv_id)
989 int id = NOTIFICATION_PRIV_ID_NONE;
990 struct packet *packet;
991 struct packet *result;
993 packet = packet_create("del_noti_single", "si", pkgname, priv_id);
994 result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
996 NOTIFICATION_IPC_TIMEOUT);
997 packet_destroy(packet);
999 if (result != NULL) {
1000 if (packet_get(result, "ii", &status, &id) != 2) {
1001 NOTIFICATION_ERR("Failed to get a result packet");
1002 packet_unref(result);
1003 return NOTIFICATION_ERROR_IO;
1005 packet_unref(result);
1007 NOTIFICATION_ERR("failed to receive answer(delete)");
1008 return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1014 notification_error_e notification_ipc_request_delete_multiple(notification_type_e type, char *pkgname)
1017 int num_deleted = 0;
1018 struct packet *packet;
1019 struct packet *result;
1021 packet = packet_create("del_noti_multiple", "si", pkgname, type);
1022 result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1024 NOTIFICATION_IPC_TIMEOUT);
1025 packet_destroy(packet);
1027 if (result != NULL) {
1028 if (packet_get(result, "ii", &status, &num_deleted) != 2) {
1029 NOTIFICATION_ERR("Failed to get a result packet");
1030 packet_unref(result);
1031 return NOTIFICATION_ERROR_IO;
1033 NOTIFICATION_ERR("num deleted:%d", num_deleted);
1034 packet_unref(result);
1036 NOTIFICATION_ERR("failed to receive answer(delete multiple)");
1037 return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1043 notification_error_e notification_ipc_request_update(notification_h noti)
1046 int id = NOTIFICATION_PRIV_ID_NONE;
1047 struct packet *packet;
1048 struct packet *result;
1050 packet = notification_ipc_make_packet_from_noti(noti, "update_noti", 1);
1051 result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1053 NOTIFICATION_IPC_TIMEOUT);
1054 packet_destroy(packet);
1056 if (result != NULL) {
1057 if (packet_get(result, "ii", &status, &id) != 2) {
1058 NOTIFICATION_ERR("Failed to get a result packet");
1059 packet_unref(result);
1060 return NOTIFICATION_ERROR_IO;
1062 packet_unref(result);
1064 NOTIFICATION_ERR("failed to receive answer(update)");
1065 return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1071 static int _notification_ipc_update_cb(pid_t pid, int handle, const struct packet *packet, void *data)
1074 int id = NOTIFICATION_PRIV_ID_NONE;
1075 result_cb_item *cb_item = (result_cb_item *)data;
1077 if (cb_item == NULL) {
1078 NOTIFICATION_ERR("Failed to get a callback item");
1079 return NOTIFICATION_ERROR_INVALID_DATA;
1081 s_info.server_cl_fd_ref_cnt = (s_info.server_cl_fd_ref_cnt <= 1) ? 0 : s_info.server_cl_fd_ref_cnt - 1;
1082 if (s_info.server_cl_fd_ref_cnt <= 0) {
1083 NOTIFICATION_DBG("REFCNT: %d (fd: %d)", s_info.server_cl_fd_ref_cnt, s_info.server_cl_fd);
1084 int fd_temp = s_info.server_cl_fd;
1085 s_info.server_cl_fd = -1;
1086 com_core_packet_client_fini(fd_temp);
1087 NOTIFICATION_DBG("FD(%d) finalized", fd_temp);
1090 if (packet != NULL) {
1091 if (packet_get(packet, "ii", &status, &id) != 2) {
1092 NOTIFICATION_ERR("Failed to get a result packet");
1093 status = NOTIFICATION_ERROR_IO;
1097 if (cb_item->result_cb != NULL) {
1098 cb_item->result_cb(id, status, cb_item->data);
1105 notification_error_e notification_ipc_request_update_async(notification_h noti,
1106 void (*result_cb)(int priv_id, int result, void *data), void *user_data)
1108 int ret = NOTIFICATION_ERROR_NONE;
1110 struct packet *packet = NULL;
1111 result_cb_item *cb_item = NULL;
1113 packet = notification_ipc_make_packet_from_noti(noti, "update_noti", 1);
1114 if (packet == NULL) {
1115 ret = NOTIFICATION_ERROR_INVALID_DATA;
1119 cb_item = calloc(1, sizeof(result_cb_item));
1120 if (cb_item == NULL) {
1121 ret = NOTIFICATION_ERROR_NO_MEMORY;
1125 if (s_info.server_cl_fd < 0) {
1126 com_core_packet_use_thread(1);
1127 s_info.server_cl_fd = com_core_packet_client_init(s_info.socket_file, 0, NULL);
1128 if (s_info.server_cl_fd < 0) {
1129 NOTIFICATION_DBG("Failed to init client: %d", s_info.server_cl_fd);
1130 ret = NOTIFICATION_ERROR_SERVICE_NOT_READY;
1133 s_info.server_cl_fd_ref_cnt = 1;
1135 s_info.server_cl_fd_ref_cnt++;
1138 cb_item->result_cb = result_cb;
1139 cb_item->data = user_data;
1141 NOTIFICATION_INFO("Connection count:%d, fd:%d", s_info.server_cl_fd_ref_cnt, s_info.server_cl_fd);
1143 ret_con = com_core_packet_async_send(s_info.server_cl_fd, packet, 0.0f,
1144 _notification_ipc_update_cb, cb_item);
1146 NOTIFICATION_ERR("Failed to request update, %d\n", ret_con);
1147 s_info.server_cl_fd_ref_cnt = (s_info.server_cl_fd_ref_cnt <= 1) ? 0 : s_info.server_cl_fd_ref_cnt - 1;
1148 if (s_info.server_cl_fd_ref_cnt <= 0) {
1149 int fd_temp = s_info.server_cl_fd;
1150 s_info.server_cl_fd = -1;
1151 com_core_packet_client_fini(fd_temp);
1152 NOTIFICATION_INFO("FD(%d) finalized", fd_temp);
1154 ret = NOTIFICATION_ERROR_IO;
1157 ret = NOTIFICATION_ERROR_NONE;
1162 if (cb_item) free(cb_item);
1163 NOTIFICATION_ERR("Err: %d\n", ret);
1166 if (packet) packet_destroy(packet);
1171 notification_error_e notification_ipc_request_refresh(void)
1174 struct packet *packet;
1175 struct packet *result;
1177 packet = packet_create("refresh_noti", "i", NOTIFICATION_OP_REFRESH);
1178 result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1180 NOTIFICATION_IPC_TIMEOUT);
1181 packet_destroy(packet);
1183 if (result != NULL) {
1184 if (packet_get(result, "i", &status) != 1) {
1185 NOTIFICATION_ERR("Failed to get a result packet");
1186 packet_unref(result);
1187 return NOTIFICATION_ERROR_IO;
1189 packet_unref(result);
1191 NOTIFICATION_ERR("failed to receive answer(refresh)");
1192 return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1198 notification_error_e notification_ipc_noti_setting_property_set(const char *pkgname, const char *property, const char *value)
1202 struct packet *packet;
1203 struct packet *result;
1205 packet = packet_create("set_noti_property", "sss", pkgname, property, value);
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, &ret) != 2) {
1213 NOTIFICATION_ERR("Failed to get a result packet");
1214 packet_unref(result);
1215 return NOTIFICATION_ERROR_IO;
1217 packet_unref(result);
1219 NOTIFICATION_ERR("failed to receive answer(delete)");
1220 return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1226 notification_error_e notification_ipc_noti_setting_property_get(const char *pkgname, const char *property, char **value)
1230 struct packet *packet;
1231 struct packet *result;
1233 packet = packet_create("get_noti_property", "ss", pkgname, property);
1234 result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1236 NOTIFICATION_IPC_TIMEOUT);
1237 packet_destroy(packet);
1239 if (result != NULL) {
1240 if (packet_get(result, "is", &status, &ret) != 2) {
1241 NOTIFICATION_ERR("Failed to get a result packet");
1242 packet_unref(result);
1243 return NOTIFICATION_ERROR_IO;
1245 if (status == NOTIFICATION_ERROR_NONE && ret != NULL) {
1246 *value = strdup(ret);
1248 packet_unref(result);
1250 NOTIFICATION_ERR("failed to receive answer(delete)");
1251 return NOTIFICATION_ERROR_SERVICE_NOT_READY;