2 * Copyright 2016 Samsung Electronics Co., Ltd
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.
21 #include <gio/gunixfdlist.h>
24 #include <sys/smack.h>
25 #include <pkgmgr-info.h>
26 #include <notification.h>
31 #include "service_common.h"
32 #include "notification_service.h"
35 #include <notification_noti.h>
36 #include <notification_internal.h>
37 #include <notification_ipc.h>
38 #include <notification_setting_service.h>
39 #include <notification_db.h>
40 #include <notification_viewer.h>
41 #include <notification_shared_file.h>
43 #define PROVIDER_NOTI_INTERFACE_NAME "org.tizen.data_provider_noti_service"
44 #define PROVIDER_NOTI_EVENT_INTERFACE_NAME "org.tizen.data_provider_noti_event_service"
45 #define NOTI_TEMPLATE_LIMIT 10
48 typedef struct _dnd_alarm_id dnd_alarm_id_s;
50 static GHashTable *_monitoring_hash;
52 static GList *_dnd_alarm_id_list;
54 typedef struct _dnd_alarm_id {
56 alarm_id_t dnd_start_id;
57 alarm_id_t dnd_end_id;
60 static GList *__event_list;
62 typedef struct _event_sender_info {
66 } event_sender_info_s;
68 static int _update_noti(GVariant **reply_body, notification_h noti, uid_t uid);
69 static int _delete_noti(const char *app_id, int priv_id, uid_t uid);
76 * NOTIFICATION SERVICE INITIALIZATION
78 static void __print_noti(notification_h noti)
83 const char *tag = NULL;
85 notification_get_pkgname(noti, &pkgname);
86 notification_get_text(noti, NOTIFICATION_TEXT_TYPE_TITLE, &text);
87 notification_get_text(noti, NOTIFICATION_TEXT_TYPE_CONTENT, &content);
88 notification_get_tag(noti, &tag);
90 DBG("Noti-info : pkgname[%s] title[%s] content[%s] tag[%s]",
91 pkgname, text, content, tag);
94 static void _on_name_appeared(GDBusConnection *connection,
96 const gchar *name_owner,
99 monitoring_info_s *info = (monitoring_info_s *)user_data;
101 DBG("name[%s], uid[%d]", name, info->uid);
104 static void _on_name_vanished(GDBusConnection *connection,
108 monitoring_info_s *info = (monitoring_info_s *)user_data;
111 DBG("name[%s], uid[%d]", name, info->uid);
112 notification_remove_private_sharing_target_id(name, info->uid);
113 g_bus_unwatch_name(info->watcher_id);
114 delete_monitoring_list(&_monitoring_hash, info->bus_name, info->uid);
117 free(info->bus_name);
122 static void _noti_dbus_method_call_handler(GDBusConnection *conn,
123 const gchar *sender, const gchar *object_path,
124 const gchar *iface_name, const gchar *method_name,
125 GVariant *parameters, GDBusMethodInvocation *invocation,
128 /* TODO : sender authority(privilege) check */
129 INFO("notification method_name[%s] sender[%s]", method_name, sender);
131 GVariant *reply_body = NULL;
132 int ret = NOTIFICATION_ERROR_INVALID_OPERATION;
133 uid_t uid = get_sender_uid(sender);
134 pid_t pid = get_sender_pid(sender);
136 if (g_strcmp0(method_name, "noti_service_register") == 0) {
137 ret = service_register(parameters, &reply_body, sender,
138 _on_name_appeared, _on_name_vanished, &_monitoring_hash, uid);
139 if (ret == NOTIFICATION_ERROR_NONE)
140 notification_add_private_sharing_target_id(pid, sender, uid);
141 } else if (g_strcmp0(method_name, "update_noti") == 0) {
142 ret = notification_update_noti(parameters, &reply_body, pid, uid);
143 } else if (g_strcmp0(method_name, "add_noti") == 0) {
144 ret = notification_add_noti(parameters, &reply_body, sender, pid, uid);
145 } else if (g_strcmp0(method_name, "refresh_noti") == 0) {
146 ret = notification_refresh_noti(parameters, &reply_body, uid);
147 } else if (g_strcmp0(method_name, "del_noti_single") == 0) {
148 ret = notification_del_noti_single(parameters, &reply_body, uid);
149 } else if (g_strcmp0(method_name, "del_noti_multiple") == 0) {
150 ret = notification_del_noti_multiple(parameters, &reply_body, uid);
151 } else if (g_strcmp0(method_name, "get_noti_count") == 0) {
152 ret = notification_get_noti_count(parameters, &reply_body, uid);
153 } else if (g_strcmp0(method_name, "get_noti_all_count") == 0) {
154 ret = notification_get_noti_all_count(parameters, &reply_body, uid);
155 } else if (g_strcmp0(method_name, "update_noti_setting") == 0) {
156 ret = notification_update_noti_setting(parameters, &reply_body, uid);
157 } else if (g_strcmp0(method_name, "update_noti_sys_setting") == 0) {
158 ret = notification_update_noti_sys_setting(parameters, &reply_body, uid);
159 } else if (g_strcmp0(method_name, "load_noti_by_tag") == 0) {
160 ret = notification_load_noti_by_tag(parameters, &reply_body, uid);
161 } else if (g_strcmp0(method_name, "load_noti_by_priv_id") == 0) {
162 ret = notification_load_noti_by_priv_id(parameters, &reply_body, uid);
163 } else if (g_strcmp0(method_name, "load_noti_grouping_list") == 0) {
164 notification_add_private_sharing_target_id(pid, sender, uid);
165 notification_load_grouping_list(invocation, parameters, uid);
167 } else if (g_strcmp0(method_name, "load_noti_detail_list") == 0) {
168 notification_add_private_sharing_target_id(pid, sender, uid);
169 ret = notification_load_detail_list(parameters, &reply_body, uid);
170 } else if (g_strcmp0(method_name, "get_setting_array") == 0) {
171 ret = notification_get_setting_array(parameters, &reply_body, uid);
172 } else if (g_strcmp0(method_name, "get_setting_by_app_id") == 0) {
173 ret = notification_get_setting_by_app_id(parameters, &reply_body, uid);
174 } else if (g_strcmp0(method_name, "load_system_setting") == 0) {
175 ret = notification_load_system_setting(parameters, &reply_body, uid);
176 } else if (g_strcmp0(method_name, "save_as_template") == 0) {
177 ret = notification_add_noti_template(parameters, &reply_body, uid);
178 } else if (g_strcmp0(method_name, "create_from_template") == 0) {
179 ret = notification_get_noti_template(parameters, &reply_body, pid, uid);
180 } else if (g_strcmp0(method_name, "create_from_package_template") == 0) {
181 ret = notification_get_noti_package_template(parameters, &reply_body, uid);
182 } else if (g_strcmp0(method_name, "get_noti_block_state") == 0) {
183 ret = notification_get_block_state(parameters, &reply_body, uid);
184 } else if (g_strcmp0(method_name, "load_dnd_allow_exception") == 0) {
185 ret = notification_load_dnd_allow_exception(parameters, &reply_body, uid);
186 } else if (g_strcmp0(method_name, "update_dnd_allow_exception") == 0) {
187 ret = notification_update_dnd_allow_exception(parameters, &reply_body, uid);
188 } else if (g_strcmp0(method_name, "send_noti_event") == 0) {
189 ret = notification_send_noti_event(parameters, &reply_body);
190 } else if (g_strcmp0(method_name, "send_noti_event_by_priv_id") == 0) {
191 ret = notification_send_noti_event_by_priv_id(parameters, &reply_body);
192 } else if (g_strcmp0(method_name, "check_event_receiver") == 0) {
193 ret = notification_check_event_receiver(parameters, &reply_body);
194 } else if (g_strcmp0(method_name, "reset_event_handler") == 0) {
195 ret = notification_reset_event_receiver(parameters, &reply_body, sender);
196 } else if (g_strcmp0(method_name, "del_noti_by_display_applist") == 0) {
197 ret = notification_del_noti_by_display_applist(parameters, &reply_body, uid);
200 if (ret == NOTIFICATION_ERROR_NONE) {
201 INFO("notification service success, method name[%s]", method_name);
202 g_dbus_method_invocation_return_value(
203 invocation, reply_body);
205 ERR("notification service fail, method_name[%s] err[%d]",
207 g_dbus_method_invocation_return_error(
211 "notification service error");
215 static const GDBusInterfaceVTable _noti_interface_vtable = {
216 _noti_dbus_method_call_handler,
221 int notification_register_dbus_interface(void)
223 static gchar introspection_xml[] =
225 " <interface name='org.tizen.data_provider_noti_service'>"
226 " <method name='noti_service_register'>"
227 " <arg type='i' name='uid' direction='in'/>"
230 " <method name='add_noti'>"
231 " <arg type='v' name='noti' direction='in'/>"
232 " <arg type='i' name='priv_id' direction='out'/>"
235 " <method name='update_noti'>"
236 " <arg type='v' name='noti' direction='in'/>"
237 " <arg type='i' name='priv_id' direction='out'/>"
240 " <method name='refresh_noti'>"
241 " <arg type='i' name='uid' direction='in'/>"
244 " <method name='del_noti_single'>"
245 " <arg type='s' name='app_id' direction='in'/>"
246 " <arg type='i' name='priv_id' direction='in'/>"
247 " <arg type='i' name='uid' direction='in'/>"
248 " <arg type='i' name='priv_id' direction='out'/>"
251 " <method name='del_noti_multiple'>"
252 " <arg type='s' name='app_id' direction='in'/>"
253 " <arg type='i' name='priv_id' direction='in'/>"
254 " <arg type='i' name='uid' direction='in'/>"
255 " <arg type='i' name='priv_id' direction='out'/>"
258 " <method name='load_noti_by_tag'>"
259 " <arg type='s' name='app_id' direction='in'/>"
260 " <arg type='s' name='tag' direction='in'/>"
261 " <arg type='i' name='uid' direction='in'/>"
262 " <arg type='v' name='noti' direction='out'/>"
265 " <method name='load_noti_by_priv_id'>"
266 " <arg type='s' name='app_id' direction='in'/>"
267 " <arg type='i' name='priv_id' direction='in'/>"
268 " <arg type='i' name='uid' direction='in'/>"
269 " <arg type='v' name='noti' direction='out'/>"
272 " <method name='load_noti_grouping_list'>"
273 " <arg type='i' name='type' direction='in'/>"
274 " <arg type='i' name='count' direction='in'/>"
275 " <arg type='i' name='count_per_page' direction='in'/>"
276 " <arg type='i' name='uid' direction='in'/>"
277 " <arg type='i' name='list_count' direction='out'/>"
280 " <method name='load_noti_detail_list'>"
281 " <arg type='s' name='app_id' direction='in'/>"
282 " <arg type='i' name='group_id' direction='in'/>"
283 " <arg type='i' name='priv_id' direction='in'/>"
284 " <arg type='i' name='count' direction='in'/>"
285 " <arg type='i' name='uid' direction='in'/>"
286 " <arg type='a(v)' name='noti_list' direction='out'/>"
289 " <method name='get_noti_count'>"
290 " <arg type='i' name='type' direction='in'/>"
291 " <arg type='s' name='app_id' direction='in'/>"
292 " <arg type='i' name='group_id' direction='in'/>"
293 " <arg type='i' name='priv_id' direction='in'/>"
294 " <arg type='i' name='uid' direction='in'/>"
295 " <arg type='i' name='ret_count' direction='out'/>"
298 " <method name='get_noti_all_count'>"
299 " <arg type='i' name='type' direction='in'/>"
300 " <arg type='i' name='uid' direction='in'/>"
301 " <arg type='i' name='ret_count' direction='out'/>"
304 " <method name='update_noti_setting'>"
305 " <arg type='s' name='pkgname' direction='in'/>"
306 " <arg type='s' name='app_id' direction='in'/>"
307 " <arg type='i' name='allow_to_notify' direction='in'/>"
308 " <arg type='i' name='do_not_disturb_except' direction='in'/>"
309 " <arg type='i' name='visibility_class' direction='in'/>"
310 " <arg type='i' name='pop_up_notification' direction='in'/>"
311 " <arg type='i' name='lock_screen_content_level' direction='in'/>"
312 " <arg type='i' name='uid' direction='in'/>"
315 " <method name='update_noti_sys_setting'>"
316 " <arg type='i' name='do_not_disturb' direction='in'/>"
317 " <arg type='i' name='visibility_class' direction='in'/>"
318 " <arg type='i' name='dnd_schedule_enabled' direction='in'/>"
319 " <arg type='i' name='dnd_schedule_day' direction='in'/>"
320 " <arg type='i' name='dnd_start_hour' direction='in'/>"
321 " <arg type='i' name='dnd_start_min' direction='in'/>"
322 " <arg type='i' name='dnd_end_hour' direction='in'/>"
323 " <arg type='i' name='dnd_end_min' direction='in'/>"
324 " <arg type='i' name='lock_screen_level' direction='in'/>"
325 " <arg type='i' name='uid' direction='in'/>"
328 " <method name='get_setting_array'>"
329 " <arg type='i' name='uid' direction='in'/>"
330 " <arg type='i' name='setting_cnt' direction='out'/>"
331 " <arg type='a(v)' name='setting_arr' direction='out'/>"
334 " <method name='get_setting_by_app_id'>"
335 " <arg type='s' name='app_id' direction='in'/>"
336 " <arg type='i' name='uid' direction='in'/>"
337 " <arg type='v' name='setting' direction='out'/>"
340 " <method name='load_system_setting'>"
341 " <arg type='i' name='uid' direction='in'/>"
342 " <arg type='v' name='setting' direction='out'/>"
345 " <method name='save_as_template'>"
346 " <arg type='v' name='noti' direction='in'/>"
347 " <arg type='s' name='name' direction='in'/>"
350 " <method name='create_from_template'>"
351 " <arg type='s' name='name' direction='in'/>"
352 " <arg type='v' name='noti' direction='out'/>"
355 " <method name='create_from_package_template'>"
356 " <arg type='s' name='app_id' direction='in'/>"
357 " <arg type='s' name='name' direction='in'/>"
358 " <arg type='v' name='noti' direction='out'/>"
361 " <method name='get_noti_block_state'>"
362 " <arg type='s' name='app_id' direction='in'/>"
363 " <arg type='i' name='uid' direction='in'/>"
364 " <arg type='v' name='state' direction='out'/>"
367 " <method name='update_dnd_allow_exception'>"
368 " <arg type='i' name='type' direction='in'/>"
369 " <arg type='i' name='value' direction='in'/>"
370 " <arg type='i' name='uid' direction='in'/>"
373 " <method name='load_dnd_allow_exception'>"
374 " <arg type='i' name='uid' direction='in'/>"
375 " <arg type='i' name='count' direction='out'/>"
376 " <arg type='a(v)' name='dnd_allow_exception' direction='out'/>"
379 " <method name='send_noti_event'>"
380 " <arg type='v' name='noti' direction='in'/>"
381 " <arg type='i' name='event_type' direction='in'/>"
384 " <method name='send_noti_event_by_priv_id'>"
385 " <arg type='i' name='priv_id' direction='in'/>"
386 " <arg type='i' name='event_type' direction='in'/>"
389 " <method name='check_event_receiver'>"
390 " <arg type='i' name='priv_id' direction='in'/>"
391 " <arg type='i' name='available' direction='out'/>"
394 " <method name='reset_event_handler'>"
395 " <arg type='i' name='priv_id' direction='in'/>"
398 " <method name='del_noti_by_display_applist'>"
399 " <arg type='i' name='display_applist' direction='in'/>"
400 " <arg type='i' name='uid' direction='in'/>"
401 " <arg type='i' name='priv_id' direction='out'/>"
404 " <method name='post_toast'>"
409 return service_common_register_dbus_interface(introspection_xml, _noti_interface_vtable);
412 static void __free_event_info(gpointer data)
414 event_sender_info_s *info = (event_sender_info_s *)data;
423 static gint __priv_id_compare(gconstpointer a, gconstpointer b)
425 event_sender_info_s *info = NULL;
430 info = (event_sender_info_s *)a;
432 if (info->priv_id == GPOINTER_TO_INT(b))
438 static int __check_limit(notification_h noti, uid_t uid)
441 int priv_id = NOTIFICATION_PRIV_ID_NONE;
444 GList *iter_list = NULL;
446 ret = notification_noti_check_limit(noti, uid, &list);
447 if (ret == NOTIFICATION_ERROR_NONE && list != NULL) {
448 ret = notification_get_pkgname(noti, &app_id);
449 if (ret == NOTIFICATION_ERROR_NONE && app_id != NULL) {
452 priv_id = GPOINTER_TO_INT(iter_list->data);
454 ret = _delete_noti((const char *)app_id, priv_id, uid);
455 if (ret != NOTIFICATION_ERROR_NONE)
456 ERR("Failed to delete noti[%d], err[%d]",
459 iter_list = g_list_next(iter_list);
471 static int _add_noti(GVariant **reply_body, notification_h noti, uid_t uid)
474 int priv_id = NOTIFICATION_PRIV_ID_NONE;
475 GVariant *body = NULL;
478 ret = notification_noti_insert(noti);
479 if (ret != NOTIFICATION_ERROR_NONE) {
480 ERR("Failed to update a notification [%d]", ret);
484 ret = notification_get_id(noti, NULL, &priv_id);
485 if (ret != NOTIFICATION_ERROR_NONE) {
486 ERR("Failed to gets priv_id [%d]", ret);
490 notification_set_private_sharing(noti, uid);
492 body = notification_ipc_make_gvariant_from_noti(noti, true);
494 ERR("Failed to make gvariant to noti");
495 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
498 ret = send_notify(body, "add_noti_notify", &_monitoring_hash,
499 PROVIDER_NOTI_INTERFACE_NAME, uid);
500 g_variant_unref(body);
502 if (ret != NOTIFICATION_ERROR_NONE) {
503 ERR("Failed to send notify [%d]", ret);
507 ret = notification_launch_default_viewer(priv_id,
508 NOTIFICATION_OP_INSERT, uid);
509 if (ret != NOTIFICATION_ERROR_NONE) {
510 ERR("Failed to launch default viewer [%d]", ret);
511 ret = NOTIFICATION_ERROR_NONE;
515 *reply_body = g_variant_new("(i)", priv_id);
516 if (*reply_body == NULL) {
517 ERR("Failed to make reply");
518 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
521 ret = __check_limit(noti, uid);
522 if (ret != NOTIFICATION_ERROR_NONE) {
523 ERR("Failed to check limit [%d]", ret);
524 ret = NOTIFICATION_ERROR_NONE;
527 DBG("Success to add notification");
531 static int _validate_and_set_noti_with_uid(uid_t uid, notification_h noti, uid_t *noti_uid)
533 int ret = NOTIFICATION_ERROR_NONE;
535 ret = notification_get_uid(noti, noti_uid);
536 if (ret != NOTIFICATION_ERROR_NONE) {
537 ERR("Failed to get uid [%d]", ret);
541 if (uid > NORMAL_UID_BASE && uid != *noti_uid) {
542 ERR("Invalid seder uid[%d] noti_uid[%d]", uid, *noti_uid);
543 return NOTIFICATION_ERROR_INVALID_PARAMETER;
544 } else if (uid <= NORMAL_UID_BASE) {
545 if (*noti_uid <= NORMAL_UID_BASE) {
546 if (*noti_uid != uid)
547 return NOTIFICATION_ERROR_INVALID_PARAMETER;
549 DBG("system defualt noti post change noti_uid to default");
551 IF system (uid <= NORMAL_UID_BASE) try to send noti without specipic destination uid (using notification_pot API)
552 Send it to default user (TZ_SYS_DEFAULT_USER)
554 *noti_uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
555 ret = notification_set_uid(noti, *noti_uid);
556 if (ret != NOTIFICATION_ERROR_NONE) {
557 ERR("Failed to set uid [%d]", ret);
560 DBG("changed noti_uid[%d]", *noti_uid);
566 static int _validate_and_set_param_uid_with_uid(uid_t uid, uid_t *param_uid)
568 if (uid > NORMAL_UID_BASE && uid != *param_uid) {
569 ERR("invalid seder uid[%d], param_uid[%d]", uid, *param_uid);
570 return NOTIFICATION_ERROR_INVALID_PARAMETER;
571 } else if (uid <= NORMAL_UID_BASE) {
572 if (*param_uid <= NORMAL_UID_BASE) {
573 if (*param_uid != uid)
574 return NOTIFICATION_ERROR_INVALID_PARAMETER;
576 IF system (uid <= NORMAL_UID_BASE) try to send noti without specipic destination uid (using notification_pot API)
577 Send it to default user (TZ_SYS_DEFAULT_USER)
579 *param_uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
582 return NOTIFICATION_ERROR_NONE;
585 static void __sender_name_appeared_cb(GDBusConnection *connection,
587 const gchar *name_owner,
590 DBG("name[%s], name_owner[%s]", name, name_owner);
593 static void __sender_name_vanished_cb(GDBusConnection *connection,
597 GList *delete_list = NULL;
598 event_sender_info_s *info;
603 info = (event_sender_info_s *)user_data;
605 DBG("name[%s], priv_id[%d], watcher_id[%d]",
606 name, info->priv_id, info->watcher_id);
608 delete_list = g_list_find_custom(__event_list, GINT_TO_POINTER(info->priv_id),
609 (GCompareFunc)__priv_id_compare);
611 __event_list = g_list_remove(__event_list, info);
612 g_bus_unwatch_name(info->watcher_id);
613 __free_event_info(info);
617 static guint __insert_sender_watcher_id(event_sender_info_s *sender_info)
619 guint watcher_id = 0;
621 watcher_id = g_bus_watch_name(G_BUS_TYPE_SYSTEM,
622 sender_info->busname,
623 G_BUS_NAME_WATCHER_FLAGS_NONE,
624 __sender_name_appeared_cb,
625 __sender_name_vanished_cb,
629 ERR("Failed to watch sender name");
633 DBG("Watch on busname[%s] watcher_id[%d]", sender_info->busname, watcher_id);
637 static void __add_sender_info(int priv_id, const char *busname)
639 GList *find_list = NULL;
640 event_sender_info_s *sender_info;
641 event_sender_info_s *tmp_info = NULL;
646 sender_info = (event_sender_info_s *)malloc(sizeof(event_sender_info_s));
647 if (sender_info == NULL) {
648 ERR("malloc failed");
652 sender_info->priv_id = priv_id;
653 sender_info->busname = strdup(busname);
655 if (__event_list == NULL) {
656 sender_info->watcher_id = __insert_sender_watcher_id(sender_info);
657 __event_list = g_list_append(__event_list, sender_info);
659 __event_list = g_list_first(__event_list);
660 find_list = g_list_find_custom(__event_list, GINT_TO_POINTER(priv_id),
661 (GCompareFunc)__priv_id_compare);
662 if (find_list == NULL) {
663 sender_info->watcher_id = __insert_sender_watcher_id(sender_info);
664 __event_list = g_list_append(__event_list, sender_info);
666 tmp_info = (event_sender_info_s *)g_list_nth_data(find_list, 0);
667 if (tmp_info->busname) {
668 if (strcmp(tmp_info->busname, busname)) {
669 free(tmp_info->busname);
670 tmp_info->busname = strdup(busname);
671 g_bus_unwatch_name(tmp_info->watcher_id);
672 tmp_info->watcher_id = __insert_sender_watcher_id(sender_info);
675 tmp_info->busname = strdup(busname);
676 if (!tmp_info->watcher_id)
677 g_bus_unwatch_name(tmp_info->watcher_id);
678 tmp_info->watcher_id = __insert_sender_watcher_id(tmp_info);
680 __free_event_info(sender_info);
685 int notification_add_noti(GVariant *parameters, GVariant **reply_body,
686 const char *sender, pid_t pid, uid_t uid)
692 GVariant *body = NULL;
695 noti = notification_create(NOTIFICATION_TYPE_NOTI);
697 g_variant_get(parameters, "(v)", &body);
698 ret = notification_ipc_make_noti_from_gvariant(noti, body);
699 g_variant_unref(body);
701 if (uid >= NORMAL_UID_BASE)
702 notification_set_indirect_request(noti, pid, uid);
704 ret = _validate_and_set_noti_with_uid(uid, noti, ¬i_uid);
705 if (ret != NOTIFICATION_ERROR_NONE)
708 ret = notification_noti_check_tag(noti);
709 if (ret == NOTIFICATION_ERROR_NOT_EXIST_ID)
710 ret = _add_noti(reply_body, noti, noti_uid);
711 else if (ret == NOTIFICATION_ERROR_ALREADY_EXIST_ID)
712 ret = _update_noti(reply_body, noti, noti_uid);
714 if (ret != NOTIFICATION_ERROR_NONE)
717 ret = notification_get_event_flag(noti, &event_flag);
718 if (ret != NOTIFICATION_ERROR_NONE)
721 if (event_flag == true) {
722 ret = notification_get_id(noti, NULL, &priv_id);
723 if (ret != NOTIFICATION_ERROR_NONE)
726 __add_sender_info(priv_id, sender);
729 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
733 notification_free(noti);
739 static int _update_noti(GVariant **reply_body, notification_h noti, uid_t uid)
742 GVariant *body = NULL;
743 int priv_id = NOTIFICATION_PRIV_ID_NONE;
744 notification_h source_noti;
748 ret = notification_get_id(noti, NULL, &priv_id);
749 if (ret != NOTIFICATION_ERROR_NONE) {
750 ERR("Failed to get priv_id [%d]", ret);
754 if (notification_validate_private_sharing(noti) == false) {
755 source_noti = notification_create(NOTIFICATION_TYPE_NOTI);
756 if (source_noti == NULL)
757 return get_last_result();
758 notification_noti_get_by_priv_id(source_noti, priv_id);
760 notification_calibrate_private_sharing(noti, source_noti);
761 notification_free(source_noti);
764 ret = notification_noti_update(noti);
765 if (ret != NOTIFICATION_ERROR_NONE) {
766 ERR("Failed to update a notification [%d]", ret);
770 notification_set_private_sharing(noti, uid);
772 body = notification_ipc_make_gvariant_from_noti(noti, true);
774 ERR("Failed to make gvariant to noti");
775 return NOTIFICATION_ERROR_IO_ERROR;
778 ret = send_notify(body, "update_noti_notify", &_monitoring_hash, PROVIDER_NOTI_INTERFACE_NAME, uid);
779 g_variant_unref(body);
781 if (ret != NOTIFICATION_ERROR_NONE) {
782 ERR("Failed to send notify [%d]", ret);
786 ret = notification_launch_default_viewer(priv_id,
787 NOTIFICATION_OP_UPDATE, uid);
788 if (ret != NOTIFICATION_ERROR_NONE) {
789 ERR("Failed to launch default viewer [%d]", ret);
790 ret = NOTIFICATION_ERROR_NONE;
793 *reply_body = g_variant_new("(i)", priv_id);
794 if (*reply_body == NULL) {
795 ERR("Failed to make reply_body");
796 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
799 DBG("Success to update noti");
803 int notification_update_noti(GVariant *parameters, GVariant **reply_body,
804 pid_t pid, uid_t uid)
808 GVariant *body = NULL;
811 noti = notification_create(NOTIFICATION_TYPE_NOTI);
813 g_variant_get(parameters, "(v)", &body);
814 ret = notification_ipc_make_noti_from_gvariant(noti, body);
815 g_variant_unref(body);
817 if (uid >= NORMAL_UID_BASE)
818 notification_set_indirect_request(noti, pid, uid);
820 ret = _validate_and_set_noti_with_uid(uid, noti, ¬i_uid);
821 if (ret != NOTIFICATION_ERROR_NONE)
824 ret = _update_noti(reply_body, noti, noti_uid);
827 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
831 notification_free(noti);
835 /* load_noti_by_tag */
836 int notification_load_noti_by_tag(GVariant *parameters, GVariant **reply_body, uid_t uid)
844 noti = notification_create(NOTIFICATION_TYPE_NOTI);
846 g_variant_get(parameters, "(&s&si)", &app_id, &tag, ¶m_uid);
847 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
848 if (ret != NOTIFICATION_ERROR_NONE)
851 DBG("_load_noti_by_tag app_id : %s, tag : %s ", app_id, tag);
852 ret = notification_noti_get_by_tag(noti, app_id, tag, param_uid);
853 if (ret != NOTIFICATION_ERROR_NONE) {
854 ERR("No matched tag [%s]", tag);
859 *reply_body = notification_ipc_make_gvariant_from_noti(noti, true);
860 if (*reply_body == NULL) {
861 ERR("Failed to make reply_body");
862 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
865 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
870 notification_free(noti);
875 /* load_noti_by_priv_id */
876 int notification_load_noti_by_priv_id(GVariant *parameters, GVariant **reply_body, uid_t uid)
879 int priv_id = NOTIFICATION_PRIV_ID_NONE;
884 noti = notification_create(NOTIFICATION_TYPE_NOTI);
886 g_variant_get(parameters, "(&sii)", &app_id, &priv_id, ¶m_uid);
887 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
888 if (ret != NOTIFICATION_ERROR_NONE)
891 DBG("load_noti_by_priv_id app_id : %s, priv_id : %d ", app_id, priv_id);
892 ret = notification_noti_get_by_priv_id(noti, priv_id);
893 if (ret != NOTIFICATION_ERROR_NONE)
896 *reply_body = notification_ipc_make_gvariant_from_noti(noti, true);
897 if (*reply_body == NULL) {
898 ERR("Failed to make reply_body");
899 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
902 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
907 notification_free(noti);
912 static int __get_socket_from_invocation(GDBusMethodInvocation *invocation, int *fd)
915 GError *g_err = NULL;
916 GDBusMessage *msg = NULL;
917 GUnixFDList *fd_list = NULL;
919 msg = g_dbus_method_invocation_get_message(invocation);
920 fd_list = g_dbus_message_get_unix_fd_list(msg);
921 if (fd_list == NULL) {
922 ERR("fd list is null");
923 return NOTIFICATION_ERROR_IO_ERROR;
926 ret_fd = g_unix_fd_list_get(fd_list, 0, &g_err);
927 if (ret_fd == -1 || g_err) {
928 ERR("g_unix_fd_list_get [%s]", g_err->message);
930 return NOTIFICATION_ERROR_IO_ERROR;
935 INFO("sender fd : %d", ret_fd);
936 return NOTIFICATION_ERROR_NONE;
939 static int __send_list_to_socket(int fd, notification_list_h get_list, uid_t uid)
943 notification_list_h list_iter;
944 GVariant *body = NULL;
946 list_iter = notification_list_get_head(get_list);
948 noti = notification_list_get_data(list_iter);
949 notification_set_private_sharing(noti, uid);
950 body = notification_ipc_make_gvariant_from_noti(noti, true);
952 ERR("Failed to make gvariant to noti");
953 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
956 ret = notification_ipc_socket_write_string(fd,
957 (char *)g_variant_get_data(body),
958 g_variant_get_size(body));
959 if (ret != NOTIFICATION_ERROR_NONE) {
960 ERR("write string to socket fail");
961 g_variant_unref(body);
964 list_iter = notification_list_get_next(list_iter);
965 g_variant_unref(body);
966 } while (list_iter != NULL);
971 /* load_noti_grouping_list */
972 void notification_load_grouping_list(GDBusMethodInvocation *invocation, GVariant *parameters, uid_t uid)
975 notification_type_e type;
976 notification_list_h get_list = NULL;
977 GVariant *reply_body = NULL;
984 g_variant_get(parameters, "(iiii)", &type, &count, &count_per_page, ¶m_uid);
985 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
986 if (ret != NOTIFICATION_ERROR_NONE)
989 ret = __get_socket_from_invocation(invocation, &fd);
990 if (ret != NOTIFICATION_ERROR_NONE) {
991 ERR("get_fd_from_invocation [%d]", ret);
995 ret = notification_noti_get_grouping_list(type, count, count_per_page,
996 &get_list, &list_count, param_uid);
997 if (ret != NOTIFICATION_ERROR_NONE) {
998 ERR("notification_noti_get_grouping_list [%d]", ret);
1002 reply_body = g_variant_new("(i)", list_count);
1003 if (reply_body == NULL) {
1004 ERR("Failed to make reply_body");
1005 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
1009 g_dbus_method_invocation_return_value(invocation, reply_body);
1011 ret = __send_list_to_socket(fd, get_list, param_uid);
1012 if (ret != NOTIFICATION_ERROR_NONE)
1013 ERR("__send_list_to_socket [%d]", ret);
1014 notification_free_list(get_list);
1024 notification_free_list(get_list);
1026 ERR("notification service fail, method name[load_noti_grouping_list] [%d]", ret);
1027 g_dbus_method_invocation_return_error(invocation, NOTIFICATION_ERROR,
1028 ret, "notification_service_error");
1031 /* get_setting_array */
1032 int notification_get_setting_array(GVariant *parameters, GVariant **reply_body, uid_t uid)
1036 GVariantBuilder *builder;
1039 notification_setting_h setting_array = NULL;
1040 notification_setting_h temp;
1043 g_variant_get(parameters, "(i)", ¶m_uid);
1044 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
1045 if (ret != NOTIFICATION_ERROR_NONE)
1048 ret = noti_setting_get_setting_array(&setting_array, &count, param_uid);
1049 if (ret != NOTIFICATION_ERROR_NONE)
1052 builder = g_variant_builder_new(G_VARIANT_TYPE("a(v)"));
1054 if (setting_array) {
1055 for (i = 0; i < count; i++) {
1056 temp = setting_array + i;
1057 body = notification_ipc_make_gvariant_from_setting(temp);
1058 g_variant_builder_add(builder, "(v)", body);
1060 if (temp->package_name)
1061 free(temp->package_name);
1065 free(setting_array);
1067 *reply_body = g_variant_new("(ia(v))", count, builder);
1068 g_variant_builder_unref(builder);
1070 if (*reply_body == NULL) {
1071 ERR("Failed to make reply_body");
1072 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1075 INFO("count[%d]", count);
1079 static pkgmgrinfo_pkginfo_h __create_pkginfo_by_app_id(const char *app_id, uid_t uid)
1082 char *pkgname = NULL;
1083 pkgmgrinfo_appinfo_h app_handle = NULL;
1084 pkgmgrinfo_pkginfo_h pkg_handle = NULL;
1089 ret_pkgmgr = pkgmgrinfo_appinfo_get_usr_appinfo(app_id, uid, &app_handle);
1090 if (ret_pkgmgr != PMINFO_R_OK) {
1091 ERR("Failed to pkgmgrinfo_appinfo_get_appinfo [%s][%d]",
1092 app_id, ret_pkgmgr);
1096 ret_pkgmgr = pkgmgrinfo_appinfo_get_pkgname(app_handle, &pkgname);
1097 if (ret_pkgmgr != PMINFO_R_OK) {
1098 ERR("Failed to pkgmgrinfo_appinfo_get_pkgname [%s][%d]",
1099 app_id, ret_pkgmgr);
1103 ret_pkgmgr = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgname, uid, &pkg_handle);
1104 if (ret_pkgmgr != PMINFO_R_OK) {
1105 ERR("Failed to pkgmgrinfo_appinfo_get_pkginfo [%s][%d]",
1106 app_id, ret_pkgmgr);
1112 pkgmgrinfo_appinfo_destroy_appinfo(app_handle);
1117 #define NOTIFICATION_PRIVILEGE "http://tizen.org/privilege/notification"
1118 static int __check_privilege_cb(const char *privilege_name, void *is_existed)
1120 if (!g_strcmp0(privilege_name, NOTIFICATION_PRIVILEGE)) {
1121 *(int *)is_existed = 1;
1127 static int __has_notification_privilege(pkgmgrinfo_pkginfo_h handle)
1132 ret_pkgmgr = pkgmgrinfo_pkginfo_foreach_privilege(handle, __check_privilege_cb, &is_existed);
1133 if (ret_pkgmgr != PMINFO_R_OK) {
1134 ERR("Failed to pkgmgrinfo_foreach_privilege [%d]",
1136 return NOTIFICATION_ERROR_IO_ERROR;
1139 if (is_existed == 0)
1140 return NOTIFICATION_ERROR_NOT_EXIST_ID;
1142 return NOTIFICATION_ERROR_NONE;
1145 static int __init_setting_handle_by_app_id(const char *app_id,
1146 notification_setting_h *setting, uid_t uid)
1148 int ret = NOTIFICATION_ERROR_NONE;
1150 char *pkgname = NULL;
1151 notification_setting_h ret_setting = NULL;
1152 pkgmgrinfo_pkginfo_h handle = NULL;
1154 if (app_id == NULL || setting == NULL)
1155 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1157 handle = __create_pkginfo_by_app_id(app_id, uid);
1158 if (handle == NULL) {
1159 ERR("Failed to create pkginfo by app_id [%s]", app_id);
1160 ret = NOTIFICATION_ERROR_IO_ERROR;
1164 ret = __has_notification_privilege(handle);
1165 if (ret != NOTIFICATION_ERROR_NONE) {
1166 if (ret == NOTIFICATION_ERROR_NOT_EXIST_ID)
1167 DBG("No notification privilege [%s]", app_id);
1169 ERR("Failed to check privilege [%d]", ret);
1173 ret_pkgmgr = pkgmgrinfo_pkginfo_get_pkgname(handle, &pkgname);
1174 if (ret_pkgmgr != PMINFO_R_OK) {
1175 ERR("Failed to get pkgname from pkginfo [%d]", ret_pkgmgr);
1176 ret = NOTIFICATION_ERROR_IO_ERROR;
1180 ret_setting = (struct notification_setting *)malloc(sizeof(struct notification_setting));
1181 if (ret_setting == NULL) {
1182 ERR("Failed to alloc memory");
1183 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
1187 ret_setting->package_name = strdup(pkgname);
1188 ret_setting->app_id = strdup(app_id);
1189 ret_setting->allow_to_notify = 1;
1190 ret_setting->do_not_disturb_except = 0;
1191 ret_setting->visibility_class = 0;
1192 ret_setting->pop_up_notification = 1;
1193 ret_setting->lock_screen_content_level = 0;
1194 ret_setting->app_disabled = 0;
1196 *setting = ret_setting;
1200 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1205 /* get_setting_by_app_id */
1206 int notification_get_setting_by_app_id(GVariant *parameters, GVariant **reply_body, uid_t uid)
1210 char *app_id = NULL;
1211 notification_setting_h setting = NULL;
1214 g_variant_get(parameters, "(&si)", &app_id, ¶m_uid);
1215 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
1216 if (ret != NOTIFICATION_ERROR_NONE)
1219 ret = noti_setting_service_get_setting_by_app_id(app_id, &setting, param_uid);
1220 if (ret == NOTIFICATION_ERROR_NOT_EXIST_ID) {
1221 ret = __init_setting_handle_by_app_id(app_id, &setting, param_uid);
1222 if (ret != NOTIFICATION_ERROR_NONE)
1224 } else if (ret != NOTIFICATION_ERROR_NONE) {
1228 body = notification_ipc_make_gvariant_from_setting(setting);
1229 notification_setting_free_notification(setting);
1231 ERR("Failed to make gvariant");
1232 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1235 *reply_body = g_variant_new("(v)", body);
1236 if (*reply_body == NULL) {
1237 ERR("Failed to make reply_body");
1238 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1241 INFO("app_id[%s] uid[%d]", app_id, param_uid);
1245 /* load_system_setting */
1246 int notification_load_system_setting(GVariant *parameters, GVariant **reply_body, uid_t uid)
1250 notification_system_setting_h setting = NULL;
1253 g_variant_get(parameters, "(i)", ¶m_uid);
1254 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
1255 if (ret != NOTIFICATION_ERROR_NONE)
1258 ret = noti_system_setting_load_system_setting(&setting, param_uid);
1259 if (ret == NOTIFICATION_ERROR_NONE) {
1260 body = notification_ipc_make_gvariant_from_system_setting(setting);
1261 notification_system_setting_free_system_setting(setting);
1264 ERR("Failed to make gvariant");
1265 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1271 *reply_body = g_variant_new("(v)", body);
1272 if (*reply_body == NULL) {
1273 ERR("Failed to make reply_body");
1274 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1280 /* load_noti_detail_list */
1281 int notification_load_detail_list(GVariant *parameters, GVariant **reply_body, uid_t uid)
1284 notification_h noti;
1285 GVariant *body = NULL;
1286 notification_list_h get_list = NULL;
1287 notification_list_h list_iter;
1288 GVariantBuilder *builder;
1289 char *app_id = NULL;
1290 int group_id = NOTIFICATION_GROUP_ID_NONE;
1291 int priv_id = NOTIFICATION_PRIV_ID_NONE;
1295 g_variant_get(parameters, "(&siiii)", &app_id, &group_id, &priv_id, &count, ¶m_uid);
1296 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
1297 if (ret != NOTIFICATION_ERROR_NONE)
1300 ret = notification_noti_get_detail_list(app_id, group_id, priv_id,
1301 count, &get_list, param_uid);
1302 if (ret != NOTIFICATION_ERROR_NONE)
1305 builder = g_variant_builder_new(G_VARIANT_TYPE("a(v)"));
1308 list_iter = notification_list_get_head(get_list);
1310 noti = notification_list_get_data(list_iter);
1311 notification_set_private_sharing(noti, param_uid);
1312 body = notification_ipc_make_gvariant_from_noti(noti, true);
1314 g_variant_builder_add(builder, "(v)", body);
1315 list_iter = notification_list_get_next(list_iter);
1317 } while (list_iter != NULL);
1318 notification_free_list(get_list);
1321 *reply_body = g_variant_new("(a(v))", builder);
1322 g_variant_builder_unref(builder);
1324 if (*reply_body == NULL) {
1325 ERR("Failed to make reply_body");
1326 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1329 DBG("app_id[%s], group_id[%d], priv_id[%d], count[%d]",
1330 app_id, group_id, priv_id, count);
1335 int notification_refresh_noti(GVariant *parameters, GVariant **reply_body, uid_t uid)
1340 g_variant_get(parameters, "(i)", ¶m_uid);
1341 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
1342 if (ret != NOTIFICATION_ERROR_NONE)
1345 ret = send_notify(parameters, "refresh_noti_notify", &_monitoring_hash, PROVIDER_NOTI_INTERFACE_NAME, param_uid);
1346 if (ret != NOTIFICATION_ERROR_NONE) {
1347 ERR("Failed to send notify [%d]", ret);
1351 *reply_body = g_variant_new("()");
1352 if (*reply_body == NULL) {
1353 ERR("Failed to make reply_body");
1354 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1360 static int __delete_sender_info(int priv_id)
1362 int ret = NOTIFICATION_ERROR_NONE;
1363 event_sender_info_s *info;
1364 GList *delete_list = NULL;
1365 GVariant *body = NULL;
1367 if (__event_list != NULL) {
1368 __event_list = g_list_first(__event_list);
1369 delete_list = g_list_find_custom(__event_list, GINT_TO_POINTER(priv_id),
1370 (GCompareFunc)__priv_id_compare);
1371 if (delete_list != NULL) {
1372 info = (event_sender_info_s *)g_list_nth_data(delete_list, 0);
1373 body = g_variant_new("(i)", priv_id);
1374 ret = send_event_notify_by_busname(body, "delete_noti", info->busname, PROVIDER_NOTI_EVENT_INTERFACE_NAME);
1375 g_variant_unref(body);
1376 if (ret != NOTIFICATION_ERROR_NONE) {
1377 ERR("Failed to send event notify [%d]", ret);
1380 __event_list = g_list_remove(g_list_first(__event_list), info);
1381 g_bus_unwatch_name(info->watcher_id);
1382 __free_event_info(info);
1383 if (g_list_length(__event_list) == 0)
1384 __event_list = NULL;
1391 static int _delete_noti(const char *app_id, int priv_id, uid_t uid)
1394 int num_changes = 0;
1395 GVariant *body = NULL;
1398 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1400 ret = notification_noti_delete_by_priv_id_get_changes(app_id, priv_id,
1402 if (ret != NOTIFICATION_ERROR_NONE) {
1403 ERR("Failed to delete noti, err[%d] num_changes[%d]",
1408 if (num_changes > 0) {
1409 body = g_variant_new("(iii)", 1, priv_id, uid);
1411 ERR("Failed to make gvariant to noti");
1412 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1414 ret = send_notify(body, "delete_single_notify",
1415 &_monitoring_hash, PROVIDER_NOTI_INTERFACE_NAME, uid);
1416 g_variant_unref(body);
1417 if (ret != NOTIFICATION_ERROR_NONE) {
1418 ERR("Failed to send notify [%d]", ret);
1422 notification_remove_private_sharing(app_id, priv_id, uid);
1424 ret = __delete_sender_info(priv_id);
1425 if (ret != NOTIFICATION_ERROR_NONE)
1428 ret = notification_launch_default_viewer(NOTIFICATION_PRIV_ID_NONE,
1429 NOTIFICATION_OP_DELETE,
1431 if (ret != NOTIFICATION_ERROR_NONE) {
1432 ERR("Failed to launch default viewer [%d]", ret);
1433 ret = NOTIFICATION_ERROR_NONE;
1437 DBG("app_id[%s] priv_id[%d] num_changes[%d]", app_id, priv_id, num_changes);
1442 /* del_noti_single */
1443 int notification_del_noti_single(GVariant *parameters, GVariant **reply_body, uid_t uid)
1445 int ret = NOTIFICATION_ERROR_NONE;
1446 int priv_id = NOTIFICATION_PRIV_ID_NONE;
1447 char *app_id = NULL;
1450 g_variant_get(parameters, "(&sii)", &app_id, &priv_id, ¶m_uid);
1451 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
1452 if (ret != NOTIFICATION_ERROR_NONE)
1455 ret = _delete_noti(app_id, priv_id, param_uid);
1456 if (ret != NOTIFICATION_ERROR_NONE) {
1457 ERR("Failed to delete noti, err[%d]", ret);
1461 *reply_body = g_variant_new("(i)", priv_id);
1462 if (*reply_body == NULL) {
1463 ERR("Failed to make reply_body");
1464 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1470 /* del_noti_multiple */
1471 int notification_del_noti_multiple(GVariant *parameters, GVariant **reply_body, uid_t uid)
1474 char *app_id = NULL;
1475 notification_type_e type = NOTIFICATION_TYPE_NONE;
1476 int num_deleted = 0;
1477 int *list_deleted = NULL;
1478 GVariant *deleted_noti_list;
1479 GVariantBuilder *builder;
1483 g_variant_get(parameters, "(&sii)", &app_id, &type, ¶m_uid);
1484 DBG("app_id [%s] type [%d]", app_id, type);
1485 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
1486 if (ret != NOTIFICATION_ERROR_NONE)
1489 ret = notification_noti_delete_all(type, app_id, &num_deleted, &list_deleted, param_uid);
1490 if (ret != NOTIFICATION_ERROR_NONE) {
1491 ERR("Failed to delete notifications [%d]", ret);
1492 if (list_deleted != NULL)
1497 if (num_deleted > 0) {
1498 builder = g_variant_builder_new(G_VARIANT_TYPE("a(i)"));
1500 for (i = 0; i < num_deleted; i++)
1501 g_variant_builder_add(builder, "(i)", *(list_deleted + i));
1503 deleted_noti_list = g_variant_new("(a(i)ii)", builder, num_deleted, param_uid);
1504 ret = send_notify(deleted_noti_list, "delete_multiple_notify", &_monitoring_hash, PROVIDER_NOTI_INTERFACE_NAME, param_uid);
1505 g_variant_builder_unref(builder);
1506 g_variant_unref(deleted_noti_list);
1507 if (ret != NOTIFICATION_ERROR_NONE) {
1508 ERR("Failed to send notify [%d]", ret);
1512 for (i = 0; i < num_deleted; i++) {
1513 notification_remove_private_sharing(app_id, *(list_deleted + i), param_uid);
1514 ret = __delete_sender_info(*(list_deleted + i));
1515 if (ret != NOTIFICATION_ERROR_NONE)
1521 ret = notification_launch_default_viewer(NOTIFICATION_PRIV_ID_NONE,
1522 NOTIFICATION_OP_DELETE_ALL,
1524 if (ret != NOTIFICATION_ERROR_NONE) {
1525 ERR("Failed to launch default viewer [%d]", ret);
1526 ret = NOTIFICATION_ERROR_NONE;
1530 *reply_body = g_variant_new("(i)", num_deleted);
1531 if (*reply_body == NULL) {
1532 ERR("Failed to make reply_body");
1533 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1536 INFO("type[%d] app_id[%s] num_deleted[%d]", type, app_id, num_deleted);
1540 static void __free_deleted_list_info(notification_deleted_list_info_s *info,
1545 for (i = 0; i < count; i++) {
1546 if ((info + i)->app_id != NULL)
1547 free((info + i)->app_id);
1553 int notification_del_noti_by_display_applist(GVariant *parameters,
1554 GVariant **reply_body, uid_t uid)
1557 int display_applist = 0;
1558 int deleted_num = 0;
1560 GVariant *deleted_noti_list;
1561 GVariantBuilder *builder;
1563 notification_deleted_list_info_s *deleted_list = NULL;
1565 g_variant_get(parameters, "(ii)", &display_applist, ¶m_uid);
1567 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
1568 if (ret != NOTIFICATION_ERROR_NONE)
1571 ret = notification_noti_delete_by_display_applist(display_applist,
1572 &deleted_num, &deleted_list, param_uid);
1573 if (ret != NOTIFICATION_ERROR_NONE) {
1574 ERR("Failed to delete notifications [%d]", ret);
1575 if (deleted_list != NULL)
1576 __free_deleted_list_info(deleted_list, deleted_num);
1580 if (deleted_num > 0) {
1581 builder = g_variant_builder_new(G_VARIANT_TYPE("a(i)"));
1583 for (i = 0; i < deleted_num; i++) {
1584 g_variant_builder_add(builder, "(i)",
1585 (deleted_list +i)->priv_id);
1586 notification_remove_private_sharing(
1587 (deleted_list +i)->app_id,
1588 (deleted_list +i)->priv_id,
1590 __delete_sender_info((deleted_list +i)->priv_id);
1592 __free_deleted_list_info(deleted_list, deleted_num);
1594 deleted_noti_list = g_variant_new("(a(i)ii)", builder,
1595 deleted_num, param_uid);
1596 g_variant_builder_unref(builder);
1598 ret = send_notify(deleted_noti_list,
1599 "delete_by_display_applist_notify", &_monitoring_hash,
1600 PROVIDER_NOTI_INTERFACE_NAME, param_uid);
1601 g_variant_unref(deleted_noti_list);
1602 if (ret != NOTIFICATION_ERROR_NONE) {
1603 ERR("Failed to send notify [%d]", ret);
1607 ret = notification_launch_default_viewer(NOTIFICATION_PRIV_ID_NONE,
1608 NOTIFICATION_OP_DELETE_ALL,
1610 if (ret != NOTIFICATION_ERROR_NONE) {
1611 ERR("Failed to launch default viewer [%d]", ret);
1612 ret = NOTIFICATION_ERROR_NONE;
1616 *reply_body = g_variant_new("(i)", deleted_num);
1617 if (*reply_body == NULL) {
1618 ERR("Failed to make reply_body");
1619 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1622 INFO("deleted num[%d]", deleted_num);
1626 /* get_noti_count */
1627 int notification_get_noti_count(GVariant *parameters, GVariant **reply_body, uid_t uid)
1630 notification_type_e type = NOTIFICATION_TYPE_NONE;
1631 char *app_id = NULL;
1632 int group_id = NOTIFICATION_GROUP_ID_NONE;
1633 int priv_id = NOTIFICATION_PRIV_ID_NONE;
1637 g_variant_get(parameters, "(i&siii)", &type, &app_id, &group_id, &priv_id, ¶m_uid);
1638 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
1639 if (ret != NOTIFICATION_ERROR_NONE) {
1640 ERR("Failed to validate uid [%d]", ret);
1641 return NOTIFICATION_ERROR_IO_ERROR;
1644 ret = notification_noti_get_count(type, app_id, group_id, priv_id,
1645 ¬i_count, param_uid);
1646 if (ret != NOTIFICATION_ERROR_NONE) {
1647 ERR("Failed to get count [%d]", ret);
1651 *reply_body = g_variant_new("(i)", noti_count);
1652 if (*reply_body == NULL) {
1653 ERR("Failed to make reply_body");
1654 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1657 INFO("type[%d] app_id[%s] group_id[%d] priv_id[%d] noti_count[%d]",
1658 type, app_id, group_id, priv_id, noti_count);
1662 /* get_noti_count */
1663 int notification_get_noti_all_count(GVariant *parameters, GVariant **reply_body, uid_t uid)
1670 g_variant_get(parameters, "(ii)", &type, ¶m_uid);
1671 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
1672 if (ret != NOTIFICATION_ERROR_NONE) {
1673 ERR("Failed to validate uid [%d]", ret);
1674 return NOTIFICATION_ERROR_IO_ERROR;
1677 ret = notification_noti_get_all_count(type, ¬i_count, param_uid);
1678 if (ret != NOTIFICATION_ERROR_NONE) {
1679 ERR("Failed to get count [%d]", ret);
1683 *reply_body = g_variant_new("(i)", noti_count);
1684 if (*reply_body == NULL) {
1685 ERR("Failed to make reply_body");
1686 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1689 INFO("The numbers of all notification count is [%d]", noti_count);
1693 /* update_noti_setting */
1694 int notification_update_noti_setting(GVariant *parameters, GVariant **reply_body, uid_t uid)
1697 char *pkgname = NULL;
1698 char *app_id = NULL;
1699 int allow_to_notify = 0;
1700 int do_not_disturb_except = 0;
1701 int visivility_class = 0;
1702 int pop_up_notification = 0;
1703 int lock_screen_content_level = 0;
1706 g_variant_get(parameters, "(&s&siiiiii)",
1710 &do_not_disturb_except,
1712 &pop_up_notification,
1713 &lock_screen_content_level,
1716 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
1717 if (ret != NOTIFICATION_ERROR_NONE)
1720 ret = notification_setting_db_update(pkgname, app_id, allow_to_notify, do_not_disturb_except, visivility_class,
1721 pop_up_notification, lock_screen_content_level, param_uid);
1722 if (ret != NOTIFICATION_ERROR_NONE) {
1723 ERR("Failed to setting db update : %d", ret);
1727 *reply_body = g_variant_new("()");
1728 if (*reply_body == NULL) {
1729 ERR("Failed to make reply_body");
1730 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1733 INFO("package_name[%s] app_id[%s] allow_to_notify[%d] do_not_disturb_except[%d] visivility_class[%d] pop_up_notification[%d] lock_screen_content_level[%d]",
1734 pkgname, app_id, allow_to_notify, do_not_disturb_except, visivility_class, pop_up_notification, lock_screen_content_level);
1738 static int _dnd_schedule_alarm_cb(alarm_id_t alarm_id, void *data)
1742 bool dnd_id_found = false;
1743 GVariant *body = NULL;
1744 GList *dnd_found_list = NULL;
1745 dnd_alarm_id_s *dnd_id_data = NULL;
1748 dnd_found_list = g_list_first(_dnd_alarm_id_list);
1750 for (; dnd_found_list != NULL; dnd_found_list = dnd_found_list->next) {
1751 dnd_id_data = dnd_found_list->data;
1752 uid = dnd_id_data->uid;
1754 ret = noti_system_setting_get_do_not_disturb(&do_not_disturb, uid);
1755 if (ret != NOTIFICATION_ERROR_NONE) {
1756 ERR("get do not disturb failed");
1760 if (alarm_id == dnd_id_data->dnd_start_id && !do_not_disturb) {
1762 dnd_id_found = true;
1764 } else if (alarm_id == dnd_id_data->dnd_end_id && do_not_disturb) {
1766 dnd_id_found = true;
1771 if (dnd_id_found == false) {
1772 ERR("notification wrong alarm [%d]", alarm_id);
1776 notification_setting_db_update_do_not_disturb(do_not_disturb, uid);
1778 body = g_variant_new("(ii)", do_not_disturb, uid);
1780 ret = send_notify(body, "change_dnd_notify", &_monitoring_hash, PROVIDER_NOTI_INTERFACE_NAME, uid);
1781 g_variant_unref(body);
1782 if (ret != NOTIFICATION_ERROR_NONE) {
1783 ERR("Failed to send notify [%d]", ret);
1787 INFO("dnd[%d], uid[%d]", do_not_disturb, uid);
1791 static int _get_current_time(struct tm *date)
1796 ERR("Invalid tm data");
1797 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1801 localtime_r(&now, date);
1803 return NOTIFICATION_ERROR_NONE;
1806 static int _noti_system_setting_set_alarm(int week_flag, int hour, int min, alarm_cb_t handler, alarm_id_t *dnd_schedule_alarm_id)
1808 int err = NOTIFICATION_ERROR_NONE;
1809 struct tm struct_time;
1810 alarm_entry_t *alarm_info = NULL;
1811 alarm_date_t alarm_time;
1812 alarm_id_t alarm_id = -1;
1814 err = alarmmgr_init("notification");
1816 ERR("alarmmgr_init failed [%d]", err);
1820 err = alarmmgr_set_cb(handler, NULL);
1822 ERR("alarmmgr_set_cb failed [%d]", err);
1826 err = _get_current_time(&struct_time);
1827 if (err != NOTIFICATION_ERROR_NONE) {
1828 ERR("get_current_time failed [%d]", err);
1832 alarm_info = alarmmgr_create_alarm();
1833 if (alarm_info == NULL) {
1834 ERR("alarmmgr_create_alarm failed");
1838 alarm_time.year = struct_time.tm_year + 1900;
1839 alarm_time.month = struct_time.tm_mon + 1;
1840 alarm_time.day = struct_time.tm_mday;
1841 alarm_time.hour = hour;
1842 alarm_time.min = min;
1845 err = alarmmgr_set_time(alarm_info, alarm_time);
1846 if (err != ALARMMGR_RESULT_SUCCESS) {
1847 ERR("alarmmgr_set_time failed [%d]", err);
1852 err = alarmmgr_set_repeat_mode(alarm_info, ALARM_REPEAT_MODE_WEEKLY, week_flag);
1853 if (err != ALARMMGR_RESULT_SUCCESS) {
1854 ERR("alarmmgr_set_repeat_mode failed [%d]", err);
1859 err = alarmmgr_set_type(alarm_info, ALARM_TYPE_VOLATILE);
1860 if (err != ALARMMGR_RESULT_SUCCESS) {
1861 ERR("alarmmgr_set_type failed [%d]", err);
1865 err = alarmmgr_add_alarm_with_localtime(alarm_info, NULL, &alarm_id);
1866 if (err != ALARMMGR_RESULT_SUCCESS) {
1867 ERR("alarmmgr_add_alarm_with_localtime failed [%d]", err);
1871 *dnd_schedule_alarm_id = alarm_id;
1875 alarmmgr_free_alarm(alarm_info);
1877 DBG("alarm_id [%d]", alarm_id);
1881 static gint _dnd_data_compare(gconstpointer a, gconstpointer b)
1883 const dnd_alarm_id_s *data = NULL;
1888 if (data->uid == GPOINTER_TO_UINT(b))
1894 static dnd_alarm_id_s *__malloc_dnd_alarm_id_s(uid_t uid, alarm_id_t start_alarm_id, alarm_id_t end_alarm_id)
1896 dnd_alarm_id_s *dnd_id_data = NULL;
1898 dnd_id_data = (dnd_alarm_id_s *)malloc(sizeof(dnd_alarm_id_s));
1899 if (dnd_id_data == NULL) {
1900 ERR("Failed to alloc memory");
1904 dnd_id_data->uid = uid;
1905 dnd_id_data->dnd_start_id = start_alarm_id;
1906 dnd_id_data->dnd_end_id = end_alarm_id;
1911 static int _add_alarm(int dnd_schedule_day, int dnd_start_hour, int dnd_start_min, int dnd_end_hour, int dnd_end_min, uid_t uid)
1913 int ret = NOTIFICATION_ERROR_NONE;
1914 GList *found_list = NULL;
1915 dnd_alarm_id_s *dnd_id_data = NULL;
1916 alarm_id_t dnd_schedule_start_alarm_id;
1917 alarm_id_t dnd_schedule_end_alarm_id;
1919 ret = _noti_system_setting_set_alarm(dnd_schedule_day,
1920 dnd_start_hour, dnd_start_min,
1921 _dnd_schedule_alarm_cb,
1922 &dnd_schedule_start_alarm_id);
1923 if (ret != NOTIFICATION_ERROR_NONE) {
1924 ERR("Failed to set start alarm [%d]", ret);
1928 if (dnd_end_hour < dnd_start_hour ||
1929 (dnd_end_hour == dnd_start_hour && dnd_end_min <= dnd_start_min)) {
1930 dnd_schedule_day = (dnd_schedule_day << 1);
1931 if (dnd_schedule_day & (DND_SCHEDULE_WEEK_FLAG_SATURDAY << 1))
1932 dnd_schedule_day = (dnd_schedule_day & DND_SCHEDULE_WEEK_FLAG_ALL)
1933 | DND_SCHEDULE_WEEK_FLAG_SUNDAY;
1936 ret = _noti_system_setting_set_alarm(dnd_schedule_day,
1937 dnd_end_hour, dnd_end_min,
1938 _dnd_schedule_alarm_cb,
1939 &dnd_schedule_end_alarm_id);
1940 if (ret != NOTIFICATION_ERROR_NONE) {
1941 ERR("Failed to set end alarm [%d]", ret);
1945 if (_dnd_alarm_id_list == NULL) {
1946 dnd_id_data = __malloc_dnd_alarm_id_s(uid, dnd_schedule_start_alarm_id, dnd_schedule_end_alarm_id);
1948 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1949 _dnd_alarm_id_list = g_list_append(_dnd_alarm_id_list, dnd_id_data);
1951 found_list = g_list_find_custom(g_list_first(_dnd_alarm_id_list), GUINT_TO_POINTER(uid),
1952 (GCompareFunc)_dnd_data_compare);
1954 dnd_id_data = g_list_nth_data(found_list, 0);
1955 if (dnd_id_data->dnd_start_id) {
1956 alarmmgr_remove_alarm(dnd_id_data->dnd_start_id);
1957 dnd_id_data->dnd_start_id = dnd_schedule_start_alarm_id;
1959 if (dnd_id_data->dnd_end_id) {
1960 alarmmgr_remove_alarm(dnd_id_data->dnd_end_id);
1961 dnd_id_data->dnd_end_id = dnd_schedule_end_alarm_id;
1964 dnd_id_data = __malloc_dnd_alarm_id_s(uid, dnd_schedule_start_alarm_id, dnd_schedule_end_alarm_id);
1966 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1967 _dnd_alarm_id_list = g_list_append(_dnd_alarm_id_list, dnd_id_data);
1974 static void _delete_alarm(uid_t uid)
1976 GList *found_list = NULL;
1977 dnd_alarm_id_s *dnd_id_data = NULL;
1979 if (_dnd_alarm_id_list == NULL)
1982 _dnd_alarm_id_list = g_list_first(_dnd_alarm_id_list);
1983 found_list = g_list_find_custom(_dnd_alarm_id_list, GUINT_TO_POINTER(uid),
1984 (GCompareFunc)_dnd_data_compare);
1986 if (found_list == NULL)
1989 dnd_id_data = g_list_nth_data(found_list, 0);
1991 if (dnd_id_data->dnd_start_id)
1992 alarmmgr_remove_alarm(dnd_id_data->dnd_start_id);
1993 if (dnd_id_data->dnd_end_id)
1994 alarmmgr_remove_alarm(dnd_id_data->dnd_end_id);
1996 _dnd_alarm_id_list = g_list_remove(g_list_first(_dnd_alarm_id_list), dnd_id_data);
2000 /* update_noti_sys_setting */
2001 int notification_update_noti_sys_setting(GVariant *parameters, GVariant **reply_body, uid_t uid)
2004 int pre_do_not_disturb = 0;
2005 int do_not_disturb = 0;
2006 int visivility_class = 0;
2007 int dnd_schedule_enabled = 0;
2008 int dnd_schedule_day = 0;
2009 int dnd_start_hour = 0;
2010 int dnd_start_min = 0;
2011 int dnd_end_hour = 0;
2012 int dnd_end_min = 0;
2013 int lock_screen_level = 0;
2015 GVariant *body = NULL;
2017 g_variant_get(parameters, "(iiiiiiiiii)",
2020 &dnd_schedule_enabled,
2029 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
2030 if (ret != NOTIFICATION_ERROR_NONE)
2033 ret = noti_system_setting_get_do_not_disturb(&pre_do_not_disturb, param_uid);
2034 if (ret != NOTIFICATION_ERROR_NONE) {
2035 ERR("Failed to get do not disturb");
2039 ret = notification_setting_db_update_system_setting(do_not_disturb,
2041 dnd_schedule_enabled,
2049 if (ret != NOTIFICATION_ERROR_NONE) {
2050 ERR("Failed to setting db update system setting : %d", ret);
2054 if (pre_do_not_disturb != do_not_disturb) {
2055 body = g_variant_new("(ii)", do_not_disturb, param_uid);
2056 ret = send_notify(body, "change_dnd_notify", &_monitoring_hash, PROVIDER_NOTI_INTERFACE_NAME, param_uid);
2057 g_variant_unref(body);
2060 *reply_body = g_variant_new("()");
2061 if (*reply_body == NULL) {
2062 ERR("Failed to make reply_body");
2063 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
2066 if (dnd_schedule_enabled) {
2067 ret = _add_alarm(dnd_schedule_day, dnd_start_hour, dnd_start_min,
2068 dnd_end_hour, dnd_end_min, param_uid);
2069 if (ret != NOTIFICATION_ERROR_NONE)
2070 ERR("Failed to add alarm for dnd_schedule");
2072 _delete_alarm(param_uid);
2075 INFO("do_not_disturb [%d] visivility_class [%d] set_schedule [%d] lock_screen_level [%d]",
2076 do_not_disturb, visivility_class, dnd_schedule_enabled, lock_screen_level);
2080 int notification_add_noti_template(GVariant *parameters, GVariant **reply_body, uid_t uid)
2082 notification_h noti;
2084 GVariant *body = NULL;
2085 GVariant *coupled_body = NULL;
2086 char *template_name = NULL;
2089 noti = notification_create(NOTIFICATION_TYPE_NOTI);
2091 g_variant_get(parameters, "(v&s)", &coupled_body, &template_name);
2092 g_variant_get(coupled_body, "(v)", &body);
2094 ret = notification_ipc_make_noti_from_gvariant(noti, body);
2095 g_variant_unref(coupled_body);
2096 g_variant_unref(body);
2097 if (ret != NOTIFICATION_ERROR_NONE) {
2098 ERR("Failed to make a notification [%d]", ret);
2102 ret = notification_noti_check_count_for_template(noti, &count);
2103 if (count >= NOTI_TEMPLATE_LIMIT) {
2104 ERR("Exceed limit value that is saved tamplate [%d]", ret);
2105 ret = NOTIFICATION_ERROR_MAX_EXCEEDED;
2109 ret = notification_noti_add_template(noti, template_name);
2110 if (ret != NOTIFICATION_ERROR_NONE)
2111 ERR("Failed to add a notification [%d]", ret);
2113 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
2118 notification_free(noti);
2123 int notification_get_noti_template(GVariant *parameters, GVariant **reply_body, pid_t pid, uid_t uid)
2126 char app_id[BUF_LEN] = {0, };
2127 char *template_name = NULL;
2128 notification_h noti;
2130 noti = notification_create(NOTIFICATION_TYPE_NOTI);
2132 g_variant_get(parameters, "(&s)", &template_name);
2133 INFO("template name[%s]", template_name);
2135 ret = aul_app_get_appid_bypid_for_uid(pid, app_id, sizeof(app_id), uid);
2136 if (ret != AUL_R_OK) {
2137 ERR("Failed to get app_id [%d]", ret);
2138 ret = NOTIFICATION_ERROR_INVALID_PARAMETER;
2142 ret = notification_noti_get_package_template(noti, app_id, template_name);
2143 if (ret != NOTIFICATION_ERROR_NONE) {
2144 ERR("Failed to get template [%d]", ret);
2148 *reply_body = notification_ipc_make_gvariant_from_noti(noti, false);
2149 if (*reply_body == NULL) {
2150 ERR("Failed to make reply_body");
2151 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
2154 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
2159 notification_free(noti);
2164 int notification_get_noti_package_template(GVariant *parameters, GVariant **reply_body, uid_t uid)
2167 char *app_id = NULL;
2168 char *template_name = NULL;
2169 notification_h noti;
2171 noti = notification_create(NOTIFICATION_TYPE_NOTI);
2173 g_variant_get(parameters, "(&s&s)", &app_id, &template_name);
2174 INFO("app_id[%s] template name[%s]", app_id, template_name);
2175 ret = notification_noti_get_package_template(noti, app_id, template_name);
2176 if (ret != NOTIFICATION_ERROR_NONE) {
2177 ERR("Failed to get template [%d]", ret);
2181 *reply_body = notification_ipc_make_gvariant_from_noti(noti, false);
2182 if (*reply_body == NULL) {
2183 ERR("Failed to make reply_body");
2184 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
2187 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
2192 notification_free(noti);
2197 int notification_get_block_state(GVariant *parameters, GVariant **reply_body, uid_t uid)
2202 int allow_to_notify;
2205 GVariant *body = NULL;
2207 g_variant_get(parameters, "(&si)", &app_id, ¶m_uid);
2209 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
2210 if (ret != NOTIFICATION_ERROR_NONE) {
2211 ERR("_validate_uid fail [%d]", ret);
2212 return NOTIFICATION_ERROR_IO_ERROR;
2215 ret = notification_get_dnd_and_allow_to_notify(app_id, &dnd, &dnd_except, &allow_to_notify, param_uid);
2216 INFO("app_id[%s] dnd[%d] dnd_except[%d] allow_to_notify[%d]",
2217 app_id, dnd, dnd_except, allow_to_notify);
2218 if (ret != NOTIFICATION_ERROR_NONE) {
2219 ERR("Failed to get_dnd_and_allow_to_notify [%d]", ret);
2223 body = g_variant_new("(iii)", dnd, dnd_except, allow_to_notify);
2224 *reply_body = g_variant_new("(v)", body);
2226 if (*reply_body == NULL) {
2227 ERR("Failed to make reply_body");
2228 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
2233 int notification_load_dnd_allow_exception(GVariant *parameters, GVariant **reply_body, uid_t uid)
2239 GVariant *body = NULL;
2240 GVariantBuilder *builder;
2241 dnd_allow_exception_h dnd_allow_exception = NULL;
2242 dnd_allow_exception_h temp;
2244 g_variant_get(parameters, "(i)", ¶m_uid);
2246 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
2247 if (ret != NOTIFICATION_ERROR_NONE)
2250 ret = notification_system_setting_load_dnd_allow_exception(&dnd_allow_exception, &count, param_uid);
2251 if (ret != NOTIFICATION_ERROR_NONE) {
2252 ERR("Failed to load dnd_allow_exception [%d]", ret);
2256 builder = g_variant_builder_new(G_VARIANT_TYPE("a(v)"));
2258 if (dnd_allow_exception) {
2259 for (i = 0; i < count; i++) {
2260 temp = dnd_allow_exception + i;
2261 body = notification_ipc_make_gvariant_from_dnd_allow_exception(temp);
2262 g_variant_builder_add(builder, "(v)", body);
2264 free(dnd_allow_exception);
2267 *reply_body = g_variant_new("(ia(v))", count, builder);
2268 g_variant_builder_unref(builder);
2270 if (*reply_body == NULL) {
2271 ERR("Failed to make reply_body");
2272 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
2278 int notification_update_dnd_allow_exception(GVariant *parameters, GVariant **reply_body, uid_t uid)
2285 g_variant_get(parameters, "(iii)", &type, &value, ¶m_uid);
2287 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
2288 if (ret != NOTIFICATION_ERROR_NONE)
2291 ret = notification_system_setting_update_dnd_allow_exception(type,
2294 if (ret != NOTIFICATION_ERROR_NONE) {
2295 ERR("Failed to update dnd_allow_exception [%d]", ret);
2299 *reply_body = g_variant_new("()");
2300 if (*reply_body == NULL) {
2301 ERR("Failed to make reply_body");
2302 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
2308 static event_sender_info_s *__find_sender_info_by_priv_id(int priv_id)
2310 event_sender_info_s *event_info;
2313 if (__event_list == NULL)
2316 __event_list = g_list_first(__event_list);
2317 find_list = g_list_find_custom(__event_list, GINT_TO_POINTER(priv_id),
2318 (GCompareFunc)__priv_id_compare);
2321 event_info = g_list_nth_data(find_list, 0);
2328 int notification_send_noti_event(GVariant *parameters, GVariant **reply_body)
2333 event_sender_info_s *info;
2334 GVariant *coupled_body = NULL;
2335 GVariant *body = NULL;
2336 notification_h noti;
2338 noti = notification_create(NOTIFICATION_TYPE_NOTI);
2340 g_variant_get(parameters, "(vi)", &coupled_body, &event_type);
2341 g_variant_get(coupled_body, "(v)", &body);
2343 ret = notification_ipc_make_noti_from_gvariant(noti, body);
2344 g_variant_unref(coupled_body);
2345 g_variant_unref(body);
2347 if (ret != NOTIFICATION_ERROR_NONE) {
2348 ERR("Failed to make a notification from gvariant");
2352 ret = notification_get_id(noti, NULL, &priv_id);
2353 if (ret != NOTIFICATION_ERROR_NONE)
2356 info = __find_sender_info_by_priv_id(priv_id);
2357 if (info == NULL || info->busname == NULL) {
2358 ret = NOTIFICATION_ERROR_INVALID_PARAMETER;
2362 if (!info->watcher_id) {
2363 if (!is_existed_busname(info->busname)) {
2364 __event_list = g_list_remove(g_list_first(__event_list), info);
2365 __free_event_info(info);
2366 ret = NOTIFICATION_ERROR_IO_ERROR;
2369 info->watcher_id = __insert_sender_watcher_id(info);
2373 ret = send_event_notify_by_busname(parameters, "send_event", info->busname, PROVIDER_NOTI_EVENT_INTERFACE_NAME);
2374 if (ret != NOTIFICATION_ERROR_NONE) {
2375 ERR("Failed to send event [%d]", ret);
2379 *reply_body = g_variant_new("()");
2380 if (*reply_body == NULL) {
2381 ERR("Failed to make reply body");
2382 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
2385 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
2390 notification_free(noti);
2395 int notification_send_noti_event_by_priv_id(GVariant *parameters, GVariant **reply_body)
2400 bool event_flag = false;
2401 notification_h noti;
2402 GVariant *body = NULL;
2403 event_sender_info_s *info;
2405 noti = notification_create(NOTIFICATION_TYPE_NOTI);
2407 g_variant_get(parameters, "(ii)", &priv_id, &event_type);
2409 ret = notification_noti_get_by_priv_id(noti, priv_id);
2410 if (ret != NOTIFICATION_ERROR_NONE) {
2411 ERR("Failed to get notification by priv id [%d]", ret);
2415 ret = notification_get_event_flag(noti, &event_flag);
2416 if (ret != NOTIFICATION_ERROR_NONE || event_flag == false) {
2417 ret = NOTIFICATION_ERROR_INVALID_PARAMETER;
2421 info = __find_sender_info_by_priv_id(priv_id);
2422 if (info == NULL || info->busname == NULL) {
2423 ret = NOTIFICATION_ERROR_INVALID_PARAMETER;
2424 ERR("No sender info by priv_id[%d]", priv_id);
2428 if (!info->watcher_id) {
2429 if (!is_existed_busname(info->busname)) {
2430 __event_list = g_list_remove(g_list_first(__event_list), info);
2431 __free_event_info(info);
2432 ret = NOTIFICATION_ERROR_IO_ERROR;
2435 info->watcher_id = __insert_sender_watcher_id(info);
2439 body = notification_ipc_make_gvariant_from_noti(noti, false);
2441 ERR("Can't make gvariant to noti");
2442 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
2446 ret = send_event_notify_by_busname(g_variant_new("(vi)", body, event_type), "send_event", info->busname, PROVIDER_NOTI_EVENT_INTERFACE_NAME);
2447 *reply_body = g_variant_new("()");
2448 if (*reply_body == NULL) {
2449 ERR("Failed to make reply body");
2450 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
2453 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
2458 notification_free(noti);
2463 int notification_check_event_receiver(GVariant *parameters, GVariant **reply_body)
2466 bool available = false;
2467 GList *find_list = NULL;
2468 event_sender_info_s *info = NULL;
2470 g_variant_get(parameters, "(i)", &priv_id);
2471 INFO("priv_id[%d]", priv_id);
2473 __event_list = g_list_first(__event_list);
2474 find_list = g_list_find_custom(__event_list, GINT_TO_POINTER(priv_id),
2475 (GCompareFunc)__priv_id_compare);
2477 info = g_list_nth_data(find_list, 0);
2478 if (!info->watcher_id) {
2479 if (!is_existed_busname(info->busname)) {
2480 __event_list = g_list_remove(g_list_first(__event_list), info);
2481 __free_event_info(info);
2484 info->watcher_id = __insert_sender_watcher_id(info);
2491 *reply_body = g_variant_new("(i)", (int)available);
2492 if (*reply_body == NULL) {
2493 ERR("Failed to make gvariant to noti");
2494 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
2497 INFO("Receiver available[%d]", available);
2498 return NOTIFICATION_ERROR_NONE;
2501 int notification_reset_event_receiver(GVariant *parameters, GVariant **reply_body, const char *sender)
2505 g_variant_get(parameters, "(i)", &priv_id);
2506 INFO("priv_id[%d]", priv_id);
2508 __add_sender_info(priv_id, sender);
2510 *reply_body = g_variant_new("()");
2511 if (*reply_body == NULL) {
2512 ERR("Failed to make gvariant to noti");
2513 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
2516 return NOTIFICATION_ERROR_NONE;
2519 HAPI int notification_delete_noti_by_app_id(const char *app_id, uid_t uid)
2521 GVariant *deleted_noti_list;
2522 GVariantBuilder *builder;
2523 int num_deleted = 0;
2524 int *list_deleted = NULL;
2528 ret = notification_noti_delete_all(NOTIFICATION_TYPE_NONE, app_id, &num_deleted, &list_deleted, uid);
2529 if (ret != NOTIFICATION_ERROR_NONE) {
2530 ERR("Failed to delete notifications [%d]", ret);
2534 if (num_deleted > 0) {
2535 builder = g_variant_builder_new(G_VARIANT_TYPE("a(i)"));
2537 for (i = 0; i < num_deleted; i++)
2538 g_variant_builder_add(builder, "(i)", *(list_deleted + i));
2540 deleted_noti_list = g_variant_new("(a(i)ii)", builder, num_deleted, uid);
2541 ret = send_notify(deleted_noti_list, "delete_multiple_notify", &_monitoring_hash, PROVIDER_NOTI_INTERFACE_NAME, uid);
2542 g_variant_builder_unref(builder);
2543 g_variant_unref(deleted_noti_list);
2544 if (ret != NOTIFICATION_ERROR_NONE) {
2545 ERR("Failed to send notify [%d]", ret);
2549 for (i = 0; i < num_deleted; i++) {
2550 ret = __delete_sender_info(*(list_deleted + i));
2551 if (ret != NOTIFICATION_ERROR_NONE)
2556 if (list_deleted != NULL)
2561 static int _check_dnd_schedule(uid_t uid)
2564 notification_system_setting_h setting = NULL;
2565 bool dnd_schedule_enabled = false;
2566 int dnd_schedule_day = 0;
2567 int dnd_start_hour = 0;
2568 int dnd_start_min = 0;
2569 int dnd_end_hour = 0;
2570 int dnd_end_min = 0;
2572 ret = noti_system_setting_load_system_setting(&setting, uid);
2573 if (ret != NOTIFICATION_ERROR_NONE) {
2574 ERR("noti_system_setting_load_system_setting fail [%d]", ret);
2578 ret = notification_system_setting_dnd_schedule_get_enabled(setting,
2579 &dnd_schedule_enabled);
2580 if (ret != NOTIFICATION_ERROR_NONE) {
2581 ERR("system_setting_dnd_schedule_get_enabled fail [%d]", ret);
2585 if (dnd_schedule_enabled) {
2586 ret = notification_system_setting_dnd_schedule_get_day(setting,
2588 if (ret != NOTIFICATION_ERROR_NONE) {
2589 ERR("system_setting_dnd_schedule_get_day fail [%d]", ret);
2593 ret = notification_system_setting_dnd_schedule_get_start_time(setting,
2594 &dnd_start_hour, &dnd_start_min);
2595 if (ret != NOTIFICATION_ERROR_NONE) {
2596 ERR("system_setting_dnd_schedule_get_start_time fail [%d]", ret);
2600 ret = notification_system_setting_dnd_schedule_get_end_time(setting,
2601 &dnd_end_hour, &dnd_end_min);
2602 if (ret != NOTIFICATION_ERROR_NONE) {
2603 ERR("system_setting_dnd_schedule_get_end_time fail [%d]", ret);
2607 _add_alarm(dnd_schedule_day, dnd_start_hour, dnd_start_min, dnd_end_hour, dnd_end_min, uid);
2611 notification_system_setting_free_system_setting(setting);
2616 static gboolean __refresh_setting_table(gpointer data)
2618 notification_setting_refresh_setting_table(
2619 tzplatform_getuid(TZ_SYS_DEFAULT_USER));
2620 return G_SOURCE_REMOVE;
2625 * Do not try to do any other operation in these functions
2627 HAPI int notification_service_init(void)
2633 _monitoring_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
2634 ret = notification_db_init();
2635 if (ret != NOTIFICATION_ERROR_NONE) {
2636 ERR("Failed to init DB [%d]", ret);
2640 ret = notification_register_dbus_interface();
2641 if (ret != SERVICE_COMMON_ERROR_NONE) {
2642 ERR("Failed to register dbus interface [%d]", ret);
2643 return NOTIFICATION_ERROR_IO_ERROR;
2646 notification_init_default_viewer();
2647 notification_noti_init_data();
2648 notification_system_setting_init_system_setting_table(tzplatform_getuid(TZ_SYS_DEFAULT_USER));
2650 ret = notification_system_setting_get_dnd_schedule_enabled_uid(&uids, &count);
2651 if (ret == NOTIFICATION_ERROR_NONE && count > 0) {
2652 for (i = 0; i < count; i++)
2653 _check_dnd_schedule(uids[i]);
2658 g_idle_add(__refresh_setting_table, NULL);
2660 INFO("Successfully initialized");
2661 return NOTIFICATION_ERROR_NONE;
2664 HAPI int notification_service_fini(void)
2667 DBG("Successfully Finalized");
2668 return NOTIFICATION_ERROR_NONE;