d5a3365fbd14608bb44d347432c3000596ec1afd
[platform/core/appfw/data-provider-master.git] / src / notification_service.c
1 /*
2  * Copyright 2016  Samsung Electronics Co., Ltd
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <unistd.h>
19
20 #include <gio/gio.h>
21 #include <gio/gunixfdlist.h>
22
23 #include <dlog.h>
24 #include <sys/smack.h>
25 #include <pkgmgr-info.h>
26 #include <notification.h>
27 #include <alarm.h>
28 #include <aul.h>
29
30 #include "pkgmgr.h"
31 #include "service_common.h"
32 #include "notification_service.h"
33 #include "debug.h"
34
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>
42
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
46 #define BUF_LEN 256
47
48 typedef struct _dnd_alarm_id dnd_alarm_id_s;
49
50 static GHashTable *_monitoring_hash;
51
52 static GList *_dnd_alarm_id_list;
53
54 static char *default_viewer;
55
56 typedef struct _dnd_alarm_id {
57         uid_t uid;
58         alarm_id_t dnd_start_id;
59         alarm_id_t dnd_end_id;
60 } dnd_alarm_id_s;
61
62 static GList *__event_list = NULL;
63
64 typedef struct _event_sender_info {
65         int priv_id;
66         char *busname;
67         guint watcher_id;
68 } event_sender_info_s;
69
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);
72
73 /*!
74  * SERVICE HANDLER
75  */
76
77 /*!
78  * NOTIFICATION SERVICE INITIALIZATION
79  */
80
81 static void _on_name_appeared(GDBusConnection *connection,
82                 const gchar     *name,
83                 const gchar     *name_owner,
84                 gpointer         user_data)
85 {
86         monitoring_info_s *info = (monitoring_info_s *)user_data;
87
88         DBG("name[%s], uid[%d]", name, info->uid);
89 }
90
91 static void _on_name_vanished(GDBusConnection *connection,
92                 const gchar     *name,
93                 gpointer         user_data)
94 {
95         monitoring_info_s *info = (monitoring_info_s *)user_data;
96
97         if (info) {
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);
102
103                 if (info->bus_name)
104                         free(info->bus_name);
105                 free(info);
106         }
107 }
108
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,
113                 gpointer user_data)
114 {
115         /* TODO : sender authority(privilege) check */
116         INFO("notification method_name[%s] sender[%s]", method_name, sender);
117
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);
122
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);
153                 return;
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);
183         }
184
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);
189         } else {
190                 ERR("notification service fail, method_name[%s] err[%d]",
191                         method_name, ret);
192                 g_dbus_method_invocation_return_error(
193                                 invocation,
194                                 NOTIFICATION_ERROR,
195                                 ret,
196                                 "notification service error");
197         }
198 }
199
200 static const GDBusInterfaceVTable _noti_interface_vtable = {
201                 _noti_dbus_method_call_handler,
202                 NULL,
203                 NULL
204 };
205
206 int notification_register_dbus_interface()
207 {
208         static gchar introspection_xml[] =
209                         "  <node>"
210                         "  <interface name='org.tizen.data_provider_noti_service'>"
211                         "        <method name='noti_service_register'>"
212                         "          <arg type='i' name='uid' direction='in'/>"
213                         "        </method>"
214
215                         "        <method name='add_noti'>"
216                         "          <arg type='v' name='noti' direction='in'/>"
217                         "          <arg type='i' name='priv_id' direction='out'/>"
218                         "        </method>"
219
220                         "        <method name='update_noti'>"
221                         "          <arg type='v' name='noti' direction='in'/>"
222                         "          <arg type='i' name='priv_id' direction='out'/>"
223                         "        </method>"
224
225                         "        <method name='refresh_noti'>"
226                         "          <arg type='i' name='uid' direction='in'/>"
227                         "        </method>"
228
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'/>"
234                         "        </method>"
235
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'/>"
241                         "        </method>"
242
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'/>"
248                         "        </method>"
249
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'/>"
255                         "        </method>"
256
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'/>"
263                         "        </method>"
264
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'/>"
272                         "        </method>"
273
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'/>"
281                         "        </method>"
282
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'/>"
287                         "        </method>"
288
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'/>"
298                         "        </method>"
299
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'/>"
311                         "        </method>"
312
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'/>"
317                         "        </method>"
318
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'/>"
323                         "        </method>"
324
325                         "        <method name='load_system_setting'>"
326                         "          <arg type='i' name='uid' direction='in'/>"
327                         "          <arg type='v' name='setting' direction='out'/>"
328                         "        </method>"
329
330                         "        <method name='save_as_template'>"
331                         "          <arg type='v' name='noti' direction='in'/>"
332                         "          <arg type='s' name='name' direction='in'/>"
333                         "        </method>"
334
335                         "        <method name='create_from_template'>"
336                         "          <arg type='s' name='name' direction='in'/>"
337                         "          <arg type='v' name='noti' direction='out'/>"
338                         "        </method>"
339
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'/>"
344                         "        </method>"
345
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'/>"
350                         "        </method>"
351
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'/>"
356                         "        </method>"
357
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'/>"
362                         "        </method>"
363
364                         "        <method name='send_noti_event'>"
365                         "          <arg type='v' name='noti' direction='in'/>"
366                         "          <arg type='i' name='event_type' direction='in'/>"
367                         "        </method>"
368
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'/>"
372                         "        </method>"
373
374                         "        <method name='check_event_receiver'>"
375                         "          <arg type='i' name='priv_id' direction='in'/>"
376                         "          <arg type='i' name='available' direction='out'/>"
377                         "        </method>"
378
379                         "        <method name='reset_event_handler'>"
380                         "          <arg type='i' name='priv_id' direction='in'/>"
381                         "        </method>"
382
383                         "        <method name='post_toast'>"
384                         "        </method>"
385                         "  </interface>"
386                         "  </node>";
387
388         return service_common_register_dbus_interface(introspection_xml, _noti_interface_vtable);
389 }
390
391 static void __free_event_info(gpointer data)
392 {
393         event_sender_info_s *info = (event_sender_info_s *)data;
394
395         if (info) {
396                 if (info->busname)
397                         free(info->busname);
398                 free(info);
399         }
400 }
401
402 static gint __priv_id_compare(gconstpointer a, gconstpointer b)
403 {
404         event_sender_info_s *info = NULL;
405
406         if (!a)
407                 return -1;
408
409         info = (event_sender_info_s *)a;
410
411         if (info->priv_id == GPOINTER_TO_INT(b))
412                 return 0;
413
414         return 1;
415 }
416
417 static int __check_limit(notification_h noti, uid_t uid)
418 {
419         int ret;
420         int priv_id = NOTIFICATION_PRIV_ID_NONE;
421         char *app_id = NULL;
422         GList *list = NULL;
423         GList *iter_list = NULL;
424
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) {
429                         iter_list = list;
430                         while (iter_list) {
431                                 priv_id = GPOINTER_TO_INT(iter_list->data);
432
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]",
436                                                 priv_id, ret);
437
438                                 iter_list = g_list_next(iter_list);
439                         }
440                 }
441         }
442
443         if (list)
444                 g_list_free(list);
445
446         return ret;
447 }
448
449 /* add noti */
450 static int _add_noti(GVariant **reply_body, notification_h noti, uid_t uid)
451 {
452         int ret;
453         int priv_id = NOTIFICATION_PRIV_ID_NONE;
454         GVariant *body = NULL;
455
456         print_noti(noti);
457         ret = notification_noti_insert(noti);
458         if (ret != NOTIFICATION_ERROR_NONE) {
459                 ERR("Failed to update a notification [%d]", ret);
460                 return ret;
461         }
462
463         ret = notification_get_id(noti, NULL, &priv_id);
464         if (ret != NOTIFICATION_ERROR_NONE) {
465                 ERR("Failed to gets priv_id [%d]", ret);
466                 return ret;
467         }
468
469         notification_set_private_sharing(noti, uid);
470
471         body = notification_ipc_make_gvariant_from_noti(noti, true);
472         if (body == NULL) {
473                 ERR("Failed to make gvariant to noti");
474                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
475         }
476
477         ret = send_notify(body, "add_noti_notify", &_monitoring_hash,
478                         PROVIDER_NOTI_INTERFACE_NAME, uid);
479         g_variant_unref(body);
480
481         if (ret != NOTIFICATION_ERROR_NONE) {
482                 ERR("Failed to send notify [%d]", ret);
483                 return ret;
484         }
485
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;
492                 }
493         }
494
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;
499         }
500
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;
505         }
506
507         DBG("Success to add notification");
508         return ret;
509 }
510
511 static int _validate_and_set_noti_with_uid(uid_t uid, notification_h noti, uid_t *noti_uid)
512 {
513         int ret = NOTIFICATION_ERROR_NONE;
514
515         ret = notification_get_uid(noti, noti_uid);
516         if (ret != NOTIFICATION_ERROR_NONE) {
517                 ERR("Failed to get uid [%d]", ret);
518                 return ret;
519         }
520
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;
528
529                         DBG("system defualt noti post change noti_uid to default");
530                         /*
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)
533                         */
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);
538                                 return ret;
539                         }
540                         DBG("changed noti_uid[%d]", *noti_uid);
541                 }
542         }
543         return ret;
544 }
545
546 static int _validate_and_set_param_uid_with_uid(uid_t uid, uid_t *param_uid)
547 {
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;
555                         /*
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)
558                         */
559                         *param_uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
560                 }
561         }
562         return NOTIFICATION_ERROR_NONE;
563 }
564
565 static void __sender_name_appeared_cb(GDBusConnection *connection,
566                                       const gchar *name,
567                                       const gchar *name_owner,
568                                       gpointer user_data)
569 {
570         DBG("name[%s], name_owner[%s]", name, name_owner);
571 }
572
573 static void __sender_name_vanished_cb(GDBusConnection *connection,
574                                       const gchar *name,
575                                       gpointer user_data)
576 {
577         GList *delete_list = NULL;
578         event_sender_info_s *info;
579
580         if (!user_data)
581                 return;
582
583         info = (event_sender_info_s *)user_data;
584
585         DBG("name[%s], priv_id[%d], watcher_id[%d]",
586                  name, info->priv_id, info->watcher_id);
587
588         delete_list = g_list_find_custom(__event_list, GINT_TO_POINTER(info->priv_id),
589                                          (GCompareFunc)__priv_id_compare);
590         if (delete_list) {
591                 __event_list = g_list_remove(__event_list, info);
592                 g_bus_unwatch_name(info->watcher_id);
593                 __free_event_info(info);
594         }
595 }
596
597 static guint __insert_sender_watcher_id(event_sender_info_s *sender_info)
598 {
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,
605                                       sender_info,
606                                       NULL);
607         if (!watcher_id) {
608                 ERR("Failed to watch sender name");
609                 return 0;
610         }
611
612         DBG("Watch on busname[%s] watcher_id[%d]", sender_info->busname, watcher_id);
613         return watcher_id;
614 }
615
616 static void __add_sender_info(int priv_id, const char *busname)
617 {
618         GList *find_list = NULL;
619         event_sender_info_s *sender_info;
620         event_sender_info_s *tmp_info = NULL;
621
622         if (busname == NULL)
623                 return;
624
625         sender_info = (event_sender_info_s *)malloc(sizeof(event_sender_info_s));
626         if (sender_info == NULL) {
627                 ERR("malloc failed");
628                 return;
629         }
630
631         sender_info->priv_id = priv_id;
632         sender_info->busname = strdup(busname);
633
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);
637         } else {
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);
644                 } else {
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);
652                                 }
653                         } else {
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);
658                         }
659                         __free_event_info(sender_info);
660                 }
661         }
662 }
663
664 int notification_add_noti(GVariant *parameters, GVariant **reply_body, const char *sender, uid_t uid)
665 {
666         int ret;
667         int priv_id;
668         bool event_flag;
669         notification_h noti;
670         GVariant *body = NULL;
671         uid_t noti_uid = 0;
672
673         noti = notification_create(NOTIFICATION_TYPE_NOTI);
674         if (noti != NULL) {
675                 g_variant_get(parameters, "(v)", &body);
676                 ret = notification_ipc_make_noti_from_gvariant(noti, body);
677                 g_variant_unref(body);
678
679                 ret = _validate_and_set_noti_with_uid(uid, noti, &noti_uid);
680                 if (ret != NOTIFICATION_ERROR_NONE)
681                         goto out;
682
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);
688
689                 if (ret != NOTIFICATION_ERROR_NONE)
690                         goto out;
691
692                 ret = notification_get_event_flag(noti, &event_flag);
693                 if (ret != NOTIFICATION_ERROR_NONE)
694                         goto out;
695
696                 if (event_flag == true) {
697                         ret = notification_get_id(noti, NULL, &priv_id);
698                         if (ret != NOTIFICATION_ERROR_NONE)
699                                 goto out;
700
701                         __add_sender_info(priv_id, sender);
702                 }
703         } else {
704                 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
705         }
706
707 out:
708         notification_free(noti);
709
710         return ret;
711 }
712
713 /* update noti */
714 static int _update_noti(GVariant **reply_body, notification_h noti, uid_t uid)
715 {
716         int ret;
717         GVariant *body = NULL;
718         int priv_id = NOTIFICATION_PRIV_ID_NONE;
719         notification_h source_noti;
720
721         print_noti(noti);
722
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);
727
728                 notification_calibrate_private_sharing(noti, source_noti);
729                 notification_free(source_noti);
730         }
731
732         ret = notification_noti_update(noti);
733         if (ret != NOTIFICATION_ERROR_NONE) {
734                 ERR("Failed to update a notification [%d]", ret);
735                 return ret;
736         }
737
738         ret = notification_get_id(noti, NULL, &priv_id);
739         if (ret != NOTIFICATION_ERROR_NONE) {
740                 ERR("Failed to gets priv_id [%d]", ret);
741                 return ret;
742         }
743
744         notification_set_private_sharing(noti, uid);
745
746         body = notification_ipc_make_gvariant_from_noti(noti, true);
747         if (body == NULL) {
748                 ERR("Failed to make gvariant to noti");
749                 return NOTIFICATION_ERROR_IO_ERROR;
750         }
751
752         ret = send_notify(body, "update_noti_notify", &_monitoring_hash, PROVIDER_NOTI_INTERFACE_NAME, uid);
753         g_variant_unref(body);
754
755         if (ret != NOTIFICATION_ERROR_NONE) {
756                 ERR("Failed to send notify [%d]", ret);
757                 return ret;
758         }
759
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;
766                 }
767         }
768
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;
773         }
774
775         DBG("Success to update noti");
776         return ret;
777 }
778
779 int notification_update_noti(GVariant *parameters, GVariant **reply_body, uid_t uid)
780 {
781         notification_h noti;
782         int ret;
783         GVariant *body = NULL;
784         uid_t noti_uid;
785
786         noti = notification_create(NOTIFICATION_TYPE_NOTI);
787         if (noti != NULL) {
788                 g_variant_get(parameters, "(v)", &body);
789                 ret = notification_ipc_make_noti_from_gvariant(noti, body);
790                 g_variant_unref(body);
791
792                 ret = _validate_and_set_noti_with_uid(uid, noti, &noti_uid);
793                 if (ret != NOTIFICATION_ERROR_NONE)
794                         goto out;
795
796                 ret = _update_noti(reply_body, noti, noti_uid);
797
798         } else {
799                 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
800         }
801
802 out:
803         notification_free(noti);
804         return ret;
805 }
806
807 /* load_noti_by_tag */
808 int notification_load_noti_by_tag(GVariant *parameters, GVariant **reply_body, uid_t uid)
809 {
810         int ret;
811         char *tag = NULL;
812         char *app_id = NULL;
813         notification_h noti;
814         uid_t param_uid;
815
816         noti = notification_create(NOTIFICATION_TYPE_NOTI);
817         if (noti != NULL) {
818                 g_variant_get(parameters, "(&s&si)", &app_id, &tag, &param_uid);
819                 ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
820                 if (ret != NOTIFICATION_ERROR_NONE)
821                         goto out;
822
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);
827                         goto out;
828                 }
829
830                 print_noti(noti);
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;
835                 }
836         } else {
837                 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
838         }
839
840 out:
841         if (noti)
842                 notification_free(noti);
843
844         return ret;
845 }
846
847 /* load_noti_by_priv_id */
848 int notification_load_noti_by_priv_id(GVariant *parameters, GVariant **reply_body, uid_t uid)
849 {
850         int ret;
851         int priv_id = NOTIFICATION_PRIV_ID_NONE;
852         char *app_id = NULL;
853         notification_h noti;
854         uid_t param_uid;
855
856         noti = notification_create(NOTIFICATION_TYPE_NOTI);
857         if (noti != NULL) {
858                 g_variant_get(parameters, "(&sii)", &app_id, &priv_id, &param_uid);
859                 ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
860                 if (ret != NOTIFICATION_ERROR_NONE)
861                         goto out;
862
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)
866                         goto out;
867
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;
872                 }
873         } else {
874                 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
875         }
876
877 out:
878         if (noti)
879                 notification_free(noti);
880
881         return ret;
882 }
883
884 static int __get_socket_from_invocation(GDBusMethodInvocation *invocation, int *fd)
885 {
886         int ret_fd = 0;
887         GError *g_err = NULL;
888         GDBusMessage *msg = NULL;
889         GUnixFDList *fd_list = NULL;
890
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;
896         }
897
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);
901                 g_error_free(g_err);
902                 return NOTIFICATION_ERROR_IO_ERROR;
903         }
904
905         *fd = ret_fd;
906
907         INFO("sender fd : %d", ret_fd);
908         return NOTIFICATION_ERROR_NONE;
909 }
910
911 static int __send_list_to_socket(int fd, notification_list_h get_list, uid_t uid)
912 {
913         int ret;
914         notification_h noti;
915         notification_list_h list_iter;
916         GVariant *body = NULL;
917
918         list_iter = notification_list_get_head(get_list);
919         do {
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);
923                 if (body == NULL) {
924                         ERR("Failed to make gvariant to noti");
925                         ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
926                         break;
927                 }
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);
934                         return ret;
935                 }
936                 list_iter = notification_list_get_next(list_iter);
937                 g_variant_unref(body);
938         } while (list_iter != NULL);
939
940         return ret;
941 }
942
943 /* load_noti_grouping_list */
944 void notification_load_grouping_list(GDBusMethodInvocation *invocation, GVariant *parameters, uid_t uid)
945 {
946         int ret;
947         notification_type_e type;
948         notification_list_h get_list = NULL;
949         GVariant *reply_body = NULL;
950         int fd = 0;
951         int count = 0;
952         int count_per_page;
953         int list_count = 0;
954         uid_t param_uid;
955
956         g_variant_get(parameters, "(iiii)", &type, &count, &count_per_page, &param_uid);
957         ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
958         if (ret != NOTIFICATION_ERROR_NONE)
959                 goto err;
960
961         ret = __get_socket_from_invocation(invocation, &fd);
962         if (ret != NOTIFICATION_ERROR_NONE) {
963                 ERR("get_fd_from_invocation [%d]", ret);
964                 goto err;
965         }
966
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);
971                 goto err;
972         }
973
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;
978                 goto err;
979         }
980
981         g_dbus_method_invocation_return_value(invocation, reply_body);
982         if (get_list) {
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);
987         }
988
989         close(fd);
990         return;
991
992 err:
993         if (fd)
994                 close(fd);
995         if (get_list)
996                 notification_free_list(get_list);
997
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");
1001 }
1002
1003 /* get_setting_array */
1004 int notification_get_setting_array(GVariant *parameters, GVariant **reply_body, uid_t uid)
1005 {
1006         int ret;
1007         GVariant *body;
1008         GVariantBuilder *builder;
1009         int count = 0;
1010         int i;
1011         notification_setting_h setting_array = NULL;
1012         notification_setting_h temp;
1013         uid_t param_uid;
1014
1015         g_variant_get(parameters, "(i)", &param_uid);
1016         ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
1017         if (ret != NOTIFICATION_ERROR_NONE)
1018                 return ret;
1019
1020         ret = noti_setting_get_setting_array(&setting_array, &count, param_uid);
1021         if (ret != NOTIFICATION_ERROR_NONE)
1022                 return ret;
1023
1024         builder = g_variant_builder_new(G_VARIANT_TYPE("a(v)"));
1025
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);
1031
1032                         if (temp->package_name)
1033                                 free(temp->package_name);
1034                         if (temp->app_id)
1035                                 free(temp->app_id);
1036                 }
1037                 free(setting_array);
1038         }
1039         *reply_body = g_variant_new("(ia(v))", count, builder);
1040         g_variant_builder_unref(builder);
1041
1042         if (*reply_body == NULL) {
1043                 ERR("Failed to make reply_body");
1044                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1045         }
1046
1047         INFO("count[%d]", count);
1048         return ret;
1049 }
1050
1051 static pkgmgrinfo_pkginfo_h __create_pkginfo_by_app_id(const char *app_id, uid_t uid)
1052 {
1053         int ret_pkgmgr;
1054         char *pkgname = NULL;
1055         pkgmgrinfo_appinfo_h app_handle = NULL;
1056         pkgmgrinfo_pkginfo_h pkg_handle = NULL;
1057
1058         if (app_id == NULL)
1059                 return NULL;
1060
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);
1065                 goto out;
1066         }
1067
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);
1072                 goto out;
1073         }
1074
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);
1079                 goto out;
1080         }
1081
1082 out:
1083         if (app_handle)
1084                 pkgmgrinfo_appinfo_destroy_appinfo(app_handle);
1085
1086         return pkg_handle;
1087 }
1088
1089 #define NOTIFICATION_PRIVILEGE "http://tizen.org/privilege/notification"
1090 static int __check_privilege_cb(const char *privilege_name, void *is_existed)
1091 {
1092         if (!g_strcmp0(privilege_name, NOTIFICATION_PRIVILEGE)) {
1093                 *(int *)is_existed = 1;
1094                 return -1;
1095         }
1096         return 0;
1097 }
1098
1099 static int __has_notification_privilege(pkgmgrinfo_pkginfo_h handle)
1100 {
1101         int ret_pkgmgr;
1102         int is_existed = 0;
1103
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]",
1107                         ret_pkgmgr);
1108                 return NOTIFICATION_ERROR_IO_ERROR;
1109         }
1110
1111         if (is_existed == 0)
1112                 return NOTIFICATION_ERROR_NOT_EXIST_ID;
1113
1114         return NOTIFICATION_ERROR_NONE;
1115 }
1116
1117 static int __init_setting_handle_by_app_id(const char *app_id,
1118                                 notification_setting_h *setting, uid_t uid)
1119 {
1120         int ret = NOTIFICATION_ERROR_NONE;
1121         int ret_pkgmgr;
1122         char *pkgname = NULL;
1123         notification_setting_h ret_setting = NULL;
1124         pkgmgrinfo_pkginfo_h handle = NULL;
1125
1126         if (app_id == NULL || setting == NULL)
1127                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1128
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;
1133                 goto out;
1134         }
1135
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);
1140                 else
1141                         ERR("Failed to check privilege [%d]", ret);
1142                 goto out;
1143         }
1144
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;
1149                 goto out;
1150         }
1151
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;
1156                 goto out;
1157         }
1158
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;
1167
1168         *setting = ret_setting;
1169
1170 out:
1171         if (handle)
1172                 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1173
1174         return ret;
1175 }
1176
1177 /* get_setting_by_app_id */
1178 int notification_get_setting_by_app_id(GVariant *parameters, GVariant **reply_body, uid_t uid)
1179 {
1180         int ret;
1181         GVariant *body;
1182         char *app_id = NULL;
1183         notification_setting_h setting = NULL;
1184         uid_t param_uid;
1185
1186         g_variant_get(parameters, "(&si)", &app_id, &param_uid);
1187         ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
1188         if (ret != NOTIFICATION_ERROR_NONE)
1189                 return ret;
1190
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)
1195                         return ret;
1196         } else if (ret != NOTIFICATION_ERROR_NONE) {
1197                 return ret;
1198         }
1199
1200         body = notification_ipc_make_gvariant_from_setting(setting);
1201         notification_setting_free_notification(setting);
1202         if (body == NULL) {
1203                 ERR("Failed to make gvariant");
1204                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1205         }
1206
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;
1211         }
1212
1213         INFO("app_id[%s] uid[%d]", app_id, param_uid);
1214         return ret;
1215 }
1216
1217 /* load_system_setting */
1218 int notification_load_system_setting(GVariant *parameters, GVariant **reply_body, uid_t uid)
1219 {
1220         int ret;
1221         GVariant *body;
1222         notification_system_setting_h setting = NULL;
1223         uid_t param_uid;
1224
1225         g_variant_get(parameters, "(i)", &param_uid);
1226         ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
1227         if (ret != NOTIFICATION_ERROR_NONE)
1228                 return ret;
1229
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);
1234
1235                 if (body == NULL) {
1236                         ERR("Failed to make gvariant");
1237                         return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1238                 }
1239         } else {
1240                 return ret;
1241         }
1242
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;
1247         }
1248
1249         return ret;
1250 }
1251
1252 /* load_noti_detail_list */
1253 int notification_load_detail_list(GVariant *parameters, GVariant **reply_body, uid_t uid)
1254 {
1255         int ret;
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;
1264         int count = 0;
1265         uid_t param_uid;
1266
1267         g_variant_get(parameters, "(&siiii)", &app_id, &group_id, &priv_id, &count, &param_uid);
1268         ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
1269         if (ret != NOTIFICATION_ERROR_NONE)
1270                 return ret;
1271
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)
1275                 return ret;
1276
1277         builder = g_variant_builder_new(G_VARIANT_TYPE("a(v)"));
1278
1279         if (get_list) {
1280                 list_iter = notification_list_get_head(get_list);
1281                 do {
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);
1285                         if (body) {
1286                                 g_variant_builder_add(builder, "(v)", body);
1287                                 list_iter = notification_list_get_next(list_iter);
1288                         }
1289                 } while (list_iter != NULL);
1290                 notification_free_list(get_list);
1291         }
1292
1293         *reply_body = g_variant_new("(a(v))", builder);
1294         g_variant_builder_unref(builder);
1295
1296         if (*reply_body == NULL) {
1297                 ERR("Failed to make reply_body");
1298                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1299         }
1300
1301         DBG("app_id[%s], group_id[%d], priv_id[%d], count[%d]",
1302                         app_id, group_id, priv_id, count);
1303         return ret;
1304 }
1305
1306 /* refresh_noti */
1307 int notification_refresh_noti(GVariant *parameters, GVariant **reply_body, uid_t uid)
1308 {
1309         int ret;
1310         uid_t param_uid;
1311
1312         g_variant_get(parameters, "(i)", &param_uid);
1313         ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
1314         if (ret != NOTIFICATION_ERROR_NONE)
1315                 return ret;
1316
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);
1320                 return ret;
1321         }
1322
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;
1327         }
1328
1329         return ret;
1330 }
1331
1332 static int __delete_sender_info(int priv_id)
1333 {
1334         int ret = NOTIFICATION_ERROR_NONE;
1335         event_sender_info_s *info;
1336         GList *delete_list = NULL;
1337         GVariant *body = NULL;
1338
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);
1350                                 return ret;
1351                         }
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;
1357                 }
1358         }
1359
1360         return ret;
1361 }
1362
1363 static int _delete_noti(const char *app_id, int priv_id, uid_t uid)
1364 {
1365         int ret;
1366         int num_changes = 0;
1367         GVariant *body = NULL;
1368
1369         if (app_id == NULL)
1370                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1371
1372         ret = notification_noti_delete_by_priv_id_get_changes(app_id, priv_id,
1373                                 &num_changes, uid);
1374         if (ret != NOTIFICATION_ERROR_NONE) {
1375                 ERR("Failed to delete noti, err[%d] num_changes[%d]",
1376                         ret, num_changes);
1377                 return ret;
1378         }
1379
1380         if (num_changes > 0) {
1381                 body = g_variant_new("(iii)", 1, priv_id, uid);
1382                 if (body == NULL) {
1383                         ERR("Failed to make gvariant to noti");
1384                         return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1385                 }
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);
1391                         return ret;
1392                 }
1393
1394                 notification_remove_private_sharing(app_id, priv_id, uid);
1395
1396                 ret = __delete_sender_info(priv_id);
1397                 if (ret != NOTIFICATION_ERROR_NONE)
1398                         return ret;
1399
1400                 if (default_viewer != NULL) {
1401                         ret = notification_launch_default_viewer(default_viewer,
1402                                         NOTIFICATION_PRIV_ID_NONE,
1403                                         NOTIFICATION_OP_DELETE,
1404                                         uid);
1405                         if (ret != NOTIFICATION_ERROR_NONE) {
1406                                 ERR("Failed to launch default viewer [%d]", ret);
1407                                 ret = NOTIFICATION_ERROR_NONE;
1408                         }
1409                 }
1410         }
1411
1412         DBG("app_id[%s] priv_id[%d] num_changes[%d]", app_id, priv_id, num_changes);
1413
1414         return ret;
1415 }
1416
1417 /* del_noti_single */
1418 int notification_del_noti_single(GVariant *parameters, GVariant **reply_body, uid_t uid)
1419 {
1420         int ret = NOTIFICATION_ERROR_NONE;
1421         int priv_id = NOTIFICATION_PRIV_ID_NONE;
1422         char *app_id = NULL;
1423         uid_t param_uid;
1424
1425         g_variant_get(parameters, "(&sii)", &app_id, &priv_id, &param_uid);
1426         ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
1427         if (ret != NOTIFICATION_ERROR_NONE)
1428                 return ret;
1429
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);
1433                 return ret;
1434         }
1435
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;
1440         }
1441
1442         return ret;
1443 }
1444
1445 /* del_noti_multiple */
1446 int notification_del_noti_multiple(GVariant *parameters, GVariant **reply_body, uid_t uid)
1447 {
1448         int ret;
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;
1455         int i;
1456         uid_t param_uid;
1457
1458         g_variant_get(parameters, "(&sii)", &app_id, &type, &param_uid);
1459         DBG("app_id [%s] type [%d]", app_id, type);
1460         ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
1461         if (ret != NOTIFICATION_ERROR_NONE)
1462                 return ret;
1463
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)
1468                         free(list_deleted);
1469                 return ret;
1470         }
1471
1472         if (num_deleted > 0) {
1473                 builder = g_variant_builder_new(G_VARIANT_TYPE("a(i)"));
1474
1475                 for (i = 0; i < num_deleted; i++)
1476                         g_variant_builder_add(builder, "(i)", *(list_deleted + i));
1477
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);
1484                         return ret;
1485                 }
1486
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)
1491                                 return ret;
1492                 }
1493
1494                 free(list_deleted);
1495
1496                 if (default_viewer != NULL) {
1497                         ret = notification_launch_default_viewer(default_viewer,
1498                                 NOTIFICATION_PRIV_ID_NONE,
1499                                 NOTIFICATION_OP_DELETE_ALL,
1500                                 param_uid);
1501                         if (ret != NOTIFICATION_ERROR_NONE) {
1502                                 ERR("Failed to launch default viewer [%d]", ret);
1503                                 ret = NOTIFICATION_ERROR_NONE;
1504                         }
1505                 }
1506         }
1507
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;
1512         }
1513
1514         INFO("type[%d] app_id[%s] num_deleted[%d]", type, app_id, num_deleted);
1515         return ret;
1516 }
1517
1518 /* get_noti_count */
1519 int notification_get_noti_count(GVariant *parameters, GVariant **reply_body, uid_t uid)
1520 {
1521         int ret;
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;
1526         int noti_count = 0;
1527         uid_t param_uid;
1528
1529         g_variant_get(parameters, "(i&siii)", &type, &app_id, &group_id, &priv_id, &param_uid);
1530         ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
1531         if (ret != NOTIFICATION_ERROR_NONE) {
1532                 ERR("Failed to validate uid [%d]", ret);
1533                 return NOTIFICATION_ERROR_IO_ERROR;
1534         }
1535
1536         ret = notification_noti_get_count(type, app_id, group_id, priv_id,
1537                         &noti_count, param_uid);
1538         if (ret != NOTIFICATION_ERROR_NONE) {
1539                 ERR("Failed to get count [%d]", ret);
1540                 return ret;
1541         }
1542
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;
1547         }
1548
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);
1551         return ret;
1552 }
1553
1554 /* get_noti_count */
1555 int notification_get_noti_all_count(GVariant *parameters, GVariant **reply_body, uid_t uid)
1556 {
1557         int ret;
1558         int noti_count = 0;
1559         int type;
1560         uid_t param_uid;
1561
1562         g_variant_get(parameters, "(ii)", &type, &param_uid);
1563         ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
1564         if (ret != NOTIFICATION_ERROR_NONE) {
1565                 ERR("Failed to validate uid [%d]", ret);
1566                 return NOTIFICATION_ERROR_IO_ERROR;
1567         }
1568
1569         ret = notification_noti_get_all_count(type, &noti_count, param_uid);
1570         if (ret != NOTIFICATION_ERROR_NONE) {
1571                 ERR("Failed to get count [%d]", ret);
1572                 return ret;
1573         }
1574
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;
1579         }
1580
1581         INFO("The numbers of all notification count is [%d]", noti_count);
1582         return ret;
1583 }
1584
1585 /* update_noti_setting */
1586 int notification_update_noti_setting(GVariant *parameters, GVariant **reply_body, uid_t uid)
1587 {
1588         int ret;
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;
1596         uid_t param_uid;
1597
1598         g_variant_get(parameters, "(&s&siiiiii)",
1599                         &pkgname,
1600                         &app_id,
1601                         &allow_to_notify,
1602                         &do_not_disturb_except,
1603                         &visivility_class,
1604                         &pop_up_notification,
1605                         &lock_screen_content_level,
1606                         &param_uid);
1607
1608         ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
1609         if (ret != NOTIFICATION_ERROR_NONE)
1610                 return ret;
1611
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);
1616                 return ret;
1617         }
1618
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;
1623         }
1624
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);
1627         return ret;
1628 }
1629
1630 static int _dnd_schedule_alarm_cb(alarm_id_t alarm_id, void *data)
1631 {
1632         int ret;
1633         int do_not_disturb;
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;
1638         uid_t uid;
1639
1640         dnd_found_list = g_list_first(_dnd_alarm_id_list);
1641
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;
1645
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");
1649                         return ret;
1650                 }
1651
1652                 if (alarm_id == dnd_id_data->dnd_start_id && !do_not_disturb) {
1653                         do_not_disturb = 1;
1654                         dnd_id_found = true;
1655                         break;
1656                 } else if (alarm_id == dnd_id_data->dnd_end_id && do_not_disturb) {
1657                         do_not_disturb = 0;
1658                         dnd_id_found = true;
1659                         break;
1660                 }
1661         }
1662
1663         if (dnd_id_found == false) {
1664                 ERR("notification wrong alarm [%d]", alarm_id);
1665                 return -1;
1666         }
1667
1668         notification_setting_db_update_do_not_disturb(do_not_disturb, uid);
1669
1670         body = g_variant_new("(ii)", do_not_disturb, uid);
1671
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);
1676                 return ret;
1677         }
1678
1679         INFO("dnd[%d], uid[%d]", do_not_disturb, uid);
1680         return ret;
1681 }
1682
1683 static int _get_current_time(struct tm *date)
1684 {
1685         time_t now;
1686
1687         if (date == NULL) {
1688                 ERR("Invalid tm data");
1689                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1690         }
1691
1692         time(&now);
1693         localtime_r(&now, date);
1694
1695         return NOTIFICATION_ERROR_NONE;
1696 }
1697
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)
1699 {
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;
1705
1706         err = alarmmgr_init("notification");
1707         if (err < 0) {
1708                 ERR("alarmmgr_init failed [%d]", err);
1709                 goto out;
1710         }
1711
1712         err = alarmmgr_set_cb(handler, NULL);
1713         if (err < 0) {
1714                 ERR("alarmmgr_set_cb failed [%d]", err);
1715                 goto out;
1716         }
1717
1718         err = _get_current_time(&struct_time);
1719         if (err != NOTIFICATION_ERROR_NONE) {
1720                 ERR("get_current_time failed [%d]", err);
1721                 goto out;
1722         }
1723
1724         alarm_info = alarmmgr_create_alarm();
1725         if (alarm_info == NULL) {
1726                 ERR("alarmmgr_create_alarm failed");
1727                 goto out;
1728         }
1729
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;
1735         alarm_time.sec = 0;
1736
1737         err = alarmmgr_set_time(alarm_info, alarm_time);
1738         if (err != ALARMMGR_RESULT_SUCCESS) {
1739                 ERR("alarmmgr_set_time failed [%d]", err);
1740                 goto out;
1741         }
1742
1743         if (week_flag) {
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);
1747                         goto out;
1748                 }
1749         }
1750
1751         err = alarmmgr_set_type(alarm_info, ALARM_TYPE_VOLATILE);
1752         if (err != ALARMMGR_RESULT_SUCCESS) {
1753                 ERR("alarmmgr_set_type failed [%d]", err);
1754                 goto out;
1755         }
1756
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);
1760                 goto out;
1761         }
1762
1763         *dnd_schedule_alarm_id = alarm_id;
1764
1765 out:
1766         if (alarm_info)
1767                 alarmmgr_free_alarm(alarm_info);
1768
1769         DBG("alarm_id [%d]", *dnd_schedule_alarm_id);
1770         return err;
1771 }
1772
1773 static gint _dnd_data_compare(gconstpointer a, gconstpointer b)
1774 {
1775         const dnd_alarm_id_s *data = NULL;
1776
1777         if (!a)
1778                 return -1;
1779         data = a;
1780         if (data->uid == GPOINTER_TO_UINT(b))
1781                 return 0;
1782
1783         return 1;
1784 }
1785
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)
1787 {
1788         dnd_alarm_id_s *dnd_id_data = NULL;
1789
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");
1793                 return NULL;
1794         }
1795
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;
1799
1800         return dnd_id_data;
1801 }
1802
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)
1804 {
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;
1810
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);
1817                 return ret;
1818         }
1819
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;
1826         }
1827
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);
1834                 return ret;
1835         }
1836
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);
1839                 if (!dnd_id_data)
1840                         return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1841                 _dnd_alarm_id_list = g_list_append(_dnd_alarm_id_list, dnd_id_data);
1842         } else {
1843                 found_list = g_list_find_custom(g_list_first(_dnd_alarm_id_list), GUINT_TO_POINTER(uid),
1844                                                 (GCompareFunc)_dnd_data_compare);
1845                 if (found_list) {
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;
1850                         }
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;
1854                         }
1855                 } else {
1856                         dnd_id_data = __malloc_dnd_alarm_id_s(uid, dnd_schedule_start_alarm_id, dnd_schedule_end_alarm_id);
1857                         if (!dnd_id_data)
1858                                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1859                         _dnd_alarm_id_list = g_list_append(_dnd_alarm_id_list, dnd_id_data);
1860                 }
1861         }
1862
1863         return ret;
1864 }
1865
1866 static void _delete_alarm(uid_t uid)
1867 {
1868         GList *found_list = NULL;
1869         dnd_alarm_id_s *dnd_id_data = NULL;
1870
1871         if (_dnd_alarm_id_list == NULL)
1872                 return;
1873
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);
1877
1878         if (found_list == NULL)
1879                 return;
1880
1881         dnd_id_data = g_list_nth_data(found_list, 0);
1882
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);
1887
1888         _dnd_alarm_id_list = g_list_remove(g_list_first(_dnd_alarm_id_list), dnd_id_data);
1889         free(dnd_id_data);
1890 }
1891
1892 /* update_noti_sys_setting */
1893 int notification_update_noti_sys_setting(GVariant *parameters, GVariant **reply_body, uid_t uid)
1894 {
1895         int ret;
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;
1906         uid_t param_uid;
1907         GVariant *body = NULL;
1908
1909         g_variant_get(parameters, "(iiiiiiiiii)",
1910                                 &do_not_disturb,
1911                                 &visivility_class,
1912                                 &dnd_schedule_enabled,
1913                                 &dnd_schedule_day,
1914                                 &dnd_start_hour,
1915                                 &dnd_start_min,
1916                                 &dnd_end_hour,
1917                                 &dnd_end_min,
1918                                 &lock_screen_level,
1919                                 &param_uid);
1920
1921         ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
1922         if (ret != NOTIFICATION_ERROR_NONE)
1923                 return ret;
1924
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");
1928                 return ret;
1929         }
1930
1931         ret = notification_setting_db_update_system_setting(do_not_disturb,
1932                                 visivility_class,
1933                                 dnd_schedule_enabled,
1934                                 dnd_schedule_day,
1935                                 dnd_start_hour,
1936                                 dnd_start_min,
1937                                 dnd_end_hour,
1938                                 dnd_end_min,
1939                                 lock_screen_level,
1940                                 param_uid);
1941         if (ret != NOTIFICATION_ERROR_NONE) {
1942                 ERR("Failed to setting db update system setting : %d", ret);
1943                 return ret;
1944         }
1945
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);
1950         }
1951
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;
1956         }
1957
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");
1963         } else {
1964                 _delete_alarm(param_uid);
1965         }
1966
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);
1969         return ret;
1970 }
1971
1972 int notification_add_noti_template(GVariant *parameters, GVariant **reply_body, uid_t uid)
1973 {
1974         notification_h noti;
1975         int ret;
1976         GVariant *body = NULL;
1977         GVariant *coupled_body = NULL;
1978         char *template_name = NULL;
1979         int count = 0;
1980
1981         noti = notification_create(NOTIFICATION_TYPE_NOTI);
1982         if (noti != NULL) {
1983                 g_variant_get(parameters, "(v&s)", &coupled_body, &template_name);
1984                 g_variant_get(coupled_body, "(v)", &body);
1985
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);
1991                         goto out;
1992                 }
1993
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;
1998                         goto out;
1999                 }
2000
2001                 ret = notification_noti_add_template(noti, template_name);
2002                 if (ret != NOTIFICATION_ERROR_NONE)
2003                         ERR("Failed to add a notification [%d]", ret);
2004         } else {
2005                 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
2006         }
2007
2008 out:
2009         if (noti)
2010                 notification_free(noti);
2011
2012         return ret;
2013 }
2014
2015 int notification_get_noti_template(GVariant *parameters, GVariant **reply_body, pid_t pid, uid_t uid)
2016 {
2017         int ret;
2018         char app_id[BUF_LEN] = {0, };
2019         char *template_name = NULL;
2020         notification_h noti;
2021
2022         noti = notification_create(NOTIFICATION_TYPE_NOTI);
2023         if (noti != NULL) {
2024                 g_variant_get(parameters, "(&s)", &template_name);
2025                 INFO("template name[%s]", template_name);
2026
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;
2031                         goto out;
2032                 }
2033
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);
2037                         goto out;
2038                 }
2039
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;
2044                 }
2045         } else {
2046                 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
2047         }
2048
2049 out:
2050         if (noti)
2051                 notification_free(noti);
2052
2053         return ret;
2054 }
2055
2056 int notification_get_noti_package_template(GVariant *parameters, GVariant **reply_body, uid_t uid)
2057 {
2058         int ret;
2059         char *app_id = NULL;
2060         char *template_name = NULL;
2061         notification_h noti;
2062
2063         noti = notification_create(NOTIFICATION_TYPE_NOTI);
2064         if (noti != NULL) {
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);
2070                         goto out;
2071                 }
2072
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;
2077                 }
2078         } else {
2079                 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
2080         }
2081
2082 out:
2083         if (noti)
2084                 notification_free(noti);
2085
2086         return ret;
2087 }
2088
2089 int notification_get_block_state(GVariant *parameters, GVariant **reply_body, uid_t uid)
2090 {
2091         int ret;
2092         int dnd;
2093         int dnd_except;
2094         int allow_to_notify;
2095         char *app_id;
2096         uid_t param_uid;
2097         GVariant *body = NULL;
2098
2099         g_variant_get(parameters, "(&si)", &app_id, &param_uid);
2100
2101         ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
2102         if (ret != NOTIFICATION_ERROR_NONE) {
2103                 ERR("_validate_uid fail [%d]", ret);
2104                 return NOTIFICATION_ERROR_IO_ERROR;
2105         }
2106
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);
2112                 return ret;
2113         }
2114
2115         body = g_variant_new("(iii)", dnd, dnd_except, allow_to_notify);
2116         *reply_body = g_variant_new("(v)", body);
2117
2118         if (*reply_body == NULL) {
2119                 ERR("Failed to make reply_body");
2120                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
2121         }
2122
2123         return ret;
2124 }
2125 int notification_load_dnd_allow_exception(GVariant *parameters, GVariant **reply_body, uid_t uid)
2126 {
2127         int ret;
2128         int count = 0;
2129         int i;
2130         uid_t param_uid;
2131         GVariant *body = NULL;
2132         GVariantBuilder *builder;
2133         dnd_allow_exception_h dnd_allow_exception = NULL;
2134         dnd_allow_exception_h temp;
2135
2136         g_variant_get(parameters, "(i)", &param_uid);
2137
2138         ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
2139         if (ret != NOTIFICATION_ERROR_NONE)
2140                 return ret;
2141
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);
2145                 return ret;
2146         }
2147
2148         builder = g_variant_builder_new(G_VARIANT_TYPE("a(v)"));
2149
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);
2155                 }
2156                 free(dnd_allow_exception);
2157         }
2158
2159         *reply_body = g_variant_new("(ia(v))", count, builder);
2160         g_variant_builder_unref(builder);
2161
2162         if (*reply_body == NULL) {
2163                 ERR("Failed to make reply_body");
2164                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
2165         }
2166
2167         return ret;
2168 }
2169
2170 int notification_update_dnd_allow_exception(GVariant *parameters, GVariant **reply_body, uid_t uid)
2171 {
2172         int ret;
2173         int type;
2174         int value;
2175         uid_t param_uid;
2176
2177         g_variant_get(parameters, "(iii)", &type, &value, &param_uid);
2178
2179         ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
2180         if (ret != NOTIFICATION_ERROR_NONE)
2181                 return ret;
2182
2183         ret = notification_system_setting_update_dnd_allow_exception(type,
2184                         value,
2185                         param_uid);
2186         if (ret != NOTIFICATION_ERROR_NONE) {
2187                 ERR("Failed to update dnd_allow_exception [%d]", ret);
2188                 return ret;
2189         }
2190
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;
2195         }
2196
2197         return ret;
2198 }
2199
2200 static event_sender_info_s *__find_sender_info_by_priv_id(int priv_id)
2201 {
2202         event_sender_info_s *event_info;
2203         GList *find_list;
2204
2205         if (__event_list == NULL)
2206                 return NULL;
2207
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);
2211
2212         if (find_list)
2213                 event_info = g_list_nth_data(find_list, 0);
2214         else
2215                 return NULL;
2216
2217         return event_info;
2218 }
2219
2220 int notification_send_noti_event(GVariant *parameters, GVariant **reply_body)
2221 {
2222         int ret;
2223         int event_type;
2224         int priv_id;
2225         event_sender_info_s *info;
2226         GVariant *coupled_body = NULL;
2227         GVariant *body = NULL;
2228         notification_h noti;
2229
2230         noti = notification_create(NOTIFICATION_TYPE_NOTI);
2231         if (noti != NULL) {
2232                 g_variant_get(parameters, "(vi)", &coupled_body, &event_type);
2233                 g_variant_get(coupled_body, "(v)", &body);
2234
2235                 ret = notification_ipc_make_noti_from_gvariant(noti, body);
2236                 g_variant_unref(coupled_body);
2237                 g_variant_unref(body);
2238
2239                 if (ret != NOTIFICATION_ERROR_NONE) {
2240                         ERR("Failed to make a notification from gvariant");
2241                         goto out;
2242                 }
2243
2244                 ret = notification_get_id(noti, NULL, &priv_id);
2245                 if (ret != NOTIFICATION_ERROR_NONE)
2246                         goto out;
2247
2248                 info = __find_sender_info_by_priv_id(priv_id);
2249                 if (info == NULL || info->busname == NULL) {
2250                         ret = NOTIFICATION_ERROR_INVALID_PARAMETER;
2251                         goto out;
2252                 }
2253
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;
2259                                 goto out;
2260                         } else {
2261                                 info->watcher_id = __insert_sender_watcher_id(info);
2262                         }
2263                 }
2264
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);
2268                         goto out;
2269                 }
2270
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;
2275                 }
2276         } else {
2277                 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
2278         }
2279
2280 out:
2281         if (noti)
2282                 notification_free(noti);
2283
2284         return ret;
2285 }
2286
2287 int notification_send_noti_event_by_priv_id(GVariant *parameters, GVariant **reply_body)
2288 {
2289         int ret;
2290         int event_type;
2291         int priv_id;
2292         bool event_flag = false;
2293         notification_h noti;
2294         GVariant *body = NULL;
2295         event_sender_info_s *info;
2296
2297         noti = notification_create(NOTIFICATION_TYPE_NOTI);
2298         if (noti != NULL) {
2299                 g_variant_get(parameters, "(ii)", &priv_id, &event_type);
2300
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);
2304                         goto out;
2305                 }
2306
2307                 ret = notification_get_event_flag(noti, &event_flag);
2308                 if (ret != NOTIFICATION_ERROR_NONE || event_flag == false) {
2309                         ret = NOTIFICATION_ERROR_INVALID_PARAMETER;
2310                         goto out;
2311                 }
2312
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);
2317                         goto out;
2318                 }
2319
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;
2325                                 goto out;
2326                         } else {
2327                                 info->watcher_id = __insert_sender_watcher_id(info);
2328                         }
2329                 }
2330
2331                 body = notification_ipc_make_gvariant_from_noti(noti, false);
2332                 if (body == NULL) {
2333                         ERR("Can't make gvariant to noti");
2334                         ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
2335                         goto out;
2336                 }
2337
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;
2343                 }
2344         } else {
2345                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
2346         }
2347
2348 out:
2349         if (noti)
2350                 notification_free(noti);
2351
2352         return ret;
2353 }
2354
2355 int notification_check_event_receiver(GVariant *parameters, GVariant **reply_body)
2356 {
2357         int priv_id;
2358         bool available = false;
2359         GList *find_list = NULL;
2360         event_sender_info_s *info = NULL;
2361
2362         g_variant_get(parameters, "(i)", &priv_id);
2363         INFO("priv_id[%d]", priv_id);
2364
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);
2368         if (find_list) {
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);
2374                         } else {
2375                                 available = true;
2376                                 info->watcher_id = __insert_sender_watcher_id(info);
2377                         }
2378                 } else {
2379                         available = true;
2380                 }
2381         }
2382
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;
2387         }
2388
2389         INFO("Receiver available[%d]", available);
2390         return NOTIFICATION_ERROR_NONE;
2391 }
2392
2393 int notification_reset_event_receiver(GVariant *parameters, GVariant **reply_body, const char *sender)
2394 {
2395         int priv_id;
2396
2397         g_variant_get(parameters, "(i)", &priv_id);
2398         INFO("priv_id[%d]", priv_id);
2399
2400         __add_sender_info(priv_id, sender);
2401
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;
2406         }
2407
2408         return NOTIFICATION_ERROR_NONE;
2409 }
2410
2411 HAPI int notification_delete_noti_by_app_id(const char *app_id, uid_t uid)
2412 {
2413         GVariant *deleted_noti_list;
2414         GVariantBuilder *builder;
2415         int num_deleted = 0;
2416         int *list_deleted = NULL;
2417         int ret;
2418         int i;
2419
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);
2423                 goto out;
2424         }
2425
2426         if (num_deleted > 0) {
2427                 builder = g_variant_builder_new(G_VARIANT_TYPE("a(i)"));
2428
2429                 for (i = 0; i < num_deleted; i++)
2430                         g_variant_builder_add(builder, "(i)", *(list_deleted + i));
2431
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);
2438                         goto out;
2439                 }
2440
2441                 for (i = 0; i < num_deleted; i++) {
2442                         ret = __delete_sender_info(*(list_deleted + i));
2443                         if (ret != NOTIFICATION_ERROR_NONE)
2444                                 goto out;
2445                 }
2446         }
2447 out:
2448         if (list_deleted != NULL)
2449                 free(list_deleted);
2450         return ret;
2451 }
2452
2453 static int _check_dnd_schedule(uid_t uid)
2454 {
2455         int ret;
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;
2463
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);
2467                 return ret;
2468         }
2469
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);
2474                 goto out;
2475         }
2476
2477         if (dnd_schedule_enabled) {
2478                 ret = notification_system_setting_dnd_schedule_get_day(setting,
2479                                 &dnd_schedule_day);
2480                 if (ret != NOTIFICATION_ERROR_NONE) {
2481                         ERR("system_setting_dnd_schedule_get_day fail [%d]", ret);
2482                         goto out;
2483                 }
2484
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);
2489                         goto out;
2490                 }
2491
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);
2496                         goto out;
2497                 }
2498
2499                 _add_alarm(dnd_schedule_day, dnd_start_hour, dnd_start_min, dnd_end_hour, dnd_end_min, uid);
2500         }
2501
2502 out:
2503         notification_system_setting_free_system_setting(setting);
2504
2505         return ret;
2506 }
2507
2508 static gboolean __refresh_setting_table(gpointer data)
2509 {
2510         notification_setting_refresh_setting_table(
2511                 tzplatform_getuid(TZ_SYS_DEFAULT_USER));
2512         return G_SOURCE_REMOVE;
2513 }
2514
2515 /*!
2516  * MAIN THREAD
2517  * Do not try to do any other operation in these functions
2518  */
2519 HAPI int notification_service_init(void)
2520 {
2521 #define DEFAULT_VIEWER_CONF_FILE "/usr/share/notification/notification.ini"
2522
2523         int ret, i;
2524         int count = 0;
2525         uid_t *uids = NULL;
2526
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);
2531                 return ret;
2532         }
2533
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;
2538         }
2539
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));
2543
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]);
2548         }
2549         if (uids)
2550                 free(uids);
2551
2552         g_idle_add(__refresh_setting_table, NULL);
2553
2554         INFO("Successfully initialized");
2555         return NOTIFICATION_ERROR_NONE;
2556 }
2557
2558 HAPI int notification_service_fini(void)
2559 {
2560         pkgmgr_fini();
2561         DBG("Successfully Finalized");
2562         return NOTIFICATION_ERROR_NONE;
2563 }
2564
2565 /* End of a file */