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 static char *default_viewer;
56 typedef struct _dnd_alarm_id {
58 alarm_id_t dnd_start_id;
59 alarm_id_t dnd_end_id;
62 static GList *__event_list = NULL;
64 typedef struct _event_sender_info {
68 } event_sender_info_s;
70 static int _update_noti(GVariant **reply_body, notification_h noti, uid_t uid);
71 static int _delete_noti(const char *app_id, int priv_id, uid_t uid);
78 * NOTIFICATION SERVICE INITIALIZATION
81 static void _on_name_appeared(GDBusConnection *connection,
83 const gchar *name_owner,
86 monitoring_info_s *info = (monitoring_info_s *)user_data;
88 DBG("name[%s], uid[%d]", name, info->uid);
91 static void _on_name_vanished(GDBusConnection *connection,
95 monitoring_info_s *info = (monitoring_info_s *)user_data;
98 DBG("name[%s], uid[%d]", name, info->uid);
99 notification_remove_private_sharing_target_id(name, info->uid);
100 g_bus_unwatch_name(info->watcher_id);
101 delete_monitoring_list(&_monitoring_hash, info->bus_name, info->uid);
104 free(info->bus_name);
109 static void _noti_dbus_method_call_handler(GDBusConnection *conn,
110 const gchar *sender, const gchar *object_path,
111 const gchar *iface_name, const gchar *method_name,
112 GVariant *parameters, GDBusMethodInvocation *invocation,
115 /* TODO : sender authority(privilege) check */
116 INFO("notification method_name[%s] sender[%s]", method_name, sender);
118 GVariant *reply_body = NULL;
119 int ret = NOTIFICATION_ERROR_INVALID_OPERATION;
120 uid_t uid = get_sender_uid(sender);
121 pid_t pid = get_sender_pid(sender);
123 if (g_strcmp0(method_name, "noti_service_register") == 0) {
124 ret = service_register(parameters, &reply_body, sender,
125 _on_name_appeared, _on_name_vanished, &_monitoring_hash, uid);
126 if (ret == NOTIFICATION_ERROR_NONE)
127 notification_add_private_sharing_target_id(pid, sender, uid);
128 } else if (g_strcmp0(method_name, "update_noti") == 0) {
129 ret = notification_update_noti(parameters, &reply_body, uid);
130 } else if (g_strcmp0(method_name, "add_noti") == 0) {
131 ret = notification_add_noti(parameters, &reply_body, sender, uid);
132 } else if (g_strcmp0(method_name, "refresh_noti") == 0) {
133 ret = notification_refresh_noti(parameters, &reply_body, uid);
134 } else if (g_strcmp0(method_name, "del_noti_single") == 0) {
135 ret = notification_del_noti_single(parameters, &reply_body, uid);
136 } else if (g_strcmp0(method_name, "del_noti_multiple") == 0) {
137 ret = notification_del_noti_multiple(parameters, &reply_body, uid);
138 } else if (g_strcmp0(method_name, "get_noti_count") == 0) {
139 ret = notification_get_noti_count(parameters, &reply_body, uid);
140 } else if (g_strcmp0(method_name, "get_noti_all_count") == 0) {
141 ret = notification_get_noti_all_count(parameters, &reply_body, uid);
142 } else if (g_strcmp0(method_name, "update_noti_setting") == 0) {
143 ret = notification_update_noti_setting(parameters, &reply_body, uid);
144 } else if (g_strcmp0(method_name, "update_noti_sys_setting") == 0) {
145 ret = notification_update_noti_sys_setting(parameters, &reply_body, uid);
146 } else if (g_strcmp0(method_name, "load_noti_by_tag") == 0) {
147 ret = notification_load_noti_by_tag(parameters, &reply_body, uid);
148 } else if (g_strcmp0(method_name, "load_noti_by_priv_id") == 0) {
149 ret = notification_load_noti_by_priv_id(parameters, &reply_body, uid);
150 } else if (g_strcmp0(method_name, "load_noti_grouping_list") == 0) {
151 notification_add_private_sharing_target_id(pid, sender, uid);
152 notification_load_grouping_list(invocation, parameters, uid);
154 } else if (g_strcmp0(method_name, "load_noti_detail_list") == 0) {
155 notification_add_private_sharing_target_id(pid, sender, uid);
156 ret = notification_load_detail_list(parameters, &reply_body, uid);
157 } else if (g_strcmp0(method_name, "get_setting_array") == 0) {
158 ret = notification_get_setting_array(parameters, &reply_body, uid);
159 } else if (g_strcmp0(method_name, "get_setting_by_app_id") == 0) {
160 ret = notification_get_setting_by_app_id(parameters, &reply_body, uid);
161 } else if (g_strcmp0(method_name, "load_system_setting") == 0) {
162 ret = notification_load_system_setting(parameters, &reply_body, uid);
163 } else if (g_strcmp0(method_name, "save_as_template") == 0) {
164 ret = notification_add_noti_template(parameters, &reply_body, uid);
165 } else if (g_strcmp0(method_name, "create_from_template") == 0) {
166 ret = notification_get_noti_template(parameters, &reply_body, pid, uid);
167 } else if (g_strcmp0(method_name, "create_from_package_template") == 0) {
168 ret = notification_get_noti_package_template(parameters, &reply_body, uid);
169 } else if (g_strcmp0(method_name, "get_noti_block_state") == 0) {
170 ret = notification_get_block_state(parameters, &reply_body, uid);
171 } else if (g_strcmp0(method_name, "load_dnd_allow_exception") == 0) {
172 ret = notification_load_dnd_allow_exception(parameters, &reply_body, uid);
173 } else if (g_strcmp0(method_name, "update_dnd_allow_exception") == 0) {
174 ret = notification_update_dnd_allow_exception(parameters, &reply_body, uid);
175 } else if (g_strcmp0(method_name, "send_noti_event") == 0) {
176 ret = notification_send_noti_event(parameters, &reply_body);
177 } else if (g_strcmp0(method_name, "send_noti_event_by_priv_id") == 0) {
178 ret = notification_send_noti_event_by_priv_id(parameters, &reply_body);
179 } else if (g_strcmp0(method_name, "check_event_receiver") == 0) {
180 ret = notification_check_event_receiver(parameters, &reply_body);
181 } else if (g_strcmp0(method_name, "reset_event_handler") == 0) {
182 ret = notification_reset_event_receiver(parameters, &reply_body, sender);
185 if (ret == NOTIFICATION_ERROR_NONE) {
186 INFO("notification service success, method name[%s]", method_name);
187 g_dbus_method_invocation_return_value(
188 invocation, reply_body);
190 ERR("notification service fail, method_name[%s] err[%d]",
192 g_dbus_method_invocation_return_error(
196 "notification service error");
200 static const GDBusInterfaceVTable _noti_interface_vtable = {
201 _noti_dbus_method_call_handler,
206 int notification_register_dbus_interface()
208 static gchar introspection_xml[] =
210 " <interface name='org.tizen.data_provider_noti_service'>"
211 " <method name='noti_service_register'>"
212 " <arg type='i' name='uid' direction='in'/>"
215 " <method name='add_noti'>"
216 " <arg type='v' name='noti' direction='in'/>"
217 " <arg type='i' name='priv_id' direction='out'/>"
220 " <method name='update_noti'>"
221 " <arg type='v' name='noti' direction='in'/>"
222 " <arg type='i' name='priv_id' direction='out'/>"
225 " <method name='refresh_noti'>"
226 " <arg type='i' name='uid' direction='in'/>"
229 " <method name='del_noti_single'>"
230 " <arg type='s' name='app_id' direction='in'/>"
231 " <arg type='i' name='priv_id' direction='in'/>"
232 " <arg type='i' name='uid' direction='in'/>"
233 " <arg type='i' name='priv_id' direction='out'/>"
236 " <method name='del_noti_multiple'>"
237 " <arg type='s' name='app_id' direction='in'/>"
238 " <arg type='i' name='priv_id' direction='in'/>"
239 " <arg type='i' name='uid' direction='in'/>"
240 " <arg type='i' name='priv_id' direction='out'/>"
243 " <method name='load_noti_by_tag'>"
244 " <arg type='s' name='app_id' direction='in'/>"
245 " <arg type='s' name='tag' direction='in'/>"
246 " <arg type='i' name='uid' direction='in'/>"
247 " <arg type='v' name='noti' direction='out'/>"
250 " <method name='load_noti_by_priv_id'>"
251 " <arg type='s' name='app_id' direction='in'/>"
252 " <arg type='i' name='priv_id' direction='in'/>"
253 " <arg type='i' name='uid' direction='in'/>"
254 " <arg type='v' name='noti' direction='out'/>"
257 " <method name='load_noti_grouping_list'>"
258 " <arg type='i' name='type' direction='in'/>"
259 " <arg type='i' name='count' direction='in'/>"
260 " <arg type='i' name='count_per_page' direction='in'/>"
261 " <arg type='i' name='uid' direction='in'/>"
262 " <arg type='i' name='list_count' direction='out'/>"
265 " <method name='load_noti_detail_list'>"
266 " <arg type='s' name='app_id' direction='in'/>"
267 " <arg type='i' name='group_id' direction='in'/>"
268 " <arg type='i' name='priv_id' direction='in'/>"
269 " <arg type='i' name='count' direction='in'/>"
270 " <arg type='i' name='uid' direction='in'/>"
271 " <arg type='a(v)' name='noti_list' direction='out'/>"
274 " <method name='get_noti_count'>"
275 " <arg type='i' name='type' direction='in'/>"
276 " <arg type='s' name='app_id' direction='in'/>"
277 " <arg type='i' name='group_id' direction='in'/>"
278 " <arg type='i' name='priv_id' direction='in'/>"
279 " <arg type='i' name='uid' direction='in'/>"
280 " <arg type='i' name='ret_count' direction='out'/>"
283 " <method name='get_noti_all_count'>"
284 " <arg type='i' name='type' direction='in'/>"
285 " <arg type='i' name='uid' direction='in'/>"
286 " <arg type='i' name='ret_count' direction='out'/>"
289 " <method name='update_noti_setting'>"
290 " <arg type='s' name='pkgname' direction='in'/>"
291 " <arg type='s' name='app_id' direction='in'/>"
292 " <arg type='i' name='allow_to_notify' direction='in'/>"
293 " <arg type='i' name='do_not_disturb_except' direction='in'/>"
294 " <arg type='i' name='visibility_class' direction='in'/>"
295 " <arg type='i' name='pop_up_notification' direction='in'/>"
296 " <arg type='i' name='lock_screen_content_level' direction='in'/>"
297 " <arg type='i' name='uid' direction='in'/>"
300 " <method name='update_noti_sys_setting'>"
301 " <arg type='i' name='do_not_disturb' direction='in'/>"
302 " <arg type='i' name='visibility_class' direction='in'/>"
303 " <arg type='i' name='dnd_schedule_enabled' direction='in'/>"
304 " <arg type='i' name='dnd_schedule_day' direction='in'/>"
305 " <arg type='i' name='dnd_start_hour' direction='in'/>"
306 " <arg type='i' name='dnd_start_min' direction='in'/>"
307 " <arg type='i' name='dnd_end_hour' direction='in'/>"
308 " <arg type='i' name='dnd_end_min' direction='in'/>"
309 " <arg type='i' name='lock_screen_level' direction='in'/>"
310 " <arg type='i' name='uid' direction='in'/>"
313 " <method name='get_setting_array'>"
314 " <arg type='i' name='uid' direction='in'/>"
315 " <arg type='i' name='setting_cnt' direction='out'/>"
316 " <arg type='a(v)' name='setting_arr' direction='out'/>"
319 " <method name='get_setting_by_app_id'>"
320 " <arg type='s' name='app_id' direction='in'/>"
321 " <arg type='i' name='uid' direction='in'/>"
322 " <arg type='v' name='setting' direction='out'/>"
325 " <method name='load_system_setting'>"
326 " <arg type='i' name='uid' direction='in'/>"
327 " <arg type='v' name='setting' direction='out'/>"
330 " <method name='save_as_template'>"
331 " <arg type='v' name='noti' direction='in'/>"
332 " <arg type='s' name='name' direction='in'/>"
335 " <method name='create_from_template'>"
336 " <arg type='s' name='name' direction='in'/>"
337 " <arg type='v' name='noti' direction='out'/>"
340 " <method name='create_from_package_template'>"
341 " <arg type='s' name='app_id' direction='in'/>"
342 " <arg type='s' name='name' direction='in'/>"
343 " <arg type='v' name='noti' direction='out'/>"
346 " <method name='get_noti_block_state'>"
347 " <arg type='s' name='app_id' direction='in'/>"
348 " <arg type='i' name='uid' direction='in'/>"
349 " <arg type='v' name='state' direction='out'/>"
352 " <method name='update_dnd_allow_exception'>"
353 " <arg type='i' name='type' direction='in'/>"
354 " <arg type='i' name='value' direction='in'/>"
355 " <arg type='i' name='uid' direction='in'/>"
358 " <method name='load_dnd_allow_exception'>"
359 " <arg type='i' name='uid' direction='in'/>"
360 " <arg type='i' name='count' direction='out'/>"
361 " <arg type='a(v)' name='dnd_allow_exception' direction='out'/>"
364 " <method name='send_noti_event'>"
365 " <arg type='v' name='noti' direction='in'/>"
366 " <arg type='i' name='event_type' direction='in'/>"
369 " <method name='send_noti_event_by_priv_id'>"
370 " <arg type='i' name='priv_id' direction='in'/>"
371 " <arg type='i' name='event_type' direction='in'/>"
374 " <method name='check_event_receiver'>"
375 " <arg type='i' name='priv_id' direction='in'/>"
376 " <arg type='i' name='available' direction='out'/>"
379 " <method name='reset_event_handler'>"
380 " <arg type='i' name='priv_id' direction='in'/>"
383 " <method name='post_toast'>"
388 return service_common_register_dbus_interface(introspection_xml, _noti_interface_vtable);
391 static void __free_event_info(gpointer data)
393 event_sender_info_s *info = (event_sender_info_s *)data;
402 static gint __priv_id_compare(gconstpointer a, gconstpointer b)
404 event_sender_info_s *info = NULL;
409 info = (event_sender_info_s *)a;
411 if (info->priv_id == GPOINTER_TO_INT(b))
417 static int __check_limit(notification_h noti, uid_t uid)
420 int priv_id = NOTIFICATION_PRIV_ID_NONE;
423 GList *iter_list = NULL;
425 ret = notification_noti_check_limit(noti, uid, &list);
426 if (ret == NOTIFICATION_ERROR_NONE && list != NULL) {
427 ret = notification_get_pkgname(noti, &app_id);
428 if (ret == NOTIFICATION_ERROR_NONE && app_id != NULL) {
431 priv_id = GPOINTER_TO_INT(iter_list->data);
433 ret = _delete_noti((const char *)app_id, priv_id, uid);
434 if (ret != NOTIFICATION_ERROR_NONE)
435 ERR("Failed to delete noti[%d], err[%d]",
438 iter_list = g_list_next(iter_list);
450 static int _add_noti(GVariant **reply_body, notification_h noti, uid_t uid)
453 int priv_id = NOTIFICATION_PRIV_ID_NONE;
454 GVariant *body = NULL;
457 ret = notification_noti_insert(noti);
458 if (ret != NOTIFICATION_ERROR_NONE) {
459 ERR("Failed to update a notification [%d]", ret);
463 ret = notification_get_id(noti, NULL, &priv_id);
464 if (ret != NOTIFICATION_ERROR_NONE) {
465 ERR("Failed to gets priv_id [%d]", ret);
469 notification_set_private_sharing(noti, uid);
471 body = notification_ipc_make_gvariant_from_noti(noti, true);
473 ERR("Failed to make gvariant to noti");
474 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
477 ret = send_notify(body, "add_noti_notify", &_monitoring_hash,
478 PROVIDER_NOTI_INTERFACE_NAME, uid);
479 g_variant_unref(body);
481 if (ret != NOTIFICATION_ERROR_NONE) {
482 ERR("Failed to send notify [%d]", ret);
486 if (default_viewer != NULL) {
487 ret = notification_launch_default_viewer(default_viewer,
488 priv_id, NOTIFICATION_OP_INSERT, uid);
489 if (ret != NOTIFICATION_ERROR_NONE) {
490 ERR("Failed to launch default viewer [%d]", ret);
491 ret = NOTIFICATION_ERROR_NONE;
495 *reply_body = g_variant_new("(i)", priv_id);
496 if (*reply_body == NULL) {
497 ERR("Failed to make reply");
498 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
501 ret = __check_limit(noti, uid);
502 if (ret != NOTIFICATION_ERROR_NONE) {
503 ERR("Failed to check limit [%d]", ret);
504 ret = NOTIFICATION_ERROR_NONE;
507 DBG("Success to add notification");
511 static int _validate_and_set_noti_with_uid(uid_t uid, notification_h noti, uid_t *noti_uid)
513 int ret = NOTIFICATION_ERROR_NONE;
515 ret = notification_get_uid(noti, noti_uid);
516 if (ret != NOTIFICATION_ERROR_NONE) {
517 ERR("Failed to get uid [%d]", ret);
521 if (uid > NORMAL_UID_BASE && uid != *noti_uid) {
522 ERR("Invalid seder uid[%d] noti_uid[%d]", uid, *noti_uid);
523 return NOTIFICATION_ERROR_INVALID_PARAMETER;
524 } else if (uid <= NORMAL_UID_BASE) {
525 if (*noti_uid <= NORMAL_UID_BASE) {
526 if (*noti_uid != uid)
527 return NOTIFICATION_ERROR_INVALID_PARAMETER;
529 DBG("system defualt noti post change noti_uid to default");
531 IF system (uid <= NORMAL_UID_BASE) try to send noti without specipic destination uid (using notification_pot API)
532 Send it to default user (TZ_SYS_DEFAULT_USER)
534 *noti_uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
535 ret = notification_set_uid(noti, *noti_uid);
536 if (ret != NOTIFICATION_ERROR_NONE) {
537 ERR("Failed to set uid [%d]", ret);
540 DBG("changed noti_uid[%d]", *noti_uid);
546 static int _validate_and_set_param_uid_with_uid(uid_t uid, uid_t *param_uid)
548 if (uid > NORMAL_UID_BASE && uid != *param_uid) {
549 ERR("invalid seder uid[%d], param_uid[%d]", uid, *param_uid);
550 return NOTIFICATION_ERROR_INVALID_PARAMETER;
551 } else if (uid <= NORMAL_UID_BASE) {
552 if (*param_uid <= NORMAL_UID_BASE) {
553 if (*param_uid != uid)
554 return NOTIFICATION_ERROR_INVALID_PARAMETER;
556 IF system (uid <= NORMAL_UID_BASE) try to send noti without specipic destination uid (using notification_pot API)
557 Send it to default user (TZ_SYS_DEFAULT_USER)
559 *param_uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
562 return NOTIFICATION_ERROR_NONE;
565 static void __sender_name_appeared_cb(GDBusConnection *connection,
567 const gchar *name_owner,
570 DBG("name[%s], name_owner[%s]", name, name_owner);
573 static void __sender_name_vanished_cb(GDBusConnection *connection,
577 GList *delete_list = NULL;
578 event_sender_info_s *info;
583 info = (event_sender_info_s *)user_data;
585 DBG("name[%s], priv_id[%d], watcher_id[%d]",
586 name, info->priv_id, info->watcher_id);
588 delete_list = g_list_find_custom(__event_list, GINT_TO_POINTER(info->priv_id),
589 (GCompareFunc)__priv_id_compare);
591 __event_list = g_list_remove(__event_list, info);
592 g_bus_unwatch_name(info->watcher_id);
593 __free_event_info(info);
597 static guint __insert_sender_watcher_id(event_sender_info_s *sender_info)
599 guint watcher_id = 0;
600 watcher_id = g_bus_watch_name(G_BUS_TYPE_SYSTEM,
601 sender_info->busname,
602 G_BUS_NAME_WATCHER_FLAGS_NONE,
603 __sender_name_appeared_cb,
604 __sender_name_vanished_cb,
608 ERR("Failed to watch sender name");
612 DBG("Watch on busname[%s] watcher_id[%d]", sender_info->busname, watcher_id);
616 static void __add_sender_info(int priv_id, const char *busname)
618 GList *find_list = NULL;
619 event_sender_info_s *sender_info;
620 event_sender_info_s *tmp_info = NULL;
625 sender_info = (event_sender_info_s *)malloc(sizeof(event_sender_info_s));
626 if (sender_info == NULL) {
627 ERR("malloc failed");
631 sender_info->priv_id = priv_id;
632 sender_info->busname = strdup(busname);
634 if (__event_list == NULL) {
635 sender_info->watcher_id = __insert_sender_watcher_id(sender_info);
636 __event_list = g_list_append(__event_list, sender_info);
638 __event_list = g_list_first(__event_list);
639 find_list = g_list_find_custom(__event_list, GINT_TO_POINTER(priv_id),
640 (GCompareFunc)__priv_id_compare);
641 if (find_list == NULL) {
642 sender_info->watcher_id = __insert_sender_watcher_id(sender_info);
643 __event_list = g_list_append(__event_list, sender_info);
645 tmp_info = (event_sender_info_s *)g_list_nth_data(find_list, 0);
646 if (tmp_info->busname) {
647 if (strcmp(tmp_info->busname, busname)) {
648 free(tmp_info->busname);
649 tmp_info->busname = strdup(busname);
650 g_bus_unwatch_name(tmp_info->watcher_id);
651 tmp_info->watcher_id = __insert_sender_watcher_id(sender_info);
654 tmp_info->busname = strdup(busname);
655 if (!tmp_info->watcher_id)
656 g_bus_unwatch_name(tmp_info->watcher_id);
657 tmp_info->watcher_id = __insert_sender_watcher_id(tmp_info);
659 __free_event_info(sender_info);
664 int notification_add_noti(GVariant *parameters, GVariant **reply_body, const char *sender, uid_t uid)
670 GVariant *body = NULL;
673 noti = notification_create(NOTIFICATION_TYPE_NOTI);
675 g_variant_get(parameters, "(v)", &body);
676 ret = notification_ipc_make_noti_from_gvariant(noti, body);
677 g_variant_unref(body);
679 ret = _validate_and_set_noti_with_uid(uid, noti, ¬i_uid);
680 if (ret != NOTIFICATION_ERROR_NONE)
683 ret = notification_noti_check_tag(noti);
684 if (ret == NOTIFICATION_ERROR_NOT_EXIST_ID)
685 ret = _add_noti(reply_body, noti, noti_uid);
686 else if (ret == NOTIFICATION_ERROR_ALREADY_EXIST_ID)
687 ret = _update_noti(reply_body, noti, noti_uid);
689 if (ret != NOTIFICATION_ERROR_NONE)
692 ret = notification_get_event_flag(noti, &event_flag);
693 if (ret != NOTIFICATION_ERROR_NONE)
696 if (event_flag == true) {
697 ret = notification_get_id(noti, NULL, &priv_id);
698 if (ret != NOTIFICATION_ERROR_NONE)
701 __add_sender_info(priv_id, sender);
704 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
708 notification_free(noti);
714 static int _update_noti(GVariant **reply_body, notification_h noti, uid_t uid)
717 GVariant *body = NULL;
718 int priv_id = NOTIFICATION_PRIV_ID_NONE;
719 notification_h source_noti;
723 if (notification_validate_private_sharing(noti) == false) {
724 source_noti = notification_create(NOTIFICATION_TYPE_NOTI);
725 notification_get_id(noti, NULL, &priv_id);
726 notification_noti_get_by_priv_id(source_noti, priv_id);
728 notification_calibrate_private_sharing(noti, source_noti);
729 notification_free(source_noti);
732 ret = notification_noti_update(noti);
733 if (ret != NOTIFICATION_ERROR_NONE) {
734 ERR("Failed to update a notification [%d]", ret);
738 ret = notification_get_id(noti, NULL, &priv_id);
739 if (ret != NOTIFICATION_ERROR_NONE) {
740 ERR("Failed to gets priv_id [%d]", ret);
744 notification_set_private_sharing(noti, uid);
746 body = notification_ipc_make_gvariant_from_noti(noti, true);
748 ERR("Failed to make gvariant to noti");
749 return NOTIFICATION_ERROR_IO_ERROR;
752 ret = send_notify(body, "update_noti_notify", &_monitoring_hash, PROVIDER_NOTI_INTERFACE_NAME, uid);
753 g_variant_unref(body);
755 if (ret != NOTIFICATION_ERROR_NONE) {
756 ERR("Failed to send notify [%d]", ret);
760 if (default_viewer != NULL) {
761 ret = notification_launch_default_viewer(default_viewer,
762 priv_id, NOTIFICATION_OP_UPDATE, uid);
763 if (ret != NOTIFICATION_ERROR_NONE) {
764 ERR("Failed to launch default viewer [%d]", ret);
765 ret = NOTIFICATION_ERROR_NONE;
769 *reply_body = g_variant_new("(i)", priv_id);
770 if (*reply_body == NULL) {
771 ERR("Failed to make reply_body");
772 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
775 DBG("Success to update noti");
779 int notification_update_noti(GVariant *parameters, GVariant **reply_body, uid_t uid)
783 GVariant *body = NULL;
786 noti = notification_create(NOTIFICATION_TYPE_NOTI);
788 g_variant_get(parameters, "(v)", &body);
789 ret = notification_ipc_make_noti_from_gvariant(noti, body);
790 g_variant_unref(body);
792 ret = _validate_and_set_noti_with_uid(uid, noti, ¬i_uid);
793 if (ret != NOTIFICATION_ERROR_NONE)
796 ret = _update_noti(reply_body, noti, noti_uid);
799 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
803 notification_free(noti);
807 /* load_noti_by_tag */
808 int notification_load_noti_by_tag(GVariant *parameters, GVariant **reply_body, uid_t uid)
816 noti = notification_create(NOTIFICATION_TYPE_NOTI);
818 g_variant_get(parameters, "(&s&si)", &app_id, &tag, ¶m_uid);
819 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
820 if (ret != NOTIFICATION_ERROR_NONE)
823 DBG("_load_noti_by_tag app_id : %s, tag : %s ", app_id, tag);
824 ret = notification_noti_get_by_tag(noti, app_id, tag, param_uid);
825 if (ret != NOTIFICATION_ERROR_NONE) {
826 ERR("No matched tag [%s]", tag);
831 *reply_body = notification_ipc_make_gvariant_from_noti(noti, true);
832 if (*reply_body == NULL) {
833 ERR("Failed to make reply_body");
834 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
837 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
842 notification_free(noti);
847 /* load_noti_by_priv_id */
848 int notification_load_noti_by_priv_id(GVariant *parameters, GVariant **reply_body, uid_t uid)
851 int priv_id = NOTIFICATION_PRIV_ID_NONE;
856 noti = notification_create(NOTIFICATION_TYPE_NOTI);
858 g_variant_get(parameters, "(&sii)", &app_id, &priv_id, ¶m_uid);
859 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
860 if (ret != NOTIFICATION_ERROR_NONE)
863 DBG("load_noti_by_priv_id app_id : %s, priv_id : %d ", app_id, priv_id);
864 ret = notification_noti_get_by_priv_id(noti, priv_id);
865 if (ret != NOTIFICATION_ERROR_NONE)
868 *reply_body = notification_ipc_make_gvariant_from_noti(noti, true);
869 if (*reply_body == NULL) {
870 ERR("Failed to make reply_body");
871 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
874 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
879 notification_free(noti);
884 static int __get_socket_from_invocation(GDBusMethodInvocation *invocation, int *fd)
887 GError *g_err = NULL;
888 GDBusMessage *msg = NULL;
889 GUnixFDList *fd_list = NULL;
891 msg = g_dbus_method_invocation_get_message(invocation);
892 fd_list = g_dbus_message_get_unix_fd_list(msg);
893 if (fd_list == NULL) {
894 ERR("fd list is null");
895 return NOTIFICATION_ERROR_IO_ERROR;
898 ret_fd = g_unix_fd_list_get(fd_list, 0, &g_err);
899 if (ret_fd == -1 || g_err) {
900 ERR("g_unix_fd_list_get [%s]", g_err->message);
902 return NOTIFICATION_ERROR_IO_ERROR;
907 INFO("sender fd : %d", ret_fd);
908 return NOTIFICATION_ERROR_NONE;
911 static int __send_list_to_socket(int fd, notification_list_h get_list, uid_t uid)
915 notification_list_h list_iter;
916 GVariant *body = NULL;
918 list_iter = notification_list_get_head(get_list);
920 noti = notification_list_get_data(list_iter);
921 notification_set_private_sharing(noti, uid);
922 body = notification_ipc_make_gvariant_from_noti(noti, true);
924 ERR("Failed to make gvariant to noti");
925 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
928 ret = notification_ipc_socket_write_string(fd,
929 (char *)g_variant_get_data(body),
930 g_variant_get_size(body));
931 if (ret != NOTIFICATION_ERROR_NONE) {
932 ERR("write string to socket fail");
933 g_variant_unref(body);
936 list_iter = notification_list_get_next(list_iter);
937 g_variant_unref(body);
938 } while (list_iter != NULL);
943 /* load_noti_grouping_list */
944 void notification_load_grouping_list(GDBusMethodInvocation *invocation, GVariant *parameters, uid_t uid)
947 notification_type_e type;
948 notification_list_h get_list = NULL;
949 GVariant *reply_body = NULL;
956 g_variant_get(parameters, "(iiii)", &type, &count, &count_per_page, ¶m_uid);
957 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
958 if (ret != NOTIFICATION_ERROR_NONE)
961 ret = __get_socket_from_invocation(invocation, &fd);
962 if (ret != NOTIFICATION_ERROR_NONE) {
963 ERR("get_fd_from_invocation [%d]", ret);
967 ret = notification_noti_get_grouping_list(type, count, count_per_page,
968 &get_list, &list_count, param_uid);
969 if (ret != NOTIFICATION_ERROR_NONE) {
970 ERR("notification_noti_get_grouping_list [%d]", ret);
974 reply_body = g_variant_new("(i)", list_count);
975 if (reply_body == NULL) {
976 ERR("Failed to make reply_body");
977 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
981 g_dbus_method_invocation_return_value(invocation, reply_body);
983 ret = __send_list_to_socket(fd, get_list, param_uid);
984 if (ret != NOTIFICATION_ERROR_NONE)
985 ERR("__send_list_to_socket [%d]", ret);
986 notification_free_list(get_list);
996 notification_free_list(get_list);
998 ERR("notification service fail, method name[load_noti_grouping_list] [%d]", ret);
999 g_dbus_method_invocation_return_error(invocation, NOTIFICATION_ERROR,
1000 ret, "notification_service_error");
1003 /* get_setting_array */
1004 int notification_get_setting_array(GVariant *parameters, GVariant **reply_body, uid_t uid)
1008 GVariantBuilder *builder;
1011 notification_setting_h setting_array = NULL;
1012 notification_setting_h temp;
1015 g_variant_get(parameters, "(i)", ¶m_uid);
1016 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
1017 if (ret != NOTIFICATION_ERROR_NONE)
1020 ret = noti_setting_get_setting_array(&setting_array, &count, param_uid);
1021 if (ret != NOTIFICATION_ERROR_NONE)
1024 builder = g_variant_builder_new(G_VARIANT_TYPE("a(v)"));
1026 if (setting_array) {
1027 for (i = 0; i < count; i++) {
1028 temp = setting_array + i;
1029 body = notification_ipc_make_gvariant_from_setting(temp);
1030 g_variant_builder_add(builder, "(v)", body);
1032 if (temp->package_name)
1033 free(temp->package_name);
1037 free(setting_array);
1039 *reply_body = g_variant_new("(ia(v))", count, builder);
1040 g_variant_builder_unref(builder);
1042 if (*reply_body == NULL) {
1043 ERR("Failed to make reply_body");
1044 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1047 INFO("count[%d]", count);
1051 static pkgmgrinfo_pkginfo_h __create_pkginfo_by_app_id(const char *app_id, uid_t uid)
1054 char *pkgname = NULL;
1055 pkgmgrinfo_appinfo_h app_handle = NULL;
1056 pkgmgrinfo_pkginfo_h pkg_handle = NULL;
1061 ret_pkgmgr = pkgmgrinfo_appinfo_get_usr_appinfo(app_id, uid, &app_handle);
1062 if (ret_pkgmgr != PMINFO_R_OK) {
1063 ERR("Failed to pkgmgrinfo_appinfo_get_appinfo [%s][%d]",
1064 app_id, ret_pkgmgr);
1068 ret_pkgmgr = pkgmgrinfo_appinfo_get_pkgname(app_handle, &pkgname);
1069 if (ret_pkgmgr != PMINFO_R_OK) {
1070 ERR("Failed to pkgmgrinfo_appinfo_get_pkgname [%s][%d]",
1071 app_id, ret_pkgmgr);
1075 ret_pkgmgr = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgname, uid, &pkg_handle);
1076 if (ret_pkgmgr != PMINFO_R_OK) {
1077 ERR("Failed to pkgmgrinfo_appinfo_get_pkginfo [%s][%d]",
1078 app_id, ret_pkgmgr);
1084 pkgmgrinfo_appinfo_destroy_appinfo(app_handle);
1089 #define NOTIFICATION_PRIVILEGE "http://tizen.org/privilege/notification"
1090 static int __check_privilege_cb(const char *privilege_name, void *is_existed)
1092 if (!g_strcmp0(privilege_name, NOTIFICATION_PRIVILEGE)) {
1093 *(int *)is_existed = 1;
1099 static int __has_notification_privilege(pkgmgrinfo_pkginfo_h handle)
1104 ret_pkgmgr = pkgmgrinfo_pkginfo_foreach_privilege(handle, __check_privilege_cb, &is_existed);
1105 if (ret_pkgmgr != PMINFO_R_OK) {
1106 ERR("Failed to pkgmgrinfo_foreach_privilege [%d]",
1108 return NOTIFICATION_ERROR_IO_ERROR;
1111 if (is_existed == 0)
1112 return NOTIFICATION_ERROR_NOT_EXIST_ID;
1114 return NOTIFICATION_ERROR_NONE;
1117 static int __init_setting_handle_by_app_id(const char *app_id,
1118 notification_setting_h *setting, uid_t uid)
1120 int ret = NOTIFICATION_ERROR_NONE;
1122 char *pkgname = NULL;
1123 notification_setting_h ret_setting = NULL;
1124 pkgmgrinfo_pkginfo_h handle = NULL;
1126 if (app_id == NULL || setting == NULL)
1127 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1129 handle = __create_pkginfo_by_app_id(app_id, uid);
1130 if (handle == NULL) {
1131 ERR("Failed to create pkginfo by app_id [%s]", app_id);
1132 ret = NOTIFICATION_ERROR_IO_ERROR;
1136 ret = __has_notification_privilege(handle);
1137 if (ret != NOTIFICATION_ERROR_NONE) {
1138 if (ret == NOTIFICATION_ERROR_NOT_EXIST_ID)
1139 DBG("No notification privilege [%s]", app_id);
1141 ERR("Failed to check privilege [%d]", ret);
1145 ret_pkgmgr = pkgmgrinfo_pkginfo_get_pkgname(handle, &pkgname);
1146 if (ret_pkgmgr != PMINFO_R_OK) {
1147 ERR("Failed to get pkgname from pkginfo [%d]", ret_pkgmgr);
1148 ret = NOTIFICATION_ERROR_IO_ERROR;
1152 ret_setting = (struct notification_setting *)malloc(sizeof(struct notification_setting));
1153 if (ret_setting == NULL) {
1154 ERR("Failed to alloc memory");
1155 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
1159 ret_setting->package_name = strdup(pkgname);
1160 ret_setting->app_id = strdup(app_id);
1161 ret_setting->allow_to_notify = 1;
1162 ret_setting->do_not_disturb_except = 0;
1163 ret_setting->visibility_class = 0;
1164 ret_setting->pop_up_notification = 1;
1165 ret_setting->lock_screen_content_level = 0;
1166 ret_setting->app_disabled = 0;
1168 *setting = ret_setting;
1172 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1177 /* get_setting_by_app_id */
1178 int notification_get_setting_by_app_id(GVariant *parameters, GVariant **reply_body, uid_t uid)
1182 char *app_id = NULL;
1183 notification_setting_h setting = NULL;
1186 g_variant_get(parameters, "(&si)", &app_id, ¶m_uid);
1187 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
1188 if (ret != NOTIFICATION_ERROR_NONE)
1191 ret = noti_setting_service_get_setting_by_app_id(app_id, &setting, param_uid);
1192 if (ret == NOTIFICATION_ERROR_NOT_EXIST_ID) {
1193 ret = __init_setting_handle_by_app_id(app_id, &setting, param_uid);
1194 if (ret != NOTIFICATION_ERROR_NONE)
1196 } else if (ret != NOTIFICATION_ERROR_NONE) {
1200 body = notification_ipc_make_gvariant_from_setting(setting);
1201 notification_setting_free_notification(setting);
1203 ERR("Failed to make gvariant");
1204 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1207 *reply_body = g_variant_new("(v)", body);
1208 if (*reply_body == NULL) {
1209 ERR("Failed to make reply_body");
1210 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1213 INFO("app_id[%s] uid[%d]", app_id, param_uid);
1217 /* load_system_setting */
1218 int notification_load_system_setting(GVariant *parameters, GVariant **reply_body, uid_t uid)
1222 notification_system_setting_h setting = NULL;
1225 g_variant_get(parameters, "(i)", ¶m_uid);
1226 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
1227 if (ret != NOTIFICATION_ERROR_NONE)
1230 ret = noti_system_setting_load_system_setting(&setting, param_uid);
1231 if (ret == NOTIFICATION_ERROR_NONE) {
1232 body = notification_ipc_make_gvariant_from_system_setting(setting);
1233 notification_system_setting_free_system_setting(setting);
1236 ERR("Failed to make gvariant");
1237 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1243 *reply_body = g_variant_new("(v)", body);
1244 if (*reply_body == NULL) {
1245 ERR("Failed to make reply_body");
1246 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1252 /* load_noti_detail_list */
1253 int notification_load_detail_list(GVariant *parameters, GVariant **reply_body, uid_t uid)
1256 notification_h noti;
1257 GVariant *body = NULL;
1258 notification_list_h get_list = NULL;
1259 notification_list_h list_iter;
1260 GVariantBuilder *builder;
1261 char *app_id = NULL;
1262 int group_id = NOTIFICATION_GROUP_ID_NONE;
1263 int priv_id = NOTIFICATION_PRIV_ID_NONE;
1267 g_variant_get(parameters, "(&siiii)", &app_id, &group_id, &priv_id, &count, ¶m_uid);
1268 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
1269 if (ret != NOTIFICATION_ERROR_NONE)
1272 ret = notification_noti_get_detail_list(app_id, group_id, priv_id,
1273 count, &get_list, param_uid);
1274 if (ret != NOTIFICATION_ERROR_NONE)
1277 builder = g_variant_builder_new(G_VARIANT_TYPE("a(v)"));
1280 list_iter = notification_list_get_head(get_list);
1282 noti = notification_list_get_data(list_iter);
1283 notification_set_private_sharing(noti, param_uid);
1284 body = notification_ipc_make_gvariant_from_noti(noti, true);
1286 g_variant_builder_add(builder, "(v)", body);
1287 list_iter = notification_list_get_next(list_iter);
1289 } while (list_iter != NULL);
1290 notification_free_list(get_list);
1293 *reply_body = g_variant_new("(a(v))", builder);
1294 g_variant_builder_unref(builder);
1296 if (*reply_body == NULL) {
1297 ERR("Failed to make reply_body");
1298 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1301 DBG("app_id[%s], group_id[%d], priv_id[%d], count[%d]",
1302 app_id, group_id, priv_id, count);
1307 int notification_refresh_noti(GVariant *parameters, GVariant **reply_body, uid_t uid)
1312 g_variant_get(parameters, "(i)", ¶m_uid);
1313 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
1314 if (ret != NOTIFICATION_ERROR_NONE)
1317 ret = send_notify(parameters, "refresh_noti_notify", &_monitoring_hash, PROVIDER_NOTI_INTERFACE_NAME, param_uid);
1318 if (ret != NOTIFICATION_ERROR_NONE) {
1319 ERR("Failed to send notify [%d]", ret);
1323 *reply_body = g_variant_new("()");
1324 if (*reply_body == NULL) {
1325 ERR("Failed to make reply_body");
1326 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1332 static int __delete_sender_info(int priv_id)
1334 int ret = NOTIFICATION_ERROR_NONE;
1335 event_sender_info_s *info;
1336 GList *delete_list = NULL;
1337 GVariant *body = NULL;
1339 if (__event_list != NULL) {
1340 __event_list = g_list_first(__event_list);
1341 delete_list = g_list_find_custom(__event_list, GINT_TO_POINTER(priv_id),
1342 (GCompareFunc)__priv_id_compare);
1343 if (delete_list != NULL) {
1344 info = (event_sender_info_s *)g_list_nth_data(delete_list, 0);
1345 body = g_variant_new("(i)", priv_id);
1346 ret = send_event_notify_by_busname(body, "delete_noti", info->busname, PROVIDER_NOTI_EVENT_INTERFACE_NAME);
1347 g_variant_unref(body);
1348 if (ret != NOTIFICATION_ERROR_NONE) {
1349 ERR("Failed to send event notify [%d]", ret);
1352 __event_list = g_list_remove(g_list_first(__event_list), info);
1353 g_bus_unwatch_name(info->watcher_id);
1354 __free_event_info(info);
1355 if (g_list_length(__event_list) == 0)
1356 __event_list = NULL;
1363 static int _delete_noti(const char *app_id, int priv_id, uid_t uid)
1366 int num_changes = 0;
1367 GVariant *body = NULL;
1370 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1372 ret = notification_noti_delete_by_priv_id_get_changes(app_id, priv_id,
1374 if (ret != NOTIFICATION_ERROR_NONE) {
1375 ERR("Failed to delete noti, err[%d] num_changes[%d]",
1380 if (num_changes > 0) {
1381 body = g_variant_new("(iii)", 1, priv_id, uid);
1383 ERR("Failed to make gvariant to noti");
1384 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1386 ret = send_notify(body, "delete_single_notify",
1387 &_monitoring_hash, PROVIDER_NOTI_INTERFACE_NAME, uid);
1388 g_variant_unref(body);
1389 if (ret != NOTIFICATION_ERROR_NONE) {
1390 ERR("Failed to send notify [%d]", ret);
1394 notification_remove_private_sharing(app_id, priv_id, uid);
1396 ret = __delete_sender_info(priv_id);
1397 if (ret != NOTIFICATION_ERROR_NONE)
1400 if (default_viewer != NULL) {
1401 ret = notification_launch_default_viewer(default_viewer,
1402 NOTIFICATION_PRIV_ID_NONE,
1403 NOTIFICATION_OP_DELETE,
1405 if (ret != NOTIFICATION_ERROR_NONE) {
1406 ERR("Failed to launch default viewer [%d]", ret);
1407 ret = NOTIFICATION_ERROR_NONE;
1412 DBG("app_id[%s] priv_id[%d] num_changes[%d]", app_id, priv_id, num_changes);
1417 /* del_noti_single */
1418 int notification_del_noti_single(GVariant *parameters, GVariant **reply_body, uid_t uid)
1420 int ret = NOTIFICATION_ERROR_NONE;
1421 int priv_id = NOTIFICATION_PRIV_ID_NONE;
1422 char *app_id = NULL;
1425 g_variant_get(parameters, "(&sii)", &app_id, &priv_id, ¶m_uid);
1426 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
1427 if (ret != NOTIFICATION_ERROR_NONE)
1430 ret = _delete_noti(app_id, priv_id, param_uid);
1431 if (ret != NOTIFICATION_ERROR_NONE) {
1432 ERR("Failed to delete noti, err[%d]", ret);
1436 *reply_body = g_variant_new("(i)", priv_id);
1437 if (*reply_body == NULL) {
1438 ERR("Failed to make reply_body");
1439 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1445 /* del_noti_multiple */
1446 int notification_del_noti_multiple(GVariant *parameters, GVariant **reply_body, uid_t uid)
1449 char *app_id = NULL;
1450 notification_type_e type = NOTIFICATION_TYPE_NONE;
1451 int num_deleted = 0;
1452 int *list_deleted = NULL;
1453 GVariant *deleted_noti_list;
1454 GVariantBuilder *builder;
1458 g_variant_get(parameters, "(&sii)", &app_id, &type, ¶m_uid);
1459 DBG("app_id [%s] type [%d]", app_id, type);
1460 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
1461 if (ret != NOTIFICATION_ERROR_NONE)
1464 ret = notification_noti_delete_all(type, app_id, &num_deleted, &list_deleted, param_uid);
1465 if (ret != NOTIFICATION_ERROR_NONE) {
1466 ERR("Failed to delete notifications [%d]", ret);
1467 if (list_deleted != NULL)
1472 if (num_deleted > 0) {
1473 builder = g_variant_builder_new(G_VARIANT_TYPE("a(i)"));
1475 for (i = 0; i < num_deleted; i++)
1476 g_variant_builder_add(builder, "(i)", *(list_deleted + i));
1478 deleted_noti_list = g_variant_new("(a(i)i)", builder, param_uid);
1479 ret = send_notify(deleted_noti_list, "delete_multiple_notify", &_monitoring_hash, PROVIDER_NOTI_INTERFACE_NAME, param_uid);
1480 g_variant_builder_unref(builder);
1481 g_variant_unref(deleted_noti_list);
1482 if (ret != NOTIFICATION_ERROR_NONE) {
1483 ERR("Failed to send notify [%d]", ret);
1487 for (i = 0; i < num_deleted; i++) {
1488 notification_remove_private_sharing(app_id, *(list_deleted + i), param_uid);
1489 ret = __delete_sender_info(*(list_deleted + i));
1490 if (ret != NOTIFICATION_ERROR_NONE)
1496 if (default_viewer != NULL) {
1497 ret = notification_launch_default_viewer(default_viewer,
1498 NOTIFICATION_PRIV_ID_NONE,
1499 NOTIFICATION_OP_DELETE_ALL,
1501 if (ret != NOTIFICATION_ERROR_NONE) {
1502 ERR("Failed to launch default viewer [%d]", ret);
1503 ret = NOTIFICATION_ERROR_NONE;
1508 *reply_body = g_variant_new("(i)", num_deleted);
1509 if (*reply_body == NULL) {
1510 ERR("Failed to make reply_body");
1511 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1514 INFO("type[%d] app_id[%s] num_deleted[%d]", type, app_id, num_deleted);
1518 /* get_noti_count */
1519 int notification_get_noti_count(GVariant *parameters, GVariant **reply_body, uid_t uid)
1522 notification_type_e type = NOTIFICATION_TYPE_NONE;
1523 char *app_id = NULL;
1524 int group_id = NOTIFICATION_GROUP_ID_NONE;
1525 int priv_id = NOTIFICATION_PRIV_ID_NONE;
1529 g_variant_get(parameters, "(i&siii)", &type, &app_id, &group_id, &priv_id, ¶m_uid);
1530 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
1531 if (ret != NOTIFICATION_ERROR_NONE) {
1532 ERR("Failed to validate uid [%d]", ret);
1533 return NOTIFICATION_ERROR_IO_ERROR;
1536 ret = notification_noti_get_count(type, app_id, group_id, priv_id,
1537 ¬i_count, param_uid);
1538 if (ret != NOTIFICATION_ERROR_NONE) {
1539 ERR("Failed to get count [%d]", ret);
1543 *reply_body = g_variant_new("(i)", noti_count);
1544 if (*reply_body == NULL) {
1545 ERR("Failed to make reply_body");
1546 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1549 INFO("type[%d] app_id[%s] group_id[%d] priv_id[%d] noti_count[%d]",
1550 type, app_id, group_id, priv_id, noti_count);
1554 /* get_noti_count */
1555 int notification_get_noti_all_count(GVariant *parameters, GVariant **reply_body, uid_t uid)
1562 g_variant_get(parameters, "(ii)", &type, ¶m_uid);
1563 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
1564 if (ret != NOTIFICATION_ERROR_NONE) {
1565 ERR("Failed to validate uid [%d]", ret);
1566 return NOTIFICATION_ERROR_IO_ERROR;
1569 ret = notification_noti_get_all_count(type, ¬i_count, param_uid);
1570 if (ret != NOTIFICATION_ERROR_NONE) {
1571 ERR("Failed to get count [%d]", ret);
1575 *reply_body = g_variant_new("(i)", noti_count);
1576 if (*reply_body == NULL) {
1577 ERR("Failed to make reply_body");
1578 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1581 INFO("The numbers of all notification count is [%d]", noti_count);
1585 /* update_noti_setting */
1586 int notification_update_noti_setting(GVariant *parameters, GVariant **reply_body, uid_t uid)
1589 char *pkgname = NULL;
1590 char *app_id = NULL;
1591 int allow_to_notify = 0;
1592 int do_not_disturb_except = 0;
1593 int visivility_class = 0;
1594 int pop_up_notification = 0;
1595 int lock_screen_content_level = 0;
1598 g_variant_get(parameters, "(&s&siiiiii)",
1602 &do_not_disturb_except,
1604 &pop_up_notification,
1605 &lock_screen_content_level,
1608 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
1609 if (ret != NOTIFICATION_ERROR_NONE)
1612 ret = notification_setting_db_update(pkgname, app_id, allow_to_notify, do_not_disturb_except, visivility_class,
1613 pop_up_notification, lock_screen_content_level, param_uid);
1614 if (ret != NOTIFICATION_ERROR_NONE) {
1615 ERR("Failed to setting db update : %d", ret);
1619 *reply_body = g_variant_new("()");
1620 if (*reply_body == NULL) {
1621 ERR("Failed to make reply_body");
1622 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1625 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]",
1626 pkgname, app_id, allow_to_notify, do_not_disturb_except, visivility_class, pop_up_notification, lock_screen_content_level);
1630 static int _dnd_schedule_alarm_cb(alarm_id_t alarm_id, void *data)
1634 bool dnd_id_found = false;
1635 GVariant *body = NULL;
1636 GList *dnd_found_list = NULL;
1637 dnd_alarm_id_s *dnd_id_data = NULL;
1640 dnd_found_list = g_list_first(_dnd_alarm_id_list);
1642 for (; dnd_found_list != NULL; dnd_found_list = dnd_found_list->next) {
1643 dnd_id_data = dnd_found_list->data;
1644 uid = dnd_id_data->uid;
1646 ret = noti_system_setting_get_do_not_disturb(&do_not_disturb, uid);
1647 if (ret != NOTIFICATION_ERROR_NONE) {
1648 ERR("get do not disturb failed");
1652 if (alarm_id == dnd_id_data->dnd_start_id && !do_not_disturb) {
1654 dnd_id_found = true;
1656 } else if (alarm_id == dnd_id_data->dnd_end_id && do_not_disturb) {
1658 dnd_id_found = true;
1663 if (dnd_id_found == false) {
1664 ERR("notification wrong alarm [%d]", alarm_id);
1668 notification_setting_db_update_do_not_disturb(do_not_disturb, uid);
1670 body = g_variant_new("(ii)", do_not_disturb, uid);
1672 ret = send_notify(body, "change_dnd_notify", &_monitoring_hash, PROVIDER_NOTI_INTERFACE_NAME, uid);
1673 g_variant_unref(body);
1674 if (ret != NOTIFICATION_ERROR_NONE) {
1675 ERR("Failed to send notify [%d]", ret);
1679 INFO("dnd[%d], uid[%d]", do_not_disturb, uid);
1683 static int _get_current_time(struct tm *date)
1688 ERR("Invalid tm data");
1689 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1693 localtime_r(&now, date);
1695 return NOTIFICATION_ERROR_NONE;
1698 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)
1700 int err = NOTIFICATION_ERROR_NONE;
1701 struct tm struct_time;
1702 alarm_entry_t *alarm_info = NULL;
1703 alarm_date_t alarm_time;
1704 alarm_id_t alarm_id = -1;
1706 err = alarmmgr_init("notification");
1708 ERR("alarmmgr_init failed [%d]", err);
1712 err = alarmmgr_set_cb(handler, NULL);
1714 ERR("alarmmgr_set_cb failed [%d]", err);
1718 err = _get_current_time(&struct_time);
1719 if (err != NOTIFICATION_ERROR_NONE) {
1720 ERR("get_current_time failed [%d]", err);
1724 alarm_info = alarmmgr_create_alarm();
1725 if (alarm_info == NULL) {
1726 ERR("alarmmgr_create_alarm failed");
1730 alarm_time.year = struct_time.tm_year + 1900;
1731 alarm_time.month = struct_time.tm_mon + 1;
1732 alarm_time.day = struct_time.tm_mday;
1733 alarm_time.hour = hour;
1734 alarm_time.min = min;
1737 err = alarmmgr_set_time(alarm_info, alarm_time);
1738 if (err != ALARMMGR_RESULT_SUCCESS) {
1739 ERR("alarmmgr_set_time failed [%d]", err);
1744 err = alarmmgr_set_repeat_mode(alarm_info, ALARM_REPEAT_MODE_WEEKLY, week_flag);
1745 if (err != ALARMMGR_RESULT_SUCCESS) {
1746 ERR("alarmmgr_set_repeat_mode failed [%d]", err);
1751 err = alarmmgr_set_type(alarm_info, ALARM_TYPE_VOLATILE);
1752 if (err != ALARMMGR_RESULT_SUCCESS) {
1753 ERR("alarmmgr_set_type failed [%d]", err);
1757 err = alarmmgr_add_alarm_with_localtime(alarm_info, NULL, &alarm_id);
1758 if (err != ALARMMGR_RESULT_SUCCESS) {
1759 ERR("alarmmgr_add_alarm_with_localtime failed [%d]", err);
1763 *dnd_schedule_alarm_id = alarm_id;
1767 alarmmgr_free_alarm(alarm_info);
1769 DBG("alarm_id [%d]", *dnd_schedule_alarm_id);
1773 static gint _dnd_data_compare(gconstpointer a, gconstpointer b)
1775 const dnd_alarm_id_s *data = NULL;
1780 if (data->uid == GPOINTER_TO_UINT(b))
1786 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)
1788 dnd_alarm_id_s *dnd_id_data = NULL;
1790 dnd_id_data = (dnd_alarm_id_s *)malloc(sizeof(dnd_alarm_id_s));
1791 if (dnd_id_data == NULL) {
1792 ERR("Failed to alloc memory");
1796 dnd_id_data->uid = uid;
1797 dnd_id_data->dnd_start_id = start_alarm_id;
1798 dnd_id_data->dnd_end_id = end_alarm_id;
1803 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)
1805 int ret = NOTIFICATION_ERROR_NONE;
1806 GList *found_list = NULL;
1807 dnd_alarm_id_s *dnd_id_data = NULL;
1808 alarm_id_t dnd_schedule_start_alarm_id;
1809 alarm_id_t dnd_schedule_end_alarm_id;
1811 ret = _noti_system_setting_set_alarm(dnd_schedule_day,
1812 dnd_start_hour, dnd_start_min,
1813 _dnd_schedule_alarm_cb,
1814 &dnd_schedule_start_alarm_id);
1815 if (ret != NOTIFICATION_ERROR_NONE) {
1816 ERR("Failed to set start alarm [%d]", ret);
1820 if (dnd_end_hour < dnd_start_hour ||
1821 (dnd_end_hour == dnd_start_hour && dnd_end_min <= dnd_start_min)) {
1822 dnd_schedule_day = (dnd_schedule_day << 1);
1823 if (dnd_schedule_day & DND_SCHEDULE_WEEK_FLAG_MAX)
1824 dnd_schedule_day = (dnd_schedule_day & DND_SCHEDULE_WEEK_FLAG_ALL)
1825 | DND_SCHEDULE_WEEK_FLAG_SUNDAY;
1828 ret = _noti_system_setting_set_alarm(dnd_schedule_day,
1829 dnd_end_hour, dnd_end_min,
1830 _dnd_schedule_alarm_cb,
1831 &dnd_schedule_end_alarm_id);
1832 if (ret != NOTIFICATION_ERROR_NONE) {
1833 ERR("Failed to set end alarm [%d]", ret);
1837 if (_dnd_alarm_id_list == NULL) {
1838 dnd_id_data = __malloc_dnd_alarm_id_s(uid, dnd_schedule_start_alarm_id, dnd_schedule_end_alarm_id);
1840 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1841 _dnd_alarm_id_list = g_list_append(_dnd_alarm_id_list, dnd_id_data);
1843 found_list = g_list_find_custom(g_list_first(_dnd_alarm_id_list), GUINT_TO_POINTER(uid),
1844 (GCompareFunc)_dnd_data_compare);
1846 dnd_id_data = g_list_nth_data(found_list, 0);
1847 if (dnd_id_data->dnd_start_id) {
1848 alarmmgr_remove_alarm(dnd_id_data->dnd_start_id);
1849 dnd_id_data->dnd_start_id = dnd_schedule_start_alarm_id;
1851 if (dnd_id_data->dnd_end_id) {
1852 alarmmgr_remove_alarm(dnd_id_data->dnd_end_id);
1853 dnd_id_data->dnd_end_id = dnd_schedule_end_alarm_id;
1856 dnd_id_data = __malloc_dnd_alarm_id_s(uid, dnd_schedule_start_alarm_id, dnd_schedule_end_alarm_id);
1858 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1859 _dnd_alarm_id_list = g_list_append(_dnd_alarm_id_list, dnd_id_data);
1866 static void _delete_alarm(uid_t uid)
1868 GList *found_list = NULL;
1869 dnd_alarm_id_s *dnd_id_data = NULL;
1871 if (_dnd_alarm_id_list == NULL)
1874 _dnd_alarm_id_list = g_list_first(_dnd_alarm_id_list);
1875 found_list = g_list_find_custom(_dnd_alarm_id_list, GUINT_TO_POINTER(uid),
1876 (GCompareFunc)_dnd_data_compare);
1878 if (found_list == NULL)
1881 dnd_id_data = g_list_nth_data(found_list, 0);
1883 if (dnd_id_data->dnd_start_id)
1884 alarmmgr_remove_alarm(dnd_id_data->dnd_start_id);
1885 if (dnd_id_data->dnd_end_id)
1886 alarmmgr_remove_alarm(dnd_id_data->dnd_end_id);
1888 _dnd_alarm_id_list = g_list_remove(g_list_first(_dnd_alarm_id_list), dnd_id_data);
1892 /* update_noti_sys_setting */
1893 int notification_update_noti_sys_setting(GVariant *parameters, GVariant **reply_body, uid_t uid)
1896 int pre_do_not_disturb = 0;
1897 int do_not_disturb = 0;
1898 int visivility_class = 0;
1899 int dnd_schedule_enabled = 0;
1900 int dnd_schedule_day = 0;
1901 int dnd_start_hour = 0;
1902 int dnd_start_min = 0;
1903 int dnd_end_hour = 0;
1904 int dnd_end_min = 0;
1905 int lock_screen_level = 0;
1907 GVariant *body = NULL;
1909 g_variant_get(parameters, "(iiiiiiiiii)",
1912 &dnd_schedule_enabled,
1921 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
1922 if (ret != NOTIFICATION_ERROR_NONE)
1925 ret = noti_system_setting_get_do_not_disturb(&pre_do_not_disturb, param_uid);
1926 if (ret != NOTIFICATION_ERROR_NONE) {
1927 ERR("Failed to get do not disturb");
1931 ret = notification_setting_db_update_system_setting(do_not_disturb,
1933 dnd_schedule_enabled,
1941 if (ret != NOTIFICATION_ERROR_NONE) {
1942 ERR("Failed to setting db update system setting : %d", ret);
1946 if (pre_do_not_disturb != do_not_disturb) {
1947 body = g_variant_new("(ii)", do_not_disturb, param_uid);
1948 ret = send_notify(body, "change_dnd_notify", &_monitoring_hash, PROVIDER_NOTI_INTERFACE_NAME, param_uid);
1949 g_variant_unref(body);
1952 *reply_body = g_variant_new("()");
1953 if (*reply_body == NULL) {
1954 ERR("Failed to make reply_body");
1955 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1958 if (dnd_schedule_enabled) {
1959 ret = _add_alarm(dnd_schedule_day, dnd_start_hour, dnd_start_min,
1960 dnd_end_hour, dnd_end_min, param_uid);
1961 if (ret != NOTIFICATION_ERROR_NONE)
1962 ERR("Failed to add alarm for dnd_schedule");
1964 _delete_alarm(param_uid);
1967 INFO("do_not_disturb [%d] visivility_class [%d] set_schedule [%d] lock_screen_level [%d]",
1968 do_not_disturb, visivility_class, dnd_schedule_enabled, lock_screen_level);
1972 int notification_add_noti_template(GVariant *parameters, GVariant **reply_body, uid_t uid)
1974 notification_h noti;
1976 GVariant *body = NULL;
1977 GVariant *coupled_body = NULL;
1978 char *template_name = NULL;
1981 noti = notification_create(NOTIFICATION_TYPE_NOTI);
1983 g_variant_get(parameters, "(v&s)", &coupled_body, &template_name);
1984 g_variant_get(coupled_body, "(v)", &body);
1986 ret = notification_ipc_make_noti_from_gvariant(noti, body);
1987 g_variant_unref(coupled_body);
1988 g_variant_unref(body);
1989 if (ret != NOTIFICATION_ERROR_NONE) {
1990 ERR("Failed to make a notification [%d]", ret);
1994 ret = notification_noti_check_count_for_template(noti, &count);
1995 if (count >= NOTI_TEMPLATE_LIMIT) {
1996 ERR("Exceed limit value that is saved tamplate [%d]", ret);
1997 ret = NOTIFICATION_ERROR_MAX_EXCEEDED;
2001 ret = notification_noti_add_template(noti, template_name);
2002 if (ret != NOTIFICATION_ERROR_NONE)
2003 ERR("Failed to add a notification [%d]", ret);
2005 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
2010 notification_free(noti);
2015 int notification_get_noti_template(GVariant *parameters, GVariant **reply_body, pid_t pid, uid_t uid)
2018 char app_id[BUF_LEN] = {0, };
2019 char *template_name = NULL;
2020 notification_h noti;
2022 noti = notification_create(NOTIFICATION_TYPE_NOTI);
2024 g_variant_get(parameters, "(&s)", &template_name);
2025 INFO("template name[%s]", template_name);
2027 ret = aul_app_get_appid_bypid_for_uid(pid, app_id, sizeof(app_id), uid);
2028 if (ret != AUL_R_OK) {
2029 ERR("Failed to get app_id [%d]", ret);
2030 ret = NOTIFICATION_ERROR_INVALID_PARAMETER;
2034 ret = notification_noti_get_package_template(noti, app_id, template_name);
2035 if (ret != NOTIFICATION_ERROR_NONE) {
2036 ERR("Failed to get template [%d]", ret);
2040 *reply_body = notification_ipc_make_gvariant_from_noti(noti, false);
2041 if (*reply_body == NULL) {
2042 ERR("Failed to make reply_body");
2043 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
2046 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
2051 notification_free(noti);
2056 int notification_get_noti_package_template(GVariant *parameters, GVariant **reply_body, uid_t uid)
2059 char *app_id = NULL;
2060 char *template_name = NULL;
2061 notification_h noti;
2063 noti = notification_create(NOTIFICATION_TYPE_NOTI);
2065 g_variant_get(parameters, "(&s&s)", &app_id, &template_name);
2066 INFO("app_id[%s] template name[%s]", app_id, template_name);
2067 ret = notification_noti_get_package_template(noti, app_id, template_name);
2068 if (ret != NOTIFICATION_ERROR_NONE) {
2069 ERR("Failed to get template [%d]", ret);
2073 *reply_body = notification_ipc_make_gvariant_from_noti(noti, false);
2074 if (*reply_body == NULL) {
2075 ERR("Failed to make reply_body");
2076 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
2079 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
2084 notification_free(noti);
2089 int notification_get_block_state(GVariant *parameters, GVariant **reply_body, uid_t uid)
2094 int allow_to_notify;
2097 GVariant *body = NULL;
2099 g_variant_get(parameters, "(&si)", &app_id, ¶m_uid);
2101 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
2102 if (ret != NOTIFICATION_ERROR_NONE) {
2103 ERR("_validate_uid fail [%d]", ret);
2104 return NOTIFICATION_ERROR_IO_ERROR;
2107 ret = notification_get_dnd_and_allow_to_notify(app_id, &dnd, &dnd_except, &allow_to_notify, param_uid);
2108 INFO("app_id[%s] dnd[%d] dnd_except[%d] allow_to_notify[%d]",
2109 app_id, dnd, dnd_except, allow_to_notify);
2110 if (ret != NOTIFICATION_ERROR_NONE) {
2111 ERR("Failed to get_dnd_and_allow_to_notify [%d]", ret);
2115 body = g_variant_new("(iii)", dnd, dnd_except, allow_to_notify);
2116 *reply_body = g_variant_new("(v)", body);
2118 if (*reply_body == NULL) {
2119 ERR("Failed to make reply_body");
2120 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
2125 int notification_load_dnd_allow_exception(GVariant *parameters, GVariant **reply_body, uid_t uid)
2131 GVariant *body = NULL;
2132 GVariantBuilder *builder;
2133 dnd_allow_exception_h dnd_allow_exception = NULL;
2134 dnd_allow_exception_h temp;
2136 g_variant_get(parameters, "(i)", ¶m_uid);
2138 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
2139 if (ret != NOTIFICATION_ERROR_NONE)
2142 ret = notification_system_setting_load_dnd_allow_exception(&dnd_allow_exception, &count, param_uid);
2143 if (ret != NOTIFICATION_ERROR_NONE) {
2144 ERR("Failed to load dnd_allow_exception [%d]", ret);
2148 builder = g_variant_builder_new(G_VARIANT_TYPE("a(v)"));
2150 if (dnd_allow_exception) {
2151 for (i = 0; i < count; i++) {
2152 temp = dnd_allow_exception + i;
2153 body = notification_ipc_make_gvariant_from_dnd_allow_exception(temp);
2154 g_variant_builder_add(builder, "(v)", body);
2156 free(dnd_allow_exception);
2159 *reply_body = g_variant_new("(ia(v))", count, builder);
2160 g_variant_builder_unref(builder);
2162 if (*reply_body == NULL) {
2163 ERR("Failed to make reply_body");
2164 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
2170 int notification_update_dnd_allow_exception(GVariant *parameters, GVariant **reply_body, uid_t uid)
2177 g_variant_get(parameters, "(iii)", &type, &value, ¶m_uid);
2179 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
2180 if (ret != NOTIFICATION_ERROR_NONE)
2183 ret = notification_system_setting_update_dnd_allow_exception(type,
2186 if (ret != NOTIFICATION_ERROR_NONE) {
2187 ERR("Failed to update dnd_allow_exception [%d]", ret);
2191 *reply_body = g_variant_new("()");
2192 if (*reply_body == NULL) {
2193 ERR("Failed to make reply_body");
2194 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
2200 static event_sender_info_s *__find_sender_info_by_priv_id(int priv_id)
2202 event_sender_info_s *event_info;
2205 if (__event_list == NULL)
2208 __event_list = g_list_first(__event_list);
2209 find_list = g_list_find_custom(__event_list, GINT_TO_POINTER(priv_id),
2210 (GCompareFunc)__priv_id_compare);
2213 event_info = g_list_nth_data(find_list, 0);
2220 int notification_send_noti_event(GVariant *parameters, GVariant **reply_body)
2225 event_sender_info_s *info;
2226 GVariant *coupled_body = NULL;
2227 GVariant *body = NULL;
2228 notification_h noti;
2230 noti = notification_create(NOTIFICATION_TYPE_NOTI);
2232 g_variant_get(parameters, "(vi)", &coupled_body, &event_type);
2233 g_variant_get(coupled_body, "(v)", &body);
2235 ret = notification_ipc_make_noti_from_gvariant(noti, body);
2236 g_variant_unref(coupled_body);
2237 g_variant_unref(body);
2239 if (ret != NOTIFICATION_ERROR_NONE) {
2240 ERR("Failed to make a notification from gvariant");
2244 ret = notification_get_id(noti, NULL, &priv_id);
2245 if (ret != NOTIFICATION_ERROR_NONE)
2248 info = __find_sender_info_by_priv_id(priv_id);
2249 if (info == NULL || info->busname == NULL) {
2250 ret = NOTIFICATION_ERROR_INVALID_PARAMETER;
2254 if (!info->watcher_id) {
2255 if (!is_existed_busname(info->busname)) {
2256 __event_list = g_list_remove(g_list_first(__event_list), info);
2257 __free_event_info(info);
2258 ret = NOTIFICATION_ERROR_IO_ERROR;
2261 info->watcher_id = __insert_sender_watcher_id(info);
2265 ret = send_event_notify_by_busname(parameters, "send_event", info->busname, PROVIDER_NOTI_EVENT_INTERFACE_NAME);
2266 if (ret != NOTIFICATION_ERROR_NONE) {
2267 ERR("Failed to send event [%d]", ret);
2271 *reply_body = g_variant_new("()");
2272 if (*reply_body == NULL) {
2273 ERR("Failed to make reply body");
2274 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
2277 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
2282 notification_free(noti);
2287 int notification_send_noti_event_by_priv_id(GVariant *parameters, GVariant **reply_body)
2292 bool event_flag = false;
2293 notification_h noti;
2294 GVariant *body = NULL;
2295 event_sender_info_s *info;
2297 noti = notification_create(NOTIFICATION_TYPE_NOTI);
2299 g_variant_get(parameters, "(ii)", &priv_id, &event_type);
2301 ret = notification_noti_get_by_priv_id(noti, priv_id);
2302 if (ret != NOTIFICATION_ERROR_NONE) {
2303 ERR("Failed to get notification by priv id [%d]", ret);
2307 ret = notification_get_event_flag(noti, &event_flag);
2308 if (ret != NOTIFICATION_ERROR_NONE || event_flag == false) {
2309 ret = NOTIFICATION_ERROR_INVALID_PARAMETER;
2313 info = __find_sender_info_by_priv_id(priv_id);
2314 if (info == NULL || info->busname == NULL) {
2315 ret = NOTIFICATION_ERROR_INVALID_PARAMETER;
2316 ERR("No sender info by priv_id[%d]", priv_id);
2320 if (!info->watcher_id) {
2321 if (!is_existed_busname(info->busname)) {
2322 __event_list = g_list_remove(g_list_first(__event_list), info);
2323 __free_event_info(info);
2324 ret = NOTIFICATION_ERROR_IO_ERROR;
2327 info->watcher_id = __insert_sender_watcher_id(info);
2331 body = notification_ipc_make_gvariant_from_noti(noti, false);
2333 ERR("Can't make gvariant to noti");
2334 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
2338 ret = send_event_notify_by_busname(g_variant_new("(vi)", body, event_type), "send_event", info->busname, PROVIDER_NOTI_EVENT_INTERFACE_NAME);
2339 *reply_body = g_variant_new("()");
2340 if (*reply_body == NULL) {
2341 ERR("Failed to make reply body");
2342 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
2345 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
2350 notification_free(noti);
2355 int notification_check_event_receiver(GVariant *parameters, GVariant **reply_body)
2358 bool available = false;
2359 GList *find_list = NULL;
2360 event_sender_info_s *info = NULL;
2362 g_variant_get(parameters, "(i)", &priv_id);
2363 INFO("priv_id[%d]", priv_id);
2365 __event_list = g_list_first(__event_list);
2366 find_list = g_list_find_custom(__event_list, GINT_TO_POINTER(priv_id),
2367 (GCompareFunc)__priv_id_compare);
2369 info = g_list_nth_data(find_list, 0);
2370 if (!info->watcher_id) {
2371 if (!is_existed_busname(info->busname)) {
2372 __event_list = g_list_remove(g_list_first(__event_list), info);
2373 __free_event_info(info);
2376 info->watcher_id = __insert_sender_watcher_id(info);
2383 *reply_body = g_variant_new("(i)", (int)available);
2384 if (*reply_body == NULL) {
2385 ERR("Failed to make gvariant to noti");
2386 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
2389 INFO("Receiver available[%d]", available);
2390 return NOTIFICATION_ERROR_NONE;
2393 int notification_reset_event_receiver(GVariant *parameters, GVariant **reply_body, const char *sender)
2397 g_variant_get(parameters, "(i)", &priv_id);
2398 INFO("priv_id[%d]", priv_id);
2400 __add_sender_info(priv_id, sender);
2402 *reply_body = g_variant_new("()");
2403 if (*reply_body == NULL) {
2404 ERR("Failed to make gvariant to noti");
2405 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
2408 return NOTIFICATION_ERROR_NONE;
2411 HAPI int notification_delete_noti_by_app_id(const char *app_id, uid_t uid)
2413 GVariant *deleted_noti_list;
2414 GVariantBuilder *builder;
2415 int num_deleted = 0;
2416 int *list_deleted = NULL;
2420 ret = notification_noti_delete_all(NOTIFICATION_TYPE_NONE, app_id, &num_deleted, &list_deleted, uid);
2421 if (ret != NOTIFICATION_ERROR_NONE) {
2422 ERR("Failed to delete notifications [%d]", ret);
2426 if (num_deleted > 0) {
2427 builder = g_variant_builder_new(G_VARIANT_TYPE("a(i)"));
2429 for (i = 0; i < num_deleted; i++)
2430 g_variant_builder_add(builder, "(i)", *(list_deleted + i));
2432 deleted_noti_list = g_variant_new("(a(i)i)", builder, uid);
2433 ret = send_notify(deleted_noti_list, "delete_multiple_notify", &_monitoring_hash, PROVIDER_NOTI_INTERFACE_NAME, uid);
2434 g_variant_builder_unref(builder);
2435 g_variant_unref(deleted_noti_list);
2436 if (ret != NOTIFICATION_ERROR_NONE) {
2437 ERR("Failed to send notify [%d]", ret);
2441 for (i = 0; i < num_deleted; i++) {
2442 ret = __delete_sender_info(*(list_deleted + i));
2443 if (ret != NOTIFICATION_ERROR_NONE)
2448 if (list_deleted != NULL)
2453 static int _check_dnd_schedule(uid_t uid)
2456 notification_system_setting_h setting = NULL;
2457 bool dnd_schedule_enabled = false;
2458 int dnd_schedule_day = 0;
2459 int dnd_start_hour = 0;
2460 int dnd_start_min = 0;
2461 int dnd_end_hour = 0;
2462 int dnd_end_min = 0;
2464 ret = noti_system_setting_load_system_setting(&setting, uid);
2465 if (ret != NOTIFICATION_ERROR_NONE) {
2466 ERR("noti_system_setting_load_system_setting fail [%d]", ret);
2470 ret = notification_system_setting_dnd_schedule_get_enabled(setting,
2471 &dnd_schedule_enabled);
2472 if (ret != NOTIFICATION_ERROR_NONE) {
2473 ERR("system_setting_dnd_schedule_get_enabled fail [%d]", ret);
2477 if (dnd_schedule_enabled) {
2478 ret = notification_system_setting_dnd_schedule_get_day(setting,
2480 if (ret != NOTIFICATION_ERROR_NONE) {
2481 ERR("system_setting_dnd_schedule_get_day fail [%d]", ret);
2485 ret = notification_system_setting_dnd_schedule_get_start_time(setting,
2486 &dnd_start_hour, &dnd_start_min);
2487 if (ret != NOTIFICATION_ERROR_NONE) {
2488 ERR("system_setting_dnd_schedule_get_start_time fail [%d]", ret);
2492 ret = notification_system_setting_dnd_schedule_get_end_time(setting,
2493 &dnd_end_hour, &dnd_end_min);
2494 if (ret != NOTIFICATION_ERROR_NONE) {
2495 ERR("system_setting_dnd_schedule_get_end_time fail [%d]", ret);
2499 _add_alarm(dnd_schedule_day, dnd_start_hour, dnd_start_min, dnd_end_hour, dnd_end_min, uid);
2503 notification_system_setting_free_system_setting(setting);
2508 static gboolean __refresh_setting_table(gpointer data)
2510 notification_setting_refresh_setting_table(
2511 tzplatform_getuid(TZ_SYS_DEFAULT_USER));
2512 return G_SOURCE_REMOVE;
2517 * Do not try to do any other operation in these functions
2519 HAPI int notification_service_init(void)
2521 #define DEFAULT_VIEWER_CONF_FILE "/usr/share/notification/notification.ini"
2527 _monitoring_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
2528 ret = notification_db_init();
2529 if (ret != NOTIFICATION_ERROR_NONE) {
2530 ERR("Failed to init DB [%d]", ret);
2534 ret = notification_register_dbus_interface();
2535 if (ret != SERVICE_COMMON_ERROR_NONE) {
2536 ERR("Failed to register dbus interface [%d]", ret);
2537 return NOTIFICATION_ERROR_IO_ERROR;
2540 notification_get_default_viewer(DEFAULT_VIEWER_CONF_FILE, &default_viewer);
2541 notification_noti_init_data();
2542 notification_system_setting_init_system_setting_table(tzplatform_getuid(TZ_SYS_DEFAULT_USER));
2544 ret = notification_system_setting_get_dnd_schedule_enabled_uid(&uids, &count);
2545 if (ret == NOTIFICATION_ERROR_NONE && count > 0) {
2546 for (i = 0; i < count; i++)
2547 _check_dnd_schedule(uids[i]);
2552 g_idle_add(__refresh_setting_table, NULL);
2554 INFO("Successfully initialized");
2555 return NOTIFICATION_ERROR_NONE;
2558 HAPI int notification_service_fini(void)
2561 DBG("Successfully Finalized");
2562 return NOTIFICATION_ERROR_NONE;