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 <sys/smack.h>
22 #include <pkgmgr-info.h>
24 #include <notification.h>
30 #include "service_common.h"
31 #include "notification_service.h"
34 #include <notification_noti.h>
35 #include <notification_internal.h>
36 #include <notification_ipc.h>
37 #include <notification_setting_service.h>
38 #include <notification_db.h>
40 #define PROVIDER_NOTI_INTERFACE_NAME "org.tizen.data_provider_noti_service"
41 #define PROVIDER_NOTI_EVENT_INTERFACE_NAME "org.tizen.data_provider_noti_event_service"
42 #define NOTI_TEMPLATE_LIMIT 10
45 typedef struct _dnd_alarm_id dnd_alarm_id_s;
47 static GHashTable *_monitoring_hash;
48 static int _update_noti(GVariant **reply_body, notification_h noti, uid_t uid);
50 static GList *_dnd_alarm_id_list;
52 typedef struct _dnd_alarm_id {
54 alarm_id_t dnd_start_id;
55 alarm_id_t dnd_end_id;
58 static GList *__event_list = NULL;
60 typedef struct _event_sender_info {
64 } event_sender_info_s;
71 * NOTIFICATION SERVICE INITIALIZATION
74 static void _on_name_appeared(GDBusConnection *connection,
76 const gchar *name_owner,
79 monitoring_info_s *info = (monitoring_info_s *)user_data;
81 DbgPrint("name appeared name : %s, uid : %d", name, info->uid);
84 static void _on_name_vanished(GDBusConnection *connection,
88 DbgPrint("name vanished : %s", name);
89 monitoring_info_s *info = (monitoring_info_s *)user_data;
91 DbgPrint("name vanished uid : %d", info->uid);
92 g_bus_unwatch_name(info->watcher_id);
93 delete_monitoring_list(&_monitoring_hash, info->bus_name, info->uid);
101 static void _noti_dbus_method_call_handler(GDBusConnection *conn,
102 const gchar *sender, const gchar *object_path,
103 const gchar *iface_name, const gchar *method_name,
104 GVariant *parameters, GDBusMethodInvocation *invocation,
107 /* TODO : sender authority(privilege) check */
108 DbgPrint("notification method_name: %s, sender : %s ", method_name, sender);
110 GVariant *reply_body = NULL;
111 int ret = NOTIFICATION_ERROR_INVALID_OPERATION;
112 uid_t uid = get_sender_uid(sender);
113 pid_t pid = get_sender_pid(sender);
115 if (g_strcmp0(method_name, "noti_service_register") == 0)
116 ret = service_register(parameters, &reply_body, sender,
117 _on_name_appeared, _on_name_vanished, &_monitoring_hash, uid);
118 else if (g_strcmp0(method_name, "update_noti") == 0)
119 ret = notification_update_noti(parameters, &reply_body, uid);
120 else if (g_strcmp0(method_name, "add_noti") == 0)
121 ret = notification_add_noti(parameters, &reply_body, sender, uid);
122 else if (g_strcmp0(method_name, "refresh_noti") == 0)
123 ret = notification_refresh_noti(parameters, &reply_body, uid);
124 else if (g_strcmp0(method_name, "del_noti_single") == 0)
125 ret = notification_del_noti_single(parameters, &reply_body, uid);
126 else if (g_strcmp0(method_name, "del_noti_multiple") == 0)
127 ret = notification_del_noti_multiple(parameters, &reply_body, uid);
128 else if (g_strcmp0(method_name, "get_noti_count") == 0)
129 ret = notification_get_noti_count(parameters, &reply_body, uid);
130 else if (g_strcmp0(method_name, "update_noti_setting") == 0)
131 ret = notification_update_noti_setting(parameters, &reply_body, uid);
132 else if (g_strcmp0(method_name, "update_noti_sys_setting") == 0)
133 ret = notification_update_noti_sys_setting(parameters, &reply_body, uid);
134 else if (g_strcmp0(method_name, "load_noti_by_tag") == 0)
135 ret = notification_load_noti_by_tag(parameters, &reply_body, uid);
136 else if (g_strcmp0(method_name, "load_noti_by_priv_id") == 0)
137 ret = notification_load_noti_by_priv_id(parameters, &reply_body, uid);
138 else if (g_strcmp0(method_name, "load_noti_grouping_list") == 0)
139 ret = notification_load_grouping_list(parameters, &reply_body, uid);
140 else if (g_strcmp0(method_name, "load_noti_detail_list") == 0)
141 ret = notification_load_detail_list(parameters, &reply_body, uid);
142 else if (g_strcmp0(method_name, "get_setting_array") == 0)
143 ret = notification_get_setting_array(parameters, &reply_body, uid);
144 else if (g_strcmp0(method_name, "get_setting_by_appid") == 0)
145 ret = notification_get_setting_by_appid(parameters, &reply_body, uid);
146 else if (g_strcmp0(method_name, "load_system_setting") == 0)
147 ret = notification_load_system_setting(parameters, &reply_body, uid);
148 else if (g_strcmp0(method_name, "save_as_template") == 0)
149 ret = notification_add_noti_template(parameters, &reply_body, uid);
150 else if (g_strcmp0(method_name, "create_from_template") == 0)
151 ret = notification_get_noti_template(parameters, &reply_body, pid, uid);
152 else if (g_strcmp0(method_name, "create_from_package_template") == 0)
153 ret = notification_get_noti_package_template(parameters, &reply_body, uid);
154 else if (g_strcmp0(method_name, "get_noti_block_state") == 0)
155 ret = notification_get_block_state(parameters, &reply_body, uid);
156 else if (g_strcmp0(method_name, "load_dnd_allow_exception") == 0)
157 ret = notification_load_dnd_allow_exception(parameters, &reply_body, uid);
158 else if (g_strcmp0(method_name, "update_dnd_allow_exception") == 0)
159 ret = notification_update_dnd_allow_exception(parameters, &reply_body, uid);
160 else if (g_strcmp0(method_name, "send_noti_event") == 0)
161 ret = notification_send_noti_event(parameters, &reply_body);
162 else if (g_strcmp0(method_name, "check_event_receiver") == 0)
163 ret = notification_check_event_receiver(parameters, &reply_body);
164 else if (g_strcmp0(method_name, "reset_event_handler") == 0)
165 ret = notification_reset_event_receiver(parameters, &reply_body, sender);
167 if (ret == NOTIFICATION_ERROR_NONE) {
168 DbgPrint("notification service success : %d", ret);
169 g_dbus_method_invocation_return_value(
170 invocation, reply_body);
172 DbgPrint("notification service fail : %d", ret);
173 g_dbus_method_invocation_return_error(
177 "notification service error");
181 static const GDBusInterfaceVTable _noti_interface_vtable = {
182 _noti_dbus_method_call_handler,
187 int notification_register_dbus_interface()
189 static gchar introspection_xml[] =
191 " <interface name='org.tizen.data_provider_noti_service'>"
192 " <method name='noti_service_register'>"
193 " <arg type='i' name='uid' direction='in'/>"
196 " <method name='add_noti'>"
197 " <arg type='v' name='noti' direction='in'/>"
198 " <arg type='i' name='priv_id' direction='out'/>"
201 " <method name='update_noti'>"
202 " <arg type='v' name='noti' direction='in'/>"
203 " <arg type='i' name='priv_id' direction='out'/>"
206 " <method name='refresh_noti'>"
207 " <arg type='i' name='uid' direction='in'/>"
210 " <method name='del_noti_single'>"
211 " <arg type='s' name='pkgname' direction='in'/>"
212 " <arg type='i' name='priv_id' direction='in'/>"
213 " <arg type='i' name='uid' direction='in'/>"
214 " <arg type='i' name='priv_id' direction='out'/>"
217 " <method name='del_noti_multiple'>"
218 " <arg type='s' name='pkgname' direction='in'/>"
219 " <arg type='i' name='priv_id' direction='in'/>"
220 " <arg type='i' name='uid' direction='in'/>"
221 " <arg type='i' name='priv_id' direction='out'/>"
224 " <method name='load_noti_by_tag'>"
225 " <arg type='s' name='pkgname' direction='in'/>"
226 " <arg type='s' name='tag' direction='in'/>"
227 " <arg type='i' name='uid' direction='in'/>"
228 " <arg type='v' name='noti' direction='out'/>"
231 " <method name='load_noti_by_priv_id'>"
232 " <arg type='s' name='pkgname' direction='in'/>"
233 " <arg type='i' name='priv_id' direction='in'/>"
234 " <arg type='i' name='uid' direction='in'/>"
235 " <arg type='v' name='noti' direction='out'/>"
238 " <method name='load_noti_grouping_list'>"
239 " <arg type='i' name='type' direction='in'/>"
240 " <arg type='i' name='count' direction='in'/>"
241 " <arg type='i' name='uid' direction='in'/>"
242 " <arg type='a(v)' name='noti_list' direction='out'/>"
245 " <method name='load_noti_detail_list'>"
246 " <arg type='s' name='pkgname' direction='in'/>"
247 " <arg type='i' name='group_id' direction='in'/>"
248 " <arg type='i' name='priv_id' direction='in'/>"
249 " <arg type='i' name='count' direction='in'/>"
250 " <arg type='i' name='uid' direction='in'/>"
251 " <arg type='a(v)' name='noti_list' direction='out'/>"
254 " <method name='get_noti_count'>"
255 " <arg type='i' name='type' direction='in'/>"
256 " <arg type='s' name='pkgname' direction='in'/>"
257 " <arg type='i' name='group_id' direction='in'/>"
258 " <arg type='i' name='priv_id' direction='in'/>"
259 " <arg type='i' name='uid' direction='in'/>"
260 " <arg type='i' name='ret_count' direction='out'/>"
263 " <method name='update_noti_setting'>"
264 " <arg type='s' name='pkgname' direction='in'/>"
265 " <arg type='s' name='appid' direction='in'/>"
266 " <arg type='i' name='allow_to_notify' direction='in'/>"
267 " <arg type='i' name='do_not_disturb_except' direction='in'/>"
268 " <arg type='i' name='visibility_class' direction='in'/>"
269 " <arg type='i' name='pop_up_notification' direction='in'/>"
270 " <arg type='i' name='lock_screen_content_level' direction='in'/>"
271 " <arg type='i' name='uid' direction='in'/>"
274 " <method name='update_noti_sys_setting'>"
275 " <arg type='i' name='do_not_disturb' direction='in'/>"
276 " <arg type='i' name='visibility_class' direction='in'/>"
277 " <arg type='i' name='dnd_schedule_enabled' direction='in'/>"
278 " <arg type='i' name='dnd_schedule_day' direction='in'/>"
279 " <arg type='i' name='dnd_start_hour' direction='in'/>"
280 " <arg type='i' name='dnd_start_min' direction='in'/>"
281 " <arg type='i' name='dnd_end_hour' direction='in'/>"
282 " <arg type='i' name='dnd_end_min' direction='in'/>"
283 " <arg type='i' name='lock_screen_level' direction='in'/>"
284 " <arg type='i' name='uid' direction='in'/>"
287 " <method name='get_setting_array'>"
288 " <arg type='i' name='uid' direction='in'/>"
289 " <arg type='i' name='setting_cnt' direction='out'/>"
290 " <arg type='a(v)' name='setting_arr' direction='out'/>"
293 " <method name='get_setting_by_appid'>"
294 " <arg type='s' name='appid' direction='in'/>"
295 " <arg type='i' name='uid' direction='in'/>"
296 " <arg type='v' name='setting' direction='out'/>"
299 " <method name='load_system_setting'>"
300 " <arg type='i' name='uid' direction='in'/>"
301 " <arg type='v' name='setting' direction='out'/>"
304 " <method name='save_as_template'>"
305 " <arg type='v' name='noti' direction='in'/>"
306 " <arg type='s' name='name' direction='in'/>"
309 " <method name='create_from_template'>"
310 " <arg type='s' name='name' direction='in'/>"
311 " <arg type='v' name='noti' direction='out'/>"
314 " <method name='create_from_package_template'>"
315 " <arg type='s' name='appid' direction='in'/>"
316 " <arg type='s' name='name' direction='in'/>"
317 " <arg type='v' name='noti' direction='out'/>"
320 " <method name='get_noti_block_state'>"
321 " <arg type='s' name='appid' direction='in'/>"
322 " <arg type='i' name='uid' direction='in'/>"
323 " <arg type='v' name='state' direction='out'/>"
326 " <method name='update_dnd_allow_exception'>"
327 " <arg type='i' name='type' direction='in'/>"
328 " <arg type='i' name='value' direction='in'/>"
329 " <arg type='i' name='uid' direction='in'/>"
332 " <method name='load_dnd_allow_exception'>"
333 " <arg type='i' name='uid' direction='in'/>"
334 " <arg type='i' name='count' direction='out'/>"
335 " <arg type='a(v)' name='dnd_allow_exception' direction='out'/>"
338 " <method name='send_noti_event'>"
339 " <arg type='v' name='noti' direction='in'/>"
340 " <arg type='i' name='event_type' direction='in'/>"
343 " <method name='check_event_receiver'>"
344 " <arg type='i' name='priv_id' direction='in'/>"
345 " <arg type='i' name='available' direction='out'/>"
348 " <method name='reset_event_handler'>"
349 " <arg type='i' name='priv_id' direction='in'/>"
352 " <method name='post_toast'>"
357 return service_common_register_dbus_interface(introspection_xml, _noti_interface_vtable);
360 static void __free_event_info(gpointer data)
362 event_sender_info_s *info = (event_sender_info_s *)data;
371 static gint __priv_id_compare(gconstpointer a, gconstpointer b)
373 event_sender_info_s *info = NULL;
378 info = (event_sender_info_s *)a;
380 if (info->priv_id == GPOINTER_TO_INT(b))
387 static int _add_noti(GVariant **reply_body, notification_h noti, uid_t uid)
390 int priv_id = NOTIFICATION_PRIV_ID_NONE;
391 GVariant *body = NULL;
394 ret = notification_noti_insert(noti);
395 if (ret != NOTIFICATION_ERROR_NONE) {
396 ErrPrint("failed to update a notification:%d\n", ret);
400 ret = notification_get_id(noti, NULL, &priv_id);
401 if (ret != NOTIFICATION_ERROR_NONE) {
402 ErrPrint("failed to gets priv_id:%d\n", ret);
406 body = notification_ipc_make_gvariant_from_noti(noti, true);
408 ErrPrint("cannot make gvariant to noti");
409 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
412 ret = send_notify(body, "add_noti_notify", &_monitoring_hash, PROVIDER_NOTI_INTERFACE_NAME, uid);
413 g_variant_unref(body);
415 if (ret != NOTIFICATION_ERROR_NONE) {
416 ErrPrint("failed to send notify:%d\n", ret);
420 *reply_body = g_variant_new("(i)", priv_id);
421 if (*reply_body == NULL) {
422 ErrPrint("cannot make reply_body");
423 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
426 DbgPrint("_insert_noti done !!");
430 static int _validate_and_set_noti_with_uid(uid_t uid, notification_h noti, uid_t *noti_uid)
432 int ret = NOTIFICATION_ERROR_NONE;
434 ret = notification_get_uid(noti, noti_uid);
435 if (ret != NOTIFICATION_ERROR_NONE) {
436 ErrPrint("notification_get_uid fail ret : %d", ret);
440 if (uid > NORMAL_UID_BASE && uid != *noti_uid) {
441 ErrPrint("invalid seder uid : %d, noti_uid : %d", uid, *noti_uid);
442 return NOTIFICATION_ERROR_INVALID_PARAMETER;
443 } else if (uid <= NORMAL_UID_BASE) {
444 if (*noti_uid <= NORMAL_UID_BASE) {
445 if (*noti_uid != uid)
446 return NOTIFICATION_ERROR_INVALID_PARAMETER;
448 DbgPrint("system defualt noti post change noti_uid to default");
450 IF system (uid <= NORMAL_UID_BASE) try to send noti without specipic destination uid (using notification_pot API)
451 Send it to default user (TZ_SYS_DEFAULT_USER)
453 *noti_uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
454 ret = notification_set_uid(noti, *noti_uid);
455 if (ret != NOTIFICATION_ERROR_NONE) {
456 ErrPrint("notification_set_uid fail ret : %d", ret);
459 DbgPrint("changed noti_uid %d", *noti_uid);
465 static int _validate_and_set_param_uid_with_uid(uid_t uid, uid_t *param_uid)
467 int ret = NOTIFICATION_ERROR_NONE;
468 if (uid > NORMAL_UID_BASE && uid != *param_uid) {
469 ErrPrint("invalid seder uid : %d, param_uid : %d", uid, *param_uid);
470 return NOTIFICATION_ERROR_INVALID_PARAMETER;
471 } else if (uid <= NORMAL_UID_BASE) {
472 if (*param_uid <= NORMAL_UID_BASE) {
473 if (*param_uid != uid)
474 return NOTIFICATION_ERROR_INVALID_PARAMETER;
476 IF system (uid <= NORMAL_UID_BASE) try to send noti without specipic destination uid (using notification_pot API)
477 Send it to default user (TZ_SYS_DEFAULT_USER)
479 *param_uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
485 static void __sender_name_appeared_cb(GDBusConnection *connection,
487 const gchar *name_owner,
490 DbgPrint("sender name appeared name: %s, name_owner : %s", name, name_owner);
493 static void __sender_name_vanished_cb(GDBusConnection *connection,
497 GList *delete_list = NULL;
498 event_sender_info_s *info;
503 info = (event_sender_info_s *)user_data;
505 DbgPrint("sender name vanished name : %s, priv_id : %d, watcher_id : %d",
506 name, info->priv_id, info->watcher_id);
508 delete_list = g_list_find_custom(__event_list, GINT_TO_POINTER(info->priv_id),
509 (GCompareFunc)__priv_id_compare);
511 __event_list = g_list_remove(__event_list, info);
512 g_bus_unwatch_name(info->watcher_id);
513 __free_event_info(info);
517 static guint __insert_sender_watcher_id(event_sender_info_s *sender_info)
519 guint watcher_id = 0;
520 watcher_id = g_bus_watch_name(G_BUS_TYPE_SYSTEM,
521 sender_info->busname,
522 G_BUS_NAME_WATCHER_FLAGS_NONE,
523 __sender_name_appeared_cb,
524 __sender_name_vanished_cb,
528 ErrPrint("fail to watch sender name");
532 DbgPrint("watch on %s success - watcher_id : %d", sender_info->busname, watcher_id);
536 static void __add_sender_info(int priv_id, const char *busname)
538 GList *find_list = NULL;
539 event_sender_info_s *sender_info;
540 event_sender_info_s *tmp_info = NULL;
545 sender_info = (event_sender_info_s *)malloc(sizeof(event_sender_info_s));
546 if (sender_info == NULL) {
547 ErrPrint("malloc failed");
551 sender_info->priv_id = priv_id;
552 sender_info->busname = strdup(busname);
554 if (__event_list == NULL) {
555 sender_info->watcher_id = __insert_sender_watcher_id(sender_info);
556 __event_list = g_list_append(__event_list, sender_info);
558 __event_list = g_list_first(__event_list);
559 find_list = g_list_find_custom(__event_list, GINT_TO_POINTER(priv_id),
560 (GCompareFunc)__priv_id_compare);
561 if (find_list == NULL) {
562 sender_info->watcher_id = __insert_sender_watcher_id(sender_info);
563 __event_list = g_list_append(__event_list, sender_info);
565 tmp_info = (event_sender_info_s *)g_list_nth_data(find_list, 0);
566 if (tmp_info->busname) {
567 if (strcmp(tmp_info->busname, busname)) {
568 free(tmp_info->busname);
569 tmp_info->busname = strdup(busname);
570 g_bus_unwatch_name(tmp_info->watcher_id);
571 tmp_info->watcher_id = __insert_sender_watcher_id(sender_info);
574 tmp_info->busname = strdup(busname);
575 if (!tmp_info->watcher_id)
576 g_bus_unwatch_name(tmp_info->watcher_id);
577 tmp_info->watcher_id = __insert_sender_watcher_id(tmp_info);
579 __free_event_info(sender_info);
584 int notification_add_noti(GVariant *parameters, GVariant **reply_body, const char *sender, uid_t uid)
590 GVariant *body = NULL;
593 noti = notification_create(NOTIFICATION_TYPE_NOTI);
595 g_variant_get(parameters, "(v)", &body);
596 ret = notification_ipc_make_noti_from_gvariant(noti, body);
597 g_variant_unref(body);
599 ret = _validate_and_set_noti_with_uid(uid, noti, ¬i_uid);
600 if (ret != NOTIFICATION_ERROR_NONE)
603 ret = notification_noti_check_tag(noti);
604 if (ret == NOTIFICATION_ERROR_NOT_EXIST_ID)
605 ret = _add_noti(reply_body, noti, noti_uid);
606 else if (ret == NOTIFICATION_ERROR_ALREADY_EXIST_ID)
607 ret = _update_noti(reply_body, noti, noti_uid);
609 ret = notification_get_event_flag(noti, &event_flag);
610 if (ret != NOTIFICATION_ERROR_NONE)
613 if (event_flag == true) {
614 ret = notification_get_id(noti, NULL, &priv_id);
615 if (ret != NOTIFICATION_ERROR_NONE)
618 __add_sender_info(priv_id, sender);
620 notification_free(noti);
622 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
625 DbgPrint("notification_add_noti ret : %d", ret);
630 static int _update_noti(GVariant **reply_body, notification_h noti, uid_t uid)
633 GVariant *body = NULL;
634 int priv_id = NOTIFICATION_PRIV_ID_NONE;
637 notification_get_id(noti, NULL, &priv_id);
638 DbgPrint("priv_id: [%d]", priv_id);
640 ret = notification_noti_update(noti);
641 if (ret != NOTIFICATION_ERROR_NONE)
644 body = notification_ipc_make_gvariant_from_noti(noti, true);
646 ErrPrint("cannot make gvariant to noti");
647 return NOTIFICATION_ERROR_IO_ERROR;
650 ret = send_notify(body, "update_noti_notify", &_monitoring_hash, PROVIDER_NOTI_INTERFACE_NAME, uid);
651 g_variant_unref(body);
653 if (ret != NOTIFICATION_ERROR_NONE) {
654 ErrPrint("failed to send notify:%d\n", ret);
658 *reply_body = g_variant_new("(i)", priv_id);
659 if (*reply_body == NULL) {
660 ErrPrint("cannot make reply_body");
661 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
663 DbgPrint("_update_noti done !!");
667 int notification_update_noti(GVariant *parameters, GVariant **reply_body, uid_t uid)
671 GVariant *body = NULL;
674 noti = notification_create(NOTIFICATION_TYPE_NOTI);
676 g_variant_get(parameters, "(v)", &body);
677 ret = notification_ipc_make_noti_from_gvariant(noti, body);
678 g_variant_unref(body);
680 ret = _validate_and_set_noti_with_uid(uid, noti, ¬i_uid);
681 if (ret != NOTIFICATION_ERROR_NONE)
684 if (ret == NOTIFICATION_ERROR_NONE)
685 ret = _update_noti(reply_body, noti, noti_uid);
687 notification_free(noti);
689 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
694 /* load_noti_by_tag */
695 int notification_load_noti_by_tag(GVariant *parameters, GVariant **reply_body, uid_t uid)
699 char *pkgname = NULL;
703 noti = notification_create(NOTIFICATION_TYPE_NOTI);
705 g_variant_get(parameters, "(&s&si)", &pkgname, &tag, ¶m_uid);
706 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
707 if (ret != NOTIFICATION_ERROR_NONE)
710 DbgPrint("_load_noti_by_tag pkgname : %s, tag : %s ", pkgname, tag);
711 ret = notification_noti_get_by_tag(noti, pkgname, tag, param_uid);
713 DbgPrint("notification_noti_get_by_tag ret : %d", ret);
716 *reply_body = notification_ipc_make_gvariant_from_noti(noti, true);
717 notification_free(noti);
719 if (*reply_body == NULL) {
720 ErrPrint("cannot make reply_body");
721 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
724 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
726 DbgPrint("_load_noti_by_tag done !!");
730 /* load_noti_by_priv_id */
731 int notification_load_noti_by_priv_id(GVariant *parameters, GVariant **reply_body, uid_t uid)
734 int priv_id = NOTIFICATION_PRIV_ID_NONE;
735 char *pkgname = NULL;
739 noti = notification_create(NOTIFICATION_TYPE_NOTI);
741 g_variant_get(parameters, "(&sii)", &pkgname, &priv_id, ¶m_uid);
742 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
743 if (ret != NOTIFICATION_ERROR_NONE)
746 DbgPrint("load_noti_by_priv_id pkgname : %s, priv_id : %d ", pkgname, priv_id);
747 ret = notification_noti_get_by_priv_id(noti, pkgname, priv_id, param_uid);
749 DbgPrint("notification_noti_get_by_priv_id ret : %d", ret);
752 *reply_body = notification_ipc_make_gvariant_from_noti(noti, true);
753 notification_free(noti);
755 if (*reply_body == NULL) {
756 ErrPrint("cannot make reply_body");
757 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
760 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
763 DbgPrint("_load_noti_by_priv_id done !!");
767 /* load_noti_grouping_list */
768 int notification_load_grouping_list(GVariant *parameters, GVariant **reply_body, uid_t uid)
772 GVariant *body = NULL;
773 notification_type_e type = NOTIFICATION_TYPE_NONE;
774 notification_list_h get_list = NULL;
775 notification_list_h list_iter;
776 GVariantBuilder *builder;
780 g_variant_get(parameters, "(iii)", &type, &count, ¶m_uid);
781 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
782 if (ret != NOTIFICATION_ERROR_NONE)
784 DbgPrint("load grouping list type : %d, count : %d ", type, count);
786 ret = notification_noti_get_grouping_list(type, count, &get_list, param_uid);
787 if (ret != NOTIFICATION_ERROR_NONE)
790 builder = g_variant_builder_new(G_VARIANT_TYPE("a(v)"));
792 list_iter = notification_list_get_head(get_list);
794 noti = notification_list_get_data(list_iter);
795 body = notification_ipc_make_gvariant_from_noti(noti, true);
796 g_variant_builder_add(builder, "(v)", body);
798 list_iter = notification_list_get_next(list_iter);
799 } while (list_iter != NULL);
801 notification_free_list(get_list);
804 *reply_body = g_variant_new("(a(v))", builder);
805 g_variant_builder_unref(builder);
807 if (*reply_body == NULL) {
808 ErrPrint("cannot make reply_body");
809 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
812 DbgPrint("load grouping list done !!");
816 /* get_setting_array */
817 int notification_get_setting_array(GVariant *parameters, GVariant **reply_body, uid_t uid)
821 GVariantBuilder *builder;
824 notification_setting_h setting_array = NULL;
825 notification_setting_h temp;
828 g_variant_get(parameters, "(i)", ¶m_uid);
829 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
830 if (ret != NOTIFICATION_ERROR_NONE)
833 ret = noti_setting_get_setting_array(&setting_array, &count, param_uid);
834 if (ret != NOTIFICATION_ERROR_NONE)
837 DbgPrint("get setting array : %d", count);
838 builder = g_variant_builder_new(G_VARIANT_TYPE("a(v)"));
841 for (i = 0; i < count; i++) {
842 temp = setting_array + i;
843 body = notification_ipc_make_gvariant_from_setting(temp);
844 g_variant_builder_add(builder, "(v)", body);
846 if (temp->package_name)
847 free(temp->package_name);
853 *reply_body = g_variant_new("(ia(v))", count, builder);
854 g_variant_builder_unref(builder);
856 if (*reply_body == NULL) {
857 ErrPrint("cannot make reply_body");
858 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
863 /* get_setting_by_appid */
864 int notification_get_setting_by_appid(GVariant *parameters, GVariant **reply_body, uid_t uid)
869 notification_setting_h setting = NULL;
872 g_variant_get(parameters, "(&si)", &appid, ¶m_uid);
873 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
874 if (ret != NOTIFICATION_ERROR_NONE)
876 DbgPrint("get setting by appid : %s uid : %d", appid, param_uid);
878 ret = noti_setting_service_get_setting_by_appid(appid, &setting, param_uid);
879 if (ret == NOTIFICATION_ERROR_NONE) {
880 body = notification_ipc_make_gvariant_from_setting(setting);
881 notification_setting_free_notification(setting);
884 ErrPrint("fail to make gvariant");
885 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
891 *reply_body = g_variant_new("(v)", body);
892 if (*reply_body == NULL) {
893 ErrPrint("cannot make reply_body");
894 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
899 /* load_system_setting */
900 int notification_load_system_setting(GVariant *parameters, GVariant **reply_body, uid_t uid)
904 notification_system_setting_h setting = NULL;
908 g_variant_get(parameters, "(i)", ¶m_uid);
909 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
910 if (ret != NOTIFICATION_ERROR_NONE)
913 ret = noti_system_setting_load_system_setting(&setting, param_uid);
914 if (ret == NOTIFICATION_ERROR_NONE) {
915 body = notification_ipc_make_gvariant_from_system_setting(setting);
916 notification_system_setting_free_system_setting(setting);
919 ErrPrint("fail to make gvariant");
920 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
926 *reply_body = g_variant_new("(v)", body);
927 if (*reply_body == NULL) {
928 ErrPrint("cannot make reply_body");
929 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
931 DbgPrint("load system setting done !!");
935 /* load_noti_detail_list */
936 int notification_load_detail_list(GVariant *parameters, GVariant **reply_body, uid_t uid)
940 GVariant *body = NULL;
941 notification_list_h get_list = NULL;
942 notification_list_h list_iter;
943 GVariantBuilder *builder;
944 char *pkgname = NULL;
945 int group_id = NOTIFICATION_GROUP_ID_NONE;
946 int priv_id = NOTIFICATION_PRIV_ID_NONE;
950 g_variant_get(parameters, "(&siiii)", &pkgname, &group_id, &priv_id, &count, ¶m_uid);
951 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
952 if (ret != NOTIFICATION_ERROR_NONE)
954 DbgPrint("load detail list pkgname : %s, group_id : %d, priv_id : %d, count : %d ",
955 pkgname, group_id, priv_id, count);
957 ret = notification_noti_get_detail_list(pkgname, group_id, priv_id,
958 count, &get_list, param_uid);
959 if (ret != NOTIFICATION_ERROR_NONE)
962 builder = g_variant_builder_new(G_VARIANT_TYPE("a(v)"));
965 list_iter = notification_list_get_head(get_list);
967 noti = notification_list_get_data(list_iter);
968 body = notification_ipc_make_gvariant_from_noti(noti, true);
970 g_variant_builder_add(builder, "(v)", body);
971 list_iter = notification_list_get_next(list_iter);
973 } while (list_iter != NULL);
974 notification_free_list(get_list);
977 *reply_body = g_variant_new("(a(v))", builder);
978 g_variant_builder_unref(builder);
980 if (*reply_body == NULL) {
981 ErrPrint("cannot make reply_body");
982 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
985 DbgPrint("load detail list done !!");
990 int notification_refresh_noti(GVariant *parameters, GVariant **reply_body, uid_t uid)
995 g_variant_get(parameters, "(i)", ¶m_uid);
996 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
997 if (ret != NOTIFICATION_ERROR_NONE)
1000 ret = send_notify(parameters, "refresh_noti_notify", &_monitoring_hash, PROVIDER_NOTI_INTERFACE_NAME, param_uid);
1001 if (ret != NOTIFICATION_ERROR_NONE) {
1002 ErrPrint("failed to send notify:%d\n", ret);
1006 *reply_body = g_variant_new("()");
1007 if (*reply_body == NULL) {
1008 ErrPrint("cannot make reply_body");
1009 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1012 DbgPrint("_refresh_noti_service done !!");
1016 static int __delete_sender_info(int priv_id)
1018 int ret = NOTIFICATION_ERROR_NONE;
1019 event_sender_info_s *info;
1020 GList *delete_list = NULL;
1021 GVariant *body = NULL;
1023 if (__event_list != NULL) {
1024 __event_list = g_list_first(__event_list);
1025 delete_list = g_list_find_custom(__event_list, GINT_TO_POINTER(priv_id),
1026 (GCompareFunc)__priv_id_compare);
1027 if (delete_list != NULL) {
1028 info = (event_sender_info_s *)g_list_nth_data(delete_list, 0);
1029 body = g_variant_new("(i)", priv_id);
1030 ret = send_event_notify_by_busname(body, "delete_noti", info->busname, PROVIDER_NOTI_EVENT_INTERFACE_NAME);
1031 g_variant_unref(body);
1032 if (ret != NOTIFICATION_ERROR_NONE) {
1033 ErrPrint("failed to send event notify:%d\n", ret);
1036 __event_list = g_list_remove(g_list_first(__event_list), info);
1037 g_bus_unwatch_name(info->watcher_id);
1038 __free_event_info(info);
1039 if (g_list_length(__event_list) == 0)
1040 __event_list = NULL;
1047 /* del_noti_single */
1048 int notification_del_noti_single(GVariant *parameters, GVariant **reply_body, uid_t uid)
1051 int num_changes = 0;
1052 int priv_id = NOTIFICATION_PRIV_ID_NONE;
1053 char *pkgname = NULL;
1054 GVariant *body = NULL;
1057 g_variant_get(parameters, "(&sii)", &pkgname, &priv_id, ¶m_uid);
1058 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
1059 if (ret != NOTIFICATION_ERROR_NONE)
1061 ret = notification_noti_delete_by_priv_id_get_changes(pkgname, priv_id, &num_changes, param_uid);
1062 DbgPrint("priv_id: [%d] num_delete:%d\n", priv_id, num_changes);
1063 if (ret != NOTIFICATION_ERROR_NONE) {
1064 ErrPrint("failed to delete a notification:%d %d\n", ret, num_changes);
1068 if (num_changes > 0) {
1069 body = g_variant_new("(iii)", 1, priv_id, param_uid);
1071 ErrPrint("cannot make gvariant to noti");
1072 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1074 ret = send_notify(body, "delete_single_notify", &_monitoring_hash, PROVIDER_NOTI_INTERFACE_NAME, param_uid);
1075 g_variant_unref(body);
1076 if (ret != NOTIFICATION_ERROR_NONE) {
1077 ErrPrint("failed to send notify:%d\n", ret);
1081 ret = __delete_sender_info(priv_id);
1082 if (ret != NOTIFICATION_ERROR_NONE)
1086 *reply_body = g_variant_new("(i)", priv_id);
1087 if (*reply_body == NULL) {
1088 ErrPrint("cannot make reply_body");
1089 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1091 DbgPrint("_del_noti_single done !!");
1095 /* del_noti_multiple */
1096 int notification_del_noti_multiple(GVariant *parameters, GVariant **reply_body, uid_t uid)
1099 char *pkgname = NULL;
1100 notification_type_e type = NOTIFICATION_TYPE_NONE;
1101 int num_deleted = 0;
1102 int *list_deleted = NULL;
1103 GVariant *deleted_noti_list;
1104 GVariantBuilder *builder;
1108 g_variant_get(parameters, "(&sii)", &pkgname, &type, ¶m_uid);
1109 DbgPrint("pkgname: [%s] type: [%d]\n", pkgname, type);
1110 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
1111 if (ret != NOTIFICATION_ERROR_NONE)
1114 ret = notification_noti_delete_all(type, pkgname, &num_deleted, &list_deleted, param_uid);
1116 DbgPrint("ret: [%d] num_deleted: [%d]\n", ret, num_deleted);
1118 if (ret != NOTIFICATION_ERROR_NONE) {
1119 ErrPrint("failed to delete notifications:%d\n", ret);
1120 if (list_deleted != NULL)
1125 if (num_deleted > 0) {
1126 builder = g_variant_builder_new(G_VARIANT_TYPE("a(i)"));
1128 for (i = 0; i < num_deleted; i++)
1129 g_variant_builder_add(builder, "(i)", *(list_deleted + i));
1131 deleted_noti_list = g_variant_new("(a(i)i)", builder, param_uid);
1132 ret = send_notify(deleted_noti_list, "delete_multiple_notify", &_monitoring_hash, PROVIDER_NOTI_INTERFACE_NAME, param_uid);
1133 g_variant_builder_unref(builder);
1134 g_variant_unref(deleted_noti_list);
1135 if (ret != NOTIFICATION_ERROR_NONE) {
1136 ErrPrint("failed to send notify:%d\n", ret);
1140 for (i = 0; i < num_deleted; i++) {
1141 ret = __delete_sender_info(*(list_deleted + i));
1142 if (ret != NOTIFICATION_ERROR_NONE)
1149 *reply_body = g_variant_new("(i)", num_deleted);
1150 if (*reply_body == NULL) {
1151 ErrPrint("cannot make reply_body");
1152 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1155 DbgPrint("_del_noti_multiple done !!");
1159 /* get_noti_count */
1160 int notification_get_noti_count(GVariant *parameters, GVariant **reply_body, uid_t uid)
1163 notification_type_e type = NOTIFICATION_TYPE_NONE;
1164 char *pkgname = NULL;
1165 int group_id = NOTIFICATION_GROUP_ID_NONE;
1166 int priv_id = NOTIFICATION_PRIV_ID_NONE;
1170 g_variant_get(parameters, "(i&siii)", &type, &pkgname, &group_id, &priv_id, ¶m_uid);
1171 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
1172 if (ret != NOTIFICATION_ERROR_NONE) {
1173 ErrPrint("_validate_uid fail ret : %d", ret);
1174 return NOTIFICATION_ERROR_IO_ERROR;
1177 ret = notification_noti_get_count(type, pkgname, group_id, priv_id,
1178 ¬i_count, param_uid);
1179 if (ret != NOTIFICATION_ERROR_NONE) {
1180 ErrPrint("failed to get count : %d\n", ret);
1184 *reply_body = g_variant_new("(i)", noti_count);
1185 if (*reply_body == NULL) {
1186 ErrPrint("cannot make reply_body");
1187 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1189 DbgPrint("_get_noti_property_service done !! %d", ret);
1193 /* update_noti_setting */
1194 int notification_update_noti_setting(GVariant *parameters, GVariant **reply_body, uid_t uid)
1197 char *pkgname = NULL;
1199 int allow_to_notify = 0;
1200 int do_not_disturb_except = 0;
1201 int visivility_class = 0;
1202 int pop_up_notification = 0;
1203 int lock_screen_content_level = 0;
1206 g_variant_get(parameters, "(&s&siiiiii)",
1210 &do_not_disturb_except,
1212 &pop_up_notification,
1213 &lock_screen_content_level,
1216 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
1217 if (ret != NOTIFICATION_ERROR_NONE)
1220 DbgPrint("package_name: [%s] appid: [%s] allow_to_notify: [%d] do_not_disturb_except: [%d] visivility_class: [%d] pop_up_notification: [%d] lock_screen_content_level: [%d]\n",
1221 pkgname, appid, allow_to_notify, do_not_disturb_except, visivility_class, pop_up_notification, lock_screen_content_level);
1223 ret = notification_setting_db_update(pkgname, appid, allow_to_notify, do_not_disturb_except, visivility_class,
1224 pop_up_notification, lock_screen_content_level, param_uid);
1225 if (ret != NOTIFICATION_ERROR_NONE) {
1226 ErrPrint("failed to setting db update : %d\n", ret);
1230 *reply_body = g_variant_new("()");
1231 if (*reply_body == NULL) {
1232 ErrPrint("cannot make reply_body");
1233 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1235 DbgPrint("_update_noti_setting_service done !! %d", ret);
1239 static int _dnd_schedule_alarm_cb(alarm_id_t alarm_id, void *data)
1243 bool dnd_id_found = false;
1244 GVariant *body = NULL;
1245 GList *dnd_found_list = NULL;
1246 dnd_alarm_id_s *dnd_id_data = NULL;
1249 dnd_found_list = g_list_first(_dnd_alarm_id_list);
1251 for (; dnd_found_list != NULL; dnd_found_list = dnd_found_list->next) {
1252 dnd_id_data = dnd_found_list->data;
1253 uid = dnd_id_data->uid;
1255 ret = noti_system_setting_get_do_not_disturb(&do_not_disturb, uid);
1256 if (ret != NOTIFICATION_ERROR_NONE) {
1257 ErrPrint("get do not disturb failed");
1261 if (alarm_id == dnd_id_data->dnd_start_id && !do_not_disturb) {
1263 dnd_id_found = true;
1265 } else if (alarm_id == dnd_id_data->dnd_end_id && do_not_disturb) {
1267 dnd_id_found = true;
1272 if (dnd_id_found == false) {
1273 ErrPrint("notification wrong alarm [%d]", alarm_id);
1277 notification_setting_db_update_do_not_disturb(do_not_disturb, uid);
1279 body = g_variant_new("(ii)", do_not_disturb, uid);
1281 ret = send_notify(body, "change_dnd_notify", &_monitoring_hash, PROVIDER_NOTI_INTERFACE_NAME, uid);
1282 g_variant_unref(body);
1283 if (ret != NOTIFICATION_ERROR_NONE) {
1284 ErrPrint("failed to send notify:%d\n", ret);
1288 DbgPrint("_dnd_schedule_alarm_cb done");
1292 static int _get_current_time(struct tm *date)
1297 ErrPrint("NOTIFICATION_ERROR_INVALID_PARAMETER");
1298 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1302 localtime_r(&now, date);
1304 return NOTIFICATION_ERROR_NONE;
1307 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)
1309 int err = NOTIFICATION_ERROR_NONE;
1310 struct tm struct_time;
1311 alarm_entry_t *alarm_info = NULL;
1312 alarm_date_t alarm_time;
1313 alarm_id_t alarm_id = -1;
1315 err = alarmmgr_init("notification");
1317 ErrPrint("alarmmgr_init failed [%d]", err);
1321 err = alarmmgr_set_cb(handler, NULL);
1323 ErrPrint("alarmmgr_set_cb failed [%d]", err);
1327 err = _get_current_time(&struct_time);
1328 if (err != NOTIFICATION_ERROR_NONE) {
1329 ErrPrint("get_current_time failed");
1333 alarm_info = alarmmgr_create_alarm();
1334 if (alarm_info == NULL) {
1335 ErrPrint("alarmmgr_create_alarm failed");
1339 alarm_time.year = struct_time.tm_year + 1900;
1340 alarm_time.month = struct_time.tm_mon + 1;
1341 alarm_time.day = struct_time.tm_mday;
1342 alarm_time.hour = hour;
1343 alarm_time.min = min;
1346 err = alarmmgr_set_time(alarm_info, alarm_time);
1347 if (err != ALARMMGR_RESULT_SUCCESS) {
1348 ErrPrint("alarmmgr_set_time failed (%d)", err);
1353 err = alarmmgr_set_repeat_mode(alarm_info, ALARM_REPEAT_MODE_WEEKLY, week_flag);
1354 if (err != ALARMMGR_RESULT_SUCCESS) {
1355 ErrPrint("alarmmgr_set_repeat_mode failed [%d]", err);
1360 err = alarmmgr_set_type(alarm_info, ALARM_TYPE_VOLATILE);
1361 if (err != ALARMMGR_RESULT_SUCCESS) {
1362 ErrPrint("alarmmgr_set_type failed [%d]", err);
1366 err = alarmmgr_add_alarm_with_localtime(alarm_info, NULL, &alarm_id);
1367 if (err != ALARMMGR_RESULT_SUCCESS) {
1368 ErrPrint("alarmmgr_add_alarm_with_localtime failed [%d]", err);
1372 *dnd_schedule_alarm_id = alarm_id;
1374 DbgPrint("alarm_id [%d]", *dnd_schedule_alarm_id);
1378 alarmmgr_free_alarm(alarm_info);
1383 static gint _dnd_data_compare(gconstpointer a, gconstpointer b)
1385 const dnd_alarm_id_s *data = NULL;
1390 if (data->uid == GPOINTER_TO_UINT(b))
1396 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)
1398 dnd_alarm_id_s *dnd_id_data = NULL;
1400 dnd_id_data = (dnd_alarm_id_s *)malloc(sizeof(dnd_alarm_id_s));
1401 if (dnd_id_data == NULL) {
1402 ErrPrint("memory allocation fail");
1406 dnd_id_data->uid = uid;
1407 dnd_id_data->dnd_start_id = start_alarm_id;
1408 dnd_id_data->dnd_end_id = end_alarm_id;
1413 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)
1415 int ret = NOTIFICATION_ERROR_NONE;
1416 GList *found_list = NULL;
1417 dnd_alarm_id_s *dnd_id_data = NULL;
1418 alarm_id_t dnd_schedule_start_alarm_id;
1419 alarm_id_t dnd_schedule_end_alarm_id;
1421 ret = _noti_system_setting_set_alarm(dnd_schedule_day,
1422 dnd_start_hour, dnd_start_min,
1423 _dnd_schedule_alarm_cb,
1424 &dnd_schedule_start_alarm_id);
1425 if (ret != NOTIFICATION_ERROR_NONE) {
1426 ErrPrint("_add_alarm fail %d", ret);
1430 if (dnd_end_hour < dnd_start_hour ||
1431 (dnd_end_hour == dnd_start_hour && dnd_end_min <= dnd_start_min)) {
1432 dnd_schedule_day = (dnd_schedule_day << 1);
1433 if (dnd_schedule_day & DND_SCHEDULE_WEEK_FLAG_MAX)
1434 dnd_schedule_day = (dnd_schedule_day & DND_SCHEDULE_WEEK_FLAG_ALL)
1435 | DND_SCHEDULE_WEEK_FLAG_SUNDAY;
1438 ret = _noti_system_setting_set_alarm(dnd_schedule_day,
1439 dnd_end_hour, dnd_end_min,
1440 _dnd_schedule_alarm_cb,
1441 &dnd_schedule_end_alarm_id);
1442 if (ret != NOTIFICATION_ERROR_NONE) {
1443 ErrPrint("_add_alarm fail %d", ret);
1447 if (_dnd_alarm_id_list == NULL) {
1448 dnd_id_data = __malloc_dnd_alarm_id_s(uid, dnd_schedule_start_alarm_id, dnd_schedule_end_alarm_id);
1450 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1451 _dnd_alarm_id_list = g_list_append(_dnd_alarm_id_list, dnd_id_data);
1453 found_list = g_list_find_custom(g_list_first(_dnd_alarm_id_list), GUINT_TO_POINTER(uid),
1454 (GCompareFunc)_dnd_data_compare);
1456 dnd_id_data = g_list_nth_data(found_list, 0);
1457 if (dnd_id_data->dnd_start_id) {
1458 alarmmgr_remove_alarm(dnd_id_data->dnd_start_id);
1459 dnd_id_data->dnd_start_id = dnd_schedule_start_alarm_id;
1461 if (dnd_id_data->dnd_end_id) {
1462 alarmmgr_remove_alarm(dnd_id_data->dnd_end_id);
1463 dnd_id_data->dnd_end_id = dnd_schedule_end_alarm_id;
1466 dnd_id_data = __malloc_dnd_alarm_id_s(uid, dnd_schedule_start_alarm_id, dnd_schedule_end_alarm_id);
1468 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1469 _dnd_alarm_id_list = g_list_append(_dnd_alarm_id_list, dnd_id_data);
1476 static void _delete_alarm(uid_t uid)
1478 GList *found_list = NULL;
1479 dnd_alarm_id_s *dnd_id_data = NULL;
1481 if (_dnd_alarm_id_list == NULL)
1484 _dnd_alarm_id_list = g_list_first(_dnd_alarm_id_list);
1485 found_list = g_list_find_custom(_dnd_alarm_id_list, GUINT_TO_POINTER(uid),
1486 (GCompareFunc)_dnd_data_compare);
1488 if (found_list == NULL)
1491 dnd_id_data = g_list_nth_data(found_list, 0);
1493 if (dnd_id_data->dnd_start_id)
1494 alarmmgr_remove_alarm(dnd_id_data->dnd_start_id);
1495 if (dnd_id_data->dnd_end_id)
1496 alarmmgr_remove_alarm(dnd_id_data->dnd_end_id);
1498 _dnd_alarm_id_list = g_list_remove(g_list_first(_dnd_alarm_id_list), dnd_id_data);
1502 /* update_noti_sys_setting */
1503 int notification_update_noti_sys_setting(GVariant *parameters, GVariant **reply_body, uid_t uid)
1506 int pre_do_not_disturb = 0;
1507 int do_not_disturb = 0;
1508 int visivility_class = 0;
1509 int dnd_schedule_enabled = 0;
1510 int dnd_schedule_day = 0;
1511 int dnd_start_hour = 0;
1512 int dnd_start_min = 0;
1513 int dnd_end_hour = 0;
1514 int dnd_end_min = 0;
1515 int lock_screen_level = 0;
1517 GVariant *body = NULL;
1519 g_variant_get(parameters, "(iiiiiiiiii)",
1522 &dnd_schedule_enabled,
1531 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
1532 if (ret != NOTIFICATION_ERROR_NONE)
1535 DbgPrint("do_not_disturb [%d] visivility_class [%d] set_schedule [%d] lock_screen_level [%d]\n",
1536 do_not_disturb, visivility_class, dnd_schedule_enabled, lock_screen_level);
1538 ret = noti_system_setting_get_do_not_disturb(&pre_do_not_disturb, param_uid);
1539 if (ret != NOTIFICATION_ERROR_NONE) {
1540 ErrPrint("failed to get do not disturb");
1544 ret = notification_setting_db_update_system_setting(do_not_disturb,
1546 dnd_schedule_enabled,
1554 if (ret != NOTIFICATION_ERROR_NONE) {
1555 ErrPrint("failed to setting db update system setting : %d\n", ret);
1559 if (pre_do_not_disturb != do_not_disturb) {
1560 body = g_variant_new("(ii)", do_not_disturb, param_uid);
1561 ret = send_notify(body, "change_dnd_notify", &_monitoring_hash, PROVIDER_NOTI_INTERFACE_NAME, param_uid);
1562 g_variant_unref(body);
1565 *reply_body = g_variant_new("()");
1566 if (*reply_body == NULL) {
1567 ErrPrint("cannot make reply_body");
1568 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1571 if (dnd_schedule_enabled) {
1572 ret = _add_alarm(dnd_schedule_day, dnd_start_hour, dnd_start_min,
1573 dnd_end_hour, dnd_end_min, param_uid);
1574 if (ret != NOTIFICATION_ERROR_NONE)
1575 ErrPrint("failed to add alarm for dnd_schedule");
1577 _delete_alarm(param_uid);
1580 DbgPrint("_update_noti_sys_setting_service done !! %d", ret);
1585 int notification_add_noti_template(GVariant *parameters, GVariant **reply_body, uid_t uid)
1587 notification_h noti;
1589 GVariant *body = NULL;
1590 GVariant *coupled_body = NULL;
1591 char *template_name = NULL;
1594 noti = notification_create(NOTIFICATION_TYPE_NOTI);
1596 g_variant_get(parameters, "(v&s)", &coupled_body, &template_name);
1597 g_variant_get(coupled_body, "(v)", &body);
1599 ret = notification_ipc_make_noti_from_gvariant(noti, body);
1600 g_variant_unref(coupled_body);
1601 g_variant_unref(body);
1602 if (ret != NOTIFICATION_ERROR_NONE) {
1603 ErrPrint("failed to make a notification:%d\n", ret);
1607 ret = notification_noti_check_count_for_template(noti, &count);
1608 if (count > NOTI_TEMPLATE_LIMIT)
1609 return NOTIFICATION_ERROR_MAX_EXCEEDED;
1611 ret = notification_noti_add_template(noti, template_name);
1612 if (ret != NOTIFICATION_ERROR_NONE) {
1613 ErrPrint("failed to add a notification:%d\n", ret);
1617 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
1623 int notification_get_noti_template(GVariant *parameters, GVariant **reply_body, pid_t pid, uid_t uid)
1626 char appid[BUF_LEN] = {0, };
1627 char *template_name = NULL;
1628 notification_h noti;
1630 noti = notification_create(NOTIFICATION_TYPE_NOTI);
1632 g_variant_get(parameters, "(&s)", &template_name);
1634 ret = aul_app_get_appid_bypid_for_uid(pid, appid, sizeof(appid), uid);
1635 if (ret != AUL_R_OK) {
1636 ErrPrint("failed to get appid:%d", ret);
1640 ret = notification_noti_get_package_template(noti, appid, template_name);
1641 if (ret != NOTIFICATION_ERROR_NONE) {
1642 DbgPrint("failed to get template:%d", ret);
1646 *reply_body = notification_ipc_make_gvariant_from_noti(noti, false);
1647 notification_free(noti);
1649 if (*reply_body == NULL) {
1650 ErrPrint("cannot make reply_body");
1651 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1654 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
1657 DbgPrint("_get_noti_template done !!");
1661 int notification_get_noti_package_template(GVariant *parameters, GVariant **reply_body, uid_t uid)
1664 char *pkgname = NULL;
1665 char *template_name = NULL;
1666 notification_h noti;
1668 noti = notification_create(NOTIFICATION_TYPE_NOTI);
1670 g_variant_get(parameters, "(&s&s)", &pkgname, &template_name);
1672 ret = notification_noti_get_package_template(noti, pkgname, template_name);
1673 if (ret != NOTIFICATION_ERROR_NONE) {
1674 DbgPrint("failed to get template:%d", ret);
1678 *reply_body = notification_ipc_make_gvariant_from_noti(noti, false);
1679 notification_free(noti);
1681 if (*reply_body == NULL) {
1682 ErrPrint("cannot make reply_body");
1683 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1686 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
1689 DbgPrint("_get_noti_package_template done !!");
1694 int notification_get_block_state(GVariant *parameters, GVariant **reply_body, uid_t uid)
1699 int allow_to_notify;
1702 GVariant *body = NULL;
1704 g_variant_get(parameters, "(&si)", &appid, ¶m_uid);
1706 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
1707 if (ret != NOTIFICATION_ERROR_NONE) {
1708 ErrPrint("_validate_uid fail ret : %d", ret);
1709 return NOTIFICATION_ERROR_IO_ERROR;
1712 ret = notification_get_dnd_and_allow_to_notify(appid, &dnd, &dnd_except, &allow_to_notify, param_uid);
1713 if (ret != NOTIFICATION_ERROR_NONE) {
1714 ErrPrint("failed to get_dnd_and_allow_to_notify : %d\n", ret);
1718 body = g_variant_new("(iii)", dnd, dnd_except, allow_to_notify);
1719 *reply_body = g_variant_new("(v)", body);
1721 if (*reply_body == NULL) {
1722 ErrPrint("cannot make reply_body");
1723 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1726 DbgPrint("get notification block state done");
1729 int notification_load_dnd_allow_exception(GVariant *parameters, GVariant **reply_body, uid_t uid)
1735 GVariant *body = NULL;
1736 GVariantBuilder *builder;
1737 dnd_allow_exception_h dnd_allow_exception = NULL;
1738 dnd_allow_exception_h temp;
1740 g_variant_get(parameters, "(i)", ¶m_uid);
1742 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
1743 if (ret != NOTIFICATION_ERROR_NONE)
1746 ret = notification_system_setting_load_dnd_allow_exception(&dnd_allow_exception, &count, param_uid);
1747 if (ret != NOTIFICATION_ERROR_NONE) {
1748 ErrPrint("failed to load dnd_allow_exception : %d", ret);
1752 builder = g_variant_builder_new(G_VARIANT_TYPE("a(v)"));
1754 if (dnd_allow_exception) {
1755 for (i = 0; i < count; i++) {
1756 temp = dnd_allow_exception + i;
1757 body = notification_ipc_make_gvariant_from_dnd_allow_exception(temp);
1758 g_variant_builder_add(builder, "(v)", body);
1760 free(dnd_allow_exception);
1763 *reply_body = g_variant_new("(ia(v))", count, builder);
1764 g_variant_builder_unref(builder);
1766 if (*reply_body == NULL) {
1767 ErrPrint("cannot make reply_body");
1768 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1771 DbgPrint("load dnd_allow_exception");
1775 int notification_update_dnd_allow_exception(GVariant *parameters, GVariant **reply_body, uid_t uid)
1782 g_variant_get(parameters, "(iii)", &type, &value, ¶m_uid);
1784 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
1785 if (ret != NOTIFICATION_ERROR_NONE)
1788 ret = notification_system_setting_update_dnd_allow_exception(type,
1791 if (ret != NOTIFICATION_ERROR_NONE) {
1792 ErrPrint("failed to update dnd_allow_exception : %d", ret);
1796 *reply_body = g_variant_new("()");
1797 if (*reply_body == NULL) {
1798 ErrPrint("cannot make reply_body");
1799 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1802 DbgPrint("update dnd_allow_exception");
1806 static event_sender_info_s *__find_sender_info_by_priv_id(int priv_id)
1808 event_sender_info_s *event_info;
1811 if (__event_list == NULL)
1814 __event_list = g_list_first(__event_list);
1815 find_list = g_list_find_custom(__event_list, GINT_TO_POINTER(priv_id),
1816 (GCompareFunc)__priv_id_compare);
1819 event_info = g_list_nth_data(find_list, 0);
1826 int notification_send_noti_event(GVariant *parameters, GVariant **reply_body)
1831 event_sender_info_s *info;
1832 GVariant *coupled_body = NULL;
1833 GVariant *body = NULL;
1834 notification_h noti;
1836 noti = notification_create(NOTIFICATION_TYPE_NOTI);
1839 g_variant_get(parameters, "(vi)", &coupled_body, &event_type);
1840 g_variant_get(coupled_body, "(v)", &body);
1842 ret = notification_ipc_make_noti_from_gvariant(noti, body);
1843 if (ret != NOTIFICATION_ERROR_NONE) {
1844 ErrPrint("failed to make a notification from gvariant");
1848 g_variant_unref(coupled_body);
1849 g_variant_unref(body);
1851 ret = notification_get_id(noti, NULL, &priv_id);
1852 if (ret != NOTIFICATION_ERROR_NONE)
1855 info = __find_sender_info_by_priv_id(priv_id);
1856 if (info == NULL || info->busname == NULL)
1857 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1859 if (!info->watcher_id) {
1860 if (!is_existed_busname(info->busname)) {
1861 __event_list = g_list_remove(g_list_first(__event_list), info);
1862 __free_event_info(info);
1863 return NOTIFICATION_ERROR_IO_ERROR;
1865 info->watcher_id = __insert_sender_watcher_id(info);
1869 ret = send_event_notify_by_busname(parameters, "send_event", info->busname, PROVIDER_NOTI_EVENT_INTERFACE_NAME);
1870 notification_free(noti);
1873 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
1876 *reply_body = g_variant_new("()");
1877 if (*reply_body == NULL) {
1878 ErrPrint("cannot make reply body");
1879 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1882 DbgPrint("notification_send_noti_event done !! %d", ret);
1887 int notification_check_event_receiver(GVariant *parameters, GVariant **reply_body)
1890 bool available = false;
1891 GList *find_list = NULL;
1892 event_sender_info_s *info = NULL;
1894 g_variant_get(parameters, "(i)", &priv_id);
1895 DbgPrint("check event sender - priv_id : %d", priv_id);
1897 __event_list = g_list_first(__event_list);
1898 find_list = g_list_find_custom(__event_list, GINT_TO_POINTER(priv_id),
1899 (GCompareFunc)__priv_id_compare);
1901 info = g_list_nth_data(find_list, 0);
1902 if (!info->watcher_id) {
1903 if (!is_existed_busname(info->busname)) {
1904 __event_list = g_list_remove(g_list_first(__event_list), info);
1905 __free_event_info(info);
1908 info->watcher_id = __insert_sender_watcher_id(info);
1915 *reply_body = g_variant_new("(i)", (int)available);
1916 if (*reply_body == NULL) {
1917 ErrPrint("cannot make gvariant to noti");
1918 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1921 DbgPrint("notification check event receiver - available[%d]", available);
1922 return NOTIFICATION_ERROR_NONE;
1925 int notification_reset_event_receiver(GVariant *parameters, GVariant **reply_body, const char *sender)
1929 g_variant_get(parameters, "(i)", &priv_id);
1930 DbgPrint("reset event sender - priv_id : %d", priv_id);
1932 __add_sender_info(priv_id, sender);
1934 *reply_body = g_variant_new("()");
1935 if (*reply_body == NULL) {
1936 ErrPrint("cannot make gvariant to noti");
1937 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1940 return NOTIFICATION_ERROR_NONE;
1943 HAPI int notification_delete_noti_by_appid(const char *appid, uid_t uid)
1945 GVariant *deleted_noti_list;
1946 GVariantBuilder *builder;
1947 int num_deleted = 0;
1948 int *list_deleted = NULL;
1952 ret = notification_noti_delete_all(NOTIFICATION_TYPE_NONE, appid, &num_deleted, &list_deleted, uid);
1953 if (ret != NOTIFICATION_ERROR_NONE) {
1954 ErrPrint("failed to delete notifications:%d\n", ret);
1955 if (list_deleted != NULL)
1960 if (num_deleted > 0) {
1961 builder = g_variant_builder_new(G_VARIANT_TYPE("a(i)"));
1963 for (i = 0; i < num_deleted; i++)
1964 g_variant_builder_add(builder, "(i)", *(list_deleted + i));
1966 deleted_noti_list = g_variant_new("(a(i)i)", builder, uid);
1967 ret = send_notify(deleted_noti_list, "delete_multiple_notify", &_monitoring_hash, PROVIDER_NOTI_INTERFACE_NAME, uid);
1968 g_variant_builder_unref(builder);
1969 g_variant_unref(deleted_noti_list);
1970 if (ret != NOTIFICATION_ERROR_NONE) {
1971 ErrPrint("failed to send notify:%d\n", ret);
1975 for (i = 0; i < num_deleted; i++) {
1976 ret = __delete_sender_info(*(list_deleted + i));
1977 if (ret != NOTIFICATION_ERROR_NONE)
1987 static void _notification_data_init(void)
1991 char *noti_pkgname = NULL;
1992 notification_h noti = NULL;
1993 notification_list_h noti_list = NULL;
1994 notification_list_h noti_list_head = NULL;
1995 notification_type_e noti_type = NOTIFICATION_TYPE_NONE;
1997 notification_noti_get_grouping_list(NOTIFICATION_TYPE_NONE, -1, ¬i_list, NOTIFICATION_GLOBAL_UID);
1998 noti_list_head = noti_list;
2000 while (noti_list != NULL) {
2001 noti = notification_list_get_data(noti_list);
2003 notification_get_id(noti, NULL, &priv_id);
2004 notification_get_pkgname(noti, ¬i_pkgname);
2005 notification_get_property(noti, &property);
2006 notification_get_type(noti, ¬i_type);
2008 if (noti_type == NOTIFICATION_TYPE_ONGOING
2009 || property & NOTIFICATION_PROP_VOLATILE_DISPLAY) {
2010 notification_noti_delete_by_priv_id(noti_pkgname, priv_id);
2013 noti_list = notification_list_get_next(noti_list);
2016 if (noti_list_head != NULL)
2017 notification_free_list(noti_list_head);
2020 static int _check_dnd_schedule(uid_t uid)
2023 notification_system_setting_h setting = NULL;
2024 bool dnd_schedule_enabled = false;
2025 int dnd_schedule_day = 0;
2026 int dnd_start_hour = 0;
2027 int dnd_start_min = 0;
2028 int dnd_end_hour = 0;
2029 int dnd_end_min = 0;
2031 ret = noti_system_setting_load_system_setting(&setting, uid);
2032 if (ret != NOTIFICATION_ERROR_NONE) {
2033 ErrPrint("noti_system_setting_load_system_setting fail %d", ret);
2037 ret = notification_system_setting_dnd_schedule_get_enabled(setting,
2038 &dnd_schedule_enabled);
2039 if (ret != NOTIFICATION_ERROR_NONE) {
2040 ErrPrint("system_setting_dnd_schedule_get_enabled fail %d", ret);
2044 if (dnd_schedule_enabled) {
2045 ret = notification_system_setting_dnd_schedule_get_day(setting,
2047 if (ret != NOTIFICATION_ERROR_NONE) {
2048 ErrPrint("system_setting_dnd_schedule_get_day fail %d", ret);
2052 ret = notification_system_setting_dnd_schedule_get_start_time(setting,
2053 &dnd_start_hour, &dnd_start_min);
2054 if (ret != NOTIFICATION_ERROR_NONE) {
2055 ErrPrint("system_setting_dnd_schedule_get_start_time fail %d", ret);
2059 ret = notification_system_setting_dnd_schedule_get_end_time(setting,
2060 &dnd_end_hour, &dnd_end_min);
2061 if (ret != NOTIFICATION_ERROR_NONE) {
2062 ErrPrint("system_setting_dnd_schedule_get_end_time fail %d", ret);
2066 _add_alarm(dnd_schedule_day, dnd_start_hour, dnd_start_min, dnd_end_hour, dnd_end_min, uid);
2070 notification_system_setting_free_system_setting(setting);
2077 * Do not try to do any other operation in these functions
2079 HAPI int notification_service_init(void)
2085 _monitoring_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
2086 ret = notification_db_init();
2087 if (ret != NOTIFICATION_ERROR_NONE) {
2088 ErrPrint("notification db init fail %d", ret);
2092 ret = notification_register_dbus_interface();
2093 if (ret != SERVICE_COMMON_ERROR_NONE) {
2094 ErrPrint("notification register dbus fail %d", ret);
2095 return NOTIFICATION_ERROR_IO_ERROR;
2098 _notification_data_init();
2099 notification_setting_refresh_setting_table(tzplatform_getuid(TZ_SYS_DEFAULT_USER));
2100 notification_system_setting_init_system_setting_table(tzplatform_getuid(TZ_SYS_DEFAULT_USER));
2102 ret = notification_system_setting_get_dnd_schedule_enabled_uid(&uids, &count);
2103 if (ret == NOTIFICATION_ERROR_NONE && count > 0) {
2104 for (i = 0; i < count; i++)
2105 _check_dnd_schedule(uids[i]);
2110 DbgPrint("Successfully initiated\n");
2111 return NOTIFICATION_ERROR_NONE;
2114 HAPI int notification_service_fini(void)
2117 DbgPrint("Successfully Finalized\n");
2118 return NOTIFICATION_ERROR_NONE;