Fix notification dnd alarm setting
[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 <dlog.h>
21 #include <sys/smack.h>
22 #include <pkgmgr-info.h>
23
24 #include <notification.h>
25 #include <gio/gio.h>
26 #include <alarm.h>
27 #include <aul.h>
28
29 #include "pkgmgr.h"
30 #include "service_common.h"
31 #include "notification_service.h"
32 #include "debug.h"
33
34 #include <notification_noti.h>
35 #include <notification_internal.h>
36 #include <notification_ipc.h>
37 #include <notification_setting_service.h>
38 #include <notification_db.h>
39
40 #define PROVIDER_NOTI_INTERFACE_NAME "org.tizen.data_provider_noti_service"
41 #define PROVIDER_NOTI_EVENT_INTERFACE_NAME "org.tizen.data_provider_noti_event_service"
42 #define NOTI_TEMPLATE_LIMIT 10
43 #define BUF_LEN 256
44
45 typedef struct _dnd_alarm_id dnd_alarm_id_s;
46
47 static GHashTable *_monitoring_hash;
48 static int _update_noti(GVariant **reply_body, notification_h noti, uid_t uid);
49
50 static GList *_dnd_alarm_id_list;
51
52 typedef struct _dnd_alarm_id {
53         uid_t uid;
54         alarm_id_t dnd_start_id;
55         alarm_id_t dnd_end_id;
56 } dnd_alarm_id_s;
57
58 static GList *__event_list = NULL;
59
60 typedef struct _event_sender_info {
61         int priv_id;
62         char *busname;
63         guint watcher_id;
64 } event_sender_info_s;
65
66 /*!
67  * SERVICE HANDLER
68  */
69
70 /*!
71  * NOTIFICATION SERVICE INITIALIZATION
72  */
73
74 static void _on_name_appeared(GDBusConnection *connection,
75                 const gchar     *name,
76                 const gchar     *name_owner,
77                 gpointer         user_data)
78 {
79         monitoring_info_s *info = (monitoring_info_s *)user_data;
80
81         DbgPrint("name appeared name : %s, uid : %d", name, info->uid);
82 }
83
84 static void _on_name_vanished(GDBusConnection *connection,
85                 const gchar     *name,
86                 gpointer         user_data)
87 {
88         DbgPrint("name vanished : %s", name);
89         monitoring_info_s *info = (monitoring_info_s *)user_data;
90         if (info) {
91                 DbgPrint("name vanished uid : %d", info->uid);
92                 g_bus_unwatch_name(info->watcher_id);
93                 delete_monitoring_list(&_monitoring_hash, info->bus_name, info->uid);
94
95                 if (info->bus_name)
96                         free(info->bus_name);
97                 free(info);
98         }
99 }
100
101 static void _noti_dbus_method_call_handler(GDBusConnection *conn,
102                 const gchar *sender, const gchar *object_path,
103                 const gchar *iface_name, const gchar *method_name,
104                 GVariant *parameters, GDBusMethodInvocation *invocation,
105                 gpointer user_data)
106 {
107         /* TODO : sender authority(privilege) check */
108         DbgPrint("notification method_name: %s, sender : %s ", method_name, sender);
109
110         GVariant *reply_body = NULL;
111         int ret = NOTIFICATION_ERROR_INVALID_OPERATION;
112         uid_t uid = get_sender_uid(sender);
113         pid_t pid = get_sender_pid(sender);
114
115         if (g_strcmp0(method_name, "noti_service_register") == 0)
116                 ret = service_register(parameters, &reply_body, sender,
117                                 _on_name_appeared, _on_name_vanished, &_monitoring_hash, uid);
118         else if (g_strcmp0(method_name, "update_noti") == 0)
119                 ret = notification_update_noti(parameters, &reply_body, uid);
120         else if (g_strcmp0(method_name, "add_noti") == 0)
121                 ret = notification_add_noti(parameters, &reply_body, sender, uid);
122         else if (g_strcmp0(method_name, "refresh_noti") == 0)
123                 ret = notification_refresh_noti(parameters, &reply_body, uid);
124         else if (g_strcmp0(method_name, "del_noti_single") == 0)
125                 ret = notification_del_noti_single(parameters, &reply_body, uid);
126         else if (g_strcmp0(method_name, "del_noti_multiple") == 0)
127                 ret = notification_del_noti_multiple(parameters, &reply_body, uid);
128         else if (g_strcmp0(method_name, "get_noti_count") == 0)
129                 ret = notification_get_noti_count(parameters, &reply_body, uid);
130         else if (g_strcmp0(method_name, "update_noti_setting") == 0)
131                 ret = notification_update_noti_setting(parameters, &reply_body, uid);
132         else if (g_strcmp0(method_name, "update_noti_sys_setting") == 0)
133                 ret = notification_update_noti_sys_setting(parameters, &reply_body, uid);
134         else if (g_strcmp0(method_name, "load_noti_by_tag") == 0)
135                 ret = notification_load_noti_by_tag(parameters, &reply_body, uid);
136         else if (g_strcmp0(method_name, "load_noti_by_priv_id") == 0)
137                 ret = notification_load_noti_by_priv_id(parameters, &reply_body, uid);
138         else if (g_strcmp0(method_name, "load_noti_grouping_list") == 0)
139                 ret = notification_load_grouping_list(parameters, &reply_body, uid);
140         else if (g_strcmp0(method_name, "load_noti_detail_list") == 0)
141                 ret = notification_load_detail_list(parameters, &reply_body, uid);
142         else if (g_strcmp0(method_name, "get_setting_array") == 0)
143                 ret = notification_get_setting_array(parameters, &reply_body, uid);
144         else if (g_strcmp0(method_name, "get_setting_by_appid") == 0)
145                 ret = notification_get_setting_by_appid(parameters, &reply_body, uid);
146         else if (g_strcmp0(method_name, "load_system_setting") == 0)
147                 ret = notification_load_system_setting(parameters, &reply_body, uid);
148         else if (g_strcmp0(method_name, "save_as_template") == 0)
149                 ret = notification_add_noti_template(parameters, &reply_body, uid);
150         else if (g_strcmp0(method_name, "create_from_template") == 0)
151                 ret = notification_get_noti_template(parameters, &reply_body, pid, uid);
152         else if (g_strcmp0(method_name, "create_from_package_template") == 0)
153                 ret = notification_get_noti_package_template(parameters, &reply_body, uid);
154         else if (g_strcmp0(method_name, "get_noti_block_state") == 0)
155                 ret = notification_get_block_state(parameters, &reply_body, uid);
156         else if (g_strcmp0(method_name, "load_dnd_allow_exception") == 0)
157                 ret = notification_load_dnd_allow_exception(parameters, &reply_body, uid);
158         else if (g_strcmp0(method_name, "update_dnd_allow_exception") == 0)
159                 ret = notification_update_dnd_allow_exception(parameters, &reply_body, uid);
160         else if (g_strcmp0(method_name, "send_noti_event") == 0)
161                 ret = notification_send_noti_event(parameters, &reply_body);
162         else if (g_strcmp0(method_name, "check_event_receiver") == 0)
163                 ret = notification_check_event_receiver(parameters, &reply_body);
164         else if (g_strcmp0(method_name, "reset_event_handler") == 0)
165                 ret = notification_reset_event_receiver(parameters, &reply_body, sender);
166
167         if (ret == NOTIFICATION_ERROR_NONE) {
168                 DbgPrint("notification service success : %d", ret);
169                 g_dbus_method_invocation_return_value(
170                                 invocation, reply_body);
171         } else {
172                 DbgPrint("notification service fail : %d", ret);
173                 g_dbus_method_invocation_return_error(
174                                 invocation,
175                                 NOTIFICATION_ERROR,
176                                 ret,
177                                 "notification service error");
178         }
179 }
180
181 static const GDBusInterfaceVTable _noti_interface_vtable = {
182                 _noti_dbus_method_call_handler,
183                 NULL,
184                 NULL
185 };
186
187 int notification_register_dbus_interface()
188 {
189         static gchar introspection_xml[] =
190                         "  <node>"
191                         "  <interface name='org.tizen.data_provider_noti_service'>"
192                         "        <method name='noti_service_register'>"
193                         "          <arg type='i' name='uid' direction='in'/>"
194                         "        </method>"
195
196                         "        <method name='add_noti'>"
197                         "          <arg type='v' name='noti' direction='in'/>"
198                         "          <arg type='i' name='priv_id' direction='out'/>"
199                         "        </method>"
200
201                         "        <method name='update_noti'>"
202                         "          <arg type='v' name='noti' direction='in'/>"
203                         "          <arg type='i' name='priv_id' direction='out'/>"
204                         "        </method>"
205
206                         "        <method name='refresh_noti'>"
207                         "          <arg type='i' name='uid' direction='in'/>"
208                         "        </method>"
209
210                         "        <method name='del_noti_single'>"
211                         "          <arg type='s' name='pkgname' direction='in'/>"
212                         "          <arg type='i' name='priv_id' direction='in'/>"
213                         "          <arg type='i' name='uid' direction='in'/>"
214                         "          <arg type='i' name='priv_id' direction='out'/>"
215                         "        </method>"
216
217                         "        <method name='del_noti_multiple'>"
218                         "          <arg type='s' name='pkgname' direction='in'/>"
219                         "          <arg type='i' name='priv_id' direction='in'/>"
220                         "          <arg type='i' name='uid' direction='in'/>"
221                         "          <arg type='i' name='priv_id' direction='out'/>"
222                         "        </method>"
223
224                         "        <method name='load_noti_by_tag'>"
225                         "          <arg type='s' name='pkgname' direction='in'/>"
226                         "          <arg type='s' name='tag' direction='in'/>"
227                         "          <arg type='i' name='uid' direction='in'/>"
228                         "          <arg type='v' name='noti' direction='out'/>"
229                         "        </method>"
230
231                         "        <method name='load_noti_by_priv_id'>"
232                         "          <arg type='s' name='pkgname' direction='in'/>"
233                         "          <arg type='i' name='priv_id' direction='in'/>"
234                         "          <arg type='i' name='uid' direction='in'/>"
235                         "          <arg type='v' name='noti' direction='out'/>"
236                         "        </method>"
237
238                         "        <method name='load_noti_grouping_list'>"
239                         "          <arg type='i' name='type' direction='in'/>"
240                         "          <arg type='i' name='count' direction='in'/>"
241                         "          <arg type='i' name='uid' direction='in'/>"
242                         "          <arg type='a(v)' name='noti_list' direction='out'/>"
243                         "        </method>"
244
245                         "        <method name='load_noti_detail_list'>"
246                         "          <arg type='s' name='pkgname' direction='in'/>"
247                         "          <arg type='i' name='group_id' direction='in'/>"
248                         "          <arg type='i' name='priv_id' direction='in'/>"
249                         "          <arg type='i' name='count' direction='in'/>"
250                         "          <arg type='i' name='uid' direction='in'/>"
251                         "          <arg type='a(v)' name='noti_list' direction='out'/>"
252                         "        </method>"
253
254                         "        <method name='get_noti_count'>"
255                         "          <arg type='i' name='type' direction='in'/>"
256                         "          <arg type='s' name='pkgname' direction='in'/>"
257                         "          <arg type='i' name='group_id' direction='in'/>"
258                         "          <arg type='i' name='priv_id' direction='in'/>"
259                         "          <arg type='i' name='uid' direction='in'/>"
260                         "          <arg type='i' name='ret_count' direction='out'/>"
261                         "        </method>"
262
263                         "        <method name='update_noti_setting'>"
264                         "          <arg type='s' name='pkgname' direction='in'/>"
265                         "          <arg type='s' name='appid' direction='in'/>"
266                         "          <arg type='i' name='allow_to_notify' direction='in'/>"
267                         "          <arg type='i' name='do_not_disturb_except' direction='in'/>"
268                         "          <arg type='i' name='visibility_class' direction='in'/>"
269                         "          <arg type='i' name='pop_up_notification' direction='in'/>"
270                         "          <arg type='i' name='lock_screen_content_level' direction='in'/>"
271                         "          <arg type='i' name='uid' direction='in'/>"
272                         "        </method>"
273
274                         "        <method name='update_noti_sys_setting'>"
275                         "          <arg type='i' name='do_not_disturb' direction='in'/>"
276                         "          <arg type='i' name='visibility_class' direction='in'/>"
277                         "          <arg type='i' name='dnd_schedule_enabled' direction='in'/>"
278                         "          <arg type='i' name='dnd_schedule_day' direction='in'/>"
279                         "          <arg type='i' name='dnd_start_hour' direction='in'/>"
280                         "          <arg type='i' name='dnd_start_min' direction='in'/>"
281                         "          <arg type='i' name='dnd_end_hour' direction='in'/>"
282                         "          <arg type='i' name='dnd_end_min' direction='in'/>"
283                         "          <arg type='i' name='lock_screen_level' direction='in'/>"
284                         "          <arg type='i' name='uid' direction='in'/>"
285                         "        </method>"
286
287                         "        <method name='get_setting_array'>"
288                         "          <arg type='i' name='uid' direction='in'/>"
289                         "          <arg type='i' name='setting_cnt' direction='out'/>"
290                         "          <arg type='a(v)' name='setting_arr' direction='out'/>"
291                         "        </method>"
292
293                         "        <method name='get_setting_by_appid'>"
294                         "          <arg type='s' name='appid' direction='in'/>"
295                         "          <arg type='i' name='uid' direction='in'/>"
296                         "          <arg type='v' name='setting' direction='out'/>"
297                         "        </method>"
298
299                         "        <method name='load_system_setting'>"
300                         "          <arg type='i' name='uid' direction='in'/>"
301                         "          <arg type='v' name='setting' direction='out'/>"
302                         "        </method>"
303
304                         "        <method name='save_as_template'>"
305                         "          <arg type='v' name='noti' direction='in'/>"
306                         "          <arg type='s' name='name' direction='in'/>"
307                         "        </method>"
308
309                         "        <method name='create_from_template'>"
310                         "          <arg type='s' name='name' direction='in'/>"
311                         "          <arg type='v' name='noti' direction='out'/>"
312                         "        </method>"
313
314                         "        <method name='create_from_package_template'>"
315                         "          <arg type='s' name='appid' direction='in'/>"
316                         "          <arg type='s' name='name' direction='in'/>"
317                         "          <arg type='v' name='noti' direction='out'/>"
318                         "        </method>"
319
320                         "        <method name='get_noti_block_state'>"
321                         "          <arg type='s' name='appid' direction='in'/>"
322                         "          <arg type='i' name='uid' direction='in'/>"
323                         "          <arg type='v' name='state' direction='out'/>"
324                         "        </method>"
325
326                         "        <method name='update_dnd_allow_exception'>"
327                         "          <arg type='i' name='type' direction='in'/>"
328                         "          <arg type='i' name='value' direction='in'/>"
329                         "          <arg type='i' name='uid' direction='in'/>"
330                         "        </method>"
331
332                         "        <method name='load_dnd_allow_exception'>"
333                         "          <arg type='i' name='uid' direction='in'/>"
334                         "          <arg type='i' name='count' direction='out'/>"
335                         "          <arg type='a(v)' name='dnd_allow_exception' direction='out'/>"
336                         "        </method>"
337
338                         "        <method name='send_noti_event'>"
339                         "          <arg type='v' name='noti' direction='in'/>"
340                         "          <arg type='i' name='event_type' direction='in'/>"
341                         "        </method>"
342
343                         "        <method name='check_event_receiver'>"
344                         "          <arg type='i' name='priv_id' direction='in'/>"
345                         "          <arg type='i' name='available' direction='out'/>"
346                         "        </method>"
347
348                         "        <method name='reset_event_handler'>"
349                         "          <arg type='i' name='priv_id' direction='in'/>"
350                         "        </method>"
351
352                         "        <method name='post_toast'>"
353                         "        </method>"
354                         "  </interface>"
355                         "  </node>";
356
357         return service_common_register_dbus_interface(introspection_xml, _noti_interface_vtable);
358 }
359
360 static void __free_event_info(gpointer data)
361 {
362         event_sender_info_s *info = (event_sender_info_s *)data;
363
364         if (info) {
365                 if (info->busname)
366                         free(info->busname);
367                 free(info);
368         }
369 }
370
371 static gint __priv_id_compare(gconstpointer a, gconstpointer b)
372 {
373         event_sender_info_s *info = NULL;
374
375         if (!a)
376                 return -1;
377
378         info = (event_sender_info_s *)a;
379
380         if (info->priv_id == GPOINTER_TO_INT(b))
381                 return 0;
382
383         return 1;
384 }
385
386 /* add noti */
387 static int _add_noti(GVariant **reply_body, notification_h noti, uid_t uid)
388 {
389         int ret;
390         int priv_id = NOTIFICATION_PRIV_ID_NONE;
391         GVariant *body = NULL;
392
393         print_noti(noti);
394         ret = notification_noti_insert(noti);
395         if (ret != NOTIFICATION_ERROR_NONE) {
396                 ErrPrint("failed to update a notification:%d\n", ret);
397                 return ret;
398         }
399
400         ret = notification_get_id(noti, NULL, &priv_id);
401         if (ret != NOTIFICATION_ERROR_NONE) {
402                 ErrPrint("failed to gets priv_id:%d\n", ret);
403                 return ret;
404         }
405
406         body = notification_ipc_make_gvariant_from_noti(noti, true);
407         if (body == NULL) {
408                 ErrPrint("cannot make gvariant to noti");
409                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
410         }
411
412         ret = send_notify(body, "add_noti_notify", &_monitoring_hash, PROVIDER_NOTI_INTERFACE_NAME, uid);
413         g_variant_unref(body);
414
415         if (ret != NOTIFICATION_ERROR_NONE) {
416                 ErrPrint("failed to send notify:%d\n", ret);
417                 return ret;
418         }
419
420         *reply_body = g_variant_new("(i)", priv_id);
421         if (*reply_body == NULL) {
422                 ErrPrint("cannot make reply_body");
423                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
424         }
425
426         DbgPrint("_insert_noti done !!");
427         return ret;
428 }
429
430 static int _validate_and_set_noti_with_uid(uid_t uid, notification_h noti, uid_t *noti_uid)
431 {
432         int ret = NOTIFICATION_ERROR_NONE;
433
434         ret = notification_get_uid(noti, noti_uid);
435         if (ret != NOTIFICATION_ERROR_NONE) {
436                 ErrPrint("notification_get_uid fail ret : %d", ret);
437                 return ret;
438         }
439
440         if (uid > NORMAL_UID_BASE && uid != *noti_uid) {
441                 ErrPrint("invalid seder uid : %d, noti_uid : %d", uid, *noti_uid);
442                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
443         } else if (uid <= NORMAL_UID_BASE) {
444                 if (*noti_uid <= NORMAL_UID_BASE) {
445                         if (*noti_uid != uid)
446                                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
447
448                         DbgPrint("system defualt noti post change noti_uid to default");
449                         /*
450                         IF system (uid <= NORMAL_UID_BASE) try to send noti without specipic destination uid (using notification_pot API)
451                         Send it to default user (TZ_SYS_DEFAULT_USER)
452                         */
453                         *noti_uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
454                         ret = notification_set_uid(noti, *noti_uid);
455                         if (ret != NOTIFICATION_ERROR_NONE) {
456                                 ErrPrint("notification_set_uid fail ret : %d", ret);
457                                 return ret;
458                         }
459                         DbgPrint("changed noti_uid %d", *noti_uid);
460                 }
461         }
462         return ret;
463 }
464
465 static int _validate_and_set_param_uid_with_uid(uid_t uid, uid_t *param_uid)
466 {
467         int ret = NOTIFICATION_ERROR_NONE;
468         if (uid > NORMAL_UID_BASE && uid != *param_uid) {
469                 ErrPrint("invalid seder uid : %d, param_uid : %d", uid, *param_uid);
470                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
471         } else if (uid <= NORMAL_UID_BASE) {
472                 if (*param_uid <= NORMAL_UID_BASE) {
473                         if (*param_uid != uid)
474                                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
475                         /*
476                         IF system (uid <= NORMAL_UID_BASE) try to send noti without specipic destination uid (using notification_pot API)
477                         Send it to default user (TZ_SYS_DEFAULT_USER)
478                         */
479                         *param_uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
480                 }
481         }
482         return ret;
483 }
484
485 static void __sender_name_appeared_cb(GDBusConnection *connection,
486                                       const gchar *name,
487                                       const gchar *name_owner,
488                                       gpointer user_data)
489 {
490         DbgPrint("sender name appeared name: %s, name_owner : %s", name, name_owner);
491 }
492
493 static void __sender_name_vanished_cb(GDBusConnection *connection,
494                                       const gchar *name,
495                                       gpointer user_data)
496 {
497         GList *delete_list = NULL;
498         event_sender_info_s *info;
499
500         if (!user_data)
501                 return;
502
503         info = (event_sender_info_s *)user_data;
504
505         DbgPrint("sender name vanished name : %s, priv_id : %d, watcher_id : %d",
506                  name, info->priv_id, info->watcher_id);
507
508         delete_list = g_list_find_custom(__event_list, GINT_TO_POINTER(info->priv_id),
509                                          (GCompareFunc)__priv_id_compare);
510         if (delete_list) {
511                 __event_list = g_list_remove(__event_list, info);
512                 g_bus_unwatch_name(info->watcher_id);
513                 __free_event_info(info);
514         }
515 }
516
517 static guint __insert_sender_watcher_id(event_sender_info_s *sender_info)
518 {
519         guint watcher_id = 0;
520         watcher_id = g_bus_watch_name(G_BUS_TYPE_SYSTEM,
521                                       sender_info->busname,
522                                       G_BUS_NAME_WATCHER_FLAGS_NONE,
523                                       __sender_name_appeared_cb,
524                                       __sender_name_vanished_cb,
525                                       sender_info,
526                                       NULL);
527         if (!watcher_id) {
528                 ErrPrint("fail to watch sender name");
529                 return 0;
530         }
531
532         DbgPrint("watch on %s success - watcher_id : %d", sender_info->busname, watcher_id);
533         return watcher_id;
534 }
535
536 static void __add_sender_info(int priv_id, const char *busname)
537 {
538         GList *find_list = NULL;
539         event_sender_info_s *sender_info;
540         event_sender_info_s *tmp_info = NULL;
541
542         if (busname == NULL)
543                 return;
544
545         sender_info = (event_sender_info_s *)malloc(sizeof(event_sender_info_s));
546         if (sender_info == NULL) {
547                 ErrPrint("malloc failed");
548                 return;
549         }
550
551         sender_info->priv_id = priv_id;
552         sender_info->busname = strdup(busname);
553
554         if (__event_list == NULL) {
555                 sender_info->watcher_id = __insert_sender_watcher_id(sender_info);
556                 __event_list = g_list_append(__event_list, sender_info);
557         } else {
558                 __event_list = g_list_first(__event_list);
559                 find_list = g_list_find_custom(__event_list, GINT_TO_POINTER(priv_id),
560                                                (GCompareFunc)__priv_id_compare);
561                 if (find_list == NULL) {
562                         sender_info->watcher_id = __insert_sender_watcher_id(sender_info);
563                         __event_list = g_list_append(__event_list, sender_info);
564                 } else {
565                         tmp_info = (event_sender_info_s *)g_list_nth_data(find_list, 0);
566                         if (tmp_info->busname) {
567                                 if (strcmp(tmp_info->busname, busname)) {
568                                         free(tmp_info->busname);
569                                         tmp_info->busname = strdup(busname);
570                                         g_bus_unwatch_name(tmp_info->watcher_id);
571                                         tmp_info->watcher_id = __insert_sender_watcher_id(sender_info);
572                                 }
573                         } else {
574                                 tmp_info->busname = strdup(busname);
575                                 if (!tmp_info->watcher_id)
576                                         g_bus_unwatch_name(tmp_info->watcher_id);
577                                 tmp_info->watcher_id = __insert_sender_watcher_id(tmp_info);
578                         }
579                         __free_event_info(sender_info);
580                 }
581         }
582 }
583
584 int notification_add_noti(GVariant *parameters, GVariant **reply_body, const char *sender, uid_t uid)
585 {
586         int ret;
587         int priv_id;
588         bool event_flag;
589         notification_h noti;
590         GVariant *body = NULL;
591         uid_t noti_uid = 0;
592
593         noti = notification_create(NOTIFICATION_TYPE_NOTI);
594         if (noti != NULL) {
595                 g_variant_get(parameters, "(v)", &body);
596                 ret = notification_ipc_make_noti_from_gvariant(noti, body);
597                 g_variant_unref(body);
598
599                 ret = _validate_and_set_noti_with_uid(uid, noti, &noti_uid);
600                 if (ret != NOTIFICATION_ERROR_NONE)
601                         return ret;
602
603                 ret = notification_noti_check_tag(noti);
604                 if (ret == NOTIFICATION_ERROR_NOT_EXIST_ID)
605                         ret = _add_noti(reply_body, noti, noti_uid);
606                 else if (ret == NOTIFICATION_ERROR_ALREADY_EXIST_ID)
607                         ret = _update_noti(reply_body, noti, noti_uid);
608
609                 ret = notification_get_event_flag(noti, &event_flag);
610                 if (ret != NOTIFICATION_ERROR_NONE)
611                         return ret;
612
613                 if (event_flag == true) {
614                         ret = notification_get_id(noti, NULL, &priv_id);
615                         if (ret != NOTIFICATION_ERROR_NONE)
616                                 return ret;
617
618                         __add_sender_info(priv_id, sender);
619                 }
620                 notification_free(noti);
621         } else {
622                 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
623         }
624
625         DbgPrint("notification_add_noti ret : %d", ret);
626         return ret;
627 }
628
629 /* update noti */
630 static int _update_noti(GVariant **reply_body, notification_h noti, uid_t uid)
631 {
632         int ret;
633         GVariant *body = NULL;
634         int priv_id = NOTIFICATION_PRIV_ID_NONE;
635
636         print_noti(noti);
637         notification_get_id(noti, NULL, &priv_id);
638         DbgPrint("priv_id: [%d]", priv_id);
639
640         ret = notification_noti_update(noti);
641         if (ret != NOTIFICATION_ERROR_NONE)
642                 return ret;
643
644         body = notification_ipc_make_gvariant_from_noti(noti, true);
645         if (body == NULL) {
646                 ErrPrint("cannot make gvariant to noti");
647                 return NOTIFICATION_ERROR_IO_ERROR;
648         }
649
650         ret = send_notify(body, "update_noti_notify", &_monitoring_hash, PROVIDER_NOTI_INTERFACE_NAME, uid);
651         g_variant_unref(body);
652
653         if (ret != NOTIFICATION_ERROR_NONE) {
654                 ErrPrint("failed to send notify:%d\n", ret);
655                 return ret;
656         }
657
658         *reply_body = g_variant_new("(i)", priv_id);
659         if (*reply_body == NULL) {
660                 ErrPrint("cannot make reply_body");
661                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
662         }
663         DbgPrint("_update_noti done !!");
664         return ret;
665 }
666
667 int notification_update_noti(GVariant *parameters, GVariant **reply_body, uid_t uid)
668 {
669         notification_h noti;
670         int ret;
671         GVariant *body = NULL;
672         uid_t noti_uid;
673
674         noti = notification_create(NOTIFICATION_TYPE_NOTI);
675         if (noti != NULL) {
676                 g_variant_get(parameters, "(v)", &body);
677                 ret = notification_ipc_make_noti_from_gvariant(noti, body);
678                 g_variant_unref(body);
679
680                 ret = _validate_and_set_noti_with_uid(uid, noti, &noti_uid);
681                 if (ret != NOTIFICATION_ERROR_NONE)
682                         return ret;
683
684                 if (ret == NOTIFICATION_ERROR_NONE)
685                         ret = _update_noti(reply_body, noti, noti_uid);
686
687                 notification_free(noti);
688         } else {
689                 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
690         }
691         return ret;
692 }
693
694 /* load_noti_by_tag */
695 int notification_load_noti_by_tag(GVariant *parameters, GVariant **reply_body, uid_t uid)
696 {
697         int ret;
698         char *tag = NULL;
699         char *pkgname = NULL;
700         notification_h noti;
701         uid_t param_uid;
702
703         noti = notification_create(NOTIFICATION_TYPE_NOTI);
704         if (noti != NULL) {
705                 g_variant_get(parameters, "(&s&si)", &pkgname, &tag, &param_uid);
706                 ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
707                 if (ret != NOTIFICATION_ERROR_NONE)
708                         return ret;
709
710                 DbgPrint("_load_noti_by_tag pkgname : %s, tag : %s ", pkgname, tag);
711                 ret = notification_noti_get_by_tag(noti, pkgname, tag, param_uid);
712
713                 DbgPrint("notification_noti_get_by_tag ret : %d", ret);
714                 print_noti(noti);
715
716                 *reply_body = notification_ipc_make_gvariant_from_noti(noti, true);
717                 notification_free(noti);
718
719                 if (*reply_body == NULL) {
720                         ErrPrint("cannot make reply_body");
721                         return NOTIFICATION_ERROR_OUT_OF_MEMORY;
722                 }
723         } else {
724                 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
725         }
726         DbgPrint("_load_noti_by_tag done !!");
727         return ret;
728 }
729
730 /* load_noti_by_priv_id */
731 int notification_load_noti_by_priv_id(GVariant *parameters, GVariant **reply_body, uid_t uid)
732 {
733         int ret;
734         int priv_id = NOTIFICATION_PRIV_ID_NONE;
735         char *pkgname = NULL;
736         notification_h noti;
737         uid_t param_uid;
738
739         noti = notification_create(NOTIFICATION_TYPE_NOTI);
740         if (noti != NULL) {
741                 g_variant_get(parameters, "(&sii)", &pkgname, &priv_id, &param_uid);
742                 ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
743                 if (ret != NOTIFICATION_ERROR_NONE)
744                         return ret;
745
746                 DbgPrint("load_noti_by_priv_id pkgname : %s, priv_id : %d ", pkgname, priv_id);
747                 ret = notification_noti_get_by_priv_id(noti, pkgname, priv_id, param_uid);
748
749                 DbgPrint("notification_noti_get_by_priv_id ret : %d", ret);
750                 print_noti(noti);
751
752                 *reply_body = notification_ipc_make_gvariant_from_noti(noti, true);
753                 notification_free(noti);
754
755                 if (*reply_body == NULL) {
756                         ErrPrint("cannot make reply_body");
757                         return NOTIFICATION_ERROR_OUT_OF_MEMORY;
758                 }
759         } else {
760                 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
761         }
762
763         DbgPrint("_load_noti_by_priv_id done !!");
764         return ret;
765 }
766
767 /* load_noti_grouping_list */
768 int notification_load_grouping_list(GVariant *parameters, GVariant **reply_body, uid_t uid)
769 {
770         int ret;
771         notification_h noti;
772         GVariant *body = NULL;
773         notification_type_e type = NOTIFICATION_TYPE_NONE;
774         notification_list_h get_list = NULL;
775         notification_list_h list_iter;
776         GVariantBuilder *builder;
777         int count = 0;
778         uid_t param_uid;
779
780         g_variant_get(parameters, "(iii)", &type, &count, &param_uid);
781         ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
782         if (ret != NOTIFICATION_ERROR_NONE)
783                 return ret;
784         DbgPrint("load grouping list type : %d, count : %d ", type, count);
785
786         ret = notification_noti_get_grouping_list(type, count, &get_list, param_uid);
787         if (ret != NOTIFICATION_ERROR_NONE)
788                 return ret;
789
790         builder = g_variant_builder_new(G_VARIANT_TYPE("a(v)"));
791         if (get_list) {
792                 list_iter = notification_list_get_head(get_list);
793                 do {
794                         noti = notification_list_get_data(list_iter);
795                         body = notification_ipc_make_gvariant_from_noti(noti, true);
796                         g_variant_builder_add(builder, "(v)", body);
797
798                         list_iter = notification_list_get_next(list_iter);
799                 } while (list_iter != NULL);
800
801                 notification_free_list(get_list);
802         }
803
804         *reply_body = g_variant_new("(a(v))", builder);
805         g_variant_builder_unref(builder);
806
807         if (*reply_body == NULL) {
808                 ErrPrint("cannot make reply_body");
809                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
810         }
811
812         DbgPrint("load grouping list done !!");
813         return ret;
814 }
815
816 /* get_setting_array */
817 int notification_get_setting_array(GVariant *parameters, GVariant **reply_body, uid_t uid)
818 {
819         int ret;
820         GVariant *body;
821         GVariantBuilder *builder;
822         int count = 0;
823         int i;
824         notification_setting_h setting_array = NULL;
825         notification_setting_h temp;
826         uid_t param_uid;
827
828         g_variant_get(parameters, "(i)", &param_uid);
829         ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
830         if (ret != NOTIFICATION_ERROR_NONE)
831                 return ret;
832
833         ret = noti_setting_get_setting_array(&setting_array, &count, param_uid);
834         if (ret != NOTIFICATION_ERROR_NONE)
835                 return ret;
836
837         DbgPrint("get setting array : %d", count);
838         builder = g_variant_builder_new(G_VARIANT_TYPE("a(v)"));
839
840         if (setting_array) {
841                 for (i = 0; i < count; i++) {
842                         temp = setting_array + i;
843                         body = notification_ipc_make_gvariant_from_setting(temp);
844                         g_variant_builder_add(builder, "(v)", body);
845
846                         if (temp->package_name)
847                                 free(temp->package_name);
848                         if (temp->appid)
849                                 free(temp->appid);
850                 }
851                 free(setting_array);
852         }
853         *reply_body = g_variant_new("(ia(v))", count, builder);
854         g_variant_builder_unref(builder);
855
856         if (*reply_body == NULL) {
857                 ErrPrint("cannot make reply_body");
858                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
859         }
860         return ret;
861 }
862
863 /* get_setting_by_appid */
864 int notification_get_setting_by_appid(GVariant *parameters, GVariant **reply_body, uid_t uid)
865 {
866         int ret;
867         GVariant *body;
868         char *appid = NULL;
869         notification_setting_h setting = NULL;
870         uid_t param_uid;
871
872         g_variant_get(parameters, "(&si)", &appid, &param_uid);
873         ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
874         if (ret != NOTIFICATION_ERROR_NONE)
875                 return ret;
876         DbgPrint("get setting by appid : %s uid : %d", appid, param_uid);
877
878         ret = noti_setting_service_get_setting_by_appid(appid, &setting, param_uid);
879         if (ret == NOTIFICATION_ERROR_NONE) {
880                 body = notification_ipc_make_gvariant_from_setting(setting);
881                 notification_setting_free_notification(setting);
882
883                 if (body == NULL) {
884                         ErrPrint("fail to make gvariant");
885                         return NOTIFICATION_ERROR_OUT_OF_MEMORY;
886                 }
887         } else {
888                 return ret;
889         }
890
891         *reply_body = g_variant_new("(v)", body);
892         if (*reply_body == NULL) {
893                 ErrPrint("cannot make reply_body");
894                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
895         }
896         return ret;
897 }
898
899 /* load_system_setting */
900 int notification_load_system_setting(GVariant *parameters, GVariant **reply_body, uid_t uid)
901 {
902         int ret;
903         GVariant *body;
904         notification_system_setting_h setting = NULL;
905         uid_t param_uid;
906
907
908         g_variant_get(parameters, "(i)", &param_uid);
909         ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
910         if (ret != NOTIFICATION_ERROR_NONE)
911                 return ret;
912
913         ret = noti_system_setting_load_system_setting(&setting, param_uid);
914         if (ret == NOTIFICATION_ERROR_NONE) {
915                 body = notification_ipc_make_gvariant_from_system_setting(setting);
916                 notification_system_setting_free_system_setting(setting);
917
918                 if (body == NULL) {
919                         ErrPrint("fail to make gvariant");
920                         return NOTIFICATION_ERROR_OUT_OF_MEMORY;
921                 }
922         } else {
923                 return ret;
924         }
925
926         *reply_body = g_variant_new("(v)", body);
927         if (*reply_body == NULL) {
928                 ErrPrint("cannot make reply_body");
929                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
930         }
931         DbgPrint("load system setting done !!");
932         return ret;
933 }
934
935 /* load_noti_detail_list */
936 int notification_load_detail_list(GVariant *parameters, GVariant **reply_body, uid_t uid)
937 {
938         int ret;
939         notification_h noti;
940         GVariant *body = NULL;
941         notification_list_h get_list = NULL;
942         notification_list_h list_iter;
943         GVariantBuilder *builder;
944         char *pkgname = NULL;
945         int group_id = NOTIFICATION_GROUP_ID_NONE;
946         int priv_id = NOTIFICATION_PRIV_ID_NONE;
947         int count = 0;
948         uid_t param_uid;
949
950         g_variant_get(parameters, "(&siiii)", &pkgname, &group_id, &priv_id, &count, &param_uid);
951         ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
952         if (ret != NOTIFICATION_ERROR_NONE)
953                 return ret;
954         DbgPrint("load detail list pkgname : %s, group_id : %d, priv_id : %d, count : %d ",
955                         pkgname, group_id, priv_id, count);
956
957         ret = notification_noti_get_detail_list(pkgname, group_id, priv_id,
958                         count, &get_list, param_uid);
959         if (ret != NOTIFICATION_ERROR_NONE)
960                 return ret;
961
962         builder = g_variant_builder_new(G_VARIANT_TYPE("a(v)"));
963
964         if (get_list) {
965                 list_iter = notification_list_get_head(get_list);
966                 do {
967                         noti = notification_list_get_data(list_iter);
968                         body = notification_ipc_make_gvariant_from_noti(noti, true);
969                         if (body) {
970                                 g_variant_builder_add(builder, "(v)", body);
971                                 list_iter = notification_list_get_next(list_iter);
972                         }
973                 } while (list_iter != NULL);
974                 notification_free_list(get_list);
975         }
976
977         *reply_body = g_variant_new("(a(v))", builder);
978         g_variant_builder_unref(builder);
979
980         if (*reply_body == NULL) {
981                 ErrPrint("cannot make reply_body");
982                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
983         }
984
985         DbgPrint("load detail list done !!");
986         return ret;
987 }
988
989 /* refresh_noti */
990 int notification_refresh_noti(GVariant *parameters, GVariant **reply_body, uid_t uid)
991 {
992         int ret;
993         uid_t param_uid;
994
995         g_variant_get(parameters, "(i)", &param_uid);
996         ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
997         if (ret != NOTIFICATION_ERROR_NONE)
998                 return ret;
999
1000         ret = send_notify(parameters, "refresh_noti_notify", &_monitoring_hash, PROVIDER_NOTI_INTERFACE_NAME, param_uid);
1001         if (ret != NOTIFICATION_ERROR_NONE) {
1002                 ErrPrint("failed to send notify:%d\n", ret);
1003                 return ret;
1004         }
1005
1006         *reply_body = g_variant_new("()");
1007         if (*reply_body == NULL) {
1008                 ErrPrint("cannot make reply_body");
1009                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1010         }
1011
1012         DbgPrint("_refresh_noti_service done !!");
1013         return ret;
1014 }
1015
1016 static int __delete_sender_info(int priv_id)
1017 {
1018         int ret = NOTIFICATION_ERROR_NONE;
1019         event_sender_info_s *info;
1020         GList *delete_list = NULL;
1021         GVariant *body = NULL;
1022
1023         if (__event_list != NULL) {
1024                 __event_list = g_list_first(__event_list);
1025                 delete_list = g_list_find_custom(__event_list, GINT_TO_POINTER(priv_id),
1026                                                  (GCompareFunc)__priv_id_compare);
1027                 if (delete_list != NULL) {
1028                         info = (event_sender_info_s *)g_list_nth_data(delete_list, 0);
1029                         body = g_variant_new("(i)", priv_id);
1030                         ret = send_event_notify_by_busname(body, "delete_noti", info->busname, PROVIDER_NOTI_EVENT_INTERFACE_NAME);
1031                         g_variant_unref(body);
1032                         if (ret != NOTIFICATION_ERROR_NONE) {
1033                                 ErrPrint("failed to send event notify:%d\n", ret);
1034                                 return ret;
1035                         }
1036                         __event_list = g_list_remove(g_list_first(__event_list), info);
1037                         g_bus_unwatch_name(info->watcher_id);
1038                         __free_event_info(info);
1039                         if (g_list_length(__event_list) == 0)
1040                                 __event_list = NULL;
1041                 }
1042         }
1043
1044         return ret;
1045 }
1046
1047 /* del_noti_single */
1048 int notification_del_noti_single(GVariant *parameters, GVariant **reply_body, uid_t uid)
1049 {
1050         int ret;
1051         int num_changes = 0;
1052         int priv_id = NOTIFICATION_PRIV_ID_NONE;
1053         char *pkgname = NULL;
1054         GVariant *body = NULL;
1055         uid_t param_uid;
1056
1057         g_variant_get(parameters, "(&sii)", &pkgname, &priv_id, &param_uid);
1058         ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
1059         if (ret != NOTIFICATION_ERROR_NONE)
1060                 return ret;
1061         ret = notification_noti_delete_by_priv_id_get_changes(pkgname, priv_id, &num_changes, param_uid);
1062         DbgPrint("priv_id: [%d] num_delete:%d\n", priv_id, num_changes);
1063         if (ret != NOTIFICATION_ERROR_NONE) {
1064                 ErrPrint("failed to delete a notification:%d %d\n", ret, num_changes);
1065                 return ret;
1066         }
1067
1068         if (num_changes > 0) {
1069                 body = g_variant_new("(iii)", 1, priv_id, param_uid);
1070                 if (body == NULL) {
1071                         ErrPrint("cannot make gvariant to noti");
1072                         return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1073                 }
1074                 ret = send_notify(body, "delete_single_notify", &_monitoring_hash, PROVIDER_NOTI_INTERFACE_NAME, param_uid);
1075                 g_variant_unref(body);
1076                 if (ret != NOTIFICATION_ERROR_NONE) {
1077                         ErrPrint("failed to send notify:%d\n", ret);
1078                         return ret;
1079                 }
1080
1081                 ret = __delete_sender_info(priv_id);
1082                 if (ret != NOTIFICATION_ERROR_NONE)
1083                         return ret;
1084         }
1085
1086         *reply_body = g_variant_new("(i)", priv_id);
1087         if (*reply_body == NULL) {
1088                 ErrPrint("cannot make reply_body");
1089                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1090         }
1091         DbgPrint("_del_noti_single done !!");
1092         return ret;
1093 }
1094
1095 /* del_noti_multiple */
1096 int notification_del_noti_multiple(GVariant *parameters, GVariant **reply_body, uid_t uid)
1097 {
1098         int ret;
1099         char *pkgname = NULL;
1100         notification_type_e type = NOTIFICATION_TYPE_NONE;
1101         int num_deleted = 0;
1102         int *list_deleted = NULL;
1103         GVariant *deleted_noti_list;
1104         GVariantBuilder *builder;
1105         int i;
1106         uid_t param_uid;
1107
1108         g_variant_get(parameters, "(&sii)", &pkgname, &type, &param_uid);
1109         DbgPrint("pkgname: [%s] type: [%d]\n", pkgname, type);
1110         ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
1111         if (ret != NOTIFICATION_ERROR_NONE)
1112                 return ret;
1113
1114         ret = notification_noti_delete_all(type, pkgname, &num_deleted, &list_deleted, param_uid);
1115
1116         DbgPrint("ret: [%d] num_deleted: [%d]\n", ret, num_deleted);
1117
1118         if (ret != NOTIFICATION_ERROR_NONE) {
1119                 ErrPrint("failed to delete notifications:%d\n", ret);
1120                 if (list_deleted != NULL)
1121                         free(list_deleted);
1122                 return ret;
1123         }
1124
1125         if (num_deleted > 0) {
1126                 builder = g_variant_builder_new(G_VARIANT_TYPE("a(i)"));
1127
1128                 for (i = 0; i < num_deleted; i++)
1129                         g_variant_builder_add(builder, "(i)", *(list_deleted + i));
1130
1131                 deleted_noti_list = g_variant_new("(a(i)i)", builder, param_uid);
1132                 ret = send_notify(deleted_noti_list, "delete_multiple_notify", &_monitoring_hash, PROVIDER_NOTI_INTERFACE_NAME, param_uid);
1133                 g_variant_builder_unref(builder);
1134                 g_variant_unref(deleted_noti_list);
1135                 if (ret != NOTIFICATION_ERROR_NONE) {
1136                         ErrPrint("failed to send notify:%d\n", ret);
1137                         return ret;
1138                 }
1139
1140                 for (i = 0; i < num_deleted; i++) {
1141                         ret = __delete_sender_info(*(list_deleted + i));
1142                         if (ret != NOTIFICATION_ERROR_NONE)
1143                                 return ret;
1144                 }
1145
1146                 free(list_deleted);
1147         }
1148
1149         *reply_body = g_variant_new("(i)", num_deleted);
1150         if (*reply_body == NULL) {
1151                 ErrPrint("cannot make reply_body");
1152                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1153         }
1154
1155         DbgPrint("_del_noti_multiple done !!");
1156         return ret;
1157 }
1158
1159 /* get_noti_count */
1160 int notification_get_noti_count(GVariant *parameters, GVariant **reply_body, uid_t uid)
1161 {
1162         int ret;
1163         notification_type_e type = NOTIFICATION_TYPE_NONE;
1164         char *pkgname = NULL;
1165         int group_id = NOTIFICATION_GROUP_ID_NONE;
1166         int priv_id = NOTIFICATION_PRIV_ID_NONE;
1167         int noti_count = 0;
1168         uid_t param_uid;
1169
1170         g_variant_get(parameters, "(i&siii)", &type, &pkgname, &group_id, &priv_id, &param_uid);
1171         ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
1172         if (ret != NOTIFICATION_ERROR_NONE) {
1173                 ErrPrint("_validate_uid fail ret : %d", ret);
1174                 return NOTIFICATION_ERROR_IO_ERROR;
1175         }
1176
1177         ret = notification_noti_get_count(type, pkgname, group_id, priv_id,
1178                         &noti_count, param_uid);
1179         if (ret != NOTIFICATION_ERROR_NONE) {
1180                 ErrPrint("failed to get count : %d\n", ret);
1181                 return ret;
1182         }
1183
1184         *reply_body = g_variant_new("(i)", noti_count);
1185         if (*reply_body == NULL) {
1186                 ErrPrint("cannot make reply_body");
1187                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1188         }
1189         DbgPrint("_get_noti_property_service done !! %d", ret);
1190         return ret;
1191 }
1192
1193 /* update_noti_setting */
1194 int notification_update_noti_setting(GVariant *parameters, GVariant **reply_body, uid_t uid)
1195 {
1196         int ret;
1197         char *pkgname = NULL;
1198         char *appid = NULL;
1199         int allow_to_notify = 0;
1200         int do_not_disturb_except = 0;
1201         int visivility_class = 0;
1202         int pop_up_notification = 0;
1203         int lock_screen_content_level = 0;
1204         uid_t param_uid;
1205
1206         g_variant_get(parameters, "(&s&siiiiii)",
1207                         &pkgname,
1208                         &appid,
1209                         &allow_to_notify,
1210                         &do_not_disturb_except,
1211                         &visivility_class,
1212                         &pop_up_notification,
1213                         &lock_screen_content_level,
1214                         &param_uid);
1215
1216         ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
1217         if (ret != NOTIFICATION_ERROR_NONE)
1218                 return ret;
1219
1220         DbgPrint("package_name: [%s] appid: [%s] allow_to_notify: [%d] do_not_disturb_except: [%d] visivility_class: [%d] pop_up_notification: [%d] lock_screen_content_level: [%d]\n",
1221                         pkgname, appid, allow_to_notify, do_not_disturb_except, visivility_class, pop_up_notification, lock_screen_content_level);
1222
1223         ret = notification_setting_db_update(pkgname, appid, allow_to_notify, do_not_disturb_except, visivility_class,
1224                                              pop_up_notification, lock_screen_content_level, param_uid);
1225         if (ret != NOTIFICATION_ERROR_NONE) {
1226                 ErrPrint("failed to setting db update : %d\n", ret);
1227                 return ret;
1228         }
1229
1230         *reply_body = g_variant_new("()");
1231         if (*reply_body == NULL) {
1232                 ErrPrint("cannot make reply_body");
1233                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1234         }
1235         DbgPrint("_update_noti_setting_service done !! %d", ret);
1236         return ret;
1237 }
1238
1239 static int _dnd_schedule_alarm_cb(alarm_id_t alarm_id, void *data)
1240 {
1241         int ret;
1242         int do_not_disturb;
1243         bool dnd_id_found = false;
1244         GVariant *body = NULL;
1245         GList *dnd_found_list = NULL;
1246         dnd_alarm_id_s *dnd_id_data = NULL;
1247         uid_t uid;
1248
1249         dnd_found_list = g_list_first(_dnd_alarm_id_list);
1250
1251         for (; dnd_found_list != NULL; dnd_found_list = dnd_found_list->next) {
1252                 dnd_id_data = dnd_found_list->data;
1253                 uid = dnd_id_data->uid;
1254
1255                 ret = noti_system_setting_get_do_not_disturb(&do_not_disturb, uid);
1256                 if (ret != NOTIFICATION_ERROR_NONE) {
1257                         ErrPrint("get do not disturb failed");
1258                         return ret;
1259                 }
1260
1261                 if (alarm_id == dnd_id_data->dnd_start_id && !do_not_disturb) {
1262                         do_not_disturb = 1;
1263                         dnd_id_found = true;
1264                         break;
1265                 } else if (alarm_id == dnd_id_data->dnd_end_id && do_not_disturb) {
1266                         do_not_disturb = 0;
1267                         dnd_id_found = true;
1268                         break;
1269                 }
1270         }
1271
1272         if (dnd_id_found == false) {
1273                 ErrPrint("notification wrong alarm [%d]", alarm_id);
1274                 return -1;
1275         }
1276
1277         notification_setting_db_update_do_not_disturb(do_not_disturb, uid);
1278
1279         body = g_variant_new("(ii)", do_not_disturb, uid);
1280
1281         ret = send_notify(body, "change_dnd_notify", &_monitoring_hash, PROVIDER_NOTI_INTERFACE_NAME, uid);
1282         g_variant_unref(body);
1283         if (ret != NOTIFICATION_ERROR_NONE) {
1284                 ErrPrint("failed to send notify:%d\n", ret);
1285                 return ret;
1286         }
1287
1288         DbgPrint("_dnd_schedule_alarm_cb done");
1289         return ret;
1290 }
1291
1292 static int _get_current_time(struct tm *date)
1293 {
1294         time_t now;
1295
1296         if (date == NULL) {
1297                 ErrPrint("NOTIFICATION_ERROR_INVALID_PARAMETER");
1298                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1299         }
1300
1301         time(&now);
1302         localtime_r(&now, date);
1303
1304         return NOTIFICATION_ERROR_NONE;
1305 }
1306
1307 static int _noti_system_setting_set_alarm(int week_flag, int hour, int min, alarm_cb_t handler, alarm_id_t *dnd_schedule_alarm_id)
1308 {
1309         int err = NOTIFICATION_ERROR_NONE;
1310         struct tm struct_time;
1311         alarm_entry_t *alarm_info = NULL;
1312         alarm_date_t alarm_time;
1313         alarm_id_t alarm_id = -1;
1314
1315         err = alarmmgr_init("notification");
1316         if (err < 0) {
1317                 ErrPrint("alarmmgr_init failed [%d]", err);
1318                 goto out;
1319         }
1320
1321         err = alarmmgr_set_cb(handler, NULL);
1322         if (err < 0) {
1323                 ErrPrint("alarmmgr_set_cb failed [%d]", err);
1324                 goto out;
1325         }
1326
1327         err = _get_current_time(&struct_time);
1328         if (err != NOTIFICATION_ERROR_NONE) {
1329                 ErrPrint("get_current_time failed");
1330                 goto out;
1331         }
1332
1333         alarm_info = alarmmgr_create_alarm();
1334         if (alarm_info == NULL) {
1335                 ErrPrint("alarmmgr_create_alarm failed");
1336                 goto out;
1337         }
1338
1339         alarm_time.year = struct_time.tm_year + 1900;
1340         alarm_time.month = struct_time.tm_mon + 1;
1341         alarm_time.day = struct_time.tm_mday;
1342         alarm_time.hour = hour;
1343         alarm_time.min = min;
1344         alarm_time.sec = 0;
1345
1346         err = alarmmgr_set_time(alarm_info, alarm_time);
1347         if (err != ALARMMGR_RESULT_SUCCESS) {
1348                 ErrPrint("alarmmgr_set_time failed (%d)", err);
1349                 goto out;
1350         }
1351
1352         if (week_flag) {
1353                 err = alarmmgr_set_repeat_mode(alarm_info, ALARM_REPEAT_MODE_WEEKLY, week_flag);
1354                 if (err != ALARMMGR_RESULT_SUCCESS) {
1355                         ErrPrint("alarmmgr_set_repeat_mode failed [%d]", err);
1356                         goto out;
1357                 }
1358         }
1359
1360         err = alarmmgr_set_type(alarm_info, ALARM_TYPE_VOLATILE);
1361         if (err != ALARMMGR_RESULT_SUCCESS) {
1362                 ErrPrint("alarmmgr_set_type failed [%d]", err);
1363                 goto out;
1364         }
1365
1366         err = alarmmgr_add_alarm_with_localtime(alarm_info, NULL, &alarm_id);
1367         if (err != ALARMMGR_RESULT_SUCCESS) {
1368                 ErrPrint("alarmmgr_add_alarm_with_localtime failed [%d]", err);
1369                 goto out;
1370         }
1371
1372         *dnd_schedule_alarm_id = alarm_id;
1373
1374         DbgPrint("alarm_id [%d]", *dnd_schedule_alarm_id);
1375
1376 out:
1377         if (alarm_info)
1378                 alarmmgr_free_alarm(alarm_info);
1379
1380         return err;
1381 }
1382
1383 static gint _dnd_data_compare(gconstpointer a, gconstpointer b)
1384 {
1385         const dnd_alarm_id_s *data = NULL;
1386
1387         if (!a)
1388                 return -1;
1389         data = a;
1390         if (data->uid == GPOINTER_TO_UINT(b))
1391                 return 0;
1392
1393         return 1;
1394 }
1395
1396 static dnd_alarm_id_s *__malloc_dnd_alarm_id_s(uid_t uid, alarm_id_t start_alarm_id, alarm_id_t end_alarm_id)
1397 {
1398         dnd_alarm_id_s *dnd_id_data = NULL;
1399
1400         dnd_id_data = (dnd_alarm_id_s *)malloc(sizeof(dnd_alarm_id_s));
1401         if (dnd_id_data == NULL) {
1402                 ErrPrint("memory allocation fail");
1403                 return NULL;
1404         }
1405
1406         dnd_id_data->uid = uid;
1407         dnd_id_data->dnd_start_id = start_alarm_id;
1408         dnd_id_data->dnd_end_id = end_alarm_id;
1409
1410         return dnd_id_data;
1411 }
1412
1413 static int _add_alarm(int dnd_schedule_day, int dnd_start_hour, int dnd_start_min, int dnd_end_hour, int dnd_end_min, uid_t uid)
1414 {
1415         int ret = NOTIFICATION_ERROR_NONE;
1416         GList *found_list = NULL;
1417         dnd_alarm_id_s *dnd_id_data = NULL;
1418         alarm_id_t dnd_schedule_start_alarm_id;
1419         alarm_id_t dnd_schedule_end_alarm_id;
1420
1421         ret = _noti_system_setting_set_alarm(dnd_schedule_day,
1422                                 dnd_start_hour, dnd_start_min,
1423                                 _dnd_schedule_alarm_cb,
1424                                 &dnd_schedule_start_alarm_id);
1425         if (ret != NOTIFICATION_ERROR_NONE) {
1426                 ErrPrint("_add_alarm fail %d", ret);
1427                 return ret;
1428         }
1429
1430         if (dnd_end_hour < dnd_start_hour ||
1431             (dnd_end_hour == dnd_start_hour && dnd_end_min <= dnd_start_min)) {
1432                 dnd_schedule_day = (dnd_schedule_day << 1);
1433                 if (dnd_schedule_day & DND_SCHEDULE_WEEK_FLAG_MAX)
1434                         dnd_schedule_day = (dnd_schedule_day & DND_SCHEDULE_WEEK_FLAG_ALL)
1435                                         | DND_SCHEDULE_WEEK_FLAG_SUNDAY;
1436         }
1437
1438         ret = _noti_system_setting_set_alarm(dnd_schedule_day,
1439                                 dnd_end_hour, dnd_end_min,
1440                                 _dnd_schedule_alarm_cb,
1441                                 &dnd_schedule_end_alarm_id);
1442         if (ret != NOTIFICATION_ERROR_NONE) {
1443                 ErrPrint("_add_alarm fail %d", ret);
1444                 return ret;
1445         }
1446
1447         if (_dnd_alarm_id_list == NULL) {
1448                 dnd_id_data = __malloc_dnd_alarm_id_s(uid, dnd_schedule_start_alarm_id, dnd_schedule_end_alarm_id);
1449                 if (!dnd_id_data)
1450                         return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1451                 _dnd_alarm_id_list = g_list_append(_dnd_alarm_id_list, dnd_id_data);
1452         } else {
1453                 found_list = g_list_find_custom(g_list_first(_dnd_alarm_id_list), GUINT_TO_POINTER(uid),
1454                                                 (GCompareFunc)_dnd_data_compare);
1455                 if (found_list) {
1456                         dnd_id_data = g_list_nth_data(found_list, 0);
1457                         if (dnd_id_data->dnd_start_id) {
1458                                 alarmmgr_remove_alarm(dnd_id_data->dnd_start_id);
1459                                 dnd_id_data->dnd_start_id = dnd_schedule_start_alarm_id;
1460                         }
1461                         if (dnd_id_data->dnd_end_id) {
1462                                 alarmmgr_remove_alarm(dnd_id_data->dnd_end_id);
1463                                 dnd_id_data->dnd_end_id = dnd_schedule_end_alarm_id;
1464                         }
1465                 } else {
1466                         dnd_id_data = __malloc_dnd_alarm_id_s(uid, dnd_schedule_start_alarm_id, dnd_schedule_end_alarm_id);
1467                         if (!dnd_id_data)
1468                                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1469                         _dnd_alarm_id_list = g_list_append(_dnd_alarm_id_list, dnd_id_data);
1470                 }
1471         }
1472
1473         return ret;
1474 }
1475
1476 static void _delete_alarm(uid_t uid)
1477 {
1478         GList *found_list = NULL;
1479         dnd_alarm_id_s *dnd_id_data = NULL;
1480
1481         if (_dnd_alarm_id_list == NULL)
1482                 return;
1483
1484         _dnd_alarm_id_list = g_list_first(_dnd_alarm_id_list);
1485         found_list = g_list_find_custom(_dnd_alarm_id_list, GUINT_TO_POINTER(uid),
1486                                         (GCompareFunc)_dnd_data_compare);
1487
1488         if (found_list == NULL)
1489                 return;
1490
1491         dnd_id_data = g_list_nth_data(found_list, 0);
1492
1493         if (dnd_id_data->dnd_start_id)
1494                 alarmmgr_remove_alarm(dnd_id_data->dnd_start_id);
1495         if (dnd_id_data->dnd_end_id)
1496                 alarmmgr_remove_alarm(dnd_id_data->dnd_end_id);
1497
1498         _dnd_alarm_id_list = g_list_remove(g_list_first(_dnd_alarm_id_list), dnd_id_data);
1499         free(dnd_id_data);
1500 }
1501
1502 /* update_noti_sys_setting */
1503 int notification_update_noti_sys_setting(GVariant *parameters, GVariant **reply_body, uid_t uid)
1504 {
1505         int ret;
1506         int pre_do_not_disturb = 0;
1507         int do_not_disturb = 0;
1508         int visivility_class = 0;
1509         int dnd_schedule_enabled = 0;
1510         int dnd_schedule_day = 0;
1511         int dnd_start_hour = 0;
1512         int dnd_start_min = 0;
1513         int dnd_end_hour = 0;
1514         int dnd_end_min = 0;
1515         int lock_screen_level = 0;
1516         uid_t param_uid;
1517         GVariant *body = NULL;
1518
1519         g_variant_get(parameters, "(iiiiiiiiii)",
1520                                 &do_not_disturb,
1521                                 &visivility_class,
1522                                 &dnd_schedule_enabled,
1523                                 &dnd_schedule_day,
1524                                 &dnd_start_hour,
1525                                 &dnd_start_min,
1526                                 &dnd_end_hour,
1527                                 &dnd_end_min,
1528                                 &lock_screen_level,
1529                                 &param_uid);
1530
1531         ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
1532         if (ret != NOTIFICATION_ERROR_NONE)
1533                 return ret;
1534
1535         DbgPrint("do_not_disturb [%d] visivility_class [%d] set_schedule [%d] lock_screen_level [%d]\n",
1536                         do_not_disturb, visivility_class, dnd_schedule_enabled, lock_screen_level);
1537
1538         ret = noti_system_setting_get_do_not_disturb(&pre_do_not_disturb, param_uid);
1539         if (ret != NOTIFICATION_ERROR_NONE) {
1540                 ErrPrint("failed to get do not disturb");
1541                 return ret;
1542         }
1543
1544         ret = notification_setting_db_update_system_setting(do_not_disturb,
1545                                 visivility_class,
1546                                 dnd_schedule_enabled,
1547                                 dnd_schedule_day,
1548                                 dnd_start_hour,
1549                                 dnd_start_min,
1550                                 dnd_end_hour,
1551                                 dnd_end_min,
1552                                 lock_screen_level,
1553                                 param_uid);
1554         if (ret != NOTIFICATION_ERROR_NONE) {
1555                 ErrPrint("failed to setting db update system setting : %d\n", ret);
1556                 return ret;
1557         }
1558
1559         if (pre_do_not_disturb != do_not_disturb) {
1560                 body = g_variant_new("(ii)", do_not_disturb, param_uid);
1561                 ret = send_notify(body, "change_dnd_notify", &_monitoring_hash, PROVIDER_NOTI_INTERFACE_NAME, param_uid);
1562                 g_variant_unref(body);
1563         }
1564
1565         *reply_body = g_variant_new("()");
1566         if (*reply_body == NULL) {
1567                 ErrPrint("cannot make reply_body");
1568                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1569         }
1570
1571         if (dnd_schedule_enabled) {
1572                 ret = _add_alarm(dnd_schedule_day, dnd_start_hour, dnd_start_min,
1573                                 dnd_end_hour, dnd_end_min, param_uid);
1574                 if (ret != NOTIFICATION_ERROR_NONE)
1575                         ErrPrint("failed to add alarm for dnd_schedule");
1576         } else {
1577                 _delete_alarm(param_uid);
1578         }
1579
1580         DbgPrint("_update_noti_sys_setting_service done !! %d", ret);
1581
1582         return ret;
1583 }
1584
1585 int notification_add_noti_template(GVariant *parameters, GVariant **reply_body, uid_t uid)
1586 {
1587         notification_h noti;
1588         int ret;
1589         GVariant *body = NULL;
1590         GVariant *coupled_body = NULL;
1591         char *template_name = NULL;
1592         int count = 0;
1593
1594         noti = notification_create(NOTIFICATION_TYPE_NOTI);
1595         if (noti != NULL) {
1596                 g_variant_get(parameters, "(v&s)", &coupled_body, &template_name);
1597                 g_variant_get(coupled_body, "(v)", &body);
1598
1599                 ret = notification_ipc_make_noti_from_gvariant(noti, body);
1600                 g_variant_unref(coupled_body);
1601                 g_variant_unref(body);
1602                 if (ret != NOTIFICATION_ERROR_NONE) {
1603                         ErrPrint("failed to make a notification:%d\n", ret);
1604                         return ret;
1605                 }
1606
1607                 ret = notification_noti_check_count_for_template(noti, &count);
1608                 if (count > NOTI_TEMPLATE_LIMIT)
1609                         return NOTIFICATION_ERROR_MAX_EXCEEDED;
1610
1611                 ret = notification_noti_add_template(noti, template_name);
1612                 if (ret != NOTIFICATION_ERROR_NONE) {
1613                         ErrPrint("failed to add a notification:%d\n", ret);
1614                         return ret;
1615                 }
1616         } else {
1617                 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
1618         }
1619
1620         return ret;
1621 }
1622
1623 int notification_get_noti_template(GVariant *parameters, GVariant **reply_body, pid_t pid, uid_t uid)
1624 {
1625         int ret;
1626         char appid[BUF_LEN] = {0, };
1627         char *template_name = NULL;
1628         notification_h noti;
1629
1630         noti = notification_create(NOTIFICATION_TYPE_NOTI);
1631         if (noti != NULL) {
1632                 g_variant_get(parameters, "(&s)", &template_name);
1633
1634                 ret = aul_app_get_appid_bypid_for_uid(pid, appid, sizeof(appid), uid);
1635                 if (ret != AUL_R_OK) {
1636                         ErrPrint("failed to get appid:%d", ret);
1637                         return ret;
1638                 }
1639
1640                 ret = notification_noti_get_package_template(noti, appid, template_name);
1641                 if (ret != NOTIFICATION_ERROR_NONE) {
1642                         DbgPrint("failed to get template:%d", ret);
1643                         return ret;
1644                 }
1645
1646                 *reply_body = notification_ipc_make_gvariant_from_noti(noti, false);
1647                 notification_free(noti);
1648
1649                 if (*reply_body == NULL) {
1650                         ErrPrint("cannot make reply_body");
1651                         return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1652                 }
1653         } else {
1654                 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
1655         }
1656
1657         DbgPrint("_get_noti_template done !!");
1658         return ret;
1659 }
1660
1661 int notification_get_noti_package_template(GVariant *parameters, GVariant **reply_body, uid_t uid)
1662 {
1663         int ret;
1664         char *pkgname = NULL;
1665         char *template_name = NULL;
1666         notification_h noti;
1667
1668         noti = notification_create(NOTIFICATION_TYPE_NOTI);
1669         if (noti != NULL) {
1670                 g_variant_get(parameters, "(&s&s)", &pkgname, &template_name);
1671
1672                 ret = notification_noti_get_package_template(noti, pkgname, template_name);
1673                 if (ret != NOTIFICATION_ERROR_NONE) {
1674                         DbgPrint("failed to get template:%d", ret);
1675                         return ret;
1676                 }
1677
1678                 *reply_body = notification_ipc_make_gvariant_from_noti(noti, false);
1679                 notification_free(noti);
1680
1681                 if (*reply_body == NULL) {
1682                         ErrPrint("cannot make reply_body");
1683                         return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1684                 }
1685         } else {
1686                 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
1687         }
1688
1689         DbgPrint("_get_noti_package_template done !!");
1690
1691         return ret;
1692 }
1693
1694 int notification_get_block_state(GVariant *parameters, GVariant **reply_body, uid_t uid)
1695 {
1696         int ret;
1697         int dnd;
1698         int dnd_except;
1699         int allow_to_notify;
1700         char *appid;
1701         uid_t param_uid;
1702         GVariant *body = NULL;
1703
1704         g_variant_get(parameters, "(&si)", &appid, &param_uid);
1705
1706         ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
1707         if (ret != NOTIFICATION_ERROR_NONE) {
1708                 ErrPrint("_validate_uid fail ret : %d", ret);
1709                 return NOTIFICATION_ERROR_IO_ERROR;
1710         }
1711
1712         ret = notification_get_dnd_and_allow_to_notify(appid, &dnd, &dnd_except, &allow_to_notify, param_uid);
1713         if (ret != NOTIFICATION_ERROR_NONE) {
1714                 ErrPrint("failed to get_dnd_and_allow_to_notify : %d\n", ret);
1715                 return ret;
1716         }
1717
1718         body = g_variant_new("(iii)", dnd, dnd_except, allow_to_notify);
1719         *reply_body = g_variant_new("(v)", body);
1720
1721         if (*reply_body == NULL) {
1722                 ErrPrint("cannot make reply_body");
1723                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1724         }
1725
1726         DbgPrint("get notification block state done");
1727         return ret;
1728 }
1729 int notification_load_dnd_allow_exception(GVariant *parameters, GVariant **reply_body, uid_t uid)
1730 {
1731         int ret;
1732         int count = 0;
1733         int i;
1734         uid_t param_uid;
1735         GVariant *body = NULL;
1736         GVariantBuilder *builder;
1737         dnd_allow_exception_h dnd_allow_exception = NULL;
1738         dnd_allow_exception_h temp;
1739
1740         g_variant_get(parameters, "(i)", &param_uid);
1741
1742         ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
1743         if (ret != NOTIFICATION_ERROR_NONE)
1744                 return ret;
1745
1746         ret = notification_system_setting_load_dnd_allow_exception(&dnd_allow_exception, &count, param_uid);
1747         if (ret != NOTIFICATION_ERROR_NONE) {
1748                 ErrPrint("failed to load dnd_allow_exception : %d", ret);
1749                 return ret;
1750         }
1751
1752         builder = g_variant_builder_new(G_VARIANT_TYPE("a(v)"));
1753
1754         if (dnd_allow_exception) {
1755                 for (i = 0; i < count; i++) {
1756                         temp = dnd_allow_exception + i;
1757                         body = notification_ipc_make_gvariant_from_dnd_allow_exception(temp);
1758                         g_variant_builder_add(builder, "(v)", body);
1759                 }
1760                 free(dnd_allow_exception);
1761         }
1762
1763         *reply_body = g_variant_new("(ia(v))", count, builder);
1764         g_variant_builder_unref(builder);
1765
1766         if (*reply_body == NULL) {
1767                 ErrPrint("cannot make reply_body");
1768                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1769         }
1770
1771         DbgPrint("load dnd_allow_exception");
1772         return ret;
1773 }
1774
1775 int notification_update_dnd_allow_exception(GVariant *parameters, GVariant **reply_body, uid_t uid)
1776 {
1777         int ret;
1778         int type;
1779         int value;
1780         uid_t param_uid;
1781
1782         g_variant_get(parameters, "(iii)", &type, &value, &param_uid);
1783
1784         ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
1785         if (ret != NOTIFICATION_ERROR_NONE)
1786                 return ret;
1787
1788         ret = notification_system_setting_update_dnd_allow_exception(type,
1789                         value,
1790                         param_uid);
1791         if (ret != NOTIFICATION_ERROR_NONE) {
1792                 ErrPrint("failed to update dnd_allow_exception : %d", ret);
1793                 return ret;
1794         }
1795
1796         *reply_body = g_variant_new("()");
1797         if (*reply_body == NULL) {
1798                 ErrPrint("cannot make reply_body");
1799                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1800         }
1801
1802         DbgPrint("update dnd_allow_exception");
1803         return ret;
1804 }
1805
1806 static event_sender_info_s *__find_sender_info_by_priv_id(int priv_id)
1807 {
1808         event_sender_info_s *event_info;
1809         GList *find_list;
1810
1811         if (__event_list == NULL)
1812                 return NULL;
1813
1814         __event_list = g_list_first(__event_list);
1815         find_list = g_list_find_custom(__event_list, GINT_TO_POINTER(priv_id),
1816                                        (GCompareFunc)__priv_id_compare);
1817
1818         if (find_list)
1819                 event_info = g_list_nth_data(find_list, 0);
1820         else
1821                 return NULL;
1822
1823         return event_info;
1824 }
1825
1826 int notification_send_noti_event(GVariant *parameters, GVariant **reply_body)
1827 {
1828         int ret;
1829         int event_type;
1830         int priv_id;
1831         event_sender_info_s *info;
1832         GVariant *coupled_body = NULL;
1833         GVariant *body = NULL;
1834         notification_h noti;
1835
1836         noti = notification_create(NOTIFICATION_TYPE_NOTI);
1837
1838         if (noti != NULL) {
1839                 g_variant_get(parameters, "(vi)", &coupled_body, &event_type);
1840                 g_variant_get(coupled_body, "(v)", &body);
1841
1842                 ret = notification_ipc_make_noti_from_gvariant(noti, body);
1843                 if (ret != NOTIFICATION_ERROR_NONE) {
1844                         ErrPrint("failed to make a notification from gvariant");
1845                         return ret;
1846                 }
1847
1848                 g_variant_unref(coupled_body);
1849                 g_variant_unref(body);
1850
1851                 ret = notification_get_id(noti, NULL, &priv_id);
1852                 if (ret != NOTIFICATION_ERROR_NONE)
1853                         return ret;
1854
1855                 info = __find_sender_info_by_priv_id(priv_id);
1856                 if (info == NULL || info->busname == NULL)
1857                         return NOTIFICATION_ERROR_INVALID_PARAMETER;
1858
1859                 if (!info->watcher_id) {
1860                         if (!is_existed_busname(info->busname)) {
1861                                 __event_list = g_list_remove(g_list_first(__event_list), info);
1862                                 __free_event_info(info);
1863                                 return NOTIFICATION_ERROR_IO_ERROR;
1864                         } else {
1865                                 info->watcher_id = __insert_sender_watcher_id(info);
1866                         }
1867                 }
1868
1869                 ret = send_event_notify_by_busname(parameters, "send_event", info->busname, PROVIDER_NOTI_EVENT_INTERFACE_NAME);
1870                 notification_free(noti);
1871
1872         } else {
1873                 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
1874         }
1875
1876         *reply_body = g_variant_new("()");
1877         if (*reply_body == NULL) {
1878                 ErrPrint("cannot make reply body");
1879                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1880         }
1881
1882         DbgPrint("notification_send_noti_event done !! %d", ret);
1883
1884         return ret;
1885 }
1886
1887 int notification_check_event_receiver(GVariant *parameters, GVariant **reply_body)
1888 {
1889         int priv_id;
1890         bool available = false;
1891         GList *find_list = NULL;
1892         event_sender_info_s *info = NULL;
1893
1894         g_variant_get(parameters, "(i)", &priv_id);
1895         DbgPrint("check event sender - priv_id : %d", priv_id);
1896
1897         __event_list = g_list_first(__event_list);
1898         find_list = g_list_find_custom(__event_list, GINT_TO_POINTER(priv_id),
1899                                        (GCompareFunc)__priv_id_compare);
1900         if (find_list) {
1901                 info = g_list_nth_data(find_list, 0);
1902                 if (!info->watcher_id) {
1903                         if (!is_existed_busname(info->busname)) {
1904                                 __event_list = g_list_remove(g_list_first(__event_list), info);
1905                                 __free_event_info(info);
1906                         } else {
1907                                 available = true;
1908                                 info->watcher_id = __insert_sender_watcher_id(info);
1909                         }
1910                 } else {
1911                         available = true;
1912                 }
1913         }
1914
1915         *reply_body = g_variant_new("(i)", (int)available);
1916         if (*reply_body == NULL) {
1917                 ErrPrint("cannot make gvariant to noti");
1918                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1919         }
1920
1921         DbgPrint("notification check event receiver - available[%d]", available);
1922         return NOTIFICATION_ERROR_NONE;
1923 }
1924
1925 int notification_reset_event_receiver(GVariant *parameters, GVariant **reply_body, const char *sender)
1926 {
1927         int priv_id;
1928
1929         g_variant_get(parameters, "(i)", &priv_id);
1930         DbgPrint("reset event sender - priv_id : %d", priv_id);
1931
1932         __add_sender_info(priv_id, sender);
1933
1934         *reply_body = g_variant_new("()");
1935         if (*reply_body == NULL) {
1936                 ErrPrint("cannot make gvariant to noti");
1937                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1938         }
1939
1940         return NOTIFICATION_ERROR_NONE;
1941 }
1942
1943 HAPI int notification_delete_noti_by_appid(const char *appid, uid_t uid)
1944 {
1945         GVariant *deleted_noti_list;
1946         GVariantBuilder *builder;
1947         int num_deleted = 0;
1948         int *list_deleted = NULL;
1949         int ret;
1950         int i;
1951
1952         ret = notification_noti_delete_all(NOTIFICATION_TYPE_NONE, appid, &num_deleted, &list_deleted, uid);
1953         if (ret != NOTIFICATION_ERROR_NONE) {
1954                 ErrPrint("failed to delete notifications:%d\n", ret);
1955                 if (list_deleted != NULL)
1956                         free(list_deleted);
1957                 return ret;
1958         }
1959
1960         if (num_deleted > 0) {
1961                 builder = g_variant_builder_new(G_VARIANT_TYPE("a(i)"));
1962
1963                 for (i = 0; i < num_deleted; i++)
1964                         g_variant_builder_add(builder, "(i)", *(list_deleted + i));
1965
1966                 deleted_noti_list = g_variant_new("(a(i)i)", builder, uid);
1967                 ret = send_notify(deleted_noti_list, "delete_multiple_notify", &_monitoring_hash, PROVIDER_NOTI_INTERFACE_NAME, uid);
1968                 g_variant_builder_unref(builder);
1969                 g_variant_unref(deleted_noti_list);
1970                 if (ret != NOTIFICATION_ERROR_NONE) {
1971                         ErrPrint("failed to send notify:%d\n", ret);
1972                         return ret;
1973                 }
1974
1975                 for (i = 0; i < num_deleted; i++) {
1976                         ret = __delete_sender_info(*(list_deleted + i));
1977                         if (ret != NOTIFICATION_ERROR_NONE)
1978                                 return ret;
1979                 }
1980
1981                 free(list_deleted);
1982         }
1983
1984         return ret;
1985 }
1986
1987 static void _notification_data_init(void)
1988 {
1989         int property = 0;
1990         int priv_id = 0;
1991         char *noti_pkgname = NULL;
1992         notification_h noti = NULL;
1993         notification_list_h noti_list = NULL;
1994         notification_list_h noti_list_head = NULL;
1995         notification_type_e noti_type = NOTIFICATION_TYPE_NONE;
1996
1997         notification_noti_get_grouping_list(NOTIFICATION_TYPE_NONE, -1, &noti_list, NOTIFICATION_GLOBAL_UID);
1998         noti_list_head = noti_list;
1999
2000         while (noti_list != NULL) {
2001                 noti = notification_list_get_data(noti_list);
2002                 if (noti) {
2003                         notification_get_id(noti, NULL, &priv_id);
2004                         notification_get_pkgname(noti, &noti_pkgname);
2005                         notification_get_property(noti, &property);
2006                         notification_get_type(noti, &noti_type);
2007
2008                         if (noti_type == NOTIFICATION_TYPE_ONGOING
2009                             || property & NOTIFICATION_PROP_VOLATILE_DISPLAY) {
2010                                 notification_noti_delete_by_priv_id(noti_pkgname, priv_id);
2011                         }
2012                 }
2013                 noti_list = notification_list_get_next(noti_list);
2014         }
2015
2016         if (noti_list_head != NULL)
2017                 notification_free_list(noti_list_head);
2018 }
2019
2020 static int _check_dnd_schedule(uid_t uid)
2021 {
2022         int ret;
2023         notification_system_setting_h setting = NULL;
2024         bool dnd_schedule_enabled = false;
2025         int dnd_schedule_day = 0;
2026         int dnd_start_hour = 0;
2027         int dnd_start_min = 0;
2028         int dnd_end_hour = 0;
2029         int dnd_end_min = 0;
2030
2031         ret = noti_system_setting_load_system_setting(&setting, uid);
2032         if (ret != NOTIFICATION_ERROR_NONE) {
2033                 ErrPrint("noti_system_setting_load_system_setting fail %d", ret);
2034                 return ret;
2035         }
2036
2037         ret = notification_system_setting_dnd_schedule_get_enabled(setting,
2038                                 &dnd_schedule_enabled);
2039         if (ret != NOTIFICATION_ERROR_NONE) {
2040                 ErrPrint("system_setting_dnd_schedule_get_enabled fail %d", ret);
2041                 goto out;
2042         }
2043
2044         if (dnd_schedule_enabled) {
2045                 ret = notification_system_setting_dnd_schedule_get_day(setting,
2046                                 &dnd_schedule_day);
2047                 if (ret != NOTIFICATION_ERROR_NONE) {
2048                         ErrPrint("system_setting_dnd_schedule_get_day fail %d", ret);
2049                         goto out;
2050                 }
2051
2052                 ret = notification_system_setting_dnd_schedule_get_start_time(setting,
2053                                 &dnd_start_hour, &dnd_start_min);
2054                 if (ret != NOTIFICATION_ERROR_NONE) {
2055                         ErrPrint("system_setting_dnd_schedule_get_start_time fail %d", ret);
2056                         goto out;
2057                 }
2058
2059                 ret = notification_system_setting_dnd_schedule_get_end_time(setting,
2060                                 &dnd_end_hour, &dnd_end_min);
2061                 if (ret != NOTIFICATION_ERROR_NONE) {
2062                         ErrPrint("system_setting_dnd_schedule_get_end_time fail %d", ret);
2063                         goto out;
2064                 }
2065
2066                 _add_alarm(dnd_schedule_day, dnd_start_hour, dnd_start_min, dnd_end_hour, dnd_end_min, uid);
2067         }
2068
2069 out:
2070         notification_system_setting_free_system_setting(setting);
2071
2072         return ret;
2073 }
2074
2075 /*!
2076  * MAIN THREAD
2077  * Do not try to do any other operation in these functions
2078  */
2079 HAPI int notification_service_init(void)
2080 {
2081         int ret, i;
2082         int count = 0;
2083         uid_t *uids = NULL;
2084
2085         _monitoring_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
2086         ret = notification_db_init();
2087         if (ret != NOTIFICATION_ERROR_NONE) {
2088                 ErrPrint("notification db init fail %d", ret);
2089                 return ret;
2090         }
2091
2092         ret = notification_register_dbus_interface();
2093         if (ret != SERVICE_COMMON_ERROR_NONE) {
2094                 ErrPrint("notification register dbus fail %d", ret);
2095                 return NOTIFICATION_ERROR_IO_ERROR;
2096         }
2097
2098         _notification_data_init();
2099         notification_setting_refresh_setting_table(tzplatform_getuid(TZ_SYS_DEFAULT_USER));
2100         notification_system_setting_init_system_setting_table(tzplatform_getuid(TZ_SYS_DEFAULT_USER));
2101
2102         ret = notification_system_setting_get_dnd_schedule_enabled_uid(&uids, &count);
2103         if (ret == NOTIFICATION_ERROR_NONE && count > 0) {
2104                 for (i = 0; i < count; i++)
2105                         _check_dnd_schedule(uids[i]);
2106         }
2107         if (uids)
2108                 free(uids);
2109
2110         DbgPrint("Successfully initiated\n");
2111         return NOTIFICATION_ERROR_NONE;
2112 }
2113
2114 HAPI int notification_service_fini(void)
2115 {
2116         pkgmgr_fini();
2117         DbgPrint("Successfully Finalized\n");
2118         return NOTIFICATION_ERROR_NONE;
2119 }
2120
2121 /* End of a file */