Release version 1.6.27
[platform/core/appfw/data-provider-master.git] / src / badge_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
17 #include <dlog.h>
18 #include <gio/gio.h>
19 #include <sys/smack.h>
20 #include <badge.h>
21 #include <badge_db.h>
22 #include <badge_internal.h>
23 #include <badge_setting.h>
24 #include <badge_setting_service.h>
25 #include <badge_ipc.h>
26 #include <tzplatform_config.h>
27
28 #include "service_common.h"
29 #include "badge_service.h"
30 #include "debug.h"
31
32 #define PROVIDER_BADGE_INTERFACE_NAME "org.tizen.data_provider_badge_service"
33 static GHashTable *_monitoring_hash;
34
35 static void _on_name_appeared(GDBusConnection *connection,
36                 const gchar     *name,
37                 const gchar     *name_owner,
38                 gpointer         user_data)
39 {
40         DBG("name [%s]", name);
41 }
42
43 static void _on_name_vanished(GDBusConnection *connection,
44                 const gchar     *name,
45                 gpointer         user_data)
46 {
47         DBG("name [%s]", name);
48         monitoring_info_s *info = (monitoring_info_s *)user_data;
49
50         if (info) {
51                 DBG("vanished uid [%d]", info->uid);
52                 g_bus_unwatch_name(info->watcher_id);
53                 delete_monitoring_list(&_monitoring_hash, name, info->uid);
54
55                 if (info->bus_name)
56                         free(info->bus_name);
57                 free(info);
58         }
59 }
60
61 static void _badge_dbus_method_call_handler(GDBusConnection *conn,
62                 const gchar *sender, const gchar *object_path,
63                 const gchar *iface_name, const gchar *method_name,
64                 GVariant *parameters, GDBusMethodInvocation *invocation,
65                 gpointer user_data)
66 {
67         DBG("badge method_name [%s]", method_name);
68
69         GVariant *reply_body = NULL;
70         int ret = BADGE_ERROR_INVALID_PARAMETER;
71         uid_t uid = get_sender_uid(sender);
72         pid_t pid = get_sender_pid(sender);
73
74         if (g_strcmp0(method_name, "badge_service_register") == 0)
75                 ret = service_register(parameters, &reply_body, sender,
76                                 _on_name_appeared, _on_name_vanished, &_monitoring_hash, uid);
77         else if (g_strcmp0(method_name, "get_badge_existing") == 0)
78                 ret = badge_get_badge_existing(parameters, &reply_body, uid);
79         else if (g_strcmp0(method_name, "get_list") == 0)
80                 ret = badge_get_badge_list(parameters, &reply_body, uid);
81         else if (g_strcmp0(method_name, "insert_badge") == 0)
82                 ret = badge_insert(parameters, &reply_body, uid);
83         else if (g_strcmp0(method_name, "delete_badge") == 0)
84                 ret = badge_delete(parameters, &reply_body, uid, pid);
85         else if (g_strcmp0(method_name, "set_badge_count") == 0)
86                 ret = badge_set_badge_count(parameters, &reply_body, uid, pid);
87         else if (g_strcmp0(method_name, "get_badge_count") == 0)
88                 ret = badge_get_badge_count(parameters, &reply_body, uid);
89         else if (g_strcmp0(method_name, "set_disp_option") == 0)
90                 ret = badge_set_display_option(parameters, &reply_body, uid);
91         else if (g_strcmp0(method_name, "get_disp_option") == 0)
92                 ret = badge_get_display_option(parameters, &reply_body, sender, uid);
93         else if (g_strcmp0(method_name, "update_badge_setting") == 0)
94                 ret = badge_update_badge_setting(parameters, &reply_body, uid);
95         else if (g_strcmp0(method_name, "get_setting_by_appid") == 0)
96                 ret = badge_get_setting_by_appid(parameters, &reply_body, uid);
97         else if (g_strcmp0(method_name, "init_badge") == 0)
98                 ret = badge_init_display(parameters, &reply_body, uid);
99
100         if (ret == BADGE_ERROR_NONE) {
101                 DBG("Badge service success, method [%s]", method_name);
102                 g_dbus_method_invocation_return_value(
103                                 invocation, reply_body);
104         } else {
105                 ERR("Badge service fail, method_name[%s] err[%d]",
106                         method_name, ret);
107                 g_dbus_method_invocation_return_error(
108                                 invocation,
109                                 BADGE_ERROR,
110                                 ret,
111                                 "badge service error");
112         }
113 }
114
115 static const GDBusInterfaceVTable _badge_interface_vtable = {
116                 _badge_dbus_method_call_handler,
117                 NULL,
118                 NULL
119 };
120
121 int badge_register_dbus_interface(void)
122 {
123         static gchar introspection_xml[] =
124                         "  <node>"
125                         "  <interface name='org.tizen.data_provider_badge_service'>"
126                         "        <method name='badge_service_register'>"
127                         "          <arg type='i' name='uid' direction='in'/>"
128                         "        </method>"
129
130                         "        <method name='get_badge_existing'>"
131                         "          <arg type='s' name='pkgname' direction='in'/>"
132                         "          <arg type='i' name='uid' direction='in'/>"
133                         "          <arg type='i' name='exist' direction='out'/>"
134                         "        </method>"
135
136                         "        <method name='get_list'>"
137                         "          <arg type='i' name='uid' direction='in'/>"
138                         "          <arg type='a(v)' name='badge_list' direction='out'/>"
139                         "        </method>"
140
141                         "        <method name='insert_badge'>"
142                         "          <arg type='s' name='pkgname' direction='in'/>"
143                         "          <arg type='s' name='writable_pkg' direction='in'/>"
144                         "          <arg type='s' name='caller' direction='in'/>"
145                         "          <arg type='i' name='uid' direction='in'/>"
146                         "        </method>"
147
148                         "        <method name='delete_badge'>"
149                         "          <arg type='s' name='pkgname' direction='in'/>"
150                         "          <arg type='s' name='caller' direction='in'/>"
151                         "          <arg type='i' name='uid' direction='in'/>"
152                         "        </method>"
153
154                         "        <method name='set_badge_count'>"
155                         "          <arg type='s' name='pkgname' direction='in'/>"
156                         "          <arg type='s' name='caller' direction='in'/>"
157                         "          <arg type='i' name='count' direction='in'/>"
158                         "          <arg type='i' name='uid' direction='in'/>"
159                         "        </method>"
160
161                         "        <method name='get_badge_count'>"
162                         "          <arg type='s' name='pkgname' direction='in'/>"
163                         "          <arg type='i' name='uid' direction='in'/>"
164                         "          <arg type='i' name='count' direction='out'/>"
165                         "        </method>"
166
167                         "        <method name='set_disp_option'>"
168                         "          <arg type='s' name='pkgname' direction='in'/>"
169                         "          <arg type='s' name='caller' direction='in'/>"
170                         "          <arg type='i' name='is_display' direction='in'/>"
171                         "          <arg type='i' name='uid' direction='in'/>"
172                         "        </method>"
173
174                         "        <method name='get_disp_option'>"
175                         "          <arg type='s' name='pkgname' direction='in'/>"
176                         "          <arg type='i' name='uid' direction='in'/>"
177                         "          <arg type='i' name='is_display' direction='out'/>"
178                         "        </method>"
179
180                         "        <method name='update_badge_setting'>"
181                         "          <arg type='s' name='pkgname' direction='in'/>"
182                         "          <arg type='s' name='appid' direction='in'/>"
183                         "          <arg type='i' name='allow_to_display' direction='in'/>"
184                         "          <arg type='i' name='uid' direction='in'/>"
185                         "        </method>"
186
187                         "        <method name='get_setting_by_appid'>"
188                         "          <arg type='s' name='appid' direction='in'/>"
189                         "          <arg type='i' name='uid' direction='in'/>"
190                         "          <arg type='v' name='setting' direction='out'/>"
191                         "        </method>"
192
193                         "        <method name='init_badge'>"
194                         "          <arg type='i' name='uid' direction='in'/>"
195                         "        </method>"
196
197                         "  </interface>"
198                         "  </node>";
199
200         return service_common_register_dbus_interface(introspection_xml, _badge_interface_vtable);
201 }
202
203 static int _validate_and_set_param_uid_with_uid(uid_t uid, uid_t *param_uid)
204 {
205         if (uid > NORMAL_UID_BASE && uid != *param_uid) {
206                 ERR("Invalid sender uid[%d] param_uid[%d]", uid, *param_uid);
207                 return BADGE_ERROR_INVALID_PARAMETER;
208         } else if (uid <= NORMAL_UID_BASE) {
209                 if (*param_uid <= NORMAL_UID_BASE) {
210                         if (*param_uid != uid)
211                                 return BADGE_ERROR_INVALID_PARAMETER;
212                         *param_uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
213                 }
214         }
215         return BADGE_ERROR_NONE;
216 }
217
218 static void _release_badge_info(gpointer data)
219 {
220         badge_info_s *badge;
221
222         badge = (badge_info_s *)data;
223         if (badge == NULL)
224                 return;
225         if (badge->pkg)
226                 free(badge->pkg);
227         free(badge);
228 }
229
230 /* get_badge_existing */
231 int badge_get_badge_existing(GVariant *parameters, GVariant **reply_body, uid_t uid)
232 {
233         int ret = BADGE_ERROR_NONE;
234         char *pkgname = NULL;
235         bool existing = 0;
236         uid_t param_uid;
237
238         g_variant_get(parameters, "(&si)", &pkgname, &param_uid);
239
240         if (pkgname == NULL)
241                 return BADGE_ERROR_INVALID_PARAMETER;
242
243         ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
244         if (ret != BADGE_ERROR_NONE)
245                 return ret;
246
247         ret = badge_db_is_existing(pkgname, &existing, param_uid);
248         if (ret != BADGE_ERROR_NONE) {
249                 ERR("Failed to get badge existing :%d", ret);
250                 return ret;
251         }
252         INFO("The badge of [%s] exists", pkgname);
253
254         *reply_body = g_variant_new("(i)", existing);
255         if (*reply_body == NULL) {
256                 ERR("Failed to make gvariant");
257                 return BADGE_ERROR_OUT_OF_MEMORY;
258         }
259
260         DBG("result [%d]", ret);
261         return ret;
262 }
263
264 /* get_list */
265 int badge_get_badge_list(GVariant *parameters, GVariant **reply_body, uid_t uid)
266 {
267         GList *badge_list = NULL;
268         GList *iter_list = NULL;
269         GVariant *body = NULL;
270         badge_info_s *badge;
271         GVariantBuilder *builder;
272         int ret;
273         uid_t param_uid;
274
275         g_variant_get(parameters, "(i)", &param_uid);
276
277         ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
278         if (ret != BADGE_ERROR_NONE)
279                 return ret;
280
281         ret = badge_db_get_list(&badge_list, param_uid);
282         if (ret != BADGE_ERROR_NONE) {
283                 ERR("Failed to get list [%d]", ret);
284                 return ret;
285         }
286
287         builder = g_variant_builder_new(G_VARIANT_TYPE("a(v)"));
288         iter_list = g_list_first(badge_list);
289         for (; iter_list != NULL; iter_list = iter_list->next) {
290                 badge = iter_list->data;
291                 body = g_variant_new("(si)", badge->pkg, badge->badge_count);
292                 g_variant_builder_add(builder, "(v)", body);
293         }
294         g_list_free_full(badge_list, (GDestroyNotify)_release_badge_info);
295
296         *reply_body = g_variant_new("(a(v))", builder);
297         g_variant_builder_unref(builder);
298
299         if (*reply_body == NULL) {
300                 ERR("Failed to make reply");
301                 return BADGE_ERROR_OUT_OF_MEMORY;
302         }
303
304         DBG("Success to get badge list");
305         return BADGE_ERROR_NONE;
306 }
307
308 /* insert_badge */
309 int badge_insert(GVariant *parameters, GVariant **reply_body, uid_t uid)
310 {
311         int ret = BADGE_ERROR_NONE;
312         char *pkgname = NULL;
313         char *writable_pkg = NULL;
314         char *caller = NULL;
315         GVariant *body = NULL;
316         uid_t param_uid;
317         int allow_to_display = 0;
318
319         g_variant_get(parameters, "(&s&s&si)", &pkgname, &writable_pkg, &caller, &param_uid);
320
321         ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
322         if (ret != BADGE_ERROR_NONE)
323                 return ret;
324
325         if (pkgname != NULL && writable_pkg != NULL && caller != NULL)
326                 ret = badge_db_insert(pkgname, writable_pkg, caller, param_uid);
327         else
328                 return BADGE_ERROR_INVALID_PARAMETER;
329
330         if (ret != BADGE_ERROR_NONE) {
331                 ERR("Failed to insert badge [%d]", ret);
332                 return ret;
333         }
334
335         ret = badge_db_get_allow_to_display_by_appid(pkgname, &allow_to_display, param_uid);
336         if (ret != BADGE_ERROR_NONE) {
337                 ERR("Failed to get allow_to_display by appid [%d]", ret);
338                 return ret;
339         }
340
341         if (allow_to_display) {
342                 body = g_variant_new("(si)", pkgname, param_uid);
343                 if (body == NULL) {
344                         ERR("Failed to make gvariant");
345                         return BADGE_ERROR_OUT_OF_MEMORY;
346                 }
347
348                 ret = send_notify(body, "insert_badge_notify", &_monitoring_hash, PROVIDER_BADGE_INTERFACE_NAME, param_uid);
349                 g_variant_unref(body);
350
351                 if (ret != BADGE_ERROR_NONE) {
352                         ERR("Failed to send notify [%d]", ret);
353                         return ret;
354                 }
355         }
356
357         *reply_body = g_variant_new("()");
358         if (*reply_body == NULL) {
359                 ERR("Failed to make reply");
360                 return BADGE_ERROR_OUT_OF_MEMORY;
361         }
362
363         INFO("Success, pkgname[%s] writable_pkg[%s] caller[%s]", pkgname, writable_pkg, caller);
364
365         return ret;
366 }
367
368 /* delete_badge */
369 int badge_delete(GVariant *parameters, GVariant **reply_body, uid_t uid, pid_t pid)
370 {
371         int ret = BADGE_ERROR_NONE;
372         char *pkgname = NULL;
373         char *caller = NULL;
374         GVariant *body = NULL;
375         uid_t param_uid;
376
377         g_variant_get(parameters, "(&s&si)", &pkgname, &caller, &param_uid);
378
379         if (pkgname == NULL || caller == NULL)
380                 return BADGE_ERROR_INVALID_PARAMETER;
381
382         ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
383         if (ret != BADGE_ERROR_NONE)
384                 return ret;
385
386         ret = badge_db_delete(pkgname, caller, param_uid, pid);
387         if (ret != BADGE_ERROR_NONE) {
388                 ERR("Failed to delete badge [%d]", ret);
389                 return ret;
390         }
391
392         body = g_variant_new("(si)", pkgname, param_uid);
393         if (body == NULL) {
394                 ERR("Failed to make gvariant");
395                 return BADGE_ERROR_OUT_OF_MEMORY;
396         }
397
398         ret = send_notify(body, "delete_badge_notify", &_monitoring_hash, PROVIDER_BADGE_INTERFACE_NAME, param_uid);
399         g_variant_unref(body);
400
401         if (ret != BADGE_ERROR_NONE) {
402                 ERR("Failed to send notify:%d", ret);
403                 return ret;
404         }
405
406         *reply_body = g_variant_new("()");
407         if (*reply_body == NULL) {
408                 ERR("Failed to make reply");
409                 return BADGE_ERROR_OUT_OF_MEMORY;
410         }
411
412         INFO("success, pkgname[%s] caller[%s]", pkgname, caller);
413
414         return ret;
415 }
416
417 /* set_badge_count */
418 int badge_set_badge_count(GVariant *parameters, GVariant **reply_body, uid_t uid, pid_t pid)
419 {
420         int ret = BADGE_ERROR_NONE;
421         char *pkgname = NULL;
422         char *caller = NULL;
423         unsigned int count = 0;
424         GVariant *body = NULL;
425         uid_t param_uid;
426         int allow_to_display = 0;
427
428         g_variant_get(parameters, "(&s&sii)", &pkgname, &caller, &count, &param_uid);
429
430         if (pkgname == NULL || caller == NULL)
431                 return BADGE_ERROR_INVALID_PARAMETER;
432
433         ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
434         if (ret != BADGE_ERROR_NONE)
435                 return ret;
436
437         ret = badge_db_set_count(pkgname, caller, count, param_uid, pid);
438         if (ret != BADGE_ERROR_NONE) {
439                 ERR("Failed to set badge [%d]", ret);
440                 return ret;
441         }
442
443         ret = badge_db_get_allow_to_display_by_appid(pkgname, &allow_to_display, param_uid);
444         if (ret != BADGE_ERROR_NONE) {
445                 ERR("Failed to get allow_to_display [%d]", ret);
446                 return ret;
447         }
448
449         if (allow_to_display) {
450                 body = g_variant_new("(sii)", pkgname, count, param_uid);
451                 if (body == NULL) {
452                         ERR("Failed to make gvariant");
453                         return BADGE_ERROR_OUT_OF_MEMORY;
454                 }
455
456                 ret = send_notify(body, "set_badge_count_notify", &_monitoring_hash, PROVIDER_BADGE_INTERFACE_NAME, param_uid);
457                 g_variant_unref(body);
458
459                 if (ret != BADGE_ERROR_NONE) {
460                         ERR("Failed to send notify [%d]", ret);
461                         return ret;
462                 }
463         }
464
465         *reply_body = g_variant_new("()");
466         if (*reply_body == NULL) {
467                 ERR("Failed to make reply");
468                 return BADGE_ERROR_OUT_OF_MEMORY;
469         }
470
471         INFO("Success, pkgname[%s] caller[%s] count[%d]", pkgname, caller, count);
472
473         return ret;
474 }
475
476 /* get_badge_count */
477 int badge_get_badge_count(GVariant *parameters, GVariant **reply_body, uid_t uid)
478 {
479         int ret = BADGE_ERROR_NONE;
480         char *pkgname = NULL;
481         unsigned int count = 0;
482         uid_t param_uid;
483
484         g_variant_get(parameters, "(&si)", &pkgname, &param_uid);
485
486         if (pkgname == NULL)
487                 return BADGE_ERROR_INVALID_PARAMETER;
488
489         ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
490         if (ret != BADGE_ERROR_NONE)
491                 return ret;
492
493         ret =  badge_db_get_count(pkgname, &count, param_uid);
494         if (ret != BADGE_ERROR_NONE) {
495                 ERR("Failed to get badge count [%d]", ret);
496                 return ret;
497         }
498
499         *reply_body = g_variant_new("(i)", count);
500         if (*reply_body == NULL) {
501                 ERR("Failed to make gvariant");
502                 return BADGE_ERROR_OUT_OF_MEMORY;
503         }
504
505         INFO("Success, count[%d]", count);
506         return ret;
507 }
508
509 /* set_disp_option */
510 int badge_set_display_option(GVariant *parameters, GVariant **reply_body, uid_t uid)
511 {
512         int ret = BADGE_ERROR_NONE;
513         char *pkgname = NULL;
514         char *caller = NULL;
515         unsigned int is_display = 0;
516         GVariant *body = NULL;
517         uid_t param_uid;
518         int allow_to_display = 0;
519
520         g_variant_get(parameters, "(&s&sii)", &pkgname, &caller, &is_display, &param_uid);
521
522         if (pkgname == NULL || caller == NULL)
523                 return BADGE_ERROR_INVALID_PARAMETER;
524
525         ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
526         if (ret != BADGE_ERROR_NONE)
527                 return ret;
528
529         ret = badge_db_set_display_option(pkgname, is_display, param_uid);
530         if (ret != BADGE_ERROR_NONE) {
531                 ERR("Failed to set display option [%d]", ret);
532                 return ret;
533         }
534
535         ret = badge_db_get_allow_to_display_by_appid(pkgname, &allow_to_display, param_uid);
536         if (ret != BADGE_ERROR_NONE) {
537                 ERR("Failed to get allow_to_display [%d]", ret);
538                 return ret;
539         }
540
541         if (allow_to_display) {
542                 body = g_variant_new("(sii)", pkgname, is_display, param_uid);
543                 if (body == NULL) {
544                         ERR("Failed to make gvariant");
545                         return BADGE_ERROR_OUT_OF_MEMORY;
546                 }
547
548                 ret = send_notify(body, "set_disp_option_notify", &_monitoring_hash, PROVIDER_BADGE_INTERFACE_NAME, param_uid);
549                 g_variant_unref(body);
550
551                 if (ret != BADGE_ERROR_NONE) {
552                         ERR("Failed to send notify [%d]", ret);
553                         return ret;
554                 }
555         }
556
557         *reply_body = g_variant_new("()");
558         if (*reply_body == NULL) {
559                 ERR("Failed to make reply");
560                 return BADGE_ERROR_OUT_OF_MEMORY;
561         }
562
563         INFO("Success, pkgname[%s] caller[%s] is_dispaly[%d]",
564                 pkgname, caller, is_display);
565
566         return ret;
567 }
568
569 static gint __compare_sender(gconstpointer a, gconstpointer b)
570 {
571         if (!a)
572                 return -1;
573
574         return strcmp(a, b);
575 }
576
577 /* get_disp_option */
578 int badge_get_display_option(GVariant *parameters, GVariant **reply_body, const gchar *sender, uid_t uid)
579 {
580         int ret = BADGE_ERROR_NONE;
581         char *pkgname = NULL;
582         unsigned int is_display = 0;
583         int allow_to_display;
584         GList *monitoring_list = NULL;
585         GList *find_list = NULL;
586         uid_t param_uid;
587
588         g_variant_get(parameters, "(&si)", &pkgname, &param_uid);
589
590         if (pkgname == NULL)
591                 return BADGE_ERROR_INVALID_PARAMETER;
592
593         ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
594         if (ret != BADGE_ERROR_NONE)
595                 return ret;
596
597         ret = badge_db_get_display_option(pkgname, &is_display, param_uid);
598         if (ret != BADGE_ERROR_NONE) {
599                 ERR("Failed to get display option [%d]", ret);
600                 return ret;
601         }
602
603         ret = badge_db_get_allow_to_display_by_appid(pkgname, &allow_to_display, param_uid);
604         if (ret != BADGE_ERROR_NONE) {
605                 ERR("Failed to get allow_to_display [%d]", ret);
606                 return ret;
607         }
608
609         if (!allow_to_display) {
610                 monitoring_list = (GList *)g_hash_table_lookup(_monitoring_hash, GUINT_TO_POINTER(param_uid));
611                 monitoring_list = g_list_first(monitoring_list);
612                 find_list = g_list_find_custom(monitoring_list, (gconstpointer)sender,
613                                                (GCompareFunc)__compare_sender);
614                 if (find_list != NULL)
615                         is_display = 0;
616         }
617
618         *reply_body = g_variant_new("(i)", is_display);
619         if (*reply_body == NULL) {
620                 ERR("Failed to make reply");
621                 return BADGE_ERROR_OUT_OF_MEMORY;
622         }
623
624         INFO("Success, display option[%d]", is_display);
625         return ret;
626 }
627
628 static int __badge_emit_fake_signal(char *appid, unsigned int disp_option, uid_t uid)
629 {
630         int ret;
631         GVariant *fake_body = NULL;
632
633         fake_body = g_variant_new("(sii)", appid, disp_option, uid);
634         if (fake_body == NULL) {
635                 ERR("Failed to make gvariant");
636                 return BADGE_ERROR_OUT_OF_MEMORY;
637         }
638
639         ret = send_notify(fake_body, "set_disp_option_notify", &_monitoring_hash, PROVIDER_BADGE_INTERFACE_NAME, uid);
640         g_variant_unref(fake_body);
641         if (ret != BADGE_ERROR_NONE)
642                 ERR("Failed to send notify [%d]", ret);
643
644         return ret;
645 }
646
647 /* update_badge_setting */
648 int badge_update_badge_setting(GVariant *parameters, GVariant **reply_body, uid_t uid)
649 {
650         int ret = BADGE_ERROR_NONE;
651         uid_t param_uid;
652         unsigned int allow_to_display;
653         unsigned int disp_option = 0;
654         char *pkgname = NULL;
655         char *appid = NULL;
656
657         g_variant_get(parameters, "(&s&sii)", &pkgname, &appid, &allow_to_display, &param_uid);
658
659         ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
660         if (ret != BADGE_ERROR_NONE)
661                 return ret;
662
663         ret = badge_db_update_setting(pkgname, appid, allow_to_display, param_uid);
664         if (ret != BADGE_ERROR_NONE) {
665                 ERR("Failed to update badge setting [%d]", ret);
666                 return ret;
667         }
668
669         if (!allow_to_display) {
670                 ret = __badge_emit_fake_signal(appid, allow_to_display, param_uid);
671                 if (ret != BADGE_ERROR_NONE)
672                         return ret;
673         } else {
674                 ret = badge_db_get_display_option(appid, &disp_option, param_uid);
675                 if (ret != BADGE_ERROR_NONE && ret != BADGE_ERROR_NOT_EXIST) {
676                         ERR("Failed to get display_option [%d]", ret);
677                         return ret;
678                 }
679
680                 if (disp_option) {
681                         ret = __badge_emit_fake_signal(appid, disp_option, param_uid);
682                         if (ret != BADGE_ERROR_NONE)
683                                 return ret;
684                 }
685         }
686
687         *reply_body = g_variant_new("()");
688         if (*reply_body == NULL) {
689                 ERR("Failed to make reply_body");
690                 return BADGE_ERROR_OUT_OF_MEMORY;
691         }
692
693         INFO("Success, pkgname[%s], appid[%s]", pkgname, appid);
694         return ret;
695 }
696
697 int badge_get_setting_by_appid(GVariant *parameters, GVariant **reply_body, uid_t uid)
698 {
699         int ret;
700         char *appid = NULL;
701         GVariant *body;
702         badge_setting_h setting = NULL;
703         uid_t param_uid;
704
705         g_variant_get(parameters, "(&si)", &appid, &param_uid);
706
707         if (appid == NULL)
708                 return BADGE_ERROR_INVALID_PARAMETER;
709
710         ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
711         if (ret != NOTIFICATION_ERROR_NONE)
712                 return ret;
713
714         ret = badge_db_get_setting_by_appid(appid, &setting, param_uid);
715         if (ret == BADGE_ERROR_NONE) {
716                 body = badge_ipc_make_gvariant_from_setting(setting);
717                 badge_setting_free_setting(setting);
718                 if (body == NULL) {
719                         ERR("Failed to make gvariant from setting");
720                         return NOTIFICATION_ERROR_OUT_OF_MEMORY;
721                 }
722         } else {
723                 return ret;
724         }
725
726         *reply_body = g_variant_new("(v)", body);
727         if (*reply_body == NULL) {
728                 ERR("Failed to make reply");
729                 return BADGE_ERROR_OUT_OF_MEMORY;
730         }
731
732         INFO("Success, appid[%s]", appid);
733         return ret;
734 }
735
736 /* init badge */
737 int badge_init_display(GVariant *parameters, GVariant **reply_body, uid_t uid)
738 {
739         int ret = BADGE_ERROR_NONE;
740         unsigned int disp_option;
741         int allow_to_display;
742         GList *badge_list = NULL;
743         GList *iter_list  = NULL;
744         GVariant *body = NULL;
745         badge_info_s *badge;
746         uid_t param_uid;
747
748         g_variant_get(parameters, "(i)", &param_uid);
749
750         ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
751         if (ret != BADGE_ERROR_NONE)
752                 return ret;
753
754         ret = badge_db_get_list(&badge_list, param_uid);
755         if (ret != BADGE_ERROR_NONE) {
756                 ERR("Failed to get list [%d]", ret);
757                 return ret;
758         }
759
760         iter_list = g_list_first(badge_list);
761         while (iter_list) {
762                 badge = (badge_info_s *)g_list_nth_data(iter_list, 0);
763                 iter_list = g_list_next(iter_list);
764
765                 ret = badge_db_get_display_option(badge->pkg, &disp_option, param_uid);
766                 if (ret != BADGE_ERROR_NONE) {
767                         ERR("Failed to get display option [%d]", ret);
768                         continue;
769                 }
770
771                 ret = badge_db_get_allow_to_display_by_appid(badge->pkg, &allow_to_display, param_uid);
772                 if (ret != BADGE_ERROR_NONE) {
773                         ERR("Failed to get allow_to_display [%d]", ret);
774                         continue;
775                 }
776
777                 if (disp_option && allow_to_display) {
778                         body = g_variant_new("(sii)", badge->pkg, disp_option, param_uid);
779                         ret = send_notify(body, "set_disp_option_notify", &_monitoring_hash, PROVIDER_BADGE_INTERFACE_NAME, param_uid);
780                         if (ret != BADGE_ERROR_NONE) {
781                                 ERR("Failed to send notify");
782                                 continue;
783                         }
784                         g_variant_unref(body);
785                 }
786         }
787
788         if (badge_list)
789                 g_list_free_full(badge_list, (GDestroyNotify)_release_badge_info);
790
791         *reply_body = g_variant_new("()");
792         if (*reply_body == NULL) {
793                 ERR("Failed to make reply_body");
794                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
795         }
796
797         DBG("result [%d]", ret);
798         return ret;
799 }
800
801 static gboolean __refresh_setting_table(gpointer data)
802 {
803         uid_t uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
804
805         badge_setting_refresh_setting_table(uid);
806         badge_setting_arrange_tables(uid);
807
808         return G_SOURCE_REMOVE;
809 }
810
811 /*!
812  * MAIN THREAD
813  * Do not try to do anyother operation in these functions
814  */
815 HAPI int badge_service_init(void)
816 {
817         int result;
818
819         _monitoring_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
820         result = badge_db_init();
821         if (result != BADGE_ERROR_NONE) {
822                 ERR("Failed to init DB [%d]", result);
823                 return result;
824         }
825
826         result = badge_register_dbus_interface();
827         if (result != SERVICE_COMMON_ERROR_NONE) {
828                 ERR("Failed to register dbus interface [%d]", result);
829                 return BADGE_ERROR_IO_ERROR;
830         }
831
832         g_idle_add(__refresh_setting_table, NULL);
833         INFO("Successfully initialized");
834         return BADGE_ERROR_NONE;
835 }
836
837 HAPI int badge_service_fini(void)
838 {
839         return BADGE_ERROR_NONE;
840 }
841
842 /* End of a file */