2 * Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
22 #include <bundle_internal.h>
24 #include <notification_ipc.h>
25 #include <notification_db.h>
26 #include <notification_type.h>
27 #include <notification_private.h>
28 #include <notification_debug.h>
29 #include <notification_setting.h>
30 #include <notification_setting_internal.h>
31 #include <notification_internal.h>
35 #define PROVIDER_BUS_NAME "org.tizen.data_provider_service"
36 #define PROVIDER_OBJECT_PATH "/org/tizen/data_provider_service"
37 #define PROVIDER_NOTI_INTERFACE_NAME "org.tizen.data_provider_noti_service"
39 #define DBUS_SERVICE_DBUS "org.freedesktop.DBus"
40 #define DBUS_PATH_DBUS "/org/freedesktop/DBus"
41 #define DBUS_INTERFACE_DBUS "org.freedesktop.DBus"
42 #define ERR_BUFFER_SIZE 1024
44 static const gchar *_bus_name = NULL;
45 static GDBusConnection *_gdbus_conn = NULL;
46 static int monitor_id = 0;
47 static int provider_monitor_id = 0;
48 static int is_master_started = 0;
50 typedef struct _result_cb_item {
51 void (*result_cb)(int priv_id, int result, void *data);
55 typedef struct _task_list task_list;
60 void (*task_cb) (void *data);
64 static task_list *g_task_list;
66 static int _ipc_monitor_register(uid_t uid);
67 static int _ipc_monitor_deregister(void);
68 static void _do_deffered_task(void);
70 static void _print_noti(notification_h noti)
75 const char *tag = NULL;
76 notification_vibration_type_e vib_type = NOTIFICATION_VIBRATION_TYPE_NONE;
78 notification_get_pkgname(noti, &pkgname);
79 notification_get_text(noti, NOTIFICATION_TEXT_TYPE_TITLE, &text);
80 notification_get_text(noti, NOTIFICATION_TEXT_TYPE_CONTENT, &content);
81 notification_get_tag(noti, &tag);
82 notification_get_vibration(noti, &vib_type, NULL);
84 NOTIFICATION_DBG("client print_noti pkgname = %s ", pkgname);
85 NOTIFICATION_DBG("client print_noti title = %s ", text);
86 NOTIFICATION_DBG("client print_noti content = %s ", content);
87 NOTIFICATION_DBG("client print_noti tag = %s ", tag);
88 NOTIFICATION_DBG("client print_noti priv_id = %d ", noti->priv_id);
89 NOTIFICATION_DBG("client print_noti vibration_path = %s ", noti->vibration_path);
90 NOTIFICATION_DBG("client print_noti vibration_type = %d ", vib_type);
93 static inline char *_string_get(char *string)
98 if (string[0] == '\0')
104 static int _dbus_init()
106 GError *error = NULL;
108 if (_gdbus_conn == NULL) {
109 _gdbus_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
111 if (_gdbus_conn == NULL) {
113 NOTIFICATION_ERR("Failed to get dbus [%s]", error->message);
116 return NOTIFICATION_ERROR_IO_ERROR;
118 _bus_name = g_dbus_connection_get_unique_name(_gdbus_conn);
119 NOTIFICATION_DBG("bus name : %s", _bus_name);
121 notification_error_quark();
124 return NOTIFICATION_ERROR_NONE;
127 /* LCOV_EXCL_START */
128 int notification_ipc_is_master_ready(void)
133 int ret = NOTIFICATION_ERROR_NONE;
136 if (ret != NOTIFICATION_ERROR_NONE) {
137 NOTIFICATION_ERR("Can't init dbus %d", ret);
138 is_master_started = 0;
139 return is_master_started;
142 result = g_dbus_connection_call_sync(
148 g_variant_new("(s)", PROVIDER_BUS_NAME),
149 G_VARIANT_TYPE("(b)"),
150 G_DBUS_CALL_FLAGS_NONE,
155 if (err || (result == NULL)) {
157 NOTIFICATION_ERR("No reply. error = %s", err->message);
160 NOTIFICATION_ERR("is master ready fail");
161 is_master_started = 0;
163 g_variant_get(result, "(b)", &name_exist);
166 NOTIFICATION_ERR("Name not exist %s", PROVIDER_BUS_NAME);
167 NOTIFICATION_ERR("the master has been stopped");
168 is_master_started = 0;
170 NOTIFICATION_DBG("the master has been started");
171 is_master_started = 1;
176 g_variant_unref(result);
178 return is_master_started;
182 /* TODO: dbus activation isn't enough ? */
184 * store tasks when daemon stopped
186 int notification_ipc_add_deffered_task(
187 void (*deferred_task_cb)(void *data),
193 list_new = (task_list *) malloc(sizeof(task_list));
194 if (list_new == NULL)
195 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
197 list_new->next = NULL;
198 list_new->prev = NULL;
200 list_new->task_cb = deferred_task_cb;
201 list_new->data = user_data;
203 if (g_task_list == NULL) {
204 g_task_list = list_new;
208 while (list->next != NULL)
211 list->next = list_new;
212 list_new->prev = list;
215 return NOTIFICATION_ERROR_NONE;
218 int notification_ipc_del_deffered_task(
219 void (*deferred_task_cb)(void *data))
222 task_list *list_prev;
223 task_list *list_next;
225 list_del = g_task_list;
227 if (list_del == NULL)
228 return NOTIFICATION_ERROR_INVALID_PARAMETER;
230 while (list_del->prev != NULL)
231 list_del = list_del->prev;
234 if (list_del->task_cb == deferred_task_cb) {
235 list_prev = list_del->prev;
236 list_next = list_del->next;
238 if (list_prev == NULL)
239 g_task_list = list_next;
241 list_prev->next = list_next;
243 if (list_next == NULL) {
244 if (list_prev != NULL)
245 list_prev->next = NULL;
247 list_next->prev = list_prev;
251 return NOTIFICATION_ERROR_NONE;
253 list_del = list_del->next;
254 } while (list_del != NULL);
256 return NOTIFICATION_ERROR_INVALID_PARAMETER;
259 /* LCOV_EXCL_START */
260 static void _do_deffered_task(void)
263 task_list *list_temp;
265 if (g_task_list == NULL)
268 list_do = g_task_list;
271 while (list_do->prev != NULL)
272 list_do = list_do->prev;
274 while (list_do != NULL) {
275 if (list_do->task_cb != NULL) {
276 list_do->task_cb(list_do->data);
277 NOTIFICATION_DBG("called:%p", list_do->task_cb);
279 list_temp = list_do->next;
287 * functions to create operation list
289 static notification_op *_ipc_create_op(notification_op_type_e type,
290 int num_op, int *list_priv_id, int num_priv_id, notification_h *noti_list)
293 notification_op *op_list;
298 op_list = (notification_op *)malloc(sizeof(notification_op) * num_op);
299 if (op_list == NULL) {
300 NOTIFICATION_ERR("malloc failed");
304 memset(op_list, 0x0, sizeof(notification_op) * num_op);
306 for (i = 0; i < num_op; i++) {
307 (op_list + i)->type = type;
308 if (list_priv_id != NULL)
309 (op_list + i)->priv_id = *(list_priv_id + i);
310 if (noti_list != NULL)
311 (op_list + i)->noti = *(noti_list + i);
318 * utility functions creating notification packet
320 static inline char *_dup_string(const char *string)
323 char err_buf[ERR_BUFFER_SIZE];
325 if (string == NULL || string[0] == '\0')
328 ret = strdup(string);
330 NOTIFICATION_ERR("Error: %s\n", strerror_r(errno, err_buf, sizeof(err_buf)));
335 static inline bundle *_create_bundle_from_bundle_raw(bundle_raw *string)
337 if (string == NULL || string[0] == '\0')
340 return bundle_decode(string, strlen((char *)string));
343 /* LCOV_EXCL_START */
344 static void _add_noti_notify(GVariant *parameters)
348 notification_op *noti_op;
349 GVariant *body = NULL;
352 NOTIFICATION_DBG("add noti notify");
353 noti = notification_create(NOTIFICATION_TYPE_NOTI);
355 NOTIFICATION_ERR("failed to create a notification");
359 g_variant_get(parameters, "(v)", &body);
360 notification_ipc_make_noti_from_gvariant(noti, body);
362 if (noti->flags_for_property & NOTIFICATION_PROP_DISABLE_UPDATE_ON_INSERT) {
363 NOTIFICATION_ERR("disable changed callback %d", noti->flags_for_property);
364 /* Disable changed cb */
366 /* Enable changed cb */
367 noti_op = _ipc_create_op(NOTIFICATION_OP_INSERT, 1, &(noti->priv_id), 1, ¬i);
368 ret = notification_get_uid(noti, &uid);
369 if (noti_op != NULL && ret == NOTIFICATION_ERROR_NONE) {
370 notification_call_changed_cb_for_uid(noti_op, 1, uid);
374 g_variant_unref(body);
375 notification_free(noti);
379 /* LCOV_EXCL_START */
380 static void _update_noti_notify(GVariant *parameters)
384 notification_op *noti_op;
385 GVariant *body = NULL;
388 noti = notification_create(NOTIFICATION_TYPE_NOTI);
390 NOTIFICATION_ERR("failed to create a notification");
394 g_variant_get(parameters, "(v)", &body);
395 notification_ipc_make_noti_from_gvariant(noti, body);
398 noti_op = _ipc_create_op(NOTIFICATION_OP_UPDATE, 1, &(noti->priv_id), 1, ¬i);
399 ret = notification_get_uid(noti, &uid);
400 if (noti_op != NULL && ret == NOTIFICATION_ERROR_NONE) {
401 notification_call_changed_cb_for_uid(noti_op, 1, uid);
405 g_variant_unref(body);
406 notification_free(noti);
410 /* LCOV_EXCL_START */
411 static void _refresh_noti_notify(GVariant *parameters)
414 notification_op *noti_op = _ipc_create_op(NOTIFICATION_OP_REFRESH, 1, NULL, 0, NULL);
416 g_variant_get(parameters, "(i)", &uid);
418 if (noti_op != NULL) {
419 notification_call_changed_cb_for_uid(noti_op, 1, uid);
425 /* LCOV_EXCL_START */
426 static void _delete_single_notify(GVariant *parameters)
430 notification_op *noti_op;
434 g_variant_get(parameters, "(iii)", &num_deleted, &priv_id, &uid);
436 noti_op = _ipc_create_op(NOTIFICATION_OP_DELETE, 1, &priv_id, 1, NULL);
437 if (noti_op != NULL) {
438 notification_call_changed_cb_for_uid(noti_op, 1, uid);
444 /* LCOV_EXCL_START */
445 static void _delete_multiple_notify(GVariant *parameters)
449 notification_op *noti_op;
453 g_variant_get(parameters, "(a(i)i)", &iter, &uid);
454 while (g_variant_iter_loop(iter, "(i)", &buf[idx])) {
455 NOTIFICATION_DBG("delete_noti_multiple priv_id : %d", buf[idx]);
458 g_variant_iter_free(iter);
460 NOTIFICATION_DBG("data num deleted:%d", idx);
461 noti_op = _ipc_create_op(NOTIFICATION_OP_DELETE, idx, buf, idx, NULL);
462 if (noti_op == NULL) {
463 NOTIFICATION_ERR("_ipc_create_op failed");
467 notification_call_changed_cb_for_uid(noti_op, idx, uid);
472 /* LCOV_EXCL_START */
473 static void _change_dnd_notify(GVariant *parameters)
478 g_variant_get(parameters, "(ii)", &do_not_disturb, &uid);
479 NOTIFICATION_DBG("do_not_disturb[%d], uid[%d]", do_not_disturb, uid);
481 notification_call_dnd_changed_cb_for_uid(do_not_disturb, uid);
485 /* LCOV_EXCL_START */
486 static void _handle_noti_notify(GDBusConnection *connection,
487 const gchar *sender_name,
488 const gchar *object_path,
489 const gchar *interface_name,
490 const gchar *signal_name,
491 GVariant *parameters,
494 NOTIFICATION_DBG("own_name : %s signal_name: %s",
495 g_dbus_connection_get_unique_name(connection), signal_name);
497 if (g_strcmp0(signal_name, "add_noti_notify") == 0)
498 _add_noti_notify(parameters);
499 else if (g_strcmp0(signal_name, "update_noti_notify") == 0)
500 _update_noti_notify(parameters);
501 else if (g_strcmp0(signal_name, "delete_single_notify") == 0)
502 _delete_single_notify(parameters);
503 else if (g_strcmp0(signal_name, "delete_multiple_notify") == 0)
504 _delete_multiple_notify(parameters);
505 else if (g_strcmp0(signal_name, "refresh_noti_notify") == 0)
506 _refresh_noti_notify(parameters);
507 else if (g_strcmp0(signal_name, "change_dnd_notify") == 0)
508 _change_dnd_notify(parameters);
512 static int _dbus_signal_init()
515 int ret = NOTIFICATION_ERROR_NONE;
517 if (monitor_id == 0) {
518 id = g_dbus_connection_signal_subscribe(_gdbus_conn,
520 PROVIDER_NOTI_INTERFACE_NAME, /* interface */
522 PROVIDER_OBJECT_PATH, /* path */
524 G_DBUS_SIGNAL_FLAGS_NONE,
529 NOTIFICATION_DBG("subscribe id : %d", id);
531 /* LCOV_EXCL_START */
532 ret = NOTIFICATION_ERROR_IO_ERROR;
533 NOTIFICATION_ERR("Failed to _register_noti_dbus_interface");
537 ret = NOTIFICATION_ERROR_NONE;
544 static int _send_sync_noti(GVariant *body, GDBusMessage **reply, char *cmd)
546 int ret = NOTIFICATION_ERROR_NONE;
550 msg = g_dbus_message_new_method_call(
552 PROVIDER_OBJECT_PATH,
553 PROVIDER_NOTI_INTERFACE_NAME,
556 /* LCOV_EXCL_START */
557 NOTIFICATION_ERR("Can't allocate new method call");
559 g_variant_unref(body);
560 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
565 g_dbus_message_set_body(msg, body);
567 *reply = g_dbus_connection_send_message_with_reply_sync(
570 G_DBUS_SEND_MESSAGE_FLAGS_NONE,
579 /* LCOV_EXCL_START */
580 ret = NOTIFICATION_ERROR_SERVICE_NOT_READY;
582 NOTIFICATION_ERR("No reply. cmd = %s, error = %s", cmd, err->message);
583 if (err->code == G_DBUS_ERROR_ACCESS_DENIED)
584 ret = NOTIFICATION_ERROR_PERMISSION_DENIED;
591 if (g_dbus_message_to_gerror(*reply, &err)) {
592 if (err->code == G_DBUS_ERROR_ACCESS_DENIED)
593 ret = NOTIFICATION_ERROR_PERMISSION_DENIED;
597 NOTIFICATION_ERR("_send_sync_noti cmd = %s, error %s, err code %d", cmd, err->message, ret);
602 NOTIFICATION_DBG("_send_sync_noti done !!");
603 return NOTIFICATION_ERROR_NONE;
606 static void _send_message_with_reply_async_cb(GDBusConnection *connection,
611 int result = NOTIFICATION_ERROR_NONE;
613 GDBusMessage *reply = NULL;
615 result_cb_item *cb_item = (result_cb_item *)user_data;
617 if (cb_item == NULL) {
618 NOTIFICATION_ERR("Failed to get a callback item");
622 reply = g_dbus_connection_send_message_with_reply_finish(
628 /* LCOV_EXCL_START */
630 NOTIFICATION_ERR("No reply. error = %s", err->message);
633 result = NOTIFICATION_ERROR_SERVICE_NOT_READY;
636 } else if (g_dbus_message_to_gerror(reply, &err)) {
637 /* LCOV_EXCL_START */
638 if (err->code == G_DBUS_ERROR_ACCESS_DENIED)
639 result = NOTIFICATION_ERROR_PERMISSION_DENIED;
643 NOTIFICATION_ERR("_send_async_noti error %s", err->message);
648 NOTIFICATION_DBG("_send_async_noti done !![%d]", result);
650 if (result == NOTIFICATION_ERROR_NONE) {
651 body = g_dbus_message_get_body(reply);
652 g_variant_get(body, "(i)", &priv_id);
654 if (cb_item->result_cb)
655 cb_item->result_cb(priv_id, result, cb_item->data);
657 if (cb_item->result_cb)
658 cb_item->result_cb(NOTIFICATION_PRIV_ID_NONE, result, cb_item->data);
662 g_object_unref(reply);
666 static int _send_async_noti(GVariant *body, result_cb_item *cb_item, char *cmd)
670 msg = g_dbus_message_new_method_call(
672 PROVIDER_OBJECT_PATH,
673 PROVIDER_NOTI_INTERFACE_NAME,
676 /* LCOV_EXCL_START */
677 NOTIFICATION_ERR("Can't allocate new method call");
678 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
683 g_dbus_message_set_body(msg, body);
685 g_dbus_connection_send_message_with_reply(
688 G_DBUS_SEND_MESSAGE_FLAGS_NONE,
692 (GAsyncReadyCallback)_send_message_with_reply_async_cb,
695 NOTIFICATION_DBG("_send_async_noti done !!");
698 return NOTIFICATION_ERROR_NONE;
701 int notification_ipc_request_insert(notification_h noti, int *priv_id)
704 int id = NOTIFICATION_PRIV_ID_NONE;
705 GDBusMessage *reply = NULL;
707 GVariant *reply_body;
709 result = _dbus_init();
710 if (result != NOTIFICATION_ERROR_NONE) {
711 NOTIFICATION_ERR("Can't init dbus %d", result);
715 /* Initialize private ID */
716 noti->group_id = NOTIFICATION_GROUP_ID_NONE;
717 noti->internal_group_id = NOTIFICATION_GROUP_ID_NONE;
720 body = notification_ipc_make_gvariant_from_noti(noti, false);
722 /* LCOV_EXCL_START */
723 NOTIFICATION_ERR("cannot make gvariant");
724 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
728 result = _send_sync_noti(body, &reply, "add_noti");
729 NOTIFICATION_DBG("_send_sync_noti %d", result);
731 if (result == NOTIFICATION_ERROR_NONE) {
732 reply_body = g_dbus_message_get_body(reply);
733 g_variant_get(reply_body, "(i)", &id);
740 g_object_unref(reply);
742 NOTIFICATION_DBG("notification_ipc_request_insert done [priv_id : %d, result: %d]", id, result);
746 int notification_ipc_request_update(notification_h noti)
749 int priv_id = NOTIFICATION_PRIV_ID_NONE;
751 GDBusMessage *reply = NULL;
753 GVariant *reply_body;
755 result = _dbus_init();
756 if (result != NOTIFICATION_ERROR_NONE) {
757 /* LCOV_EXCL_START */
758 NOTIFICATION_ERR("Can't init dbus %d", result);
763 body = notification_ipc_make_gvariant_from_noti(noti, false);
765 /* LCOV_EXCL_START */
766 NOTIFICATION_ERR("cannot make gvariant");
767 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
771 result = _send_sync_noti(body, &reply, "update_noti");
772 if (result == NOTIFICATION_ERROR_NONE) {
773 reply_body = g_dbus_message_get_body(reply);
774 g_variant_get(reply_body, "(i)", &priv_id);
778 g_object_unref(reply);
780 NOTIFICATION_DBG("notification_ipc_request_update done [result: %d, priv_id :%d]", result, priv_id);
784 int notification_ipc_request_update_async(notification_h noti,
785 void (*result_cb)(int priv_id, int result, void *data), void *user_data)
788 result_cb_item *cb_item;
791 result = _dbus_init();
792 if (result != NOTIFICATION_ERROR_NONE) {
793 /* LCOV_EXCL_START */
794 NOTIFICATION_ERR("Can't init dbus %d", result);
799 cb_item = calloc(1, sizeof(result_cb_item));
801 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
803 cb_item->result_cb = result_cb;
804 cb_item->data = user_data;
806 body = notification_ipc_make_gvariant_from_noti(noti, false);
808 /* LCOV_EXCL_START */
809 NOTIFICATION_ERR("cannot make gvariant");
811 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
815 result = _send_async_noti(body, cb_item, "update_noti");
816 NOTIFICATION_DBG("notification_ipc_request_update_async done [result: %d]", result);
818 if (result != NOTIFICATION_ERROR_NONE) {
819 /* LCOV_EXCL_START */
825 g_variant_unref(body);
830 int notification_ipc_request_refresh(uid_t uid)
833 GDBusMessage *reply = NULL;
836 result = _dbus_init();
837 if (result != NOTIFICATION_ERROR_NONE) {
838 NOTIFICATION_ERR("Can't init dbus %d", result);
842 body = g_variant_new("(i)", uid);
843 result = _send_sync_noti(body, &reply, "refresh_noti");
846 g_object_unref(reply);
848 NOTIFICATION_ERR("notification_ipc_request_refresh done [result: %d]", result);
852 int notification_ipc_request_delete_single(notification_type_e type, char *pkgname, int priv_id, uid_t uid)
856 GDBusMessage *reply = NULL;
858 GVariant *reply_body;
860 result = _dbus_init();
861 if (result != NOTIFICATION_ERROR_NONE) {
862 NOTIFICATION_ERR("Can't init dbus %d", result);
869 body = g_variant_new("(sii)", pkgname, priv_id, uid);
870 result = _send_sync_noti(body, &reply, "del_noti_single");
872 if (result == NOTIFICATION_ERROR_NONE) {
873 reply_body = g_dbus_message_get_body(reply);
874 g_variant_get(reply_body, "(i)", &id);
878 g_object_unref(reply);
880 NOTIFICATION_ERR("notification_ipc_request_delete_single done [result: %d]", result);
884 int notification_ipc_request_delete_multiple(notification_type_e type, char *pkgname, uid_t uid)
889 GVariant *reply_body;
890 GDBusMessage *reply = NULL;
892 result = _dbus_init();
893 if (result != NOTIFICATION_ERROR_NONE) {
894 NOTIFICATION_ERR("Can't init dbus %d", result);
901 body = g_variant_new("(sii)", pkgname, type, uid);
902 result = _send_sync_noti(body, &reply, "del_noti_multiple");
904 if (result == NOTIFICATION_ERROR_NONE) {
905 reply_body = g_dbus_message_get_body(reply);
906 g_variant_get(reply_body, "(i)", &num_deleted);
907 NOTIFICATION_ERR("num deleted:%d", num_deleted);
911 g_object_unref(reply);
916 int notification_ipc_request_load_noti_by_tag(notification_h noti, const char *pkgname, const char *tag, uid_t uid)
919 GDBusMessage *reply = NULL;
921 GVariant *reply_body;
924 result = _dbus_init();
925 if (result != NOTIFICATION_ERROR_NONE) {
926 NOTIFICATION_ERR("Can't init dbus %d", result);
933 body = g_variant_new("(ssi)", pkgname, tag, uid);
934 result = _send_sync_noti(body, &reply, "load_noti_by_tag");
936 if (result == NOTIFICATION_ERROR_NONE) {
937 reply_body = g_dbus_message_get_body(reply);
938 g_variant_get(reply_body, "(v)", ¬i_body);
940 notification_ipc_make_noti_from_gvariant(noti, noti_body);
941 g_variant_unref(noti_body);
947 g_object_unref(reply);
949 NOTIFICATION_DBG("notification_ipc_request_load_noti_by_tag done [result: %d]", result);
953 /* LCOV_EXCL_START */
954 int notification_ipc_request_load_noti_by_priv_id(notification_h noti, const char *pkgname, int priv_id, uid_t uid)
957 GDBusMessage *reply = NULL;
959 GVariant *reply_body;
962 result = _dbus_init();
963 if (result != NOTIFICATION_ERROR_NONE) {
964 NOTIFICATION_ERR("Can't init dbus %d", result);
971 body = g_variant_new("(sii)", pkgname, priv_id, uid);
972 result = _send_sync_noti(body, &reply, "load_noti_by_priv_id");
974 if (result == NOTIFICATION_ERROR_NONE) {
975 reply_body = g_dbus_message_get_body(reply);
976 g_variant_get(reply_body, "(v)", ¬i_body);
978 notification_ipc_make_noti_from_gvariant(noti, noti_body);
979 g_variant_unref(noti_body);
984 g_object_unref(reply);
986 NOTIFICATION_DBG("notification_ipc_request_load_noti_by_priv_id done [result: %d]", result);
991 /* LCOV_EXCL_START */
992 int notification_ipc_request_get_count(notification_type_e type,
993 const char *pkgname, int group_id, int priv_id, int *count, uid_t uid)
996 GDBusMessage *reply = NULL;
998 GVariant *reply_body;
1001 result = _dbus_init();
1002 if (result != NOTIFICATION_ERROR_NONE) {
1003 NOTIFICATION_ERR("Can't init dbus %d", result);
1010 body = g_variant_new("(isiii)", type, pkgname, group_id, priv_id, uid);
1011 result = _send_sync_noti(body, &reply, "get_noti_count");
1013 if (result == NOTIFICATION_ERROR_NONE) {
1014 reply_body = g_dbus_message_get_body(reply);
1015 g_variant_get(reply_body, "(i)", &re_count);
1018 NOTIFICATION_DBG("noti count [%d]", re_count);
1022 g_object_unref(reply);
1024 NOTIFICATION_DBG("notification_ipc_request_get_count done [result: %d]", result);
1027 /* LCOV_EXCL_STOP */
1029 int notification_ipc_request_load_noti_grouping_list(notification_type_e type, int count,
1030 notification_list_h *list, uid_t uid)
1033 GDBusMessage *reply = NULL;
1035 GVariant *reply_body;
1036 GVariant *iter_body;
1038 notification_h noti;
1039 GVariant *noti_body;
1041 result = _dbus_init();
1042 if (result != NOTIFICATION_ERROR_NONE) {
1043 NOTIFICATION_ERR("Can't init dbus %d", result);
1047 body = g_variant_new("(iii)", type, count, uid);
1048 result = _send_sync_noti(body, &reply, "load_noti_grouping_list");
1050 if (result == NOTIFICATION_ERROR_NONE) {
1051 reply_body = g_dbus_message_get_body(reply);
1052 g_variant_get(reply_body, "(a(v))", &iter);
1054 while (g_variant_iter_loop(iter, "(v)", &iter_body)) {
1055 noti = notification_create(NOTIFICATION_TYPE_NOTI);
1057 result = NOTIFICATION_ERROR_OUT_OF_MEMORY;
1058 NOTIFICATION_ERR("failed to create a notification");
1059 notification_free_list(*list);
1062 g_variant_get(iter_body, "(v)", ¬i_body);
1063 notification_ipc_make_noti_from_gvariant(noti, noti_body);
1064 *list = notification_list_append(*list, noti);
1065 g_variant_unref(noti_body);
1067 g_variant_iter_free(iter);
1071 g_object_unref(reply);
1073 NOTIFICATION_DBG("notification_ipc_request_load_noti_grouping_list done [result: %d]", result);
1077 int notification_ipc_request_load_noti_detail_list(const char *pkgname,
1081 notification_list_h *list,
1085 GDBusMessage *reply = NULL;
1087 GVariant *reply_body;
1088 GVariant *iter_body;
1090 notification_h noti;
1091 GVariant *noti_body;
1093 result = _dbus_init();
1094 if (result != NOTIFICATION_ERROR_NONE) {
1095 NOTIFICATION_ERR("Can't init dbus %d", result);
1099 body = g_variant_new("(siiii)", pkgname, group_id, priv_id, count, uid);
1100 result = _send_sync_noti(body, &reply, "load_noti_detail_list");
1102 if (result == NOTIFICATION_ERROR_NONE) {
1103 reply_body = g_dbus_message_get_body(reply);
1104 g_variant_get(reply_body, "(a(v))", &iter);
1106 while (g_variant_iter_loop(iter, "(v)", &iter_body)) {
1107 noti = notification_create(NOTIFICATION_TYPE_NOTI);
1109 result = NOTIFICATION_ERROR_OUT_OF_MEMORY;
1110 NOTIFICATION_ERR("failed to create a notification");
1111 notification_free_list(*list);
1114 g_variant_get(iter_body, "(v)", ¬i_body);
1115 notification_ipc_make_noti_from_gvariant(noti, noti_body);
1116 *list = notification_list_append(*list, noti);
1117 g_variant_unref(noti_body);
1119 g_variant_iter_free(iter);
1123 g_object_unref(reply);
1125 NOTIFICATION_DBG("notification_ipc_request_load_noti_detail_list done [result: %d]", result);
1129 int notification_ipc_request_get_setting_array(
1130 notification_setting_h *setting_array,
1135 GDBusMessage *reply = NULL;
1136 GVariant *reply_body;
1137 GVariant *iter_body;
1140 notification_setting_h result_setting_array;
1141 notification_setting_h temp;
1144 result = _dbus_init();
1145 if (result != NOTIFICATION_ERROR_NONE) {
1146 NOTIFICATION_ERR("Can't init dbus %d", result);
1150 result = _send_sync_noti(g_variant_new("(i)", uid), &reply, "get_setting_array");
1152 if (result == NOTIFICATION_ERROR_NONE) {
1153 reply_body = g_dbus_message_get_body(reply);
1154 g_variant_get(reply_body, "(ia(v))", &setting_cnt, &iter);
1156 NOTIFICATION_DBG("get setting arr cnt: %d", setting_cnt);
1157 result_setting_array = (struct notification_setting *)malloc(sizeof(struct notification_setting) * setting_cnt);
1158 if (result_setting_array == NULL) {
1159 NOTIFICATION_ERR("malloc failed");
1160 g_object_unref(reply);
1161 g_variant_iter_free(iter);
1162 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1166 while (g_variant_iter_loop(iter, "(v)", &iter_body)) {
1167 temp = result_setting_array + setting_idx;
1168 notification_ipc_make_setting_from_gvariant(temp, iter_body);
1172 *count = setting_cnt;
1173 *setting_array = result_setting_array;
1174 g_variant_iter_free(iter);
1178 g_object_unref(reply);
1180 NOTIFICATION_DBG("notification_ipc_request_get_setting_array done [result: %d]", result);
1184 int notification_ipc_request_get_setting_by_package_name(
1185 const char *package_name, notification_setting_h *setting, uid_t uid)
1188 GDBusMessage *reply = NULL;
1190 GVariant *reply_body;
1191 GVariant *setting_body;
1192 notification_setting_h result_setting;
1194 result = _dbus_init();
1195 if (result != NOTIFICATION_ERROR_NONE) {
1196 NOTIFICATION_ERR("Can't init dbus %d", result);
1200 body = g_variant_new("(si)", package_name, uid);
1201 result = _send_sync_noti(body, &reply, "get_setting_by_package_name");
1203 if (result == NOTIFICATION_ERROR_NONE) {
1204 reply_body = g_dbus_message_get_body(reply);
1205 g_variant_get(reply_body, "(v)", &setting_body);
1207 result_setting = (struct notification_setting *)malloc(sizeof(struct notification_setting));
1208 if (result_setting == NULL) {
1209 NOTIFICATION_ERR("malloc failed");
1210 g_object_unref(reply);
1211 g_variant_unref(body);
1212 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1214 notification_ipc_make_setting_from_gvariant(result_setting, setting_body);
1216 *setting = result_setting;
1217 g_variant_unref(setting_body);
1221 g_object_unref(reply);
1223 NOTIFICATION_DBG("notification_ipc_request_get_setting_by_package_name done [result: %d]", result);
1227 int notification_ipc_request_load_system_setting(notification_system_setting_h *setting, uid_t uid)
1230 GDBusMessage *reply = NULL;
1231 GVariant *setting_body;
1232 GVariant *reply_body;
1233 notification_system_setting_h result_setting;
1235 result = _dbus_init();
1236 if (result != NOTIFICATION_ERROR_NONE) {
1237 NOTIFICATION_ERR("Can't init dbus %d", result);
1241 result = _send_sync_noti(g_variant_new("(i)", uid), &reply, "load_system_setting");
1243 if (result == NOTIFICATION_ERROR_NONE) {
1244 reply_body = g_dbus_message_get_body(reply);
1245 g_variant_get(reply_body, "(v)", &setting_body);
1247 result_setting = (struct notification_system_setting *)malloc(sizeof(struct notification_system_setting));
1248 if (result_setting == NULL) {
1249 NOTIFICATION_ERR("malloc failed");
1250 g_object_unref(reply);
1251 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1253 notification_ipc_make_system_setting_from_gvariant(result_setting, setting_body);
1255 *setting = result_setting;
1256 g_variant_unref(setting_body);
1260 g_object_unref(reply);
1262 NOTIFICATION_DBG("notification_ipc_request_load_system_setting done [result: %d]", result);
1266 int notification_ipc_update_setting(notification_setting_h setting, uid_t uid)
1269 GDBusMessage *reply = NULL;
1272 result = _dbus_init();
1273 if (result != NOTIFICATION_ERROR_NONE) {
1274 NOTIFICATION_ERR("Can't init dbus %d", result);
1278 body = g_variant_new("(siiiiii)",
1279 setting->package_name,
1280 (int)(setting->allow_to_notify),
1281 (int)(setting->do_not_disturb_except),
1282 (int)(setting->visibility_class),
1283 (int)(setting->pop_up_notification),
1284 (int)(setting->lock_screen_content_level),
1287 result = _send_sync_noti(body, &reply, "update_noti_setting");
1290 g_object_unref(reply);
1292 NOTIFICATION_DBG("notification_ipc_update_setting done [result: %d]", result);
1296 int notification_ipc_update_system_setting(notification_system_setting_h system_setting, uid_t uid)
1299 GDBusMessage *reply = NULL;
1302 result = _dbus_init();
1303 if (result != NOTIFICATION_ERROR_NONE) {
1304 NOTIFICATION_ERR("Can't init dbus %d", result);
1308 body = g_variant_new("(iiiiiiiiii)",
1309 (int)(system_setting->do_not_disturb),
1310 (int)(system_setting->visibility_class),
1311 (int)(system_setting->dnd_schedule_enabled),
1312 (int)(system_setting->dnd_schedule_day),
1313 (int)(system_setting->dnd_start_hour),
1314 (int)(system_setting->dnd_start_min),
1315 (int)(system_setting->dnd_end_hour),
1316 (int)(system_setting->dnd_end_min),
1317 (int)(system_setting->lock_screen_content_level),
1320 result = _send_sync_noti(body, &reply, "update_noti_sys_setting");
1323 g_object_unref(reply);
1325 NOTIFICATION_DBG("notification_ipc_update_system_setting done [result: %d]", result);
1329 int notification_ipc_request_save_as_template(notification_h noti, const char *template_name)
1332 GDBusMessage *reply = NULL;
1335 result = _dbus_init();
1336 if (result != NOTIFICATION_ERROR_NONE) {
1337 NOTIFICATION_ERR("Can't init dbus %d", result);
1341 body = notification_ipc_make_gvariant_from_noti(noti, false);
1343 NOTIFICATION_ERR("cannot make gvariant");
1344 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1347 result = _send_sync_noti(g_variant_new("(vs)", body, template_name), &reply, "save_as_template");
1350 g_object_unref(reply);
1352 NOTIFICATION_DBG("notification_ipc_request_save_as_template [result: %d]", result);
1356 int notification_ipc_request_create_from_template(notification_h noti, const char *template_name)
1359 GDBusMessage *reply = NULL;
1361 GVariant *reply_body;
1362 GVariant *noti_body;
1365 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1367 result = _dbus_init();
1368 if (result != NOTIFICATION_ERROR_NONE) {
1369 NOTIFICATION_ERR("Can't init dbus %d", result);
1373 body = g_variant_new("(s)", template_name);
1375 result = _send_sync_noti(body, &reply, "create_from_template");
1376 if (result == NOTIFICATION_ERROR_NONE) {
1377 reply_body = g_dbus_message_get_body(reply);
1378 g_variant_get(reply_body, "(v)", ¬i_body);
1380 notification_ipc_make_noti_from_gvariant(noti, noti_body);
1381 g_variant_unref(noti_body);
1387 g_object_unref(reply);
1389 NOTIFICATION_DBG("notification_ipc_request_create_from_template done [result: %d]", result);
1394 int notification_ipc_request_create_from_package_template(notification_h noti, const char *pkgname, const char *template_name)
1397 GDBusMessage *reply = NULL;
1399 GVariant *reply_body;
1400 GVariant *noti_body;
1402 if (pkgname == NULL || template_name == NULL)
1403 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1405 result = _dbus_init();
1406 if (result != NOTIFICATION_ERROR_NONE) {
1407 NOTIFICATION_ERR("Can't init dbus %d", result);
1411 body = g_variant_new("(ss)", pkgname, template_name);
1413 result = _send_sync_noti(body, &reply, "create_from_package_template");
1414 if (result == NOTIFICATION_ERROR_NONE) {
1415 reply_body = g_dbus_message_get_body(reply);
1416 g_variant_get(reply_body, "(v)", ¬i_body);
1418 notification_ipc_make_noti_from_gvariant(noti, noti_body);
1419 g_variant_unref(noti_body);
1424 g_object_unref(reply);
1426 NOTIFICATION_DBG("notification_ipc_request_create_from_package_template [result: %d]", result);
1431 int notification_ipc_get_noti_block_state(const char *pkgname, int *do_not_disturb,
1432 int *do_not_disturb_except, int *allow_to_notify,
1439 GDBusMessage *reply = NULL;
1441 GVariant *reply_body;
1442 GVariant *result_body;
1444 if (pkgname == NULL)
1445 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1448 if (ret != NOTIFICATION_ERROR_NONE) {
1449 NOTIFICATION_ERR("Can't init dbus %d", ret);
1453 body = g_variant_new("(si)", pkgname, uid);
1455 ret = _send_sync_noti(body, &reply, "get_noti_block_state");
1457 if (ret == NOTIFICATION_ERROR_NONE) {
1458 reply_body = g_dbus_message_get_body(reply);
1459 g_variant_get(reply_body, "(v)", &result_body);
1460 g_variant_get(result_body, "(iii)", &dnd, &dnd_except, &allow);
1461 *do_not_disturb = dnd;
1462 *do_not_disturb_except = dnd_except;
1463 *allow_to_notify = allow;
1464 g_variant_unref(result_body);
1468 g_object_unref(reply);
1470 NOTIFICATION_DBG("notification_ipc_get_noti_block_state done");
1475 EXPORT_API GVariant *notification_ipc_make_gvariant_from_noti(notification_h noti, bool translate)
1477 NOTIFICATION_DBG("make gvariant from noti");
1479 int b_encode_len = 0;
1480 bundle_raw *args = NULL;
1481 bundle_raw *group_args = NULL;
1482 bundle_raw *b_image_path = NULL;
1483 bundle_raw *b_execute_option = NULL;
1484 bundle_raw *b_service_responding = NULL;
1485 bundle_raw *b_service_single_launch = NULL;
1486 bundle_raw *b_service_multi_launch = NULL;
1487 bundle_raw *b_event_handler[NOTIFICATION_EVENT_TYPE_MAX] = {NULL, };
1488 bundle_raw *b_text = NULL;
1489 bundle_raw *b_key = NULL;
1490 bundle_raw *b_format_args = NULL;
1491 GVariant *body = NULL;
1492 GVariant *result_body = NULL;
1493 GVariantBuilder builder;
1496 notification_translate_localized_text(noti);
1498 g_variant_builder_init(&builder, G_VARIANT_TYPE("a{iv}"));
1499 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_NOTI_TYPE, g_variant_new_int32(noti->type));
1500 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_LAYOUT, g_variant_new_int32(noti->layout));
1501 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_GROUP_ID, g_variant_new_int32(noti->group_id));
1502 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_INTERNAL_GROUP_ID, g_variant_new_int32(noti->internal_group_id));
1503 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_PRIV_ID, g_variant_new_int32(noti->priv_id));
1504 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_CALLER_PKGNAME, g_variant_new_string((const gchar *)noti->caller_pkgname));
1505 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_DISPLAY_APPLIST, g_variant_new_int32(noti->display_applist));
1508 bundle_encode(noti->args, (bundle_raw **)&args, NULL);
1509 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_ARGS, g_variant_new_string((const gchar *)args));
1512 bundle_free_encoded_rawdata(&args);
1515 if (noti->group_args) {
1516 bundle_encode(noti->group_args, (bundle_raw **)&group_args,
1518 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_GROUP_ARGS, g_variant_new_string((const gchar *)group_args));
1521 bundle_free_encoded_rawdata(&group_args);
1524 if (noti->b_execute_option) {
1525 bundle_encode(noti->b_execute_option,
1526 (bundle_raw **)&b_execute_option, &b_encode_len);
1527 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_EXECUTE_OPTION, g_variant_new_string((const gchar *)b_execute_option));
1529 if (b_execute_option)
1530 bundle_free_encoded_rawdata(&b_execute_option);
1533 if (noti->b_service_responding) {
1534 bundle_encode(noti->b_service_responding,
1535 (bundle_raw **)&b_service_responding, &b_encode_len);
1536 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_SERVICE_RESPONDING, g_variant_new_string((const gchar *)b_service_responding));
1538 if (b_service_responding)
1539 bundle_free_encoded_rawdata(&b_service_responding);
1542 if (noti->b_service_single_launch) {
1543 bundle_encode(noti->b_service_single_launch,
1544 (bundle_raw **)&b_service_single_launch, &b_encode_len);
1545 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_SERVICE_SINGLE_LAUNCH, g_variant_new_string((const gchar *)b_service_single_launch));
1547 if (b_service_single_launch)
1548 bundle_free_encoded_rawdata(&b_service_single_launch);
1551 if (noti->b_service_multi_launch) {
1552 bundle_encode(noti->b_service_multi_launch,
1553 (bundle_raw **)&b_service_multi_launch, &b_encode_len);
1554 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_SERVICE_MULTI_LAUNCH, g_variant_new_string((const gchar *)b_service_multi_launch));
1556 if (b_service_multi_launch)
1557 bundle_free_encoded_rawdata(&b_service_multi_launch);
1560 for (i = 0; i < NOTIFICATION_EVENT_TYPE_MAX; i++) {
1561 if (noti->b_event_handler[i]) {
1562 bundle_encode(noti->b_event_handler[i],
1563 (bundle_raw **)&b_event_handler[i], &b_encode_len);
1564 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_BUTTON1_EVENT + i, g_variant_new_string((const gchar *)b_event_handler[i]));
1566 if (b_event_handler[i])
1567 bundle_free_encoded_rawdata(&b_event_handler[i]);
1571 if (noti->launch_pkgname)
1572 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_LAUNCH_PKGNAME, g_variant_new_string((const gchar *)noti->launch_pkgname));
1574 if (noti->domain != NULL)
1575 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_DOMAIN, g_variant_new_string((const gchar *)noti->domain));
1577 if (noti->dir != NULL)
1578 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_DIR, g_variant_new_string((const gchar *)noti->dir));
1581 bundle_encode(noti->b_text, (bundle_raw **)&b_text, &b_encode_len);
1582 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_TEXT, g_variant_new_string((const gchar *)b_text));
1585 bundle_free_encoded_rawdata(&b_text);
1589 bundle_encode(noti->b_key, (bundle_raw **)&b_key, &b_encode_len);
1590 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_KEY, g_variant_new_string((const gchar *)b_key));
1593 bundle_free_encoded_rawdata(&b_key);
1596 if (noti->b_format_args) {
1597 bundle_encode(noti->b_format_args,
1598 (bundle_raw **)&b_format_args, &b_encode_len);
1599 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_FORMAT_ARGS, g_variant_new_string((const gchar *)b_format_args));
1602 bundle_free_encoded_rawdata(&b_format_args);
1605 if (noti->num_format_args != 0)
1606 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_NUM_FORMAT_ARGS, g_variant_new_int32(noti->num_format_args));
1608 if (noti->b_image_path) {
1609 bundle_encode(noti->b_image_path,
1610 (bundle_raw **)&b_image_path, &b_encode_len);
1611 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_IMAGE_PATH, g_variant_new_string((const gchar *)b_image_path));
1614 bundle_free_encoded_rawdata(&b_image_path);
1617 if (noti->sound_type != NOTIFICATION_SOUND_TYPE_NONE)
1618 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_SOUND_TYPE, g_variant_new_int32(noti->sound_type));
1620 if (noti->sound_path)
1621 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_SOUND_PATH, g_variant_new_string((const gchar *)noti->sound_path));
1623 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_VIBRATION_TYPE, g_variant_new_int32(noti->vibration_type));
1625 if (noti->vibration_path)
1626 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_VIBRATION_PATH, g_variant_new_string((const gchar *)noti->vibration_path));
1628 if (noti->led_operation != NOTIFICATION_LED_OP_OFF)
1629 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_LED_OPERATION, g_variant_new_int32(noti->led_operation));
1631 if (noti->led_argb != 0)
1632 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_LED_ARGB, g_variant_new_int32(noti->led_argb));
1634 if (noti->led_on_ms != 0)
1635 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_LED_ON_MS, g_variant_new_int32(noti->led_on_ms));
1637 if (noti->led_off_ms != 0)
1638 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_LED_OFF_MS, g_variant_new_int32(noti->led_off_ms));
1640 if (noti->time != 0)
1641 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_TIME, g_variant_new_int32(noti->time));
1643 if (noti->insert_time != 0)
1644 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_INSERT_TIME, g_variant_new_int32(noti->insert_time));
1646 if (noti->flags_for_property != 0)
1647 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_FLAGS_FOR_PROPERTY, g_variant_new_int32(noti->flags_for_property));
1649 if (noti->progress_size != 0.0)
1650 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_PROGRESS_SIZE, g_variant_new_double(noti->progress_size));
1652 if (noti->progress_percentage != 0.0)
1653 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_PROGRESS_PERCENTAGE, g_variant_new_double(noti->progress_percentage));
1655 if (noti->app_icon_path != NULL)
1656 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_APP_ICON_PATH, g_variant_new_string((const gchar *)noti->app_icon_path));
1657 if (noti->app_name != NULL)
1658 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_APP_NAME, g_variant_new_string((const gchar *)noti->app_name));
1659 if (noti->temp_title != NULL)
1660 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_TEMP_TITLE, g_variant_new_string((const gchar *)noti->temp_title));
1661 if (noti->temp_content != NULL)
1662 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_TEMP_CONTENT, g_variant_new_string((const gchar *)noti->temp_content));
1663 if (noti->tag != NULL)
1664 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_TAG, g_variant_new_string((const gchar *)noti->tag));
1666 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_ONGOING_FLAG, g_variant_new_int32(noti->ongoing_flag));
1667 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_ONGOING_VALUE_TYPE, g_variant_new_int32(noti->ongoing_value_type));
1668 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_ONGOING_CURRENT, g_variant_new_int32(noti->ongoing_current));
1669 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_ONGOING_DURATION, g_variant_new_int32(noti->ongoing_duration));
1670 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_AUTO_REMOVE, g_variant_new_int32(noti->auto_remove));
1671 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_DEFAULT_BUTTON, g_variant_new_int32(noti->default_button_index));
1672 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_TIMEOUT, g_variant_new_int32(noti->timeout));
1673 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_UID, g_variant_new_int32(noti->uid));
1675 result_body = g_variant_builder_end(&builder);
1676 body = g_variant_new("(v)", result_body);
1681 static gboolean _variant_to_int_dict(GHashTable **dict, GVariant *variant)
1688 *dict = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, (GDestroyNotify)g_variant_unref);
1692 g_variant_iter_init(&iter, variant);
1693 while (g_variant_iter_next(&iter, "{iv}", &key, &value)) {
1694 hash_key = (int *)calloc(sizeof(int), 1);
1695 if (hash_key == NULL) {
1696 g_hash_table_unref(*dict);
1700 g_hash_table_insert(*dict, (gpointer)hash_key, value);
1705 static gboolean _variant_dict_lookup(GHashTable *dict,
1707 const gchar *format_string,
1713 value = g_hash_table_lookup(dict, (gpointer)&key);
1715 if (value == NULL || !g_variant_check_format_string(value, format_string, FALSE))
1718 va_start(ap, format_string);
1719 g_variant_get_va(value, format_string, NULL, &ap);
1726 * functions creating notification packet
1728 EXPORT_API int notification_ipc_make_noti_from_gvariant(notification_h noti,
1729 GVariant *variant) {
1731 NOTIFICATION_DBG("make noti from GVariant");
1735 char *caller_pkgname = NULL;
1736 char *launch_pkgname = NULL;
1737 bundle_raw *args = NULL;
1738 bundle_raw *group_args = NULL;
1739 bundle_raw *b_execute_option = NULL;
1740 bundle_raw *b_service_responding = NULL;
1741 bundle_raw *b_service_single_launch = NULL;
1742 bundle_raw *b_service_multi_launch = NULL;
1743 bundle_raw *b_event_handler[NOTIFICATION_EVENT_TYPE_MAX] = { NULL, };
1744 char *domain = NULL;
1746 bundle_raw *b_text = NULL;
1747 bundle_raw *b_key = NULL;
1748 bundle_raw *b_format_args = NULL;
1749 bundle_raw *b_image_path = NULL;
1750 char *sound_path = NULL;
1751 char *vibration_path = NULL;
1752 char *app_icon_path = NULL;
1753 char *app_name = NULL;
1754 char *temp_title = NULL;
1755 char *temp_content = NULL;
1759 NOTIFICATION_ERR("invalid data noti NULL");
1760 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1763 if (variant == NULL) {
1764 NOTIFICATION_ERR("invalid data variant NULL");
1765 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1768 if (!_variant_to_int_dict(&dict, variant))
1769 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1771 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_NOTI_TYPE, "i", ¬i->type);
1772 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_LAYOUT, "i", ¬i->layout);
1773 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_GROUP_ID, "i", ¬i->group_id);
1774 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_INTERNAL_GROUP_ID, "i", ¬i->internal_group_id);
1775 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_PRIV_ID, "i", ¬i->priv_id);
1776 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_CALLER_PKGNAME, "&s", &caller_pkgname);
1777 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_LAUNCH_PKGNAME, "&s", &launch_pkgname);
1778 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_ARGS, "&s", &args);
1779 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_GROUP_ARGS, "&s", &group_args);
1780 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_EXECUTE_OPTION, "&s", &b_execute_option);
1781 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_SERVICE_RESPONDING, "&s", &b_service_responding);
1782 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_SERVICE_SINGLE_LAUNCH, "&s", &b_service_single_launch);
1783 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_SERVICE_MULTI_LAUNCH, "&s", &b_service_multi_launch);
1784 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_BUTTON1_EVENT, "&s", &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_1]);
1785 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_BUTTON2_EVENT, "&s", &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_2]);
1786 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_BUTTON3_EVENT, "&s", &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_3]);
1787 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_BUTTON4_EVENT, "&s", &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_4]);
1788 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_BUTTON5_EVENT, "&s", &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_5]);
1789 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_BUTTON6_EVENT, "&s", &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_6]);
1790 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_ICON_EVENT, "&s", &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_ICON]);
1791 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_THUMBNAIL_EVENT, "&s", &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_THUMBNAIL]);
1792 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_DOMAIN, "&s", &domain);
1793 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_DIR, "&s", &dir);
1794 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_TEXT, "&s", &b_text);
1795 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_KEY, "&s", &b_key);
1796 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_FORMAT_ARGS, "&s", &b_format_args);
1797 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_NUM_FORMAT_ARGS, "i", ¬i->num_format_args);
1798 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_IMAGE_PATH, "&s", &b_image_path);
1799 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_SOUND_TYPE, "i", ¬i->sound_type);
1800 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_SOUND_PATH, "&s", &sound_path);
1801 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_VIBRATION_TYPE, "i", ¬i->vibration_type);
1802 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_VIBRATION_PATH, "&s", &vibration_path);
1803 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_LED_OPERATION, "i", ¬i->led_operation);
1804 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_LED_ARGB, "i", ¬i->led_argb);
1805 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_LED_ON_MS, "i", ¬i->led_on_ms);
1806 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_LED_OFF_MS, "i", ¬i->led_off_ms);
1807 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_TIME, "i", ¬i->time);
1808 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_INSERT_TIME, "i", ¬i->insert_time);
1809 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_FLAGS_FOR_PROPERTY, "i", ¬i->flags_for_property);
1810 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_DISPLAY_APPLIST, "i", ¬i->display_applist);
1811 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_PROGRESS_SIZE, "d", ¬i->progress_size);
1812 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_PROGRESS_PERCENTAGE, "d", ¬i->progress_percentage);
1813 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_APP_ICON_PATH, "&s", &app_icon_path);
1814 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_APP_NAME, "&s", &app_name);
1815 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_TEMP_TITLE, "&s", &temp_title);
1816 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_TEMP_CONTENT, "&s", &temp_content);
1817 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_TAG, "&s", &tag);
1818 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_ONGOING_FLAG, "i", ¬i->ongoing_flag);
1819 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_ONGOING_VALUE_TYPE, "i", ¬i->ongoing_value_type);
1820 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_ONGOING_CURRENT, "i", ¬i->ongoing_current);
1821 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_ONGOING_DURATION, "i", ¬i->ongoing_duration);
1822 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_AUTO_REMOVE, "i", ¬i->auto_remove);
1823 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_DEFAULT_BUTTON, "i", ¬i->default_button_index);
1824 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_TIMEOUT, "i", ¬i->timeout);
1825 _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_UID, "i", ¬i->uid);
1827 noti->caller_pkgname = _dup_string(caller_pkgname);
1828 noti->launch_pkgname = _dup_string(launch_pkgname);
1829 noti->args = _create_bundle_from_bundle_raw(args);
1830 noti->group_args = _create_bundle_from_bundle_raw(group_args);
1831 noti->b_execute_option = _create_bundle_from_bundle_raw(b_execute_option);
1832 noti->b_service_responding = _create_bundle_from_bundle_raw(
1833 b_service_responding);
1834 noti->b_service_single_launch = _create_bundle_from_bundle_raw(
1835 b_service_single_launch);
1836 noti->b_service_multi_launch = _create_bundle_from_bundle_raw(
1837 b_service_multi_launch);
1838 for (i = 0; i < NOTIFICATION_EVENT_TYPE_MAX; i++) {
1839 noti->b_event_handler[i] = _create_bundle_from_bundle_raw(
1840 b_event_handler[i]);
1842 noti->domain = _dup_string(domain);
1843 noti->dir = _dup_string(dir);
1844 noti->b_text = _create_bundle_from_bundle_raw(b_text);
1845 noti->b_key = _create_bundle_from_bundle_raw(b_key);
1846 noti->b_format_args = _create_bundle_from_bundle_raw(b_format_args);
1847 noti->b_image_path = _create_bundle_from_bundle_raw(b_image_path);
1848 noti->sound_path = _dup_string(sound_path);
1849 noti->vibration_path = _dup_string(vibration_path);
1850 noti->app_icon_path = _dup_string(app_icon_path);
1851 noti->app_name = _dup_string(app_name);
1852 noti->temp_title = _dup_string(temp_title);
1853 noti->temp_content = _dup_string(temp_content);
1854 noti->tag = _dup_string(tag);
1856 g_hash_table_unref(dict);
1858 return NOTIFICATION_ERROR_NONE;
1861 EXPORT_API GVariant *notification_ipc_make_gvariant_from_system_setting(struct notification_system_setting *noti_setting)
1863 GVariant *body = NULL;
1864 body = g_variant_new("(iiiiiiiii)",
1865 noti_setting->do_not_disturb,
1866 noti_setting->visibility_class,
1867 noti_setting->dnd_schedule_enabled,
1868 noti_setting->dnd_schedule_day,
1869 noti_setting->dnd_start_hour,
1870 noti_setting->dnd_start_min,
1871 noti_setting->dnd_end_hour,
1872 noti_setting->dnd_end_min,
1873 noti_setting->lock_screen_content_level);
1877 EXPORT_API int notification_ipc_make_system_setting_from_gvariant(struct notification_system_setting *noti_setting,
1881 int visibility_class;
1882 int dnd_schedule_enabled;
1883 int dnd_schedule_day;
1888 int lock_screen_content_level;
1890 if (noti_setting == NULL) {
1891 NOTIFICATION_ERR("invalid data");
1892 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1895 g_variant_get(variant,
1899 &dnd_schedule_enabled,
1905 &lock_screen_content_level);
1907 NOTIFICATION_DBG("system setting #### %d, %d, %d, %d, [%d:%d] [%d:%d], %d",
1908 do_not_disturb, visibility_class, dnd_schedule_enabled,
1909 dnd_schedule_day, dnd_start_hour, dnd_start_min,
1910 dnd_end_hour, dnd_end_min, lock_screen_content_level);
1912 noti_setting->do_not_disturb = do_not_disturb;
1913 noti_setting->visibility_class = visibility_class;
1914 noti_setting->dnd_schedule_enabled = dnd_schedule_enabled;
1915 noti_setting->dnd_schedule_day = dnd_schedule_day;
1916 noti_setting->dnd_start_hour = dnd_start_hour;
1917 noti_setting->dnd_start_min = dnd_start_min;
1918 noti_setting->dnd_end_hour = dnd_end_hour;
1919 noti_setting->dnd_end_min = dnd_end_min;
1920 noti_setting->lock_screen_content_level = lock_screen_content_level;
1922 return NOTIFICATION_ERROR_NONE;
1925 EXPORT_API GVariant *notification_ipc_make_gvariant_from_setting(struct notification_setting *noti_setting)
1927 GVariant *body = NULL;
1929 body = g_variant_new("(siiiii)",
1930 noti_setting->package_name,
1931 noti_setting->allow_to_notify,
1932 noti_setting->do_not_disturb_except,
1933 noti_setting->visibility_class,
1934 noti_setting->pop_up_notification,
1935 noti_setting->lock_screen_content_level);
1940 EXPORT_API int notification_ipc_make_setting_from_gvariant(struct notification_setting *noti_setting,
1943 NOTIFICATION_DBG("notification_ipc_make_setting_from_gvariant !!!!");
1945 int allow_to_notify;
1946 int do_not_disturb_except;
1947 int visibility_class;
1948 int pop_up_notification;
1949 int lock_screen_content_level;
1951 if (noti_setting == NULL || variant == NULL) {
1952 NOTIFICATION_ERR("invalid data");
1953 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1955 g_variant_get(variant,
1959 &do_not_disturb_except,
1961 &pop_up_notification,
1962 &lock_screen_content_level);
1964 NOTIFICATION_DBG("setting from variant %s !!", pkgname);
1966 noti_setting->package_name = _dup_string(pkgname);
1967 noti_setting->allow_to_notify = allow_to_notify;
1968 noti_setting->do_not_disturb_except = do_not_disturb_except;
1969 noti_setting->visibility_class = visibility_class;
1970 noti_setting->pop_up_notification = pop_up_notification;
1971 noti_setting->lock_screen_content_level = lock_screen_content_level;
1973 NOTIFICATION_DBG("setting from variant %s, %s",
1974 noti_setting->package_name, pkgname);
1976 return NOTIFICATION_ERROR_NONE;
1979 static int _send_service_register(uid_t uid)
1981 GDBusMessage *reply = NULL;
1983 notification_op *noti_op = NULL;
1985 result = _send_sync_noti(g_variant_new("(i)", uid), &reply, "noti_service_register");
1988 g_object_unref(reply);
1990 NOTIFICATION_DBG("_send_service_register done = %s, result = %d", _bus_name, result);
1991 noti_op = _ipc_create_op(NOTIFICATION_OP_SERVICE_READY, 1, NULL, 1, NULL);
1992 if (noti_op != NULL) {
1993 notification_call_changed_cb_for_uid(noti_op, 1, uid);
2000 static int _ipc_monitor_register(uid_t uid)
2002 return _send_service_register(uid);
2005 /* LCOV_EXCL_START */
2006 static void _on_name_appeared(GDBusConnection *connection,
2008 const gchar *name_owner,
2011 int uid = GPOINTER_TO_INT(user_data);
2013 NOTIFICATION_DBG("name appeared [%d] : %s", uid, name);
2014 is_master_started = 1;
2015 _ipc_monitor_register(uid);
2017 /* TODO: dbus activation isn't enough ? */
2018 _do_deffered_task();
2020 /* LCOV_EXCL_STOP */
2022 /* LCOV_EXCL_START */
2023 static void _on_name_vanished(GDBusConnection *connection,
2027 int uid = GPOINTER_TO_INT(user_data);
2029 NOTIFICATION_DBG("name vanished [%d] : %s", uid, name);
2030 is_master_started = 0;
2032 /* LCOV_EXCL_STOP */
2034 int notification_ipc_monitor_init(uid_t uid)
2039 if (ret != NOTIFICATION_ERROR_NONE) {
2040 /* LCOV_EXCL_START */
2041 NOTIFICATION_ERR("Can't init dbus %d", ret);
2043 /* LCOV_EXCL_STOP */
2046 ret = _dbus_signal_init();
2047 if (ret != NOTIFICATION_ERROR_NONE) {
2048 /* LCOV_EXCL_START */
2049 NOTIFICATION_ERR("Can't signal_init %d", ret);
2051 /* LCOV_EXCL_STOP */
2054 ret = _ipc_monitor_register(uid);
2055 if (ret != NOTIFICATION_ERROR_NONE) {
2056 /* LCOV_EXCL_START */
2057 NOTIFICATION_ERR("Can't init ipc_monitor_register %d", ret);
2059 /* LCOV_EXCL_STOP */
2062 if (provider_monitor_id == 0) {
2064 provider_monitor_id = g_bus_watch_name_on_connection(
2067 G_BUS_NAME_WATCHER_FLAGS_NONE,
2070 GINT_TO_POINTER((int)uid),
2072 if (provider_monitor_id == 0) {
2073 /* LCOV_EXCL_START */
2074 g_dbus_connection_signal_unsubscribe(_gdbus_conn, monitor_id);
2076 NOTIFICATION_ERR("watch on name fail");
2077 return NOTIFICATION_ERROR_IO_ERROR;
2078 /* LCOV_EXCL_STOP */
2082 return NOTIFICATION_ERROR_NONE;
2085 static int _ipc_monitor_deregister(void)
2087 if (provider_monitor_id) {
2088 g_bus_unwatch_name(provider_monitor_id);
2089 provider_monitor_id = 0;
2093 g_dbus_connection_signal_unsubscribe(_gdbus_conn, monitor_id);
2097 return NOTIFICATION_ERROR_NONE;
2100 int notification_ipc_monitor_fini(void)
2102 return _ipc_monitor_deregister();